1/* Verify that indirect inlining can also remove references of the functions it
2   discovers calls for, even when nodes being inlined are virtual IPA-CP
3   clones.  */
4/* { dg-do compile } */
5/* { dg-options "-O3 -fno-early-inlining -fdump-ipa-cp-details -fdump-ipa-inline -fdump-tree-optimized -fno-ipa-icf"  } */
6
7
8int global;
9
10void __attribute__ ((noinline, noclone, used))
11stuff (int i)
12{
13  global = i;
14}
15
16int __attribute__ ((noinline,noclone)) get_input(void)
17{
18  return 1;
19}
20
21static void
22hooray_1 ()
23{
24  stuff (1);
25}
26
27static inline void
28hip2_1 (void (*g)())
29{
30  int i;
31  g ();
32  /* Some stuff to make the function bigger so that hip1_1 gets inlined
33     fiorst. */
34  for (i = 0; i < get_input (); i++)
35    {
36      stuff (2);
37      stuff (2+2);
38    }
39}
40
41static inline void
42hip1_1 (void (*g)())
43{
44  hip2_1 (g);
45}
46
47static void
48hooray_2 ()
49{
50  stuff (1);
51}
52
53static inline void
54hip2_2 (void (*g)())
55{
56  g ();
57}
58
59static inline void
60hip1_2 (void (*g)())
61{
62  int i;
63
64  hip2_2 (g);
65
66  /* Some stuff to make the function bigger so that hip2_2 gets inlined
67     fiorst. */
68  for (i = 0; i < get_input (); i++)
69    {
70      stuff (2);
71      stuff (2+2);
72    }
73}
74
75int
76main (int argc, int *argv[])
77{
78  int i;
79
80  for (i = 0; i < get_input (); i++)
81    {
82      hip1_1 (hooray_1);
83      hip1_2 (hooray_2);
84    }
85  return 0;
86}
87
88/* { dg-final { scan-ipa-dump-times "removing its cloning-created reference" 2 "cp"  } } */
89/* { dg-final { scan-ipa-dump "ipa-prop: Removed a reference"  "inline"  } } */
90/* { dg-final { scan-ipa-dump-times "ipa-prop: Removing cloning-created reference" 2 "inline"  } } */
91/* { dg-final { scan-tree-dump-not "hooray"  "optimized"  } } */
92/* { dg-final { cleanup-ipa-dump "cp" } } */
93/* { dg-final { cleanup-ipa-dump "inline" } } */
94/* { dg-final { cleanup-tree-dump "optimized" } } */
95