aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKazu Hirata <kazu@cs.umass.edu>2004-11-23 05:25:12 +0000
committerKazu Hirata <kazu@gcc.gnu.org>2004-11-23 05:25:12 +0000
commita100ac1e28fc8f0c22ceea85eef74b7ac8615daa (patch)
treef05fee1d28436abb25a6d378abbc0212ca41c4f5 /gcc
parent82698cdede07649ffc164d761a1d2aa1832b9cc3 (diff)
downloadgcc-a100ac1e28fc8f0c22ceea85eef74b7ac8615daa.zip
gcc-a100ac1e28fc8f0c22ceea85eef74b7ac8615daa.tar.gz
gcc-a100ac1e28fc8f0c22ceea85eef74b7ac8615daa.tar.bz2
tree-cfg.c (tree_execute_on_growing_pred): New.
* tree-cfg.c (tree_execute_on_growing_pred): New. (tree_cfg_hooks): Add tree_execute_on_growing_pred. * tree-flow.h: Add a prototype for reserve_phi_args_for_new_edge. * tree-phinodes.c (reserve_phi_args_for_new_edge): New. (add_phi_arg): Don't resize a PHI array. From-SVN: r91075
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/tree-cfg.c14
-rw-r--r--gcc/tree-flow.h1
-rw-r--r--gcc/tree-phinodes.c62
4 files changed, 53 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b3151fe..e867fbe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2004-11-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tree-cfg.c (tree_execute_on_growing_pred): New.
+ (tree_cfg_hooks): Add tree_execute_on_growing_pred.
+ * tree-flow.h: Add a prototype for
+ reserve_phi_args_for_new_edge.
+ * tree-phinodes.c (reserve_phi_args_for_new_edge): New.
+ (add_phi_arg): Don't resize a PHI array.
+
2004-11-23 Ralf Corsepius <ralf.corsepius@rtems.org>
* config.gcc: Add avr-*-rtems*.
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index e9c58d4..1f934cb 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -5339,6 +5339,18 @@ tree_purge_all_dead_eh_edges (bitmap blocks)
return changed;
}
+/* This function is called whenever a new edge is created or
+ redirected. */
+
+static void
+tree_execute_on_growing_pred (edge e)
+{
+ basic_block bb = e->dest;
+
+ if (phi_nodes (bb))
+ reserve_phi_args_for_new_edge (bb);
+}
+
/* This function is called immediately before edge E is removed from
the edge vector E->dest->preds. */
@@ -5371,7 +5383,7 @@ struct cfg_hooks tree_cfg_hooks = {
tree_block_ends_with_call_p, /* block_ends_with_call_p */
tree_block_ends_with_condjump_p, /* block_ends_with_condjump_p */
tree_flow_call_edges_add, /* flow_call_edges_add */
- NULL, /* execute_on_growing_pred */
+ tree_execute_on_growing_pred, /* execute_on_growing_pred */
tree_execute_on_shrinking_pred, /* execute_on_shrinking_pred */
};
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 45e2096..96e368d 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -508,6 +508,7 @@ extern void dump_generic_bb (FILE *, basic_block, int, int);
extern var_ann_t create_var_ann (tree);
extern stmt_ann_t create_stmt_ann (tree);
extern tree_ann_t create_tree_ann (tree);
+extern void reserve_phi_args_for_new_edge (basic_block);
extern tree create_phi_node (tree, basic_block);
extern void add_phi_arg (tree *, tree, edge);
extern void remove_phi_args (edge);
diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c
index a6be838..031a606 100644
--- a/gcc/tree-phinodes.c
+++ b/gcc/tree-phinodes.c
@@ -269,6 +269,33 @@ resize_phi_node (tree *phi, int len)
*phi = new_phi;
}
+/* Reserve PHI arguments for a new edge to basic block BB. */
+
+void
+reserve_phi_args_for_new_edge (basic_block bb)
+{
+ tree *loc;
+ int len = EDGE_COUNT (bb->preds);
+ int cap = ideal_phi_node_len (len + 4);
+
+ for (loc = &(bb_ann (bb)->phi_nodes);
+ *loc;
+ loc = &PHI_CHAIN (*loc))
+ {
+ if (len > PHI_ARG_CAPACITY (*loc))
+ {
+ tree old_phi = *loc;
+
+ resize_phi_node (loc, cap);
+
+ /* The result of the phi is defined by this phi node. */
+ SSA_NAME_DEF_STMT (PHI_RESULT (*loc)) = *loc;
+
+ release_phi_node (old_phi);
+ }
+ }
+}
+
/* Create a new PHI node for variable VAR at basic block BB. */
tree
@@ -302,38 +329,9 @@ add_phi_arg (tree *phi, tree def, edge e)
gcc_assert (bb == bb_for_stmt (*phi));
- if (i >= PHI_ARG_CAPACITY (*phi))
- {
- tree old_phi = *phi;
-
- /* Resize the phi. Unfortunately, this will relocate it. */
- resize_phi_node (phi, ideal_phi_node_len (i + 4));
-
- /* resize_phi_node will necessarily relocate the phi. */
- gcc_assert (*phi != old_phi);
-
- /* The result of the phi is defined by this phi node. */
- SSA_NAME_DEF_STMT (PHI_RESULT (*phi)) = *phi;
-
- release_phi_node (old_phi);
-
- /* Update the list head if replacing the first listed phi. */
- if (phi_nodes (bb) == old_phi)
- bb_ann (bb)->phi_nodes = *phi;
- else
- {
- /* Traverse the list looking for the phi node to chain to. */
- tree p;
-
- for (p = phi_nodes (bb);
- p && PHI_CHAIN (p) != old_phi;
- p = PHI_CHAIN (p))
- ;
-
- gcc_assert (p);
- PHI_CHAIN (p) = *phi;
- }
- }
+ /* We resize PHI nodes upon edge creation. We should always have
+ enough room at this point. */
+ gcc_assert (PHI_NUM_ARGS (*phi) < PHI_ARG_CAPACITY (*phi));
/* Copy propagation needs to know what object occur in abnormal
PHI nodes. This is a convenient place to record such information. */