diff options
Diffstat (limited to 'gcc-4.4.0/gcc/tree-outof-ssa.c')
-rw-r--r-- | gcc-4.4.0/gcc/tree-outof-ssa.c | 79 |
1 files changed, 63 insertions, 16 deletions
diff --git a/gcc-4.4.0/gcc/tree-outof-ssa.c b/gcc-4.4.0/gcc/tree-outof-ssa.c index 82cc0ffea..f6d2abb4f 100644 --- a/gcc-4.4.0/gcc/tree-outof-ssa.c +++ b/gcc-4.4.0/gcc/tree-outof-ssa.c @@ -35,6 +35,9 @@ along with GCC; see the file COPYING3. If not see #include "toplev.h" +DEF_VEC_I(source_location); +DEF_VEC_ALLOC_I(source_location,heap); + /* Used to hold all the components required to do SSA PHI elimination. The node and pred/succ list is a simple linear list of nodes and edges represented as pairs of nodes. @@ -66,6 +69,9 @@ typedef struct _elim_graph { /* The predecessor and successor edge list. */ VEC(int,heap) *edge_list; + /* Source locus on each edge */ + VEC(source_location,heap) *edge_locus; + /* Visited vector. */ sbitmap visited; @@ -80,6 +86,9 @@ typedef struct _elim_graph { /* List of constant copies to emit. These are pushed on in pairs. */ VEC(tree,heap) *const_copies; + + /* Source locations for any constant copies. */ + VEC(source_location,heap) *copy_locus; } *elim_graph; @@ -139,13 +148,16 @@ create_temp (tree t) variable DEST on edge E. */ static void -insert_copy_on_edge (edge e, tree dest, tree src) +insert_copy_on_edge (edge e, tree dest, tree src, source_location locus) { gimple copy; copy = gimple_build_assign (dest, src); set_is_used (dest); + if (locus != UNKNOWN_LOCATION) + gimple_set_location(copy, locus); + if (TREE_CODE (src) == ADDR_EXPR) src = TREE_OPERAND (src, 0); if (TREE_CODE (src) == VAR_DECL || TREE_CODE (src) == PARM_DECL) @@ -175,7 +187,9 @@ new_elim_graph (int size) g->nodes = VEC_alloc (tree, heap, 30); g->const_copies = VEC_alloc (tree, heap, 20); + g->copy_locus = VEC_alloc (source_location, heap, 10); g->edge_list = VEC_alloc (int, heap, 20); + g->edge_locus = VEC_alloc (source_location, heap, 10); g->stack = VEC_alloc (int, heap, 30); g->visited = sbitmap_alloc (size); @@ -191,6 +205,7 @@ clear_elim_graph (elim_graph g) { VEC_truncate (tree, g->nodes, 0); VEC_truncate (int, g->edge_list, 0); + VEC_truncate (source_location, g->edge_locus, 0); } @@ -204,6 +219,9 @@ delete_elim_graph (elim_graph g) VEC_free (int, heap, g->edge_list); VEC_free (tree, heap, g->const_copies); VEC_free (tree, heap, g->nodes); + VEC_free (source_location, heap, g->copy_locus); + VEC_free (source_location, heap, g->edge_locus); + free (g); } @@ -235,10 +253,11 @@ elim_graph_add_node (elim_graph g, tree node) /* Add the edge PRED->SUCC to graph G. */ static inline void -elim_graph_add_edge (elim_graph g, int pred, int succ) +elim_graph_add_edge (elim_graph g, int pred, int succ, source_location locus) { VEC_safe_push (int, heap, g->edge_list, pred); VEC_safe_push (int, heap, g->edge_list, succ); + VEC_safe_push (source_location, heap, g->edge_locus, locus); } @@ -246,7 +265,7 @@ elim_graph_add_edge (elim_graph g, int pred, int succ) return the successor node. -1 is returned if there is no such edge. */ static inline int -elim_graph_remove_succ_edge (elim_graph g, int node) +elim_graph_remove_succ_edge (elim_graph g, int node, source_location *locus) { int y; unsigned x; @@ -256,8 +275,11 @@ elim_graph_remove_succ_edge (elim_graph g, int node) VEC_replace (int, g->edge_list, x, -1); y = VEC_index (int, g->edge_list, x + 1); VEC_replace (int, g->edge_list, x + 1, -1); + *locus = VEC_index (source_location, g->edge_locus, x / 2); + VEC_replace (source_location, g->edge_locus, x / 2, UNKNOWN_LOCATION); return y; } + *locus = UNKNOWN_LOCATION; return -1; } @@ -266,7 +288,7 @@ elim_graph_remove_succ_edge (elim_graph g, int node) edge list. VAR will hold the partition number found. CODE is the code fragment executed for every node found. */ -#define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, CODE) \ +#define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, LOCUS, CODE) \ do { \ unsigned x_; \ int y_; \ @@ -276,6 +298,7 @@ do { \ if (y_ != (NODE)) \ continue; \ (VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1); \ + (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \ CODE; \ } \ } while (0) @@ -285,7 +308,7 @@ do { \ GRAPH. VAR will hold the partition number found. CODE is the code fragment executed for every node found. */ -#define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, CODE) \ +#define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, LOCUS, CODE) \ do { \ unsigned x_; \ int y_; \ @@ -295,6 +318,7 @@ do { \ if (y_ != (NODE)) \ continue; \ (VAR) = VEC_index (int, (GRAPH)->edge_list, x_); \ + (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \ CODE; \ } \ } while (0) @@ -324,6 +348,7 @@ eliminate_build (elim_graph g, basic_block B) for (gsi = gsi_start_phis (B); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple phi = gsi_stmt (gsi); + source_location locus; T0 = var_to_partition_to_var (g->map, gimple_phi_result (phi)); @@ -332,6 +357,7 @@ eliminate_build (elim_graph g, basic_block B) continue; Ti = PHI_ARG_DEF (phi, g->e->dest_idx); + locus = gimple_phi_arg_location_from_edge (phi, g->e); /* If this argument is a constant, or a SSA_NAME which is being left in SSA form, just queue a copy to be emitted on this @@ -344,6 +370,7 @@ eliminate_build (elim_graph g, basic_block B) on this edge. */ VEC_safe_push (tree, heap, g->const_copies, T0); VEC_safe_push (tree, heap, g->const_copies, Ti); + VEC_safe_push (source_location, heap, g->copy_locus, locus); } else { @@ -354,7 +381,7 @@ eliminate_build (elim_graph g, basic_block B) eliminate_name (g, Ti); p0 = var_to_partition (g->map, T0); pi = var_to_partition (g->map, Ti); - elim_graph_add_edge (g, p0, pi); + elim_graph_add_edge (g, p0, pi, locus); } } } @@ -367,8 +394,10 @@ static void elim_forward (elim_graph g, int T) { int S; + source_location locus; + SET_BIT (g->visited, T); - FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, + FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus, { if (!TEST_BIT (g->visited, S)) elim_forward (g, S); @@ -383,7 +412,9 @@ static int elim_unvisited_predecessor (elim_graph g, int T) { int P; - FOR_EACH_ELIM_GRAPH_PRED (g, T, P, + source_location locus; + + FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, { if (!TEST_BIT (g->visited, P)) return 1; @@ -397,15 +428,18 @@ static void elim_backward (elim_graph g, int T) { int P; + source_location locus; + SET_BIT (g->visited, T); - FOR_EACH_ELIM_GRAPH_PRED (g, T, P, + FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, { if (!TEST_BIT (g->visited, P)) { elim_backward (g, P); insert_copy_on_edge (g->e, partition_to_var (g->map, P), - partition_to_var (g->map, T)); + partition_to_var (g->map, T), + locus); } }); } @@ -418,29 +452,33 @@ elim_create (elim_graph g, int T) { tree U; int P, S; + source_location locus; if (elim_unvisited_predecessor (g, T)) { U = create_temp (partition_to_var (g->map, T)); - insert_copy_on_edge (g->e, U, partition_to_var (g->map, T)); - FOR_EACH_ELIM_GRAPH_PRED (g, T, P, + insert_copy_on_edge (g->e, U, partition_to_var (g->map, T), + UNKNOWN_LOCATION); + FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, { if (!TEST_BIT (g->visited, P)) { elim_backward (g, P); - insert_copy_on_edge (g->e, partition_to_var (g->map, P), U); + insert_copy_on_edge (g->e, partition_to_var (g->map, P), U, + locus); } }); } else { - S = elim_graph_remove_succ_edge (g, T); + S = elim_graph_remove_succ_edge (g, T, &locus); if (S != -1) { SET_BIT (g->visited, T); insert_copy_on_edge (g->e, partition_to_var (g->map, T), - partition_to_var (g->map, S)); + partition_to_var (g->map, S), + locus); } } @@ -456,6 +494,7 @@ eliminate_phi (edge e, elim_graph g) basic_block B = e->dest; gcc_assert (VEC_length (tree, g->const_copies) == 0); + gcc_assert (VEC_length (source_location, g->copy_locus) == 0); /* Abnormal edges already have everything coalesced. */ if (e->flags & EDGE_ABNORMAL) @@ -492,9 +531,12 @@ eliminate_phi (edge e, elim_graph g) while (VEC_length (tree, g->const_copies) > 0) { tree src, dest; + source_location locus; + src = VEC_pop (tree, g->const_copies); dest = VEC_pop (tree, g->const_copies); - insert_copy_on_edge (e, dest, src); + locus = VEC_pop (source_location, g->copy_locus); + insert_copy_on_edge (e, dest, src, locus); } } @@ -1468,6 +1510,11 @@ insert_backedge_copies (void) name = make_ssa_name (result_var, stmt); gimple_assign_set_lhs (stmt, name); + /* copy location if present. */ + if (gimple_phi_arg_has_location (phi, i)) + gimple_set_location (stmt, + gimple_phi_arg_location (phi, i)); + /* Insert the new statement into the block and update the PHI node. */ if (last && stmt_ends_bb_p (last)) |