aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/testsuite/g++.dg/tree-prof
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/testsuite/g++.dg/tree-prof')
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_1.C45
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_2.C25
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_3.C25
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_4.C41
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_5.C41
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_6.C53
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_7.C55
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_8.C19
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_split_functions_1.C63
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/indir-call-prof-2_0.C35
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/indir-call-prof_0.C39
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/inline_mismatch_args_0.C36
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/lipo.exp60
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/partition1_0.C54
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/partition2_0.C16
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/partition3_0.C18
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/vcall1_0.C41
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/vcall1_1.C23
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/vcall1_2.C31
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/morefunc.C55
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/reorder.C48
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/reorder_class1.h11
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/reorder_class2.h12
-rw-r--r--gcc-4.9/gcc/testsuite/g++.dg/tree-prof/tree-prof.exp4
24 files changed, 848 insertions, 2 deletions
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_1.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_1.C
new file mode 100644
index 000000000..c58f3ca94
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_1.C
@@ -0,0 +1,45 @@
+/* Verify if call-graph profile sections are created with -freorder-functions=.
+ Check of edge profiles and node profiles are present in the profile
+ sections. Check if the segment splitting API is invoked. */
+/* { dg-require-section-exclude "" } */
+/* { dg-require-linker-function-reordering-plugin "" } */
+/* { dg-options "-O2 -freorder-functions=callgraph -ffunction-sections --save-temps -Wl,-plugin-opt,file=linker.dump -Wl,-plugin-opt,split_segment=yes" } */
+
+int
+notcalled ()
+{
+ return 0;
+}
+
+int __attribute__ ((noinline))
+foo ()
+{
+ return 1;
+}
+
+int __attribute__ ((noinline))
+bar ()
+{
+ return 0;
+}
+
+int main ()
+{
+ int sum;
+ for (int i = 0; i< 1000; i++)
+ {
+ sum = foo () + bar();
+ }
+ return sum * bar ();
+}
+
+/* { dg-final-use { scan-assembler "\.gnu\.callgraph\.text\.main" } } */
+/* { dg-final-use { scan-assembler "\.string \"1000\"" } } */
+/* { dg-final-use { scan-assembler "\.string \"Weight 1000 1000\"" } } */
+/* { dg-final-use { scan-assembler "\.string \"Weight 1001 1001\"" } } */
+/* Check if main is next to foo or bar */
+/* { dg-final-use { scan-file linker.dump "Callgraph group : *\(_Z3foov main|main _Z3foov|_Z3barv main|main _Z3barv\).*\n" } } */
+/* { dg-final-use { scan-file linker.dump ".text\..*\._Z9notcalledv entry count = 0 computed = 0 max count = 0" } } */
+/* { dg-final-use { scan-file linker.dump "Moving .* section\\(s\\) to new segment" } } */
+/* { dg-final-use { cleanup-saved-temps } } */
+/* { dg-final-use { remove-build-file "linker.dump" } } */
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_2.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_2.C
new file mode 100644
index 000000000..5e238d8e2
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_2.C
@@ -0,0 +1,25 @@
+/* Check if the edge_cutoffa option to the function reordering plugin works as
+ expected. */
+/* { dg-require-section-exclude "" } */
+/* { dg-require-linker-function-reordering-plugin "" } */
+/* { dg-options "-O2 -freorder-functions=callgraph -ffunction-sections -Wl,-plugin-opt,file=linker.dump -Wl,-plugin-opt,edge_cutoff=a1000" } */
+
+int __attribute__ ((noinline))
+foo ()
+{
+ return 1;
+}
+
+int main ()
+{
+ int sum = 0;
+ for (int i = 0; i< 1000; i++)
+ {
+ sum += foo ();
+ }
+ return sum - 1000;
+}
+
+/* { dg-final-use { scan-file linker.dump "Not considering edge with weight 1000 and below" } } */
+/* { dg-final-use { scan-file-not linker.dump "Callgraph group" } } */
+/* { dg-final-use { remove-build-file "linker.dump" } } */
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_3.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_3.C
new file mode 100644
index 000000000..f316701c8
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_3.C
@@ -0,0 +1,25 @@
+/* Check if the edge_cutoffp option to the function reordering plugin works as
+ expected. */
+/* { dg-require-section-exclude "" } */
+/* { dg-require-linker-function-reordering-plugin "" } */
+/* { dg-options "-O2 -freorder-functions=callgraph -ffunction-sections -Wl,-plugin-opt,file=linker.dump -Wl,-plugin-opt,edge_cutoff=p100" } */
+
+int __attribute__ ((noinline))
+foo ()
+{
+ return 1;
+}
+
+int main ()
+{
+ int sum = 0;
+ for (int i = 0; i< 1000; i++)
+ {
+ sum += foo ();
+ }
+ return sum - 1000;
+}
+
+/* { dg-final-use { scan-file linker.dump "Not considering edge with weight 1000 and below" } } */
+/* { dg-final-use { scan-file-not linker.dump "Callgraph group" } } */
+/* { dg-final-use { remove-build-file "linker.dump" } } */
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_4.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_4.C
new file mode 100644
index 000000000..58e38ad35
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_4.C
@@ -0,0 +1,41 @@
+/* Check if cutting off callgraph gets all functions laid out only according to
+ function profiles and not prefixes. foo_200 is as hot as the other foo's but
+ has a unlikely section prefix. This should not matter as sort_name_prefix
+ is turned off. */
+/* { dg-require-section-exclude "" } */
+/* { dg-require-linker-function-reordering-plugin "" } */
+/* { dg-options "-O2 -freorder-functions=callgraph -ffunction-sections -Wl,-plugin-opt,file=linker.dump,-plugin-opt,edge_cutoff=p100,-plugin-opt,sort_name_prefix=no" } */
+
+int __attribute__ ((noinline, section(".text.unlikely._Z7foo_200v")))
+foo_200 ()
+{
+ return 1;
+}
+
+int __attribute__ ((noinline))
+foo_100 ()
+{
+ return 1;
+}
+
+int __attribute__ ((noinline))
+foo_300 ()
+{
+ return 1;
+}
+int main ()
+{
+ int sum = 0;
+ for (int i = 0; i< 200; i++)
+ sum += foo_200 ();
+ for (int i = 0; i< 100; i++)
+ sum += foo_100 ();
+ for (int i = 0; i< 300; i++)
+ sum += foo_300 ();
+ return sum - 600;
+}
+
+/* { dg-final-use { scan-file-not linker.dump "Callgraph group" } } */
+/* { dg-final-use { scan-file linker.dump ".text.unlikely._Z7foo_200v entry count = 200 computed = 200 max count = 200" } } */
+/* { dg-final-use { scan-file linker.dump "\.text\.*\._Z7foo_100v.*\n\.text\.unlikely\._Z7foo_200v.*\n\.text\.*\._Z7foo_300v.*\n" } } */
+/* { dg-final-use { remove-build-file "linker.dump" } } */
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_5.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_5.C
new file mode 100644
index 000000000..dbae8d774
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_5.C
@@ -0,0 +1,41 @@
+/* Check if cutting off callgraph and using sort_name_prefix gets all functions laid out
+ according to prefixes. foo_200 is almost as hot as the other foo's but should
+ not be grouped with them as it has a different section prefix and sort_name_prefix is
+ turned on. */
+/* { dg-require-section-exclude "" } */
+/* { dg-require-linker-function-reordering-plugin "" } */
+/* { dg-options "-O2 -freorder-functions=callgraph -ffunction-sections -Wl,-plugin-opt,file=linker.dump,-plugin-opt,edge_cutoff=p100,-plugin-opt,sort_name_prefix=yes" } */
+
+int __attribute__ ((noinline, section(".text.unlikely._Z7foo_200v")))
+foo_200 ()
+{
+ return 1;
+}
+
+int __attribute__ ((noinline))
+foo_100 ()
+{
+ return 1;
+}
+
+int __attribute__ ((noinline))
+foo_300 ()
+{
+ return 1;
+}
+int main ()
+{
+ int sum = 0;
+ for (int i = 0; i< 200; i++)
+ sum += foo_200 ();
+ for (int i = 0; i< 100; i++)
+ sum += foo_100 ();
+ for (int i = 0; i< 300; i++)
+ sum += foo_300 ();
+ return sum - 600;
+}
+
+/* { dg-final-use { scan-file-not linker.dump "Callgraph group" } } */
+/* { dg-final-use { scan-file linker.dump ".text.unlikely._Z7foo_200v entry count = 200 computed = 200 max count = 200" } } */
+/* { dg-final-use { scan-file linker.dump "\.text\.unlikely\._Z7foo_200v.*\n\.text\.*\._Z7foo_100v.*\n\.text\.*\._Z7foo_300v.*\n" } } */
+/* { dg-final-use { remove-build-file "linker.dump" } } */
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_6.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_6.C
new file mode 100644
index 000000000..1116a4f44
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_6.C
@@ -0,0 +1,53 @@
+/* Check if use_maxcount works as expected. This makes the node profile weight to
+ be equal to the maximum count of any basic block in a function rather than the
+ entry count. foo_100's maxcount > foo_200's max count */
+/* { dg-require-section-exclude "" } */
+/* { dg-require-linker-function-reordering-plugin "" } */
+/* { dg-options "-O2 -freorder-functions=callgraph -ffunction-sections -Wl,-plugin-opt,file=linker.dump -Wl,-plugin-opt,edge_cutoff=p100,-plugin-opt,use_maxcount=yes" } */
+
+
+int __attribute__ ((noinline))
+bar (int *i)
+{
+ (*i)--;
+ if (*i >= 0)
+ return 1;
+ return 0;
+}
+
+int __attribute__ ((noinline))
+foo_100 (int count)
+{
+ int sum = 0;
+ while (count > 0)
+ {
+ sum += bar(&count);
+ }
+ return sum;
+}
+
+int __attribute__ ((noinline))
+foo_200 (int count)
+{
+ int sum = 0;
+ while (count > 0)
+ {
+ sum += bar(&count);
+ }
+ return sum;
+}
+
+int main ()
+{
+ int sum = 0;
+ for (int i = 0; i< 200; i++)
+ sum += foo_200 (100);
+ for (int i = 0; i< 100; i++)
+ sum += foo_100 (400);
+ return sum - 60000;
+}
+/* { dg-final-use { scan-file-not linker.dump "Callgraph group" } } */
+/* { dg-final-use { scan-file linker.dump "\.text\.*\._Z7foo_100i entry count = 100 computed = 100 max count = 40000" } } */
+/* { dg-final-use { scan-file linker.dump "\.text\.*\._Z7foo_200i entry count = 200 computed = 200 max count = 20000" } } */
+/* { dg-final-use { scan-file linker.dump "\.text\.*\._Z7foo_200i.*\n\.text\.*\._Z7foo_100i.*\n\.text\.*\._Z3barPi.*\n" } } */
+/* { dg-final-use { remove-build-file "linker.dump" } } */
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_7.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_7.C
new file mode 100644
index 000000000..3af8636ad
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_7.C
@@ -0,0 +1,55 @@
+/* Check if turning off use_maxcount works as expected. This makes the node
+ profile weight to be equal to the entry count of any basic block in a
+ function rather than the max count.
+ foo_100's maxcount > foo_200's max count but
+ foo_100's entry count < foo_200's entry count. */
+/* { dg-require-section-exclude "" } */
+/* { dg-require-linker-function-reordering-plugin "" } */
+/* { dg-options "-O2 -freorder-functions=callgraph -ffunction-sections -Wl,-plugin-opt,file=linker.dump -Wl,-plugin-opt,edge_cutoff=p100,-plugin-opt,use_maxcount=no" } */
+
+
+int __attribute__ ((noinline))
+bar (int *i)
+{
+ (*i)--;
+ if (*i >= 0)
+ return 1;
+ return 0;
+}
+
+int __attribute__ ((noinline))
+foo_100 (int count)
+{
+ int sum = 0;
+ while (count > 0)
+ {
+ sum += bar(&count);
+ }
+ return sum;
+}
+
+int __attribute__ ((noinline))
+foo_200 (int count)
+{
+ int sum = 0;
+ while (count > 0)
+ {
+ sum += bar(&count);
+ }
+ return sum;
+}
+
+int main ()
+{
+ int sum = 0;
+ for (int i = 0; i< 200; i++)
+ sum += foo_200 (100);
+ for (int i = 0; i< 100; i++)
+ sum += foo_100 (400);
+ return sum - 60000;
+}
+/* { dg-final-use { scan-file-not linker.dump "Callgraph group" } } */
+/* { dg-final-use { scan-file linker.dump "\.text\.*\._Z7foo_100i entry count = 100 computed = 100 max count = 40000" } } */
+/* { dg-final-use { scan-file linker.dump "\.text\.*\._Z7foo_200i entry count = 200 computed = 200 max count = 20000" } } */
+/* { dg-final-use { scan-file linker.dump "\.text\.*\._Z7foo_100i.*\n\.text\.*\._Z7foo_200i.*\n\.text\.*\._Z3barPi.*\n" } } */
+/* { dg-final-use { remove-build-file "linker.dump" } } */
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_8.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_8.C
new file mode 100644
index 000000000..3f1a0156e
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_8.C
@@ -0,0 +1,19 @@
+/* Check if unlikely_cutoff works as expected. Function foo is unlikely because of the cutoff. */
+/* { dg-require-section-exclude "" } */
+/* { dg-require-linker-function-reordering-plugin "" } */
+/* { dg-options "-O2 -freorder-functions=callgraph -ffunction-sections -Wl,-plugin-opt,file=linker.dump -Wl,-plugin-opt,edge_cutoff=p100,-plugin-opt,unlikely_cutoff=1" } */
+
+int __attribute__ ((noinline,section(".text.hot._Z3foov")))
+foo ()
+{
+ return 0;
+}
+
+int main()
+{
+ return foo ();
+}
+
+/* { dg-final-use { scan-file-not linker.dump "Callgraph group" } } */
+/* { dg-final-use { scan-file linker.dump "=== Unlikely sections start ===\n.*\.text\.hot\._Z3foov.* entry count = 1 computed = 1 max count = 1 split = 0\n.*=== Unlikely sections end ===" } } */
+/* { dg-final-use { remove-build-file "linker.dump" } } */
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_split_functions_1.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_split_functions_1.C
new file mode 100644
index 000000000..2f184c3e8
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/func_reorder_gold_plugin_split_functions_1.C
@@ -0,0 +1,63 @@
+/* Check if the gold function reordering plugin reorders split functions.
+ Check if foo is split and the cold section of foo is not next to its hot
+ section*/
+/* { dg-require-section-exclude "" } */
+/* { dg-require-linker-function-reordering-plugin "" } */
+/* { dg-require-effective-target freorder } */
+/* { dg-options "-O2 -freorder-functions=callgraph -ffunction-sections -freorder-blocks-and-partition --save-temps -Wl,-plugin-opt,file=linker.dump" } */
+
+
+#define SIZE 10000
+
+const char *sarr[SIZE];
+const char *buf_hot;
+const char *buf_cold;
+
+__attribute__ ((noinline))
+int bar (int *arg)
+{
+ (*arg)++;
+ return 0;
+}
+
+__attribute__((noinline))
+void
+foo (int path)
+{
+ int i;
+ bar (&path);
+ if (path)
+ {
+ for (i = 0; i < SIZE; i++)
+ sarr[i] = buf_hot;
+ }
+ else
+ {
+ for (i = 0; i < SIZE; i++)
+ sarr[i] = buf_cold;
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ buf_hot = "hello";
+ buf_cold = "world";
+ foo (argc);
+ return 0;
+}
+
+/* { dg-final-use { scan-assembler "\.string \"ColdWeight 0\"" } } */
+/* { dg-final-use { scan-assembler "\.section.*\.text\.hot\._Z3fooi" } } */
+/* { dg-final-use { scan-assembler "\.section.*\.text\.unlikely\._Z3fooi" } } */
+/* { dg-final-use { cleanup-saved-temps } } */
+/* Check if foo and bar are together */
+/* { dg-final-use { scan-file linker.dump "Callgraph group :.*\(_Z3fooi _Z3barPi|_Z3barPi _Z3fooi\).*\n" } } */
+/* Check if foo and main are together */
+/* { dg-final-use { scan-file linker.dump "Callgraph group :.*\(_Z3fooi main|main _Z3fooi\).*\n" } } */
+/* { dg-final-use { scan-file linker.dump "\.text\.unlikely\._Z3fooi .* split = 1" } } */
+/* Check if unlikely sections of foo and bar are together */
+/* { dg-final-use { scan-file linker.dump "\(\.text\.unlikely\._Z3fooi\[^\n\]*\n\.text\.unlikely\._Z3barPi\[^\n\]*\n|\.text\.unlikely\._Z3barPi\[^\n\]*\n\.text\.unlikely\._Z3fooi\[^\n\]*\n\)" } } */
+/* Check if likely sections of hot foo and bar are together */
+/* { dg-final-use { scan-file linker.dump "\(\.text\._Z3barPi\[^\n\]*\n\.text\.hot\._Z3fooi|\.text\.hot\._Z3fooi\[^\n\]*\n\.text\._Z3barPi\)" } } */
+/* { dg-final-use { remove-build-file "linker.dump" } } */
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/indir-call-prof-2_0.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/indir-call-prof-2_0.C
new file mode 100644
index 000000000..e20cc64d3
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/indir-call-prof-2_0.C
@@ -0,0 +1,35 @@
+/* { dg-options "-O" } */
+
+int foo1(void) { return 0; }
+int bar1(void) { throw 1; }
+void foo2(void) { }
+void bar2(void) { throw 1; }
+void __attribute__((noinline,noclone)) test1(void (*f)(void)) { (*f)(); }
+void __attribute__((noinline,noclone)) test2(void (*f)(void)) { (*f)(); }
+int __attribute__((noinline,noclone)) test3(int (*f)(void)) { return (*f)(); }
+int __attribute__((noinline,noclone)) test4(int (*f)(void)) { return (*f)(); }
+int __attribute__((noinline,noclone)) test5(int (*f)(void), int x) { return x ? x : (*f)(); }
+int __attribute__((noinline,noclone)) test6(int (*f)(void), int x) { return x ? x : (*f)(); }
+void __attribute__((noinline,noclone)) test7(void (*f)(void)) { try { (*f)(); } catch (...) {} }
+void __attribute__((noinline,noclone)) test8(void (*f)(void)) { try { (*f)(); } catch (...) {}}
+int __attribute__((noinline,noclone)) test9(int (*f)(void)) { try { return (*f)(); } catch (...) {return 0;} }
+int __attribute__((noinline,noclone)) test10(int (*f)(void)) { try { return (*f)(); } catch (...) {return 0;} }
+int __attribute__((noinline,noclone)) test11(int (*f)(void), int x) { try { return x ? x : (*f)(); } catch (...) {return 0;} }
+int __attribute__((noinline,noclone)) test12(int (*f)(void), int x) { try { return x ? x : (*f)(); } catch (...) {return 0;} }
+
+int main()
+{
+ for (int i = 0; i < 100; ++i) test1(foo2);
+ for (int i = 0; i < 100; ++i) try { test2(bar2); } catch (...) {}
+ for (int i = 0; i < 100; ++i) test3(foo1);
+ for (int i = 0; i < 100; ++i) try { test4(bar1); } catch (...) {}
+ for (int i = 0; i < 100; ++i) test5(foo1, 0);
+ for (int i = 0; i < 100; ++i) try { test6(bar1, 0); } catch (...) {}
+ for (int i = 0; i < 100; ++i) test7(foo2);
+ for (int i = 0; i < 100; ++i) try { test8(bar2); } catch (...) {}
+ for (int i = 0; i < 100; ++i) test9(foo1);
+ for (int i = 0; i < 100; ++i) try { test10(bar1); } catch (...) {}
+ for (int i = 0; i < 100; ++i) test11(foo1, 0);
+ for (int i = 0; i < 100; ++i) try { test12(bar1, 0); } catch (...) {}
+ return 0;
+}
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/indir-call-prof_0.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/indir-call-prof_0.C
new file mode 100644
index 000000000..b34b937fd
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/indir-call-prof_0.C
@@ -0,0 +1,39 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile" } */
+
+struct A {
+ A () {}
+
+ virtual int AA (void)
+ { return 0; }
+
+};
+
+struct B : public A {
+ B () {}
+
+ virtual int AA (void)
+ { return 1; }
+};
+
+void * __attribute__((noinline,noclone)) wrap (void *p) { return p; }
+int
+main (void)
+{
+ A a;
+ B b;
+
+ A* p;
+
+ p = (A *)wrap ((void *)&a);
+ p->AA ();
+
+ p = (B *)wrap ((void *)&b);
+ p->AA ();
+
+ return 0;
+}
+
+/* { dg-final-use { scan-ipa-dump "Indirect call -> direct call.* AA " "profile" } } */
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized" } } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
+/* { dg-final-use { cleanup-ipa-dump "profile" } } */
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/inline_mismatch_args_0.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/inline_mismatch_args_0.C
new file mode 100644
index 000000000..e82a46ebf
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/inline_mismatch_args_0.C
@@ -0,0 +1,36 @@
+/* { dg-options "-O2 -fdump-tree-einline" } */
+class DocId {
+ public:
+ DocId() { }
+ DocId(const DocId &other) { }
+};
+
+int g;
+class Base {
+ public:
+ virtual void Foo(DocId id) { g++; }
+};
+
+class Super: public Base {
+ public:
+ void Foo(DocId id) { }
+ void Bar(Base *base, DocId id) __attribute__((noinline));
+};
+
+void Super::Bar(Base *base, DocId id) {
+ Super::Foo(id); // direct call is inlined
+ base->Foo(id); // indirect call is marked do not inline
+}
+
+int main(void)
+{
+ Base bah;
+ Super baz;
+ DocId gid;
+
+ baz.Bar(&baz, gid);
+ return 0;
+}
+/* { dg-final-use { scan-tree-dump "Inlining .*Super::Foo" "einline" } } */
+/* { dg-final-use { scan-tree-dump-not "mismatched arguments" "einline" } } */
+/* { dg-final-use { cleanup-tree-dump "einline" } } */
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/lipo.exp b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/lipo.exp
new file mode 100644
index 000000000..2d1ddd7cd
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/lipo.exp
@@ -0,0 +1,60 @@
+# Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Test the functionality of programs compiled with profile-directed block
+# ordering using -fprofile-generate followed by -fprofile-use.
+
+load_lib target-supports.exp
+
+# Some targets don't support tree profiling.
+if { ![check_profiling_available ""] } {
+ return
+}
+
+# The procedures in profopt.exp need these parameters.
+set tool g++
+set prof_ext [list {gcda} {gcda.imports} ]
+
+# Override the list defined in profopt.exp.
+set PROFOPT_OPTIONS [list {}]
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+# Load support procs.
+load_lib profopt.exp
+
+# These are globals used by profopt-execute. The first is options
+# needed to generate profile data, the second is options to use the
+# profile data.
+set profile_option "-fprofile-generate -fripa"
+set feedback_option "-fprofile-use -fripa"
+
+# Add -fno-section-anchors for powerpc. Workround for Google ref b/6663281
+if {[istarget powerpc*-*-*]} {
+ set profile_option "$profile_option -fno-section-anchors"
+ set feedback_option "$feedback_option -fno-section-anchors"
+}
+
+foreach src [lsort [glob -nocomplain $srcdir/$subdir/*_0.C]] {
+ # If we're only testing specific files and this isn't one of them, skip it.
+ if ![runtest_file_p $runtests $src] then {
+ continue
+ }
+ profopt-execute $src
+}
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/partition1_0.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/partition1_0.C
new file mode 100644
index 000000000..108803997
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/partition1_0.C
@@ -0,0 +1,54 @@
+/* { dg-require-effective-target freorder } */
+/* { dg-options "-O2 -freorder-blocks-and-partition" } */
+/* { dg-skip-if "PR target/47683" { mips-sgi-irix* } } */
+
+struct A { A () __attribute__((noinline)); ~A () __attribute__((noinline)); };
+A::A () { asm volatile ("" : : : "memory"); }
+A::~A () { asm volatile ("" : : : "memory"); }
+
+int bar () __attribute__((noinline));
+void foo () __attribute__((noinline));
+
+volatile int k, l;
+
+int bar (int i)
+{
+ void *p = __builtin_alloca (i);
+ asm volatile ("" : : "r" (i), "r" (p) : "memory");
+ if (k) throw 6;
+ return ++l;
+}
+
+void foo ()
+{
+ A a;
+ try {
+ A b;
+ int i = bar (5);
+ try { throw 6; } catch (int) {}
+ if (__builtin_expect (i < 4500, 0)) {
+ bar (7);
+ try { bar (8); } catch (long) {}
+ bar (10);
+ if (__builtin_expect (i < 0, 0)) {
+ try { bar (12); } catch (...) {}
+ bar (16);
+ bar (122);
+ } else {
+ try { bar (bar (7)); } catch (int) {}
+ }
+ } else {
+ try { bar (bar (bar (9))); } catch (...) {}
+ bar (5);
+ }
+ } catch (...) {
+ }
+}
+
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 10000; i++)
+ foo ();
+}
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/partition2_0.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/partition2_0.C
new file mode 100644
index 000000000..6715da57e
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/partition2_0.C
@@ -0,0 +1,16 @@
+// PR middle-end/45458
+// { dg-require-effective-target freorder }
+// { dg-options "-fnon-call-exceptions -freorder-blocks-and-partition" }
+// { dg-skip-if "PR target/47683" { mips-sgi-irix* } }
+
+int
+main ()
+{
+ try
+ {
+ throw 6;
+ }
+ catch (...)
+ {
+ }
+}
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/partition3_0.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/partition3_0.C
new file mode 100644
index 000000000..784698369
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/partition3_0.C
@@ -0,0 +1,18 @@
+// PR middle-end/45566
+// { dg-require-effective-target freorder }
+// { dg-options "-O -fnon-call-exceptions -freorder-blocks-and-partition" }
+
+int k;
+
+int
+main ()
+{
+ try
+ {
+ if (k)
+ throw 6;
+ }
+ catch (...)
+ {
+ }
+}
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/vcall1_0.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/vcall1_0.C
new file mode 100644
index 000000000..3052344b5
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/vcall1_0.C
@@ -0,0 +1,41 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile" } */
+#include <stdio.h>
+struct A {
+ A () {}
+ virtual int AA (void) { return 0; }
+};
+
+extern A* getB (void);
+extern A* getC (void);
+
+int g;
+
+int
+main (void)
+{
+ A* p;
+ int i;
+ int s = 0;
+
+ p = getB();
+ for (i = 0; i < 100; i++)
+ {
+ s += p->AA();
+ }
+
+ for (i = 0; i < 100; i++)
+ {
+ if (i%10 == 0)
+ p = getB();
+ else
+ p = getC();
+
+ s += p->AA();
+ }
+ printf ("result = %d\n",s);
+}
+
+/* { dg-final-use { scan-ipa-dump-times "Indirect call -> direct call" 2 "profile" } } */
+/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized" } } */
+/* { dg-final-use { cleanup-tree-dump "optimized" } } */
+/* { dg-final-use { cleanup-ipa-dump "profile" } } */
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/vcall1_1.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/vcall1_1.C
new file mode 100644
index 000000000..6023024f4
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/vcall1_1.C
@@ -0,0 +1,23 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile" } */
+
+struct A {
+ A () {}
+
+ virtual int AA (void)
+ { return 0; }
+
+};
+
+struct B : public A {
+ B () {}
+
+ virtual int AA (void)
+ { return 1; }
+};
+
+B b;
+
+A* getB (void)
+{
+ return &b;
+}
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/vcall1_2.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/vcall1_2.C
new file mode 100644
index 000000000..cc33d6a19
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/lipo/vcall1_2.C
@@ -0,0 +1,31 @@
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile" } */
+
+struct A {
+ A () {}
+
+ virtual int AA (void)
+ { return 0; }
+
+};
+
+struct B : public A {
+ B () {}
+
+ virtual int AA (void)
+ { return 1; }
+};
+
+struct C : public B {
+ C () {}
+
+ virtual int AA (void)
+ { return 2; }
+
+};
+
+C c;
+
+A* getC(void)
+{
+ return &c;
+}
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/morefunc.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/morefunc.C
new file mode 100644
index 000000000..d5cee40cd
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/morefunc.C
@@ -0,0 +1,55 @@
+/* { dg-options "-O2 -fno-devirtualize --param=profile-func-internal-id=0 -fdump-ipa-profile -Wno-attributes -Wno-coverage-mismatch" } */
+#include "reorder_class1.h"
+#include "reorder_class2.h"
+
+int g;
+
+#ifdef _PROFILE_USE
+/* Another function not existing
+ * in profile-gen */
+
+__attribute__((noinline)) void
+new_func (int i)
+{
+ g += i;
+}
+#endif
+
+static __attribute__((always_inline))
+void test1 (A *tc)
+{
+ int i;
+ for (i = 0; i < 1000; i++)
+ g += tc->foo();
+ if (g<100) g++;
+}
+
+static __attribute__((always_inline))
+void test2 (B *tc)
+{
+ int i;
+ for (i = 0; i < 1000; i++)
+ g += tc->foo();
+}
+
+
+__attribute__((noinline)) void test_a(A *ap) { test1 (ap); }
+__attribute__((noinline)) void test_b(B *bp) { test2 (bp); }
+
+
+int main()
+{
+ A* ap = new A();
+ B* bp = new B();
+
+ test_a(ap);
+ test_b(bp);
+
+#ifdef _PROFILE_USE
+ new_func(10);
+#endif
+
+}
+
+/* { dg-final-use { scan-ipa-dump-times "Indirect call -> direct call" 2 "profile" } } */
+
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/reorder.C b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/reorder.C
new file mode 100644
index 000000000..f0efc210a
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/reorder.C
@@ -0,0 +1,48 @@
+/* { dg-options "-O2 -fno-devirtualize --param=profile-func-internal-id=0 -fdump-ipa-profile -Wno-attributes" } */
+
+#ifdef _PROFILE_USE
+#include "reorder_class1.h"
+#include "reorder_class2.h"
+#else
+#include "reorder_class2.h"
+#include "reorder_class1.h"
+#endif
+
+int g;
+static __attribute__((always_inline))
+void test1 (A *tc)
+{
+ int i;
+ for (i = 0; i < 1000; i++)
+ g += tc->foo();
+ if (g<100) g++;
+}
+
+static __attribute__((always_inline))
+void test2 (B *tc)
+{
+ int i;
+ for (i = 0; i < 1000; i++)
+ g += tc->foo();
+}
+
+
+#ifdef _PROFILE_USE
+__attribute__((noinline)) void test_a(A *ap) { test1 (ap); }
+__attribute__((noinline)) void test_b(B *bp) { test2 (bp); }
+#else
+__attribute__((noinline)) void test_b(B *bp) { test2 (bp); }
+__attribute__((noinline)) void test_a(A *ap) { test1 (ap); }
+#endif
+
+int main()
+{
+ A* ap = new A();
+ B* bp = new B();
+
+ test_a(ap);
+ test_b(bp);
+}
+
+/* { dg-final-use { scan-ipa-dump-times "Indirect call -> direct call" 2 "profile" } } */
+
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/reorder_class1.h b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/reorder_class1.h
new file mode 100644
index 000000000..62a1e923c
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/reorder_class1.h
@@ -0,0 +1,11 @@
+struct A {
+ virtual int foo();
+};
+
+int A::foo()
+{
+ return 1;
+}
+
+
+
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/reorder_class2.h b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/reorder_class2.h
new file mode 100644
index 000000000..ee3ed109b
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/reorder_class2.h
@@ -0,0 +1,12 @@
+
+struct B {
+ virtual int foo();
+};
+
+int B::foo()
+{
+ return 2;
+}
+
+
+
diff --git a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/tree-prof.exp b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/tree-prof.exp
index 2c96ee38c..f12ddaf86 100644
--- a/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/tree-prof.exp
+++ b/gcc-4.9/gcc/testsuite/g++.dg/tree-prof/tree-prof.exp
@@ -42,8 +42,8 @@ set PROFOPT_OPTIONS [list {}]
# These are globals used by profopt-execute. The first is options
# needed to generate profile data, the second is options to use the
# profile data.
-set profile_option "-fprofile-generate"
-set feedback_option "-fprofile-use"
+set profile_option "-fprofile-generate -D_PROFILE_GENERATE"
+set feedback_option "-fprofile-use -D_PROFILE_USE"
foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.C]] {
# If we're only testing specific files and this isn't one of them, skip it.