This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[ast-optimizer-branch] Binding scope fixes [patch]
- To: gcc-patches at gcc dot gnu dot org
- Subject: [ast-optimizer-branch] Binding scope fixes [patch]
- From: Diego Novillo <dnovillo at redhat dot com>
- Date: Sun, 14 Oct 2001 22:52:01 -0400
- Cc: Graham Stott <grahams at redhat dot com>
- Organization: Red Hat Canada
Graham Stott found and fixed two problems:
- When we created basic blocks outside the main flow graph
building loop, the new basic block would not get associated
with the right binding scope.
Graham, the only thing I changed is to add the binding_scope
argument to create_bb directly. Since it's a local function we
don't really need to preserve the interface.
- When creating edges for expression-statements, make_edges would
blindly make an edge with BASIC_BLOCK (i + 1). That fails if
i == n_basic_blocks.
Bootstrapped on x86. Committed to the AST branch.
Diego.
2001-10-10 Graham Stott <grahams@redhat.com>
* tree-cfg.c (create_bb): Add new binding_scope parameter
which allows the binding scope either to be explicitly
specified if non-zero.
(make_blocks): Update call to create_bb.
(make_for_stmt_blocks): Ditto.
(make_while_stmt_blocks): Ditto.
(make_do_stmt_blocks): Ditto.
(make_if_stmt_blocks): Ditto.
(make_switch_stmt_blocks): Ditto.
(create_maximal_bb): Ditto.
(make_edges): If a statement expression is in the last basic
block create an edge to EXIT_BLOCK_PTR and not the next block.
(insert_before_normal_stmt): Pass the appropriate binding scope to
create_bb.
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.2.10
diff -d -p -d -u -p -r1.1.2.10 tree-cfg.c
--- tree-cfg.c 2001/10/15 01:06:58 1.1.2.10
+++ tree-cfg.c 2001/10/15 01:54:16
@@ -56,7 +56,8 @@ static void make_if_stmt_blocks PARAMS (
static void make_while_stmt_blocks PARAMS ((tree, basic_block, tree, tree *));
static void make_switch_stmt_blocks PARAMS ((tree, basic_block, tree, tree *));
static void make_do_stmt_blocks PARAMS ((tree, basic_block, tree, tree *));
-static basic_block create_bb PARAMS ((tree, tree, basic_block, tree *));
+static basic_block create_bb PARAMS ((tree, tree, basic_block, tree *,
+ basic_block));
static basic_block create_maximal_bb PARAMS ((tree, basic_block, tree, tree *));
static void map_stmt_to_bb PARAMS ((tree, basic_block));
static void delete_unreachable_blocks PARAMS ((void));
@@ -206,7 +207,8 @@ make_blocks (t, control_parent, compound
if (is_statement_expression (t))
{
tree expr = TREE_OPERAND (t, 0);
- basic_block bb = create_bb (t, t, control_parent, prev_chain_p);
+ basic_block bb = create_bb (t, t, control_parent, prev_chain_p,
+ NULL);
make_blocks (STMT_EXPR_STMT (expr), bb, t,
&(STMT_EXPR_STMT (expr)));
}
@@ -262,7 +264,7 @@ make_for_stmt_blocks (t, control_parent,
cond = (FOR_COND (t)) ? FOR_COND (t) : build_int_2 (1, 0);
expr = (FOR_EXPR (t)) ? FOR_EXPR (t) : build_int_2 (1, 0);
- entry = create_bb (t, t, control_parent, prev_chain_p);
+ entry = create_bb (t, t, control_parent, prev_chain_p, NULL);
entry->flags |= BB_CONTROL_ENTRY;
bb = create_maximal_bb (FOR_INIT_STMT (t), entry, compound_stmt,
@@ -296,7 +298,7 @@ make_while_stmt_blocks (t, control_paren
{
basic_block bb, entry;
- entry = create_bb (t, t, control_parent, prev_chain_p);
+ entry = create_bb (t, t, control_parent, prev_chain_p, NULL);
entry->flags |= BB_CONTROL_ENTRY | BB_CONTROL_EXPR;
make_blocks (WHILE_BODY (t), entry, compound_stmt, &(WHILE_BODY (t)));
@@ -323,7 +325,7 @@ make_do_stmt_blocks (t, control_parent,
{
basic_block bb, entry;
- entry = create_bb (t, t, control_parent, prev_chain_p);
+ entry = create_bb (t, t, control_parent, prev_chain_p, NULL);
entry->flags |= BB_CONTROL_ENTRY;
make_blocks (DO_BODY (t), entry, compound_stmt, &(DO_BODY (t)));
@@ -346,7 +348,7 @@ make_if_stmt_blocks (t, control_parent,
tree compound_stmt;
tree *prev_chain_p;
{
- basic_block bb = create_bb (t, t, control_parent, prev_chain_p);
+ basic_block bb = create_bb (t, t, control_parent, prev_chain_p, NULL);
bb->flags |= BB_CONTROL_ENTRY | BB_CONTROL_EXPR;
make_blocks (THEN_CLAUSE (t), bb, compound_stmt, &(THEN_CLAUSE (t)));
@@ -366,7 +368,7 @@ make_switch_stmt_blocks (t, control_pare
tree compound_stmt;
tree *prev_chain_p;
{
- basic_block bb = create_bb (t, t, control_parent, prev_chain_p);
+ basic_block bb = create_bb (t, t, control_parent, prev_chain_p, NULL);
bb->flags |= BB_CONTROL_ENTRY | BB_CONTROL_EXPR;
make_blocks (SWITCH_BODY (t), bb, compound_stmt, &(SWITCH_BODY (t)));
@@ -410,7 +412,7 @@ create_maximal_bb (t, control_parent, co
return NULL;
first = last = t;
- bb = create_bb (first, last, control_parent, prev_chain_p);
+ bb = create_bb (first, last, control_parent, prev_chain_p, NULL);
while (last && last != error_mark_node)
{
@@ -443,14 +445,18 @@ create_maximal_bb (t, control_parent, co
PREV_CHAIN_P is the address into the tree preceeding T that contains a
pointer to T. This is used when we need to insert statements before
- the first tree of the block. */
+ the first tree of the block.
+
+ BINDING_SCOPE is the binding scope enclosing the block. If NULL, the
+ binding scope is the top element of the array binding_stack. */
static basic_block
-create_bb (head, end, control_parent, prev_chain_p)
+create_bb (head, end, control_parent, prev_chain_p, binding_scope)
tree head;
tree end;
basic_block control_parent;
tree *prev_chain_p;
+ basic_block binding_scope;
{
basic_block bb;
@@ -459,7 +465,8 @@ create_bb (head, end, control_parent, pr
memset (bb, 0, sizeof (*bb));
/* If this block starts a new scope, push it into the stack of bindings. */
- if (TREE_CODE (head) == SCOPE_STMT && SCOPE_BEGIN_P (head))
+ if (binding_scope == NULL
+ && TREE_CODE (head) == SCOPE_STMT && SCOPE_BEGIN_P (head))
VARRAY_PUSH_BB (binding_stack, bb);
bb->head_tree = head;
@@ -470,7 +477,9 @@ create_bb (head, end, control_parent, pr
create_bb_ann (bb);
BB_PARENT (bb) = control_parent;
BB_PREV_CHAIN_P (bb) = prev_chain_p;
- BB_BINDING_SCOPE (bb) = VARRAY_TOP_BB (binding_stack);
+ BB_BINDING_SCOPE (bb) = (binding_scope)
+ ? binding_scope
+ : VARRAY_TOP_BB (binding_stack);
if (is_loop_stmt (head))
{
@@ -630,8 +639,14 @@ make_edges ()
/* Edges for statement expressions. */
if (is_statement_expression (bb->head_tree))
- make_edge (bb, BASIC_BLOCK (i + 1), 0);
+ {
+ basic_block dest = (i + 1 == n_basic_blocks)
+ ? EXIT_BLOCK_PTR
+ : BASIC_BLOCK (i + 1);
+ make_edge (bb, dest, 0);
+ }
+
/* Edges for control flow altering statements (goto, break,
continue, return) need an edge to the corresponding target
block. */
@@ -1957,7 +1972,8 @@ insert_before_normal_stmt (stmt, where,
TREE_CHAIN (stmt) = where;
if (is_ctrl_stmt (where))
{
- new_bb = create_bb (stmt, stmt, BB_PARENT (bb), prev_chain_p);
+ new_bb = create_bb (stmt, stmt, BB_PARENT (bb), prev_chain_p,
+ BB_BINDING_SCOPE (bb));
insert_bb_before (new_bb, bb);
}
else