[tree-ssa] gsi_iterator rework
Andrew MacLeod
amacleod@redhat.com
Mon Dec 2 07:14:00 GMT 2002
The following patch does a few things.
First, the gsi_ iterators are modified slightly.
gsi_start, gsi_end (renamed from gsi_after_end), and gsi_step are used
to step through a raw tree. This means you can see empty_stmt_nodes and
such. Typically its used by the cfg builder and gimplifier. The
semantics of these routines haven't really change. I renamed
gsi_after_end because it seems a little clearer to have start, end, and
step for both sets
For going through basic blocks, which most optimizations are going to
do, the routines are now gsi_start_bb, gsi_end_bb, and gsi_step_bb.
These routines have the property that you will never see an
empty_stmt_node or error_mark_node. If you create a loop:
for (i = gsi_start_bb(bb); !gsi_end_bb(i); gsi_step_bb(&i))
{ blah }
you will only see executables. If there are no executables in the
block, the loop will never execute.
On the other hand, gsi_start_bb can point to an empty_stmt_node, but
*only* if there are nothing but empty_stmt_nodes in the block. The
routine gsi_end_bb understands this and so the loop will terminate
without executing in this case. However, it does leave us with the
ability to insert into an empty block because:
i = gsi_start_bb (bb)
gsi_insert_before (i, new_stmt)
will work fine.
gsi_stmt will also now return NULL_TREE if it ever points to an
empty_stmt_node or an error_mark_node. So the comparision is against
NULL_TREE rather than empty_stmt_node.
This boostraps and produces no new regressions.
The next step is to fix latch nodes so they actually have an
empty_stmt_node in the tree, then we should be able to have a
gsi_insert_after/before routine available. This shouldn't be much work
now.
Diego made some changes over the weekend, so I have to get new source,
apply this, and make any further changes required, then bootstrap again,
but other than that, here's the patch.
Is this OK? Anything we'd rather do or name different?
Andrew
* gimplify.c (simplify_cleanup_point_expr): gsi_stmt can return NULL,
use gsi_end.
* tree-cfg.c (make_blocks): Use gsi_end, gsi_stmt can return NULL. Set
basic_block for empty_stmt_node containers.
(make_edges): Stmt's can be NULL.
(make_ctrl_stmt_edges, make_exit_edges, make_loop_expr_edges,
make_cond_expr_edges, make_goto_expr_edges, is_nonlocal_label_block,
block_invalidates_loop, cleanup_control_flow, cleanup_cond_expr_graph,
cleanup_switch_expr_graph, disconnect_unreachable_case_labels,
find_taken_edge, tree_cfg2dot, successor_block, is_latch_block,
switch_parent, first_stmt, last_stmt): Check for first_stmt() or
last_stmt() returning NULL.
(remove_tree_bb, first_exec_stmt): Use gsi_end.
(last_stmt_ptr): Iterate to find last execuatbel stmt_ptr in a block.
(gsi_start_bb): Return first non-empty stmt, if there is one.
(set_bb_for_stmt): Don't decend into an empty_stmt_node.
* tree-dfa.c (find_tree_refs): Use gsi_end.
(collect_dfa_stats): Use gsi_end_bb.
* tree-flow-inline.h (gsi_step_bb): split.
(gsi_step_in_bb): gsi_step with explicit bb specified. Never return
empty_stmt_node.
(gsi_start_bb): Move to tree-cfg.c.
(gsi_end_bb): New. Have we reached the end of a basic block.
* tree-flow.h (gsi_start_bb): Make external.
(gsi_end_bb, gsi_step_in_bb): New prototypes.
* tree-simple.h (gsi_end): renamed from gsi_after_end.
(gsi_stmt): Return NULL if stmt is an empty_stmt_node or error mark.
* tree-ssa-ccp.c (simulate_block, substitute_and_fold): Use gsi_end.
* tree-ssa-dce.c (mark_control_parent_necessary, find_useful_stmts,
remove_dead_stmts): Use gsi_end_bb.
(process_worklist): Check for NULL last_stmt.
* tree-ssa-pre.c (finalize_1): Use gsi_end_bb, gsi_stmt can be NULL.
Index: gcc/gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimplify.c,v
retrieving revision 1.1.2.10
diff -c -p -r1.1.2.10 gimplify.c
*** gcc/gimplify.c 28 Nov 2002 16:07:46 -0000 1.1.2.10
--- gcc/gimplify.c 30 Nov 2002 16:14:50 -0000
*************** simplify_cleanup_point_expr (expr_p, pre
*** 1900,1909 ****
gimplify_ctxp->conditions = old_conds;
! for (iter = gsi_start (&body); !gsi_after_end (iter); )
{
tree wce = gsi_stmt (iter);
! if (TREE_CODE (wce) == WITH_CLEANUP_EXPR)
{
tree *container = gsi_container (iter);
tree next, tfe;
--- 1900,1909 ----
gimplify_ctxp->conditions = old_conds;
! for (iter = gsi_start (&body); !gsi_end (iter); )
{
tree wce = gsi_stmt (iter);
! if (wce && TREE_CODE (wce) == WITH_CLEANUP_EXPR)
{
tree *container = gsi_container (iter);
tree next, tfe;
Index: gcc/tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.33
diff -c -p -r1.1.4.33 tree-cfg.c
*** gcc/tree-cfg.c 28 Nov 2002 16:07:46 -0000 1.1.4.33
--- gcc/tree-cfg.c 30 Nov 2002 16:14:51 -0000
*************** make_blocks (first_p, parent_block)
*** 199,218 ****
bb = NULL;
start_new_block = true;
! for (i = gsi_start (first_p); !gsi_after_end (i); gsi_step (&i))
{
tree stmt;
enum tree_code code;
tree *container = gsi_container (i);
stmt = gsi_stmt (i);
STRIP_WFL (stmt);
STRIP_NOPS (stmt);
- /* Ignore non-executable statements. */
- if (stmt == empty_stmt_node)
- continue;
-
code = TREE_CODE (stmt);
/* Note that we check whether we need to start a new block before
--- 199,223 ----
bb = NULL;
start_new_block = true;
! for (i = gsi_start (first_p); !gsi_end (i); gsi_step (&i))
{
tree stmt;
enum tree_code code;
tree *container = gsi_container (i);
stmt = gsi_stmt (i);
+
+ /* Set the block for the container of non-executable statements. */
+ if (stmt == NULL_TREE)
+ {
+ if (bb && *container != empty_stmt_node)
+ set_bb_for_stmt (*container, bb);
+ continue;
+ }
+
STRIP_WFL (stmt);
STRIP_NOPS (stmt);
code = TREE_CODE (stmt);
/* Note that we check whether we need to start a new block before
*************** make_edges ()
*** 432,462 ****
tree first = first_stmt (bb);
tree last = last_stmt (bb);
! /* Edges for control statements. */
! if (is_ctrl_stmt (first))
! make_ctrl_stmt_edges (bb);
!
! /* Edges for control flow altering statements (GOTO_EXPR and
! RETURN_EXPR) need an edge to the corresponding target block. */
! if (is_ctrl_altering_stmt (last))
! make_exit_edges (bb);
!
! /* Incoming edges for label blocks in switch statements. It's easier
! to deal with these bottom-up than top-down. */
! if (TREE_CODE (first) == CASE_LABEL_EXPR)
! make_case_label_edges (bb);
!
! /* BIND_EXPR blocks get an edge to the first basic block in the
! BIND_EXPR_BODY. */
! if (TREE_CODE (first) == BIND_EXPR)
! {
! basic_block body_bb = first_exec_block (&BIND_EXPR_BODY (first));
! if (body_bb)
! make_edge (bb, body_bb, EDGE_FALLTHRU);
! }
! /* Finally, if no edges were created above, this is a regular
! basic block that only needs a fallthru edge. */
if (bb->succ == NULL)
make_edge (bb, successor_block (bb), EDGE_FALLTHRU);
}
--- 437,470 ----
tree first = first_stmt (bb);
tree last = last_stmt (bb);
! if (first)
! {
! /* Edges for control statements. */
! if (is_ctrl_stmt (first))
! make_ctrl_stmt_edges (bb);
!
! /* Edges for control flow altering statements (GOTO_EXPR and
! RETURN_EXPR) need an edge to the corresponding target block. */
! if (is_ctrl_altering_stmt (last))
! make_exit_edges (bb);
!
! /* Incoming edges for label blocks in switch statements. It's easier
! to deal with these bottom-up than top-down. */
! if (TREE_CODE (first) == CASE_LABEL_EXPR)
! make_case_label_edges (bb);
!
! /* BIND_EXPR blocks get an edge to the first basic block in the
! BIND_EXPR_BODY. */
! if (TREE_CODE (first) == BIND_EXPR)
! {
! basic_block body_bb = first_exec_block (&BIND_EXPR_BODY (first));
! if (body_bb)
! make_edge (bb, body_bb, EDGE_FALLTHRU);
! }
! /* Finally, if no edges were created above, this is a regular
! basic block that only needs a fallthru edge. */
! }
if (bb->succ == NULL)
make_edge (bb, successor_block (bb), EDGE_FALLTHRU);
}
*************** static void
*** 472,478 ****
make_ctrl_stmt_edges (bb)
basic_block bb;
{
! switch (TREE_CODE (first_stmt (bb)))
{
case LOOP_EXPR:
make_loop_expr_edges (bb);
--- 480,493 ----
make_ctrl_stmt_edges (bb)
basic_block bb;
{
! tree first = first_stmt (bb);
!
! #if defined ENABLE_CHECKING
! if (first == NULL_TREE)
! abort();
! #endif
!
! switch (TREE_CODE (first))
{
case LOOP_EXPR:
make_loop_expr_edges (bb);
*************** make_ctrl_stmt_edges (bb)
*** 490,496 ****
first case statement, the RTL expander gets all confused
and enters an infinite loop. */
{
! tree body = SWITCH_BODY (first_stmt (bb));
STRIP_WFL (body);
STRIP_NOPS (body);
if (TREE_CODE (body) == BIND_EXPR)
--- 505,511 ----
first case statement, the RTL expander gets all confused
and enters an infinite loop. */
{
! tree body = SWITCH_BODY (first);
STRIP_WFL (body);
STRIP_NOPS (body);
if (TREE_CODE (body) == BIND_EXPR)
*************** static void
*** 514,520 ****
make_exit_edges (bb)
basic_block bb;
{
! switch (TREE_CODE (last_stmt (bb)))
{
case GOTO_EXPR:
make_goto_expr_edges (bb);
--- 529,540 ----
make_exit_edges (bb)
basic_block bb;
{
! tree last = last_stmt (bb);
!
! if (last == NULL_TREE)
! abort ();
!
! switch (TREE_CODE (last))
{
case GOTO_EXPR:
make_goto_expr_edges (bb);
*************** make_loop_expr_edges (bb)
*** 543,549 ****
basic_block end_bb, body_bb;
#if defined ENABLE_CHECKING
! if (TREE_CODE (entry) != LOOP_EXPR)
abort ();
#endif
--- 563,569 ----
basic_block end_bb, body_bb;
#if defined ENABLE_CHECKING
! if (entry == NULL_TREE || TREE_CODE (entry) != LOOP_EXPR)
abort ();
#endif
*************** make_cond_expr_edges (bb)
*** 586,592 ****
basic_block successor_bb, then_bb, else_bb;
#if defined ENABLE_CHECKING
! if (TREE_CODE (entry) != COND_EXPR)
abort ();
#endif
--- 606,612 ----
basic_block successor_bb, then_bb, else_bb;
#if defined ENABLE_CHECKING
! if (entry == NULL_TREE || TREE_CODE (entry) != COND_EXPR)
abort ();
#endif
*************** make_goto_expr_edges (bb)
*** 628,634 ****
goto_t = last_stmt (bb);
#if defined ENABLE_CHECKING
! if (goto_t == NULL || TREE_CODE (goto_t) != GOTO_EXPR)
abort ();
#endif
--- 648,654 ----
goto_t = last_stmt (bb);
#if defined ENABLE_CHECKING
! if (goto_t == NULL_TREE || TREE_CODE (goto_t) != GOTO_EXPR)
abort ();
#endif
*************** make_goto_expr_edges (bb)
*** 641,646 ****
--- 661,669 ----
{
tree target = first_stmt (target_bb);
+ if (target == NULL_TREE)
+ continue;
+
/* Common case, destination is a single label. Make the edge
and leave. */
if (TREE_CODE (dest) == LABEL_DECL
*************** remove_tree_bb (bb, remove_stmts)
*** 761,767 ****
}
/* Remove all the instructions in the block. */
! for (i = gsi_start_bb (bb); !gsi_after_end (i); gsi_step_bb (&i))
{
tree stmt = gsi_stmt (i);
--- 784,790 ----
}
/* Remove all the instructions in the block. */
! for (i = gsi_start_bb (bb); !gsi_end_bb (i); gsi_step_bb (&i))
{
tree stmt = gsi_stmt (i);
*************** is_nonlocal_label_block (bb)
*** 828,833 ****
--- 851,859 ----
{
tree t = first_stmt (bb);
+ if (t == NULL_TREE)
+ return false;
+
/* FIXME We don't compute nonlocal labels until RTL expansion. This
returns false positives. */
return (TREE_CODE (t) == LABEL_EXPR && DECL_NAME (LABEL_EXPR_LABEL (t)));
*************** block_invalidates_loop (bb, loop)
*** 1024,1037 ****
struct loop *loop;
{
ref_list_iterator i;
/* Valid loops cannot contain a return statement. */
! if (TREE_CODE (last_stmt (bb)) == RETURN_EXPR)
return true;
/* If the destination node of a goto statement is not in the loop, mark it
invalid. */
! if (TREE_CODE (last_stmt (bb)) == GOTO_EXPR
&& ! TEST_BIT (loop->nodes, bb->succ->dest->index))
return true;
--- 1050,1067 ----
struct loop *loop;
{
ref_list_iterator i;
+ tree last = last_stmt (bb);
+
+ if (last == NULL_TREE)
+ return false;
/* Valid loops cannot contain a return statement. */
! if (TREE_CODE (last) == RETURN_EXPR)
return true;
/* If the destination node of a goto statement is not in the loop, mark it
invalid. */
! if (TREE_CODE (last) == GOTO_EXPR
&& ! TEST_BIT (loop->nodes, bb->succ->dest->index))
return true;
*************** cleanup_control_flow ()
*** 1056,1066 ****
FOR_EACH_BB (bb)
{
enum tree_code code;
if (bb->flags & BB_CONTROL_EXPR
&& bb->flags & BB_COMPOUND_ENTRY)
{
! code = TREE_CODE (first_stmt (bb));
if (code == COND_EXPR)
cleanup_cond_expr_graph (bb);
--- 1086,1101 ----
FOR_EACH_BB (bb)
{
enum tree_code code;
+ tree t;
+
+ t = first_stmt (bb);
+ if (t == NULL_TREE)
+ continue;
if (bb->flags & BB_CONTROL_EXPR
&& bb->flags & BB_COMPOUND_ENTRY)
{
! code = TREE_CODE (t);
if (code == COND_EXPR)
cleanup_cond_expr_graph (bb);
*************** cleanup_cond_expr_graph (bb)
*** 1084,1090 ****
edge taken_edge;
#if defined ENABLE_CHECKING
! if (TREE_CODE (cond_expr) != COND_EXPR)
abort ();
#endif
--- 1119,1125 ----
edge taken_edge;
#if defined ENABLE_CHECKING
! if (cond_expr == NULL_TREE || TREE_CODE (cond_expr) != COND_EXPR)
abort ();
#endif
*************** cleanup_switch_expr_graph (switch_bb)
*** 1117,1123 ****
edge e;
#if defined ENABLE_CHECKING
! if (TREE_CODE (switch_expr) != SWITCH_EXPR)
abort ();
#endif
--- 1152,1158 ----
edge e;
#if defined ENABLE_CHECKING
! if (switch_expr == NULL_TREE || TREE_CODE (switch_expr) != SWITCH_EXPR)
abort ();
#endif
*************** disconnect_unreachable_case_labels (bb)
*** 1149,1156 ****
{
edge taken_edge;
tree switch_val;
! switch_val = SWITCH_COND (first_stmt (bb));
taken_edge = find_taken_edge (bb, switch_val);
if (taken_edge)
{
--- 1184,1195 ----
{
edge taken_edge;
tree switch_val;
+ tree t = first_stmt (bb);
+
+ if (t == NULL_TREE)
+ return;
! switch_val = SWITCH_COND (t);
taken_edge = find_taken_edge (bb, switch_val);
if (taken_edge)
{
*************** find_taken_edge (bb, val)
*** 1183,1189 ****
stmt = first_stmt (bb);
#if defined ENABLE_CHECKING
! if (!is_ctrl_stmt (stmt))
abort ();
#endif
--- 1222,1228 ----
stmt = first_stmt (bb);
#if defined ENABLE_CHECKING
! if (stmt == NULL_TREE || !is_ctrl_stmt (stmt))
abort ();
#endif
*************** find_taken_edge (bb, val)
*** 1238,1244 ****
/* Remember the edge out of the switch() just in case there is no
matching label in the body. */
! if (TREE_CODE (dest_t) != CASE_LABEL_EXPR)
continue;
label_val = CASE_LOW (dest_t);
--- 1277,1283 ----
/* Remember the edge out of the switch() just in case there is no
matching label in the body. */
! if (dest_t == NULL_TREE || TREE_CODE (dest_t) != CASE_LABEL_EXPR)
continue;
label_val = CASE_LOW (dest_t);
*************** tree_cfg2dot (file)
*** 1466,1481 ****
{
enum tree_code head_code, end_code;
const char *head_name, *end_name;
! int head_line, end_line;
! head_code = TREE_CODE (first_stmt (bb));
! end_code = TREE_CODE (last_stmt (bb));
! head_name = tree_code_name[head_code];
! end_name = tree_code_name[end_code];
- head_line = get_lineno (*(bb->head_tree_p));
- end_line = get_lineno (*(bb->end_tree_p));
fprintf (file, "\t%d [label=\"#%d\\n%s (%d)\\n%s (%d)\"];\n",
bb->index, bb->index, head_name, head_line, end_name,
--- 1505,1533 ----
{
enum tree_code head_code, end_code;
const char *head_name, *end_name;
! int head_line = 0;
! int end_line = 0;
! tree first = first_stmt (bb);
! tree last = last_stmt (bb);
! if (first)
! {
! head_code = TREE_CODE (first);
! head_name = tree_code_name[head_code];
! head_line = get_lineno (*(bb->head_tree_p));
! }
! else
! head_name = "no-statement";
! if (last)
! {
! end_code = TREE_CODE (last);
! end_name = tree_code_name[end_code];
! end_line = get_lineno (*(bb->end_tree_p));
! }
! else
! end_name = "no-statement";
fprintf (file, "\t%d [label=\"#%d\\n%s (%d)\\n%s (%d)\"];\n",
bb->index, bb->index, head_name, head_line, end_name,
*************** successor_block (bb)
*** 1537,1545 ****
parent_bb = parent_block (bb);
while (parent_bb)
{
/* If BB is the last block inside a loop body, return the condition
block for the loop structure. */
! if (is_loop_stmt (first_stmt (parent_bb)))
return latch_block (parent_bb);
/* Otherwise, If BB's control parent has a successor, return its
--- 1589,1598 ----
parent_bb = parent_block (bb);
while (parent_bb)
{
+ tree first = first_stmt (parent_bb);
/* If BB is the last block inside a loop body, return the condition
block for the loop structure. */
! if (first && is_loop_stmt (first))
return latch_block (parent_bb);
/* Otherwise, If BB's control parent has a successor, return its
*************** is_latch_block (bb)
*** 1703,1710 ****
basic_block bb;
{
if (bb->index > 0
! && first_stmt (bb) == empty_stmt_node
! && last_stmt (bb) == empty_stmt_node)
{
basic_block loop_bb = BASIC_BLOCK (bb->index - 1);
tree loop_t = first_stmt (loop_bb);
--- 1756,1762 ----
basic_block bb;
{
if (bb->index > 0
! && first_stmt (bb) == NULL_TREE)
{
basic_block loop_bb = BASIC_BLOCK (bb->index - 1);
tree loop_t = first_stmt (loop_bb);
*************** first_exec_stmt (entry_p)
*** 1724,1732 ****
gimple_stmt_iterator i;
tree stmt;
! for (i = gsi_start (entry_p); !gsi_after_end (i); gsi_step (&i))
{
stmt = gsi_stmt (i);
STRIP_WFL (stmt);
STRIP_NOPS (stmt);
--- 1776,1787 ----
gimple_stmt_iterator i;
tree stmt;
! for (i = gsi_start (entry_p); !gsi_end (i); gsi_step (&i))
{
stmt = gsi_stmt (i);
+ if (!stmt)
+ continue;
+
STRIP_WFL (stmt);
STRIP_NOPS (stmt);
*************** static basic_block
*** 1765,1773 ****
switch_parent (bb)
basic_block bb;
{
do
! bb = parent_block (bb);
! while (bb && TREE_CODE (first_stmt (bb)) != SWITCH_EXPR);
return bb;
}
--- 1820,1832 ----
switch_parent (bb)
basic_block bb;
{
+ tree first;
do
! {
! bb = parent_block (bb);
! first = first_stmt (bb);
! }
! while (bb && first && TREE_CODE (first) != SWITCH_EXPR);
return bb;
}
*************** first_stmt (bb)
*** 1787,1792 ****
--- 1846,1854 ----
return NULL_TREE;
i = gsi_start_bb (bb);
+ /* Check for blocks with no remaining statements. */
+ if (gsi_end_bb (i))
+ return NULL_TREE;
t = gsi_stmt (i);
STRIP_WFL (t);
STRIP_NOPS (t);
*************** first_stmt (bb)
*** 1795,1801 ****
/* Return the last statement in basic block BB, stripped of any WFL or NOP
! containers. */
tree
last_stmt (bb)
--- 1857,1864 ----
/* Return the last statement in basic block BB, stripped of any WFL or NOP
! containers. empty_stmt_nodes are never returned. NULL is returned if
! there are no such statements. */
tree
last_stmt (bb)
*************** last_stmt (bb)
*** 1809,1816 ****
i = gsi_start (bb->end_tree_p);
t = gsi_stmt (i);
! STRIP_WFL (t);
! STRIP_NOPS (t);
return t;
}
--- 1872,1890 ----
i = gsi_start (bb->end_tree_p);
t = gsi_stmt (i);
!
! /* If the last statement is an empty_stmt_node, we have to traverse through
! the basic block until we find the last non-empty statement. ick. */
! if (!t)
! {
! for (i = gsi_start_bb (bb); !gsi_end_bb (i); gsi_step_bb (&i))
! t = gsi_stmt(i);
! }
! if (t)
! {
! STRIP_WFL (t);
! STRIP_NOPS (t);
! }
return t;
}
*************** tree *
*** 1821,1835 ****
last_stmt_ptr (bb)
basic_block bb;
{
! gimple_stmt_iterator i;
if (bb == NULL || bb->index == INVALID_BLOCK)
return NULL;
! i = gsi_start (bb->end_tree_p);
return gsi_stmt_ptr (i);
}
/* Insert statement T into basic block BB. */
--- 1895,1937 ----
last_stmt_ptr (bb)
basic_block bb;
{
! gimple_stmt_iterator i, last;
!
! /* FIXME. Do we still Need this routine once we supply an insert? */
! abort();
if (bb == NULL || bb->index == INVALID_BLOCK)
return NULL;
! for (last = i = gsi_start_bb (bb); !gsi_end_bb (i); gsi_step_bb (&i))
! last = i;
return gsi_stmt_ptr (i);
}
+ /* Similar to gsi_start() but initializes the iterator at the first
+ statement in basic block BB which isn't an empty_stmt_node. NULL is
+ returned if there are no such statements. */
+
+ gimple_stmt_iterator
+ gsi_start_bb (bb)
+ basic_block bb;
+ {
+ gimple_stmt_iterator i;
+ if (bb && bb->index != INVALID_BLOCK)
+ {
+ tree *tp = bb->head_tree_p;
+ i = gsi_start (tp);
+ /* If the first stmt is empty, get the next non-empty one. */
+ if (i.tp != NULL && gsi_stmt (i) == NULL_TREE)
+ gsi_step_in_bb (&i, bb);
+ /* If there were nothing but empty_stmt_nodes, just point to one. */
+ if (i.tp == NULL)
+ i = gsi_start (tp);
+ }
+ else
+ i.tp = NULL;
+ return i;
+ }
/* Insert statement T into basic block BB. */
*************** set_bb_for_stmt (t, bb)
*** 1854,1858 ****
else
t = NULL;
}
! while (t);
}
--- 1956,1960 ----
else
t = NULL;
}
! while (t && t != empty_stmt_node);
}
Index: gcc/tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.50
diff -c -p -r1.1.4.50 tree-dfa.c
*** gcc/tree-dfa.c 28 Nov 2002 16:07:46 -0000 1.1.4.50
--- gcc/tree-dfa.c 30 Nov 2002 16:14:52 -0000
*************** find_tree_refs ()
*** 135,141 ****
{
gimple_stmt_iterator i;
! for (i = gsi_start_bb (bb); !gsi_after_end (i); gsi_step_bb (&i))
find_refs_in_stmt (gsi_stmt_ptr (i), bb);
}
--- 135,141 ----
{
gimple_stmt_iterator i;
! for (i = gsi_start_bb (bb); !gsi_end_bb (i); gsi_step_bb (&i))
find_refs_in_stmt (gsi_stmt_ptr (i), bb);
}
*************** collect_dfa_stats (dfa_stats_p)
*** 1574,1580 ****
/* Walk all the trees in the function counting references. Start at
basic block 0, but don't stop at block boundaries. */
htab = htab_create (30, htab_hash_pointer, htab_eq_pointer, NULL);
! for (i = gsi_start_bb (BASIC_BLOCK (0)); !gsi_after_end (i); gsi_step (&i))
{
tree *stmt_p = gsi_stmt_ptr (i);
walk_tree (stmt_p, collect_dfa_stats_r, (void *) dfa_stats_p,
--- 1574,1580 ----
/* Walk all the trees in the function counting references. Start at
basic block 0, but don't stop at block boundaries. */
htab = htab_create (30, htab_hash_pointer, htab_eq_pointer, NULL);
! for (i = gsi_start_bb (BASIC_BLOCK (0)); !gsi_end_bb (i); gsi_step (&i))
{
tree *stmt_p = gsi_stmt_ptr (i);
walk_tree (stmt_p, collect_dfa_stats_r, (void *) dfa_stats_p,
Index: gcc/tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow-inline.h,v
retrieving revision 1.1.2.15
diff -c -p -r1.1.2.15 tree-flow-inline.h
*** gcc/tree-flow-inline.h 28 Nov 2002 03:33:09 -0000 1.1.2.15
--- gcc/tree-flow-inline.h 30 Nov 2002 16:14:53 -0000
*************** exprphi_willbeavail (ref)
*** 657,689 ****
/* Similar to gsi_step() but stops at basic block boundaries. */
static inline void
gsi_step_bb (i)
gimple_stmt_iterator *i;
{
basic_block bb = bb_for_stmt (*(i->tp));
! if (bb && i->tp != bb->end_tree_p)
! gsi_step (i);
! else
! i->tp = NULL;
}
! /* Similar to gsi_start() but initializes the iterator at the first
! statement in basic block BB. */
! static inline gimple_stmt_iterator
! gsi_start_bb (bb)
! basic_block bb;
{
! if (bb && bb->index != INVALID_BLOCK)
! {
! tree *tp = bb->head_tree_p;
! return gsi_start (tp);
! }
! else
! {
! gimple_stmt_iterator i;
! i.tp = NULL;
! return i;
! }
}
static inline bool
--- 657,693 ----
/* Similar to gsi_step() but stops at basic block boundaries. */
static inline void
+ gsi_step_in_bb (i, bb)
+ gimple_stmt_iterator *i;
+ basic_block bb;
+ {
+ while (bb && i->tp != bb->end_tree_p)
+ {
+ gsi_step (i);
+ if (i->tp == NULL || gsi_stmt (*i) != NULL)
+ return;
+ }
+ i->tp = NULL;
+ }
+
+ /* Similar to gsi_step() but stops at basic block boundaries. Assumes stmt
+ has bb_for_stmt() set. (Can't be an empty_stmt_node). */
+
+ static inline void
gsi_step_bb (i)
gimple_stmt_iterator *i;
{
basic_block bb = bb_for_stmt (*(i->tp));
! gsi_step_in_bb (i, bb);
}
! static inline bool
! gsi_end_bb (i)
! gimple_stmt_iterator i;
{
! return (i.tp == NULL ||
! *(i.tp) == error_mark_node ||
! *(i.tp) == empty_stmt_node);
}
static inline bool
Index: gcc/tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.37
diff -c -p -r1.1.4.37 tree-flow.h
*** gcc/tree-flow.h 28 Nov 2002 03:33:09 -0000 1.1.4.37
--- gcc/tree-flow.h 30 Nov 2002 16:14:53 -0000
*************** struct dfa_counts_d
*** 566,573 ****
/* Iterator object for statements inside a basic block. See
gimple_stmt_iterator in tree-simple.h. */
static inline void gsi_step_bb PARAMS ((gimple_stmt_iterator *));
! static inline gimple_stmt_iterator gsi_start_bb PARAMS ((basic_block));
extern void gsi_remove PARAMS ((gimple_stmt_iterator));
#if 0
--- 566,575 ----
/* Iterator object for statements inside a basic block. See
gimple_stmt_iterator in tree-simple.h. */
+ static inline void gsi_step_in_bb PARAMS ((gimple_stmt_iterator *, basic_block));
static inline void gsi_step_bb PARAMS ((gimple_stmt_iterator *));
! static inline bool gsi_end_bb PARAMS ((gimple_stmt_iterator));
! extern gimple_stmt_iterator gsi_start_bb PARAMS ((basic_block));
extern void gsi_remove PARAMS ((gimple_stmt_iterator));
#if 0
Index: gcc/tree-simple.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.h,v
retrieving revision 1.1.4.16
diff -c -p -r1.1.4.16 tree-simple.h
*** gcc/tree-simple.h 20 Oct 2002 19:24:00 -0000 1.1.4.16
--- gcc/tree-simple.h 30 Nov 2002 16:14:53 -0000
*************** typedef struct {
*** 104,110 ****
} gimple_stmt_iterator;
static inline gimple_stmt_iterator gsi_start PARAMS ((tree *));
! static inline bool gsi_after_end PARAMS ((gimple_stmt_iterator));
static inline void gsi_step PARAMS ((gimple_stmt_iterator *));
static inline tree gsi_stmt PARAMS ((gimple_stmt_iterator));
static inline tree *gsi_stmt_ptr PARAMS ((gimple_stmt_iterator));
--- 104,110 ----
} gimple_stmt_iterator;
static inline gimple_stmt_iterator gsi_start PARAMS ((tree *));
! static inline bool gsi_end PARAMS ((gimple_stmt_iterator));
static inline void gsi_step PARAMS ((gimple_stmt_iterator *));
static inline tree gsi_stmt PARAMS ((gimple_stmt_iterator));
static inline tree *gsi_stmt_ptr PARAMS ((gimple_stmt_iterator));
*************** gsi_start (tp)
*** 120,126 ****
}
static inline bool
! gsi_after_end (i)
gimple_stmt_iterator i;
{
return (i.tp == NULL || *(i.tp) == error_mark_node);
--- 120,126 ----
}
static inline bool
! gsi_end (i)
gimple_stmt_iterator i;
{
return (i.tp == NULL || *(i.tp) == error_mark_node);
*************** static inline tree
*** 164,170 ****
gsi_stmt (i)
gimple_stmt_iterator i;
{
! return *(gsi_stmt_ptr (i));
}
static inline tree *
--- 164,173 ----
gsi_stmt (i)
gimple_stmt_iterator i;
{
! tree t = *(gsi_stmt_ptr (i));
! if (t == empty_stmt_node || t == error_mark_node)
! t = NULL_TREE;
! return t;
}
static inline tree *
Index: gcc/tree-ssa-ccp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-ccp.c,v
retrieving revision 1.1.2.34
diff -c -p -r1.1.2.34 tree-ssa-ccp.c
*** gcc/tree-ssa-ccp.c 28 Nov 2002 16:07:47 -0000 1.1.2.34
--- gcc/tree-ssa-ccp.c 30 Nov 2002 16:14:54 -0000
*************** simulate_block (block)
*** 222,228 ****
/* Note that we have simulated this block. */
SET_BIT (executable_blocks, block->index);
! for (j = gsi_start_bb (block); !gsi_after_end (j); gsi_step_bb (&j))
visit_stmt (gsi_stmt (j));
/* If the block has a single successor, it will always get executed.
--- 222,228 ----
/* Note that we have simulated this block. */
SET_BIT (executable_blocks, block->index);
! for (j = gsi_start_bb (block); !gsi_end_bb (j); gsi_step_bb (&j))
visit_stmt (gsi_stmt (j));
/* If the block has a single successor, it will always get executed.
*************** substitute_and_fold ()
*** 281,287 ****
{
gimple_stmt_iterator i;
! for (i = gsi_start_bb (bb); !gsi_after_end (i); gsi_step_bb (&i))
{
tree stmt = gsi_stmt (i);
--- 281,287 ----
{
gimple_stmt_iterator i;
! for (i = gsi_start_bb (bb); !gsi_end_bb (i); gsi_step_bb (&i))
{
tree stmt = gsi_stmt (i);
Index: gcc/tree-ssa-dce.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dce.c,v
retrieving revision 1.1.2.14
diff -c -p -r1.1.2.14 tree-ssa-dce.c
*** gcc/tree-ssa-dce.c 28 Nov 2002 16:07:47 -0000 1.1.2.14
--- gcc/tree-ssa-dce.c 30 Nov 2002 16:14:54 -0000
*************** mark_control_parent_necessary (bb)
*** 144,150 ****
/* Loops through the stmts in this block, marking them as necessary. */
while (bb != NULL && bb->index != INVALID_BLOCK)
{
! for (i = gsi_start_bb (bb); !gsi_after_end (i); gsi_step_bb (&i))
{
/* Avoid needless calls back to this routine by directly calling
mark_tree since we know we are going to cycle through all parent
--- 144,150 ----
/* Loops through the stmts in this block, marking them as necessary. */
while (bb != NULL && bb->index != INVALID_BLOCK)
{
! for (i = gsi_start_bb (bb); !gsi_end_bb (i); gsi_step_bb (&i))
{
/* Avoid needless calls back to this routine by directly calling
mark_tree since we know we are going to cycle through all parent
*************** find_useful_stmts ()
*** 217,223 ****
if (bb_empty_p (bb))
continue;
! for (i = gsi_start_bb (bb); !gsi_after_end (i); gsi_step_bb (&i))
{
ref_list_iterator j;
tree stmt;
--- 217,223 ----
if (bb_empty_p (bb))
continue;
! for (i = gsi_start_bb (bb); !gsi_end_bb (i); gsi_step_bb (&i))
{
ref_list_iterator j;
tree stmt;
*************** process_worklist ()
*** 331,337 ****
if (p == ENTRY_BLOCK_PTR)
continue;
j = last_stmt (p);
! if (TREE_CODE (j) == GOTO_EXPR)
mark_necessary (j);
}
--- 331,337 ----
if (p == ENTRY_BLOCK_PTR)
continue;
j = last_stmt (p);
! if (j && TREE_CODE (j) == GOTO_EXPR)
mark_necessary (j);
}
*************** remove_dead_stmts ()
*** 375,381 ****
if (bb_empty_p (bb))
continue;
! for (i = gsi_start_bb (bb); !gsi_after_end (i); gsi_step_bb (&i))
{
t = gsi_stmt (i);
stats.total++;
--- 375,381 ----
if (bb_empty_p (bb))
continue;
! for (i = gsi_start_bb (bb); !gsi_end_bb (i); gsi_step_bb (&i))
{
t = gsi_stmt (i);
stats.total++;
Index: gcc/tree-ssa-pre.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-pre.c,v
retrieving revision 1.1.4.35
diff -c -p -r1.1.4.35 tree-ssa-pre.c
*** gcc/tree-ssa-pre.c 28 Nov 2002 16:07:47 -0000 1.1.4.35
--- gcc/tree-ssa-pre.c 30 Nov 2002 16:14:55 -0000
*************** finalize_1 (ei, temp)
*** 1691,1697 ****
for (e = bb->pred; e; e = e->pred_next)
{
for (gsi = gsi_start_bb (e->src);
! !gsi_after_end (gsi);
gsi_step (&gsi))
{
tree temp = gsi_stmt (gsi);
--- 1691,1697 ----
for (e = bb->pred; e; e = e->pred_next)
{
for (gsi = gsi_start_bb (e->src);
! !gsi_end_bb (gsi);
gsi_step (&gsi))
{
tree temp = gsi_stmt (gsi);
*************** finalize_1 (ei, temp)
*** 1722,1728 ****
#endif
#if 1
for (gsi = gsi_start_bb (parent_block (bb));
! !gsi_after_end (gsi);
gsi_step (&gsi))
{
tree temp = gsi_stmt (gsi);
--- 1722,1728 ----
#endif
#if 1
for (gsi = gsi_start_bb (parent_block (bb));
! !gsi_end_bb (gsi);
gsi_step (&gsi))
{
tree temp = gsi_stmt (gsi);
*************** finalize_1 (ei, temp)
*** 1732,1737 ****
--- 1732,1739 ----
{
gsi = gsi_start (&TREE_OPERAND (LOOP_EXPR_BODY (temp), 0));
temp = gsi_stmt (gsi);
+ if (!temp)
+ continue;
STRIP_WFL (temp);
STRIP_NOPS (temp);
More information about the Gcc-patches
mailing list