aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.0/gcc/tree-outof-ssa.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.4.0/gcc/tree-outof-ssa.c')
-rw-r--r--gcc-4.4.0/gcc/tree-outof-ssa.c79
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))