diff options
Diffstat (limited to 'gcc-4.9/gcc/testsuite/g++.dg/tree-prof')
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. |