tree-ssa-sccvn.c (visit_reference_op_call): Value number virtual definition to virtual use if...
2016-09-23 Richard Biener <rguenther@suse.de> * tree-ssa-sccvn.c (visit_reference_op_call): Value number virtual definition to virtual use if the call devirtualizes to a const or pure function. (visit_use): Also visit calls we can devirtualize to a const or pure function. * gcc.dg/tree-ssa/ssa-fre-56.c: New testcase. From-SVN: r240431
This commit is contained in:
parent
26bedff5fd
commit
113d06a486
4 changed files with 68 additions and 3 deletions
|
@ -1,3 +1,11 @@
|
|||
2016-09-23 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* tree-ssa-sccvn.c (visit_reference_op_call): Value number
|
||||
virtual definition to virtual use if the call devirtualizes
|
||||
to a const or pure function.
|
||||
(visit_use): Also visit calls we can devirtualize to a
|
||||
const or pure function.
|
||||
|
||||
2016-09-23 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/77697
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2016-09-23 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* gcc.dg/tree-ssa/ssa-fre-56.c: New testcase.
|
||||
|
||||
2016-09-23 Matthew Wahab <matthew.wahab@arm.com>
|
||||
|
||||
* gcc.target/advsimd-intrinsics/advsimd-intrinsics.exp: Enable
|
||||
|
|
26
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-56.c
Normal file
26
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-56.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O -fdump-tree-fre1" } */
|
||||
|
||||
int x = 1;
|
||||
int __attribute__((noinline,noclone)) fn ()
|
||||
{
|
||||
return x;
|
||||
}
|
||||
int (*f)();
|
||||
int main ()
|
||||
{
|
||||
int res;
|
||||
f = fn;
|
||||
x = 0;
|
||||
res = f ();
|
||||
res += x;
|
||||
if (res != 0)
|
||||
__builtin_abort ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We should be able to optimize the load from x in main and thus the
|
||||
addition. */
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "= x;" 1 "fre1" } } */
|
||||
/* { dg-final { scan-tree-dump-times " \\\+ " 0 "fre1" } } */
|
|
@ -3484,8 +3484,24 @@ visit_reference_op_call (tree lhs, gcall *stmt)
|
|||
{
|
||||
vn_reference_t vr2;
|
||||
vn_reference_s **slot;
|
||||
tree vdef_val = vdef;
|
||||
if (vdef)
|
||||
changed |= set_ssa_val_to (vdef, vdef);
|
||||
{
|
||||
/* If we value numbered an indirect functions function to
|
||||
one not clobbering memory value number its VDEF to its
|
||||
VUSE. */
|
||||
tree fn = gimple_call_fn (stmt);
|
||||
if (fn && TREE_CODE (fn) == SSA_NAME)
|
||||
{
|
||||
fn = SSA_VAL (fn);
|
||||
if (TREE_CODE (fn) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
|
||||
&& (flags_from_decl_or_type (TREE_OPERAND (fn, 0))
|
||||
& (ECF_CONST | ECF_PURE)))
|
||||
vdef_val = vuse_ssa_val (gimple_vuse (stmt));
|
||||
}
|
||||
changed |= set_ssa_val_to (vdef, vdef_val);
|
||||
}
|
||||
if (lhs)
|
||||
changed |= set_ssa_val_to (lhs, lhs);
|
||||
vr2 = current_info->references_pool->allocate ();
|
||||
|
@ -3498,7 +3514,7 @@ visit_reference_op_call (tree lhs, gcall *stmt)
|
|||
vr2->set = vr1.set;
|
||||
vr2->hashcode = vr1.hashcode;
|
||||
vr2->result = lhs;
|
||||
vr2->result_vdef = vdef;
|
||||
vr2->result_vdef = vdef_val;
|
||||
slot = current_info->references->find_slot_with_hash (vr2, vr2->hashcode,
|
||||
INSERT);
|
||||
gcc_assert (!*slot);
|
||||
|
@ -3912,11 +3928,22 @@ visit_use (tree use)
|
|||
}
|
||||
}
|
||||
|
||||
/* Pick up flags from a devirtualization target. */
|
||||
tree fn = gimple_call_fn (stmt);
|
||||
int extra_fnflags = 0;
|
||||
if (fn && TREE_CODE (fn) == SSA_NAME)
|
||||
{
|
||||
fn = SSA_VAL (fn);
|
||||
if (TREE_CODE (fn) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL)
|
||||
extra_fnflags = flags_from_decl_or_type (TREE_OPERAND (fn, 0));
|
||||
}
|
||||
if (!gimple_call_internal_p (call_stmt)
|
||||
&& (/* Calls to the same function with the same vuse
|
||||
and the same operands do not necessarily return the same
|
||||
value, unless they're pure or const. */
|
||||
gimple_call_flags (call_stmt) & (ECF_PURE | ECF_CONST)
|
||||
((gimple_call_flags (call_stmt) | extra_fnflags)
|
||||
& (ECF_PURE | ECF_CONST))
|
||||
/* If calls have a vdef, subsequent calls won't have
|
||||
the same incoming vuse. So, if 2 calls with vdef have the
|
||||
same vuse, we know they're not subsequent.
|
||||
|
|
Loading…
Add table
Reference in a new issue