aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-03-16 13:51:19 +0100
committerRichard Biener <rguenther@suse.de>2023-03-24 13:52:38 +0100
commited626f18b189920aeed9974aded3f9cb6f25b543 (patch)
tree440c930adc2b51b154f7d9fa28c6fa954a3e5a05 /gcc
parentfe6e61fb236e1ac764a7f044ae80ddf458e981a6 (diff)
downloadgcc-ed626f18b189920aeed9974aded3f9cb6f25b543.zip
gcc-ed626f18b189920aeed9974aded3f9cb6f25b543.tar.gz
gcc-ed626f18b189920aeed9974aded3f9cb6f25b543.tar.bz2
tree-optimization/106912 - clear const attribute from fntype
The following makes sure that after clearing pure/const from instrumented function declarations we are adjusting call statements fntype as well to handle indirect calls and because gimple_call_flags looks at both decl and fntype. Like the pure/const flag clearing on decls we refrain from touching calls to known functions that do not have a body in the current TU. PR tree-optimization/106912 * tree-profile.cc (tree_profiling): Update stmts only when profiling or testing coverage. Make sure to update calls fntype, stripping 'const' there. * gcc.dg/profile-generate-4.c: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/profile-generate-4.c19
-rw-r--r--gcc/tree-profile.cc40
2 files changed, 49 insertions, 10 deletions
diff --git a/gcc/testsuite/gcc.dg/profile-generate-4.c b/gcc/testsuite/gcc.dg/profile-generate-4.c
new file mode 100644
index 0000000..c2b999f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/profile-generate-4.c
@@ -0,0 +1,19 @@
+/* PR106912 */
+/* { dg-require-profiling "-fprofile-generate" } */
+/* { dg-options "-O2 -fprofile-generate -ftree-vectorize" } */
+
+__attribute__ ((__simd__))
+__attribute__ ((__nothrow__ , __leaf__ , __const__, __noinline__))
+double foo (double x);
+
+void bar(double *f, int n)
+{
+ int i;
+ for (i = 0; i < n; i++)
+ f[i] = foo(f[i]);
+}
+
+double foo(double x)
+{
+ return x * x / 3.0;
+}
diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
index ea9d7a2..6f9a43e 100644
--- a/gcc/tree-profile.cc
+++ b/gcc/tree-profile.cc
@@ -835,16 +835,36 @@ tree_profiling (void)
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
- FOR_EACH_BB_FN (bb, cfun)
- {
- gimple_stmt_iterator gsi;
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gimple *stmt = gsi_stmt (gsi);
- if (is_gimple_call (stmt))
- update_stmt (stmt);
- }
- }
+ if (profile_arc_flag || flag_test_coverage)
+ FOR_EACH_BB_FN (bb, cfun)
+ {
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gcall *call = dyn_cast <gcall *> (gsi_stmt (gsi));
+ if (!call)
+ continue;
+
+ /* We do not clear pure/const on decls without body. */
+ tree fndecl = gimple_call_fndecl (call);
+ if (fndecl && !gimple_has_body_p (fndecl))
+ continue;
+
+ /* Drop the const attribute from the call type (the pure
+ attribute is not available on types). */
+ tree fntype = gimple_call_fntype (call);
+ if (fntype && TYPE_READONLY (fntype))
+ {
+ int quals = TYPE_QUALS (fntype) & ~TYPE_QUAL_CONST;
+ fntype = build_qualified_type (fntype, quals);
+ gimple_call_set_fntype (call, fntype);
+ }
+
+ /* Update virtual operands of calls to no longer const/pure
+ functions. */
+ update_stmt (call);
+ }
+ }
/* re-merge split blocks. */
cleanup_tree_cfg ();