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.
This commit is contained in:
parent
fe6e61fb23
commit
ed626f18b1
2 changed files with 49 additions and 10 deletions
19
gcc/testsuite/gcc.dg/profile-generate-4.c
Normal file
19
gcc/testsuite/gcc.dg/profile-generate-4.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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 ();
|
||||
|
|
Loading…
Add table
Reference in a new issue