aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-alias.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-05-06 08:54:40 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-05-06 08:54:40 +0000
commitf5b7359952b41c35007e5aa46f9995c9249d4c1b (patch)
treef63ad91d6bfe9b5feb25cd2a5dd5e6312fcb8556 /gcc/tree-ssa-alias.c
parent2bbbfa4e2885f86ea418de9f665375594bf38aaa (diff)
downloadgcc-f5b7359952b41c35007e5aa46f9995c9249d4c1b.zip
gcc-f5b7359952b41c35007e5aa46f9995c9249d4c1b.tar.gz
gcc-f5b7359952b41c35007e5aa46f9995c9249d4c1b.tar.bz2
re PR tree-optimization/90316 (large compile time increase in opt / alias stmt walking for Go example)
2019-05-06 Richard Biener <rguenther@suse.de> PR tree-optimization/90316 * tree-ssa-alias.c (maybe_skip_until): Pass in target BB, compute target on demand. (get_continuation_for_phi): Remove code walking stmts to get to a target virtual operand which could end up being quadratic. From-SVN: r270902
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r--gcc/tree-ssa-alias.c59
1 files changed, 20 insertions, 39 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index c0f67d1..4d00d38 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2598,8 +2598,8 @@ stmt_kills_ref_p (gimple *stmt, tree ref)
case false is returned. The walk starts with VUSE, one argument of PHI. */
static bool
-maybe_skip_until (gimple *phi, tree target, ao_ref *ref,
- tree vuse, unsigned int *cnt, bitmap *visited,
+maybe_skip_until (gimple *phi, tree &target, basic_block target_bb,
+ ao_ref *ref, tree vuse, unsigned int *cnt, bitmap *visited,
bool abort_on_visited,
void *(*translate)(ao_ref *, tree, void *, bool *),
void *data)
@@ -2615,6 +2615,19 @@ maybe_skip_until (gimple *phi, tree target, ao_ref *ref,
while (vuse != target)
{
gimple *def_stmt = SSA_NAME_DEF_STMT (vuse);
+ /* If we are searching for the target VUSE by walking up to
+ TARGET_BB dominating the original PHI we are finished once
+ we reach a default def or a definition in a block dominating
+ that block. Update TARGET and return. */
+ if (!target
+ && (gimple_nop_p (def_stmt)
+ || dominated_by_p (CDI_DOMINATORS,
+ target_bb, gimple_bb (def_stmt))))
+ {
+ target = vuse;
+ return true;
+ }
+
/* Recurse for PHI nodes. */
if (gimple_code (def_stmt) == GIMPLE_PHI)
{
@@ -2698,49 +2711,17 @@ get_continuation_for_phi (gimple *phi, ao_ref *ref,
arg0 = NULL_TREE;
}
/* If not, look if we can reach such candidate by walking defs
- of a PHI arg without crossing other PHIs. */
- if (! arg0)
- for (i = 0; i < nargs; ++i)
- {
- arg0 = PHI_ARG_DEF (phi, i);
- gimple *def = SSA_NAME_DEF_STMT (arg0);
- /* Backedges can't work. */
- if (dominated_by_p (CDI_DOMINATORS,
- gimple_bb (def), phi_bb))
- continue;
- /* See below. */
- if (gimple_code (def) == GIMPLE_PHI)
- continue;
- while (! dominated_by_p (CDI_DOMINATORS,
- phi_bb, gimple_bb (def)))
- {
- arg0 = gimple_vuse (def);
- if (SSA_NAME_IS_DEFAULT_DEF (arg0))
- break;
- def = SSA_NAME_DEF_STMT (arg0);
- if (gimple_code (def) == GIMPLE_PHI)
- {
- /* Do not try to look through arbitrarily complicated
- CFGs. For those looking for the first VUSE starting
- from the end of the immediate dominator of phi_bb
- is likely faster. */
- arg0 = NULL_TREE;
- goto next;
- }
- }
- break;
-next:;
- }
- if (! arg0)
- return NULL_TREE;
+ until we hit the immediate dominator. maybe_skip_until will
+ do that for us. */
+ basic_block dom = get_immediate_dominator (CDI_DOMINATORS, phi_bb);
- /* Then check against the found candidate. */
+ /* Then check against the (to be) found candidate. */
for (i = 0; i < nargs; ++i)
{
arg1 = PHI_ARG_DEF (phi, i);
if (arg1 == arg0)
;
- else if (! maybe_skip_until (phi, arg0, ref, arg1, cnt, visited,
+ else if (! maybe_skip_until (phi, arg0, dom, ref, arg1, cnt, visited,
abort_on_visited,
/* Do not translate when walking over
backedges. */