aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 05f271f..ad62cae 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -830,10 +830,6 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
/* Otherwise, just copy the node. Note that copy_tree_r already
knows not to copy VAR_DECLs, etc., so this is safe. */
- /* We should never have TREE_BLOCK set on non-statements. */
- if (EXPR_P (*tp))
- gcc_assert (!TREE_BLOCK (*tp));
-
if (TREE_CODE (*tp) == MEM_REF)
{
tree ptr = TREE_OPERAND (*tp, 0);
@@ -872,13 +868,9 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
{
/* Variable substitution need not be simple. In particular,
the MEM_REF substitution above. Make sure that
- TREE_CONSTANT and friends are up-to-date. But make sure
- to not improperly set TREE_BLOCK on some sub-expressions. */
+ TREE_CONSTANT and friends are up-to-date. */
int invariant = is_gimple_min_invariant (*tp);
- tree block = id->block;
- id->block = NULL_TREE;
walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL);
- id->block = block;
recompute_tree_invariant_for_addr_expr (*tp);
/* If this used to be invariant, but is not any longer,
@@ -890,6 +882,22 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
}
}
+ /* Update the TREE_BLOCK for the cloned expr. */
+ if (EXPR_P (*tp))
+ {
+ tree new_block = id->remapping_type_depth == 0 ? id->block : NULL;
+ tree old_block = TREE_BLOCK (*tp);
+ if (old_block)
+ {
+ tree *n;
+ n = (tree *) pointer_map_contains (id->decl_map,
+ TREE_BLOCK (*tp));
+ if (n)
+ new_block = *n;
+ }
+ TREE_SET_BLOCK (*tp, new_block);
+ }
+
/* Keep iterating. */
return NULL_TREE;
}
@@ -1107,11 +1115,10 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
tree *n;
n = (tree *) pointer_map_contains (id->decl_map,
TREE_BLOCK (*tp));
- gcc_assert (n || id->remapping_type_depth != 0);
if (n)
new_block = *n;
}
- TREE_BLOCK (*tp) = new_block;
+ TREE_SET_BLOCK (*tp, new_block);
}
if (TREE_CODE (*tp) != OMP_CLAUSE)
@@ -1982,6 +1989,7 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
tree new_arg;
tree block = id->block;
edge_iterator ei2;
+ location_t locus;
/* When doing partial cloning, we allow PHIs on the entry block
as long as all the arguments are the same. Find any input
@@ -1993,9 +2001,7 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
new_arg = arg;
- id->block = NULL_TREE;
walk_tree (&new_arg, copy_tree_body_r, id, NULL);
- id->block = block;
gcc_assert (new_arg);
/* With return slot optimization we can end up with
non-gimple (foo *)&this->m, fix that here. */
@@ -2008,8 +2014,20 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
gsi_insert_seq_on_edge (new_edge, stmts);
inserted = true;
}
- add_phi_arg (new_phi, new_arg, new_edge,
- gimple_phi_arg_location_from_edge (phi, old_edge));
+ locus = gimple_phi_arg_location_from_edge (phi, old_edge);
+ block = id->block;
+ if (LOCATION_BLOCK (locus))
+ {
+ tree *n;
+ n = (tree *) pointer_map_contains (id->decl_map,
+ LOCATION_BLOCK (locus));
+ gcc_assert (n);
+ block = *n;
+ }
+
+ add_phi_arg (new_phi, new_arg, new_edge, block ?
+ COMBINE_LOCATION_DATA (line_table, locus, block) :
+ LOCATION_LOCUS (locus));
}
}
}
@@ -3874,7 +3892,8 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
id->block = make_node (BLOCK);
BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
BLOCK_SOURCE_LOCATION (id->block) = input_location;
- prepend_lexical_block (gimple_block (stmt), id->block);
+ if (gimple_block (stmt))
+ prepend_lexical_block (gimple_block (stmt), id->block);
/* Local declarations will be replaced by their equivalents in this
map. */