From b9903eb32d7d396dce0f3898ea186d93577a2158 Mon Sep 17 00:00:00 2001 From: law Date: Thu, 26 Feb 2015 13:56:39 +0000 Subject: [PATCH] PR tree-optimization/65048 * tree-ssa-threadupdate.c (valid_jump_thread_path): New. (thread_through_all_blocks): Call valid_jump_thread_path. Remove invalid FSM jump-thread paths. PR tree-optimization/65048 * gcc.dg/tree-ssa/ssa-dom-thread-9.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221007 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 ++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c | 50 ++++++++++++++++++++++++ gcc/tree-ssa-threadupdate.c | 40 ++++++++++++++++--- 4 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 98a0d24..73ef79d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-02-26 Sebastian Pop + + PR tree-optimization/65048 + * tree-ssa-threadupdate.c (valid_jump_thread_path): New. + (thread_through_all_blocks): Call valid_jump_thread_path. + Remove invalid FSM jump-thread paths. + 2015-02-26 Jakub Jelinek * passes.c (ipa_write_summaries_1): Call lto_output_init_mode_table. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b1efb2b..f785408 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-02-26 Sebastian Pop + + PR tree-optimization/65048 + * gcc.dg/tree-ssa/ssa-dom-thread-9.c: New. + 2015-02-26 Uros Bizjak * lib/gcc-dg.exp (cleanup-final-insns-dump): New procedure. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c new file mode 100644 index 0000000..6be4203 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c @@ -0,0 +1,50 @@ +/* PR 65048 */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int a, b, c, d; +void fn (void); + +int +foo (x) +{ + switch (x) + { + case 'A': + return 'T'; + case 'U': + return 'A'; + } +} + +void +bar (int x, int y) +{ + switch (c) + { + case 'U': + switch (x) + { + default: + fn (); + case 'G': + switch (y) + { + case 'A': + d = 7; + } + } + } +} + +void +baz (void) +{ + while (1) + { + a = foo (); + b = foo (); + bar (a, b); + } +} + diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index 3326144..7a41ab2 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -2473,6 +2473,21 @@ duplicate_seme_region (edge entry, edge exit, return true; } +/* Return true when PATH is a valid jump-thread path. */ + +static bool +valid_jump_thread_path (vec *path) +{ + unsigned len = path->length (); + + /* Check that the path is connected. */ + for (unsigned int j = 0; j < len - 1; j++) + if ((*path)[j]->e->dest != (*path)[j+1]->e->src) + return false; + + return true; +} + /* Walk through all blocks and thread incoming edges to the appropriate outgoing edge for each edge pair recorded in THREADED_EDGES. @@ -2505,12 +2520,25 @@ thread_through_all_blocks (bool may_peel_loop_headers) vec *path = paths[i]; edge entry = (*path)[0]->e; - if ((*path)[0]->type != EDGE_FSM_THREAD - /* Do not jump-thread twice from the same block. */ - || bitmap_bit_p (threaded_blocks, entry->src->index)) { - i++; - continue; - } + /* Only code-generate FSM jump-threads in this loop. */ + if ((*path)[0]->type != EDGE_FSM_THREAD) + { + i++; + continue; + } + + /* Do not jump-thread twice from the same block. */ + if (bitmap_bit_p (threaded_blocks, entry->src->index) + /* Verify that the jump thread path is still valid: a + previous jump-thread may have changed the CFG, and + invalidated the current path. */ + || !valid_jump_thread_path (path)) + { + /* Remove invalid FSM jump-thread paths. */ + delete_jump_thread_path (path); + paths.unordered_remove (i); + continue; + } unsigned len = path->length (); edge exit = (*path)[len - 1]->e; -- 2.7.4