diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2007-11-10 08:46:31 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2007-11-10 08:46:31 +0100 |
commit | 416c991fdd5568197d0f545c0e0a2ad3fd577dc6 (patch) | |
tree | 93916a577dc944948c3fc3c3b0feb8354f23744a /gcc/tree-inline.c | |
parent | 6481b879bad720854a3a1f8be3edc2940b3d4085 (diff) | |
download | gcc-416c991fdd5568197d0f545c0e0a2ad3fd577dc6.zip gcc-416c991fdd5568197d0f545c0e0a2ad3fd577dc6.tar.gz gcc-416c991fdd5568197d0f545c0e0a2ad3fd577dc6.tar.bz2 |
re PR middle-end/34018 (ICE: verify_stmts failed)
PR middle-end/34018
* tree-inline.h (copy_body_data): Add regimplify field.
* tree-inline.c (copy_body_r): Set id->regimplify to true
if an TREE_INVARIANT ADDR_EXPR is no longer invariant after
substitutions.
(copy_bb): Clear id->regimplify before walk_tree, if it is
set afterwards, regimplify the whole statement.
* g++.dg/opt/inline14.C: New test.
From-SVN: r130068
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index e7abeff..e0d4093 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -748,6 +748,7 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data) and friends are up-to-date. */ else if (TREE_CODE (*tp) == ADDR_EXPR) { + int invariant = TREE_INVARIANT (*tp); walk_tree (&TREE_OPERAND (*tp, 0), copy_body_r, id, NULL); /* Handle the case where we substituted an INDIRECT_REF into the operand of the ADDR_EXPR. */ @@ -755,6 +756,10 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data) *tp = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0); else recompute_tree_invariant_for_addr_expr (*tp); + /* If this used to be invariant, but is not any longer, + then regimplification is probably needed. */ + if (invariant && !TREE_INVARIANT (*tp)) + id->regimplify = true; *walk_subtrees = 0; } } @@ -792,6 +797,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, int count_scal tree stmt = bsi_stmt (bsi); tree orig_stmt = stmt; + id->regimplify = false; walk_tree (&stmt, copy_body_r, id, NULL); /* RETURN_EXPR might be removed, @@ -804,9 +810,10 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, int count_scal /* With return slot optimization we can end up with non-gimple (foo *)&this->m, fix that here. */ - if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT - && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == NOP_EXPR - && !is_gimple_val (TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 0))) + if ((TREE_CODE (stmt) == GIMPLE_MODIFY_STMT + && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == NOP_EXPR + && !is_gimple_val (TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 0))) + || id->regimplify) gimplify_stmt (&stmt); bsi_insert_after (©_bsi, stmt, BSI_NEW_STMT); |