[tree-ssa]: Generic link routines and some insert infrastructure
Andrew MacLeod
amacleod@redhat.com
Wed Mar 5 20:19:00 GMT 2003
This is the first patch which provides some generalized routines which the
insert routines build upon.
First, there is a set of routines for the tsi_stmt_iterator to add and
remove statements as well as start new statement lists. These are intended to
be a generic interface which all tree's are constructed through. If all the
front ends are later modified to build trees through this mechanism, then we are
free to modify the implementation of trees. This in turn will allow us to get
rid of CE nodes as a linking mechanism, for instance. All we'd need to
change is the implementation of the tsi_ routines.
That said, anyone actually trying to do this may discover there are weaknesses
or problems with this interface, and we may have to extend or change it. We
have to start somewhere, and these seems like a reasonable place to begin. The
insert routines use these to link in any new statements created as well.
The interface basically consists of:
enum tsi_iterator_update
{
TSI_NEW_STMT,
TSI_SAME_STMT
};
void tsi_link_before (tree_stmt_iterator *, tree, enum tsi_iterator_update)
void tsi_link_after (tree_stmt_iterator *, tree, enum tsi_iterator_update)
The third parameter indicates how we want the iterator passed in to be modified.
It can either be 'left alone' and point to the same stmt, or it can point to the
new stmt which was created. I thought about seperate routines, but couldn't
think of decent concise names, so this seemed reasonably clear.
void tsi_delink (tree_stmt_iterator *)
The iterator is updated to point to the next statement after the one delinked.
typedef tree tree_stmt_anchor;
tree_stmt_iterator tsi_new_stmt_list (tree, tree_stmt_anchor *)
An anchor is simply something which starts a stmt list. Currently, its simply
a tree pointer, but down the road, an implementation of trees could
conceivably have the links outside the tree node. In this case an anchor would
be something else. At some point, child stmt lists will have to be
tree_anchor's instead of trees as they are now. But for the moment I haven't
done anything about it, thats an issue to deal with once we have an interface
we like. The routine tsi_new_stmt_list initializes a tree_stmt_anchor to
an initial tree stmt.
tree_stmt_iterator tsi_stmt_list_head (tree_stmt_anchor)
Given an anchor, returns an iterator to the first stmt.
These routines have been modestly tested, but not extensively. So far, they
aren't actually being used by anything. Its important to note that using these
routines and the tsi_stmt_iterator, you will never see a CE node, it should
always be under the covers.
---------
I modified bsi_remove() to pass in the address of the iterator, and
update it to the next statement. Previously, stmts were being removed,
and the iterator bumped after removal... If we actually delinked the
stmt under the covers when removing it, then our bumping would then be
broken. I think its cleaner to have the bsi_remove routine update the
iterator itself.
I've added a sbitmap_realloc routine. When we add basic blocks or new
variables during insertion, we have some bitmaps that need to grow as well. I
was suprised there wasn't a realloc routine already, but oh well.
Although the implementation's aren't included in this patch, the prototypes
for the bsi_insert routines are present. The implementations will follow
before long.
Anyway, this all bootstraps, and doesn't seem to cause any new errors.
So, is this OK, or are there a few things we'd like to change? :-)
Andrew
* Makefile.in (tree.o): Add tree-iterator.h dependancy.
* sbitmap.c (sbitmap_realloc): Grow a sbitmap structure.
* sbitmap.h (sbitmap_realloc): New Prototype.
* tree-cfg.c (remove_bb): Use new format for bsi_remove.
(bsi_remove): Update iterator to refer to the next stmt.
(bsi_prev): Implement previous stmt routine.
(bsi_from_tsi): Create a block iterator from a tree iterator.
* tree-flow-inline.h (bsi_prev): Remove.
(tsi_from_bsi): Create a tree iterator from a block iterator.
* tree-flow.h (bsi_prev,bsi_remove): Update prototypes.
(bsi_from_tsi, tsi_from_bsi, bsi_insert_*): New prototypes.
(bsi_iterator_update): New enum type.
* tree-iterator.h (tree_stmt_anchor, tsi_iterator_update): New type.
(tsi_link_before, tsi_link_after, tsi_delink, tsi_new_stmt_list,
tsi_stmt_list_head): New prototypes.
* tree-ssa-dce.c (remove_dead_stmts): Update removal loop to allow
that remove_dead_stmt update's the iterator.
(remove_dead_stmt): Use a pointer to the iterator since bsi_remove
requires it.
* tree.c (tsi_link_before): New function to link a stmt before an
iterator.
(tsi_link_after): New function links stmt after an iterator.
(tsi_delink): Removes a stmt from a list.
(tsi_new_stmt_list): New function to begin a new stmt list.
(tsi_stmt_list_head): New function to get the first stmt in a list.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.77
diff -c -p -r1.903.2.77 Makefile.in
*** Makefile.in 2 Mar 2003 19:58:40 -0000 1.903.2.77
--- Makefile.in 5 Mar 2003 19:05:49 -0000
*************** langhooks.o : langhooks.c $(CONFIG_H) $(
*** 1430,1436 ****
$(LANGHOOKS_DEF_H) flags.h
tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) flags.h function.h \
toplev.h $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
! real.h gt-tree.h
tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(C_TREE_H) flags.h langhooks.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
$(EXPR_H) $(SPLAY_TREE_H) $(TREE_DUMP_H)
--- 1430,1436 ----
$(LANGHOOKS_DEF_H) flags.h
tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) flags.h function.h \
toplev.h $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
! real.h gt-tree.h tree-iterator.h
tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(C_TREE_H) flags.h langhooks.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
$(EXPR_H) $(SPLAY_TREE_H) $(TREE_DUMP_H)
Index: sbitmap.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sbitmap.c,v
retrieving revision 1.21.2.4
diff -c -p -r1.21.2.4 sbitmap.c
*** sbitmap.c 23 Feb 2003 22:03:06 -0000 1.21.2.4
--- sbitmap.c 5 Mar 2003 19:05:50 -0000
*************** sbitmap_resize (bmap, n_elms, def)
*** 107,112 ****
--- 107,140 ----
return bmap;
}
+ /* Re-allocate a simple bitmap of N_ELMS bits. New storage is uninitialized. */
+
+ sbitmap
+ sbitmap_realloc (src, n_elms)
+ sbitmap src;
+ unsigned int n_elms;
+ {
+ unsigned int bytes, size, amt;
+ sbitmap bmap;
+
+ size = SBITMAP_SET_SIZE (n_elms);
+ bytes = size * sizeof (SBITMAP_ELT_TYPE);
+ amt = (sizeof (struct simple_bitmap_def)
+ + bytes - sizeof (SBITMAP_ELT_TYPE));
+
+ if (src->bytes >= bytes)
+ {
+ src->n_bits = n_elms;
+ return src;
+ }
+
+ bmap = (sbitmap) xrealloc (src, amt);
+ bmap->n_bits = n_elms;
+ bmap->size = size;
+ bmap->bytes = bytes;
+ return bmap;
+ }
+
/* Allocate a vector of N_VECS bitmaps of N_ELMS bits. */
sbitmap *
Index: sbitmap.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sbitmap.h,v
retrieving revision 1.17.2.2
diff -c -p -r1.17.2.2 sbitmap.h
*** sbitmap.h 23 Feb 2003 22:03:06 -0000 1.17.2.2
--- sbitmap.h 5 Mar 2003 19:05:50 -0000
*************** extern void dump_sbitmap_vector PARAMS
*** 124,129 ****
--- 124,130 ----
const char *, sbitmap *,
int));
extern sbitmap sbitmap_alloc PARAMS ((unsigned int));
+ extern sbitmap sbitmap_realloc PARAMS ((sbitmap, unsigned int));
extern sbitmap *sbitmap_vector_alloc PARAMS ((unsigned int, unsigned int));
extern sbitmap sbitmap_resize PARAMS ((sbitmap, unsigned int, int));
extern void sbitmap_copy PARAMS ((sbitmap, sbitmap));
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.57
diff -c -p -r1.1.4.57 tree-cfg.c
*** tree-cfg.c 25 Feb 2003 13:28:24 -0000 1.1.4.57
--- tree-cfg.c 5 Mar 2003 19:05:51 -0000
*************** remove_bb (bb, remove_stmts)
*** 1015,1027 ****
}
/* Remove all the instructions in the block. */
! for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
{
tree stmt = bsi_stmt (i);
set_bb_for_stmt (stmt, NULL);
if (remove_stmts)
! bsi_remove (i);
}
set_bb_for_stmt (*bb->head_tree_p, NULL);
--- 1015,1029 ----
}
/* Remove all the instructions in the block. */
! for (i = bsi_start (bb); !bsi_end_p (i); )
{
tree stmt = bsi_stmt (i);
set_bb_for_stmt (stmt, NULL);
if (remove_stmts)
! bsi_remove (&i);
! else
! bsi_next (&i);
}
set_bb_for_stmt (*bb->head_tree_p, NULL);
*************** is_parent (bb, child_bb)
*** 1173,1181 ****
void
bsi_remove (i)
! block_stmt_iterator i;
{
! tree t = *(i.tp);
STRIP_NOPS (t);
--- 1175,1183 ----
void
bsi_remove (i)
! block_stmt_iterator *i;
{
! tree t = *(i->tp);
STRIP_NOPS (t);
*************** bsi_remove (i)
*** 1188,1197 ****
/* If both operands are empty, delete the whole COMPOUND_EXPR. */
if (TREE_OPERAND (t, 1) == empty_stmt_node)
! remove_stmt (i.tp);
}
else
! remove_stmt (i.tp);
}
--- 1190,1201 ----
/* If both operands are empty, delete the whole COMPOUND_EXPR. */
if (TREE_OPERAND (t, 1) == empty_stmt_node)
! remove_stmt (i->tp);
}
else
! remove_stmt (i->tp);
!
! bsi_next (i);
}
*************** bsi_start (bb)
*** 2414,2419 ****
--- 2418,2475 ----
return i;
}
+ /* Find the previous iterator value. */
+
+ void
+ bsi_prev (i)
+ block_stmt_iterator *i;
+ {
+ block_stmt_iterator bi, next;
+
+ bi = bsi_start (bb_for_stmt (bsi_stmt (*i)));
+ if (bi.tp != i->tp)
+ {
+ for ( ; !bsi_end_p (bi); bi = next)
+ {
+ next = bi;
+ bsi_next (&next);
+ if (next.tp == i->tp)
+ {
+ i->tp = bi.tp;
+ return;
+ }
+ }
+ }
+
+ i->tp = NULL;
+ bi.context = NULL_TREE;
+ return;
+ }
+
+
+ /* Initialize a block_stmt_iterator with a statement pointed to by a tree
+ iterator. If this cannot be done, a NULL iterator is returned. */
+
+ block_stmt_iterator
+ bsi_from_tsi (ti)
+ tree_stmt_iterator ti;
+ {
+ basic_block bb;
+ tree stmt;
+ block_stmt_iterator bi;
+
+ stmt = tsi_stmt (ti);
+ if (stmt)
+ {
+ bb = bb_for_stmt (stmt);
+ if (bb)
+ return bsi_init (ti.tp, bb);
+ }
+
+ bi.tp = NULL;
+ bi.context = NULL_TREE;
+ return bi;
+ }
/* Insert statement T into basic block BB. */
Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow-inline.h,v
retrieving revision 1.1.2.28
diff -c -p -r1.1.2.28 tree-flow-inline.h
*** tree-flow-inline.h 25 Feb 2003 13:28:24 -0000 1.1.2.28
--- tree-flow-inline.h 5 Mar 2003 19:05:51 -0000
*************** bsi_next (i)
*** 355,368 ****
bsi_next_in_bb (i, bb);
}
- static inline void
- bsi_prev (i)
- block_stmt_iterator *i;
- {
- printf (" bsi_prev (%p) is not implemented yet\n",(void *)i);
- abort();
- }
-
static inline tree *
bsi_stmt_ptr (i)
block_stmt_iterator i;
--- 355,360 ----
*************** bsi_container (i)
*** 399,404 ****
--- 391,405 ----
block_stmt_iterator i;
{
return i.tp;
+ }
+
+ /* Return a tree_stmt_iterator for the stmt a block iterator refers to. */
+
+ static inline tree_stmt_iterator
+ tsi_from_bsi (bi)
+ block_stmt_iterator bi;
+ {
+ return tsi_start (bi.tp);
}
static inline bool
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.60
diff -c -p -r1.1.4.60 tree-flow.h
*** tree-flow.h 1 Mar 2003 00:09:07 -0000 1.1.4.60
--- tree-flow.h 5 Mar 2003 19:05:51 -0000
*************** typedef struct {
*** 275,286 ****
extern block_stmt_iterator bsi_start PARAMS ((basic_block));
static inline bool bsi_end_p PARAMS ((block_stmt_iterator));
static inline void bsi_next PARAMS ((block_stmt_iterator *));
! static inline void bsi_prev PARAMS ((block_stmt_iterator *));
static inline tree bsi_stmt PARAMS ((block_stmt_iterator));
static inline tree *bsi_stmt_ptr PARAMS ((block_stmt_iterator));
static inline tree *bsi_container PARAMS ((block_stmt_iterator));
! extern void bsi_remove PARAMS ((block_stmt_iterator));
void bsi_next_in_bb PARAMS ((block_stmt_iterator *, basic_block));
--- 275,307 ----
extern block_stmt_iterator bsi_start PARAMS ((basic_block));
static inline bool bsi_end_p PARAMS ((block_stmt_iterator));
static inline void bsi_next PARAMS ((block_stmt_iterator *));
! extern void bsi_prev PARAMS ((block_stmt_iterator *));
static inline tree bsi_stmt PARAMS ((block_stmt_iterator));
static inline tree *bsi_stmt_ptr PARAMS ((block_stmt_iterator));
static inline tree *bsi_container PARAMS ((block_stmt_iterator));
! extern block_stmt_iterator bsi_from_tsi PARAMS ((tree_stmt_iterator));
! static inline tree_stmt_iterator tsi_from_bsi PARAMS ((block_stmt_iterator));
!
! extern void bsi_remove PARAMS ((block_stmt_iterator *));
!
! enum bsi_iterator_update
! {
! BSI_NEW_STMT,
! BSI_SAME_STMT
! };
!
! /* Single stmt insertion routines. */
!
! extern void bsi_insert_before PARAMS ((block_stmt_iterator *, tree, enum bsi_iterator_update));
! extern void bsi_insert_after PARAMS ((block_stmt_iterator *, tree, enum bsi_iterator_update));
! extern block_stmt_iterator bsi_insert_on_edge PARAMS ((edge, tree));
!
! /* Stmt list insertion routines. */
!
! extern void bsi_insert_list_before PARAMS ((block_stmt_iterator *, tree_stmt_anchor));
! extern void bsi_insert_list_after PARAMS ((block_stmt_iterator *, tree_stmt_anchor));
! extern block_stmt_iterator bsi_insert_list_on_edge PARAMS ((edge, tree_stmt_anchor));
void bsi_next_in_bb PARAMS ((block_stmt_iterator *, basic_block));
Index: tree-iterator.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-iterator.h,v
retrieving revision 1.1.2.1
diff -c -p -r1.1.2.1 tree-iterator.h
*** tree-iterator.h 6 Feb 2003 04:41:05 -0000 1.1.2.1
--- tree-iterator.h 5 Mar 2003 19:05:51 -0000
*************** tsi_container (i)
*** 127,130 ****
--- 127,149 ----
return i.tp;
}
+
+ /* Abstract interface for linking and chaining stmts. Declared in tree.c. */
+
+ /* A tree_stmt_anchor is used as the root of a stmt list. */
+ typedef tree tree_stmt_anchor;
+ #define EMPTY_ANCHOR NULL_TREE
+
+ enum tsi_iterator_update
+ {
+ TSI_NEW_STMT,
+ TSI_SAME_STMT
+ };
+
+ void tsi_link_before PARAMS ((tree_stmt_iterator *, tree, enum tsi_iterator_update));
+ void tsi_link_after PARAMS ((tree_stmt_iterator *, tree, enum tsi_iterator_update));
+ void tsi_delink PARAMS ((tree_stmt_iterator *));
+ tree_stmt_iterator tsi_new_stmt_list PARAMS ((tree, tree_stmt_anchor *));
+ tree_stmt_iterator tsi_stmt_list_head PARAMS ((tree_stmt_anchor));
+
#endif /* _TREE_ITERATOR_H */
Index: tree-ssa-dce.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dce.c,v
retrieving revision 1.1.2.29
diff -c -p -r1.1.2.29 tree-ssa-dce.c
*** tree-ssa-dce.c 25 Feb 2003 13:28:25 -0000 1.1.2.29
--- tree-ssa-dce.c 5 Mar 2003 19:05:51 -0000
*************** static void find_useful_stmts PARAMS (
*** 91,97 ****
static bool stmt_useful_p PARAMS ((tree));
static void process_worklist PARAMS ((void));
static void remove_dead_stmts PARAMS ((void));
! static void remove_dead_stmt PARAMS ((block_stmt_iterator,
basic_block));
static void remove_dead_phis PARAMS ((basic_block));
--- 91,97 ----
static bool stmt_useful_p PARAMS ((tree));
static void process_worklist PARAMS ((void));
static void remove_dead_stmts PARAMS ((void));
! static void remove_dead_stmt PARAMS ((block_stmt_iterator *,
basic_block));
static void remove_dead_phis PARAMS ((basic_block));
*************** remove_dead_stmts ()
*** 413,426 ****
remove_dead_phis (bb);
/* Remove dead statements. */
! for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
{
t = bsi_stmt (i);
stats.total++;
/* If `i' is not in `necessary' then remove from B. */
if (!necessary_p (t))
! remove_dead_stmt (i, bb);
}
}
--- 413,428 ----
remove_dead_phis (bb);
/* Remove dead statements. */
! for (i = bsi_start (bb); !bsi_end_p (i); )
{
t = bsi_stmt (i);
stats.total++;
/* If `i' is not in `necessary' then remove from B. */
if (!necessary_p (t))
! remove_dead_stmt (&i, bb);
! else
! bsi_next (&i);
}
}
*************** remove_dead_phis (bb)
*** 464,475 ****
static void
remove_dead_stmt (i, bb)
! block_stmt_iterator i;
basic_block bb;
{
tree t;
! t = bsi_stmt (i);
STRIP_NOPS (t);
if (dump_file && (dump_flags & TDF_DETAILS))
--- 466,477 ----
static void
remove_dead_stmt (i, bb)
! block_stmt_iterator *i;
basic_block bb;
{
tree t;
! t = bsi_stmt (*i);
STRIP_NOPS (t);
if (dump_file && (dump_flags & TDF_DETAILS))
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.263.2.24
diff -c -p -r1.263.2.24 tree.c
*** tree.c 23 Feb 2003 22:03:06 -0000 1.263.2.24
--- tree.c 5 Mar 2003 19:05:54 -0000
*************** Software Foundation, 59 Temple Place - S
*** 45,50 ****
--- 45,51 ----
#include "output.h"
#include "target.h"
#include "langhooks.h"
+ #include "tree-iterator.h"
/* obstack.[ch] explicitly declined to prototype this. */
extern int _obstack_allocated_p PARAMS ((struct obstack *h, PTR obj));
*************** build_vdef_expr (var)
*** 4957,4962 ****
--- 4958,5092 ----
abort ();
return build (VDEF_EXPR, TREE_TYPE (var), var, var);
+ }
+
+
+
+ /* Links a stmt before the current stmt. */
+
+ void
+ tsi_link_before (i, t, mode)
+ tree_stmt_iterator *i;
+ tree t;
+ enum tsi_iterator_update mode;
+ {
+ tree ce;
+
+ /* Build a new CE which points to the current node. */
+ ce = build (COMPOUND_EXPR, void_type_node, t, *(i->tp));
+
+ /* Make the parent pointer point to this new node. At this point, the
+ iterator will be pointing to the new node we just inserted. */
+ *(i->tp) = ce;
+
+ /* Update the iterator to points to the address of the next ptr in our new
+ node, which is the current stmt again. */
+ if (mode == TSI_SAME_STMT)
+ i->tp = &(TREE_OPERAND (*(i->tp), 1));
+
+ }
+
+ /* Links a stmt after the current stmt. */
+
+ void
+ tsi_link_after (i, t, mode)
+ tree_stmt_iterator *i;
+ tree t;
+ enum tsi_iterator_update mode;
+ {
+ tree ce;
+ tree next;
+
+ /* If this node isnt a COMPUND_EXPR, we need to insert a CE node. */
+ if (TREE_CODE (*(i->tp)) != COMPOUND_EXPR)
+ {
+ /* Create a new node with the current stmt on the left, and the new
+ stmt on the right. */
+ ce = build (COMPOUND_EXPR, void_type_node, *(i->tp), t);
+
+ /* Update link to point to this CE node. */
+ *(i->tp) = ce;
+
+ /* Change new iterator to point to the new stmt. */
+ if (mode == TSI_NEW_STMT)
+ i->tp = &(TREE_OPERAND (ce, 1));
+ }
+ else
+ {
+ next = TREE_OPERAND (*(i->tp), 1);
+
+ /* Create a new node with the same 'next' link as the current one. */
+ ce = build (COMPOUND_EXPR, void_type_node, t, next);
+
+ /* Make the current one's 'next' link point to our new stmt. */
+ TREE_OPERAND (*(i->tp), 1) = ce;
+
+ /* Update the iterator to the new stmt. */
+ if (mode == TSI_NEW_STMT)
+ i->tp = &(TREE_OPERAND (*(i->tp), 1));
+ }
+
+
+ }
+
+ /* Remove a stmt from the tree list. The iterator is updated to point to
+ the next stmt. */
+
+ void
+ tsi_delink (i)
+ tree_stmt_iterator *i;
+ {
+
+ if (TREE_CODE (*(i->tp)) == COMPOUND_EXPR)
+ {
+ /* All that is needed here is to change the parent to point to the next
+ stmt in the chain. */
+ *(i->tp) = TREE_OPERAND (*(i->tp), 1);
+ }
+ else
+ {
+ /* This stmt is the last link in the CE chain, but we're screwed because
+ there isn't access to the node itself. the choices are either adding a
+ NULL link to the right side of the CE node, which is bad, or replacing
+ this node with an empty_stmt_node. Choose the latter for now, and
+ make the iterator return NULL, so that no further iterating takes
+ place. */
+ *(i->tp) = empty_stmt_node;
+ i->tp = NULL;
+ }
+ }
+
+ /* Create a new stmt list beginning with this stmt. The anchor is used mostly
+ to keep the garbage collector from collecting the root node, and to give
+ the list a place to start. */
+
+ tree_stmt_iterator
+ tsi_new_stmt_list (t, anchor)
+ tree t;
+ tree_stmt_anchor *anchor;
+ {
+ tree_stmt_iterator i;
+
+ *anchor = t;
+ i.tp = anchor;
+
+ return i;
+ }
+
+ /* Return an iterator which begins at this anchor. */
+
+ tree_stmt_iterator
+ tsi_stmt_list_head (anchor)
+ tree_stmt_anchor anchor;
+ {
+ tree_stmt_iterator i;
+
+ if (anchor == EMPTY_ANCHOR)
+ i.tp = NULL;
+ else
+ i.tp = &anchor;
+
+ return i;
}
#include "gt-tree.h"
More information about the Gcc-patches
mailing list