This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [tree-ssa] Operand management II
- From: Andrew MacLeod <amacleod at redhat dot com>
- To: Andrew MacLeod <amacleod at redhat dot com>
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: 16 Dec 2003 17:50:05 -0500
- Subject: Re: [tree-ssa] Operand management II
- References: <1071610959.13039.192.camel@p4>
On Tue, 2003-12-16 at 16:42, Andrew MacLeod wrote:
> This is the follow on patch to the operand management rework.
>
oops :-)
>
> Andrew
>
> 2003-12-16 Andrew MacLeod <amacleod@redhat.com>
>
> * tree-flow-inline.h (free_vuse, free_vdefs): Moved to
> tree-ssa-operands.c
> (get_def_ops, get_use_ops, get_vdef_ops, get_vuse_ops): Use the new
> more direct structure pointer.
> (get_use_op_ptr, get_def_op_ptr): Cast is no longer necessary.
> * tree-flow.h (struct stmt_ann_d): Replace operands and voperands
> pointers with pointers directly to the operand types.
> * tree-ssa-dom.c (cprop_into_stmt): Use new stmt based interface to
> free virtual operands. Check virtual bases of both VUSE and VDEF.
> * tree-ssa-operands.c (struct voperands_d): Declare here, used only
> for previous_vops during stmt operand construction.
> (struct vecmanage_d, vecmanage_add_segmen, vecmanage_add_special,
> vecmanage_init, vecmanage_tree_ptr_init, vecmanage_fini, check_free,
> vecmanage_new_vector, vecmanage_new_tree_ptr_vector,
> vecmanage_free_vector): Remove.
> (allocate_ssa_op_vec, free_ssa_op_vec, allocate_ssa_virtual_op_vec,
> allocate_operands_t, allocate_voperands_t): Remove.
> (finalize_new_ssa_operands, inalize_new_ssa_virtual_operand): Remove.
> (struct freelist_d): New. List of free operand structures.
> (check_optype_freelist): New. Choose memory from freelist, if available.
> (add_optype_freelist): New. Add structure to freelist, if appropriate.
> (allocate_def_optype): New. Allocate a def operand list from GC.
> (allocate_use_optype): New. Allocate a useoperand list from GC.
> (allocate_vdef_optype): New. Allocate a vdef operand list from GC.
> (allocate_vuse_optype): New. Allocate a vuse operand list from GC.
> (free_uses, free_defs, free_vuses, free_vdefs): Use GC and the freelist.
> (remove_vuses, remove_vdefs): New. External interface to remove virtual
> operands.
> (init_ssa_operands, fini_ssa_operands): Ensure the free list is empty.
> (finalize_ssa_defs, finalize_ssa_use, finalize_ssa_vdefs,
> finalize_ssa_vuses): Use new direct pointers from the stmt annotation.
> (append_vdef, append_vuse): No need to hack prev_vops pointer now.
> (get_stmt_operands): use new freeing interface, keep previous vops in
> their own local structure for now, passing its address around.
> * tree-ssa-operands.h (struct def_optype_d, struct use_optype_d,
> struct vdef_optype_d, struct vuse_optype_d): Implement as a single
> dynamically allocated structure.
> (struct operands_d, struct operands_d): Remove.
> * tree-ssa-pre.c (subst_phis): Remove virtual operands using new funcs.
>
Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow-inline.h,v
retrieving revision 1.1.2.62
diff -c -p -r1.1.2.62 tree-flow-inline.h
*** tree-flow-inline.h 15 Dec 2003 22:58:34 -0000 1.1.2.62
--- tree-flow-inline.h 16 Dec 2003 20:52:34 -0000
*************** stmt_modified_p (tree t)
*** 198,245 ****
return ann ? ann->modified : true;
}
- static inline void
- free_vuses (vuse_optype vuses)
- {
- if (NUM_VUSES (vuses) > 0)
- {
- vuses->num_vuses = 0;
- vuses->vuses = NULL;
- }
- }
-
- static inline void
- free_vdefs (vdef_optype vdefs)
- {
- if (NUM_VDEFS (vdefs) > 0)
- {
- vdefs->num_vdefs = 0;
- vdefs->vdefs = NULL;
- }
- }
-
static inline def_optype
get_def_ops (stmt_ann_t ann)
{
! return ann ? (ann->ops ? &(ann->ops->def_ops) : NULL) : NULL;
}
static inline use_optype
get_use_ops (stmt_ann_t ann)
{
! return ann ? (ann->ops ? &(ann->ops->use_ops) : NULL) : NULL;
}
static inline vdef_optype
get_vdef_ops (stmt_ann_t ann)
{
! return ann ? (ann->vops ? &(ann->vops->vdef_ops) : NULL) : NULL;
}
static inline vuse_optype
get_vuse_ops (stmt_ann_t ann)
{
! return ann ? (ann->vops ? &(ann->vops->vuse_ops) : NULL) : NULL;
}
static inline tree *
--- 198,225 ----
return ann ? ann->modified : true;
}
static inline def_optype
get_def_ops (stmt_ann_t ann)
{
! return ann ? ann->def_ops : NULL;
}
static inline use_optype
get_use_ops (stmt_ann_t ann)
{
! return ann ? ann->use_ops : NULL;
}
static inline vdef_optype
get_vdef_ops (stmt_ann_t ann)
{
! return ann ? ann->vdef_ops : NULL;
}
static inline vuse_optype
get_vuse_ops (stmt_ann_t ann)
{
! return ann ? ann->vuse_ops : NULL;
}
static inline tree *
*************** get_use_op_ptr (use_optype uses, unsigne
*** 249,255 ****
if (index >= uses->num_uses)
abort();
#endif
! return ((tree **)uses->uses)[index];
}
static inline tree *
--- 229,235 ----
if (index >= uses->num_uses)
abort();
#endif
! return uses->uses[index];
}
static inline tree *
*************** get_def_op_ptr (def_optype defs, unsigne
*** 259,265 ****
if (index >= defs->num_defs)
abort();
#endif
! return ((tree **)defs->defs)[index];
}
static inline tree *
--- 239,245 ----
if (index >= defs->num_defs)
abort();
#endif
! return defs->defs[index];
}
static inline tree *
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.171
diff -c -p -r1.1.4.171 tree-flow.h
*** tree-flow.h 15 Dec 2003 22:58:34 -0000 1.1.4.171
--- tree-flow.h 16 Dec 2003 20:52:35 -0000
*************** struct stmt_ann_d GTY(())
*** 220,229 ****
basic_block GTY ((skip (""))) bb;
/* Statement operands. */
! struct operands_d * GTY (()) ops;
/* Virtual operands (VDEF and VUSE). */
! struct voperands_d * GTY (()) vops;
/* Dataflow information. */
dataflow_t df;
--- 220,231 ----
basic_block GTY ((skip (""))) bb;
/* Statement operands. */
! struct def_optype_d * GTY (()) def_ops;
! struct use_optype_d * GTY (()) use_ops;
/* Virtual operands (VDEF and VUSE). */
! struct vdef_optype_d * GTY (()) vdef_ops;
! struct vuse_optype_d * GTY (()) vuse_ops;
/* Dataflow information. */
dataflow_t df;
Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dom.c,v
retrieving revision 1.1.2.97
diff -c -p -r1.1.2.97 tree-ssa-dom.c
*** tree-ssa-dom.c 15 Dec 2003 22:58:34 -0000 1.1.2.97
--- tree-ssa-dom.c 16 Dec 2003 20:52:35 -0000
*************** cprop_into_stmt (tree stmt)
*** 1764,1770 ****
the renamed virtual operand if we later modify this
statement. Also only allow the new value to be an SSA_NAME
for propagation into virtual operands. */
! if (table_index > 1
&& (get_virtual_var (val) != get_virtual_var (*op_p)
|| TREE_CODE (val) != SSA_NAME))
continue;
--- 1764,1770 ----
the renamed virtual operand if we later modify this
statement. Also only allow the new value to be an SSA_NAME
for propagation into virtual operands. */
! if (table_index > 0
&& (get_virtual_var (val) != get_virtual_var (*op_p)
|| TREE_CODE (val) != SSA_NAME))
continue;
*************** record_equivalences_from_stmt (tree stmt
*** 2113,2120 ****
/* Clear out the virtual operands on the new statement, we are
going to set them explicitly below. */
! free_vuses (STMT_VUSE_OPS (new));
! free_vdefs (STMT_VDEF_OPS (new));
start_ssa_stmt_operands (new);
/* For each VDEF on the original statement, we want to create a
--- 2113,2120 ----
/* Clear out the virtual operands on the new statement, we are
going to set them explicitly below. */
! remove_vuses (new);
! remove_vdefs (new);
start_ssa_stmt_operands (new);
/* For each VDEF on the original statement, we want to create a
Index: tree-ssa-operands.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-operands.c,v
retrieving revision 1.1.2.1
diff -c -p -r1.1.2.1 tree-ssa-operands.c
*** tree-ssa-operands.c 15 Dec 2003 22:58:37 -0000 1.1.2.1
--- tree-ssa-operands.c 16 Dec 2003 20:52:35 -0000
*************** static GTY (()) varray_type build_vuses;
*** 62,67 ****
--- 62,73 ----
tree check_build_stmt;
#endif
+ typedef struct voperands_d
+ {
+ vdef_optype vdef_ops;
+ vuse_optype vuse_ops;
+ } *voperands_t;
+
static void note_addressable (tree, stmt_ann_t);
static void get_expr_operands (tree, tree *, int, voperands_t);
static inline void append_def (tree *, tree);
*************** static void add_call_read_ops (tree, vop
*** 72,390 ****
static void add_stmt_operand (tree *, tree, int, voperands_t);
static int get_call_flags (tree);
- #define VECSIZE 1024
- #define SPECIAL_THRESHOLD 128
- #define NUM_FREE 3
-
- typedef struct vecmanage_d
- {
- varray_type vecs;
- varray_type special; /* Used for large vectors. */
- size_t top;
- size_t type_size;
- void *free[NUM_FREE];
- void *free_32;
- void *free_128;
- void *free_1024;
- } vecmanage_t;
-
- typedef vecmanage_t *vecmanage_type;
-
-
- /* Adds a new segment, and returns the new segments index. */
- static int
- vecmanage_add_segment (vecmanage_type sa)
- {
- void *ptr;
- ptr = xmalloc (sa->type_size * VECSIZE);
- VARRAY_PUSH_GENERIC_PTR_NOGC (sa->vecs, ptr);
- return VARRAY_ACTIVE_SIZE (sa->vecs) - 1;
- }
-
- static void *
- vecmanage_add_special (vecmanage_type sa, size_t size)
- {
- void *ptr;
- ptr = xmalloc (sa->type_size * size);
- if (!sa->special)
- VARRAY_GENERIC_PTR_NOGC_INIT (sa->special, 10, "vecmanage_special");
- VARRAY_PUSH_GENERIC_PTR_NOGC (sa->special, ptr);
- return ptr;
- }
-
- static void
- vecmanage_init (vecmanage_type sa, size_t size)
- {
- int x;
- sa->top = 0;
- sa->special = NULL;
- sa->type_size = size;
- for (x = 0; x < NUM_FREE; x++)
- sa->free[x] = NULL;
- /* Allocate the first segment. */
- VARRAY_GENERIC_PTR_NOGC_INIT (sa->vecs, 10, "vecmanage_vecs");
- vecmanage_add_segment (sa);
- }
-
- static inline void
- vecmanage_tree_ptr_init (vecmanage_type sa)
- {
- vecmanage_init (sa, sizeof (tree *));
- }
! static void
! vecmanage_fini (vecmanage_type sa)
{
! int x;
! void *ptr;
!
! sa->top = 0;
! if (!sa->vecs)
! return;
! /* Free the allocated vectors in reverse order of allocation. */
! for (x = VARRAY_ACTIVE_SIZE (sa->vecs) - 1; x >= 0; x--)
! {
! ptr = VARRAY_TOP_GENERIC_PTR_NOGC (sa->vecs);
! VARRAY_POP (sa->vecs);
! free (ptr);
! }
! VARRAY_FREE (sa->vecs);
- if (sa->special)
- {
- for (x = VARRAY_ACTIVE_SIZE (sa->special) - 1; x >= 0; x--)
- {
- ptr = VARRAY_TOP_GENERIC_PTR_NOGC (sa->special);
- VARRAY_POP (sa->special);
- free (ptr);
- }
- VARRAY_FREE (sa->special);
- }
- }
! static void **
! check_free (vecmanage_type sa, size_t num)
{
! void **vec = NULL;
! if (num <= NUM_FREE && sa->free[num - 1])
{
! vec = (void **)sa->free[num - 1];
! sa->free[num - 1] = *vec;
}
return vec;
}
/* Return a vector of contguous memory of a specified size. */
- static void *
- vecmanage_new_vector (vecmanage_type sa, size_t num)
- {
- int vec_num;
- size_t vec_index;
- void **vec;
- vec_num = VARRAY_ACTIVE_SIZE (sa->vecs) - 1;
- vec_index = sa->top;
-
- vec = check_free (sa, num);
- if (vec)
- return vec;
- if (vec_index + num >= VECSIZE)
- {
- if (num < SPECIAL_THRESHOLD)
- {
- vec_num = vecmanage_add_segment (sa);
- vec_index = 0;
- }
- else
- {
- vec = vecmanage_add_special (sa, num);
- return vec;
- }
- }
-
- vec = (void **)VARRAY_GENERIC_PTR_NOGC (sa->vecs, vec_num);
- vec = &((vec)[vec_index]);
- sa->top = vec_index + num;
- return vec;
- }
-
- static inline tree **
- vecmanage_new_tree_ptr_vector (vecmanage_type sa, size_t num)
- {
- return (tree **)vecmanage_new_vector (sa, num);
- }
static inline void
! vecmanage_free_vector (vecmanage_type sa, void **vec, size_t size)
{
#ifdef ENABLE_CHECKING
if (size == 0)
abort ();
#endif
! /* Put it into one of the free lists. */
if (size > NUM_FREE)
! size = 2;
! vec[0] = sa->free[size - 1];
! sa->free[size - 1] = (void *)vec;
! return;
}
- vecmanage_t ssa_operands;
! static inline tree **
! allocate_ssa_op_vec (unsigned num)
! {
! return vecmanage_new_tree_ptr_vector (&ssa_operands, num);
}
static inline void
! free_ssa_op_vec (tree **vec, size_t size)
! {
! vecmanage_free_vector (&ssa_operands, (void **)vec, size);
! }
! static inline tree *
! allocate_ssa_virtual_op_vec (unsigned num)
{
! return (tree *)ggc_alloc (num * sizeof (tree));
! }
!
! static inline operands_t
! allocate_operands_t (void)
! {
! operands_t ptr;
! ptr = (operands_t)ggc_alloc (sizeof (struct operands_d));
! memset ((void *) ptr , 0, sizeof (struct operands_d));
! return ptr;
}
! static inline voperands_t
! allocate_voperands_t (void)
{
! voperands_t ptr;
! ptr = (voperands_t)ggc_alloc (sizeof (struct voperands_d));
! memset ((void *) ptr , 0, sizeof (struct voperands_d));
! return ptr;
}
static inline void
! free_uses (use_optype uses)
{
! if (NUM_USES (uses) > 0)
{
! free_ssa_op_vec (uses->uses, uses->num_uses);
! uses->num_uses = 0;
! uses->uses = NULL;
}
}
static inline void
! free_defs (def_optype defs)
{
! if (NUM_DEFS (defs) > 0)
{
! free_ssa_op_vec (defs->defs, defs->num_defs);
! defs->num_defs = 0;
! defs->defs = NULL;
}
}
void
! init_ssa_operands (void)
{
! VARRAY_TREE_PTR_INIT (build_defs, 5, "build defs");
! VARRAY_TREE_PTR_INIT (build_uses, 10, "build uses");
! VARRAY_TREE_INIT (build_vdefs, 10, "build vdefs");
! VARRAY_TREE_INIT (build_vuses, 10, "build vuses");
! vecmanage_tree_ptr_init (&ssa_operands);
}
void
! fini_ssa_operands (void)
{
! vecmanage_fini (&ssa_operands);
}
- static inline tree **
- finalize_new_ssa_operands (varray_type build)
- {
- tree **vec;
- unsigned num, x;
! num = VARRAY_ACTIVE_SIZE (build);
! if (num == 0)
! return 0;
! vec = allocate_ssa_op_vec (num);
! for (x = 0; x < num; x++)
! vec[x] = VARRAY_TREE_PTR (build, x);
! VARRAY_POP_ALL (build);
! return vec;
}
! static inline tree *
! finalize_new_ssa_virtual_operands (varray_type build)
{
! tree *vec;
! unsigned num, x;
!
! num = VARRAY_ACTIVE_SIZE (build);
! if (num == 0)
! return 0;
!
! vec = allocate_ssa_virtual_op_vec (num);
! for (x = 0; x < num; x++)
! vec[x] = VARRAY_TREE (build, x);
!
! VARRAY_POP_ALL (build);
! return vec;
}
static void
finalize_ssa_defs (tree stmt)
{
! unsigned num;
! tree **vec;
stmt_ann_t ann;
num = VARRAY_ACTIVE_SIZE (build_defs);
if (num == 0)
return;
- vec = finalize_new_ssa_operands (build_defs);
#ifdef ENABLE_CHECKING
/* There should only be a single real definition per assignment. */
if (TREE_CODE (stmt) == MODIFY_EXPR && num > 1)
abort ();
#endif
ann = stmt_ann (stmt);
! if (ann->ops == NULL)
! ann->ops = allocate_operands_t ();
! ann->ops->def_ops.num_defs = num;
! ann->ops->def_ops.defs = vec;
}
static void
finalize_ssa_uses (tree stmt)
{
! unsigned num;
! tree **vec;
stmt_ann_t ann;
num = VARRAY_ACTIVE_SIZE (build_uses);
if (num == 0)
return;
- vec = finalize_new_ssa_operands (build_uses);
-
- ann = stmt_ann (stmt);
- if (ann->ops == NULL)
- ann->ops = allocate_operands_t ();
- ann->ops->use_ops.num_uses = num;
- ann->ops->use_ops.uses = vec;
#ifdef ENABLE_CHECKING
{
unsigned x;
--- 78,309 ----
static void add_stmt_operand (tree *, tree, int, voperands_t);
static int get_call_flags (tree);
! struct freelist_d GTY((chain_next ("%h.next")))
{
! struct freelist_d *next;
! };
! #define NUM_FREE 4
! static GTY ((length ("NUM_FREE"))) struct freelist_d optype_freelist[NUM_FREE] = { {0}, {0}, {0}, {0} };
! static inline void *
! check_optype_freelist (size_t num)
{
! return NULL;
! #if 0
! void *vec = NULL;
! if (num <= NUM_FREE && optype_freelist[num - 1].next)
{
! vec = (void *)optype_freelist[num - 1].next;
! optype_freelist[num - 1].next = optype_freelist[num - 1].next->next;
}
return vec;
+ #endif
}
/* Return a vector of contguous memory of a specified size. */
static inline void
! add_optype_freelist (void *vec, size_t size)
{
+ #if 0
+ struct freelist_d *ptr;
#ifdef ENABLE_CHECKING
if (size == 0)
abort ();
#endif
!
! /* if its bigger than one of our lists, simply let it go and let GC
! collect it. */
if (size > NUM_FREE)
! return;
! ptr = vec;
! ptr->next = optype_freelist[size - 1].next;;
! optype_freelist[size - 1].next = ptr;
! #endif
}
! static inline def_optype
! allocate_def_optype (unsigned num)
! {
! def_optype def_ops;
! unsigned size;
! size = sizeof (struct def_optype_d) + sizeof (tree *) * (num - 1);
! def_ops = check_optype_freelist (num);
! if (!def_ops)
! def_ops = ggc_alloc (size);
! def_ops->num_defs = num;
! return def_ops;
! }
!
! static inline use_optype
! allocate_use_optype (unsigned num)
! {
! use_optype use_ops;
! unsigned size;
! size = sizeof (struct use_optype_d) + sizeof (tree *) * (num - 1);
! use_ops = check_optype_freelist (num);
! if (!use_ops)
! use_ops = ggc_alloc (size);
! use_ops->num_uses = num;
! return use_ops;
! }
!
! static inline vdef_optype
! allocate_vdef_optype (unsigned num)
! {
! vdef_optype vdef_ops;
! unsigned size;
! size = sizeof (struct vdef_optype_d) + sizeof (tree) * ((num * 2) - 1);
! vdef_ops = check_optype_freelist (num * 2);
! if (!vdef_ops)
! vdef_ops = ggc_alloc (size);
! vdef_ops->num_vdefs = num;
! return vdef_ops;
! }
!
! static inline vuse_optype
! allocate_vuse_optype (unsigned num)
! {
! vuse_optype vuse_ops;
! unsigned size;
! size = sizeof (struct vuse_optype_d) + sizeof (tree) * (num - 1);
! vuse_ops = check_optype_freelist (num);
! if (!vuse_ops)
! vuse_ops = ggc_alloc (size);
! vuse_ops->num_vuses = num;
! return vuse_ops;
}
static inline void
! free_uses (use_optype *uses, bool dealloc)
{
! if (*uses)
! {
! if (dealloc)
! add_optype_freelist (*uses, (*uses)->num_uses);
! *uses = NULL;
! }
}
! static inline void
! free_defs (def_optype *defs, bool dealloc)
{
! if (*defs)
! {
! if (dealloc)
! add_optype_freelist (*defs, (*defs)->num_defs);
! *defs = NULL;
! }
}
static inline void
! free_vuses (vuse_optype *vuses, bool dealloc)
{
! if (*vuses)
{
! if (dealloc)
! add_optype_freelist (*vuses, (*vuses)->num_vuses);
! *vuses = NULL;
}
}
static inline void
! free_vdefs (vdef_optype *vdefs, bool dealloc)
{
! if (*vdefs)
{
! if (dealloc)
! add_optype_freelist (*vdefs, (*vdefs)->num_vdefs);
! *vdefs = NULL;
}
}
void
! remove_vuses (tree stmt)
{
! stmt_ann_t ann;
!
! ann = stmt_ann (stmt);
! if (ann)
! free_vuses (&(ann->vuse_ops), true);
}
void
! remove_vdefs (tree stmt)
{
! stmt_ann_t ann;
!
! ann = stmt_ann (stmt);
! if (ann)
! free_vdefs (&(ann->vdef_ops), true);
}
! void
! init_ssa_operands (void)
! {
! int x;
! VARRAY_TREE_PTR_INIT (build_defs, 5, "build defs");
! VARRAY_TREE_PTR_INIT (build_uses, 10, "build uses");
! VARRAY_TREE_INIT (build_vdefs, 10, "build vdefs");
! VARRAY_TREE_INIT (build_vuses, 10, "build vuses");
! for (x = 0; x < NUM_FREE; x++)
! optype_freelist[x].next = NULL;
}
! void
! fini_ssa_operands (void)
{
! int x;
! for (x = 0; x < NUM_FREE; x++)
! optype_freelist[x].next = NULL;
}
static void
finalize_ssa_defs (tree stmt)
{
! unsigned num, x;
stmt_ann_t ann;
+ def_optype def_ops;
num = VARRAY_ACTIVE_SIZE (build_defs);
if (num == 0)
return;
#ifdef ENABLE_CHECKING
/* There should only be a single real definition per assignment. */
if (TREE_CODE (stmt) == MODIFY_EXPR && num > 1)
abort ();
#endif
+ def_ops = allocate_def_optype (num);
+ for (x = 0; x < num ; x++)
+ def_ops->defs[x] = VARRAY_TREE_PTR (build_defs, x);
+ VARRAY_POP_ALL (build_defs);
+
ann = stmt_ann (stmt);
! ann->def_ops = def_ops;
}
static void
finalize_ssa_uses (tree stmt)
{
! unsigned num, x;
! use_optype use_ops;
stmt_ann_t ann;
num = VARRAY_ACTIVE_SIZE (build_uses);
if (num == 0)
return;
#ifdef ENABLE_CHECKING
{
unsigned x;
*************** finalize_ssa_uses (tree stmt)
*** 393,436 ****
initial call to get_stmt_operands does not pass a pointer to a
statement). */
for (x = 0; x < num; x++)
! if (*(vec[x]) == stmt)
abort ();
}
#endif
}
static void
finalize_ssa_vdefs (tree stmt)
{
! unsigned num;
! tree *vec;
stmt_ann_t ann;
num = VARRAY_ACTIVE_SIZE (build_vdefs);
if (num == 0)
return;
- vec = finalize_new_ssa_virtual_operands (build_vdefs);
-
#ifdef ENABLE_CHECKING
/* VDEFs must be entered in pairs of result/uses. */
if (num % 2 != 0)
abort();
#endif
ann = stmt_ann (stmt);
! if (ann->vops == NULL)
! ann->vops = allocate_voperands_t ();
! ann->vops->vdef_ops.num_vdefs = num / 2;
! ann->vops->vdef_ops.vdefs = vec;
}
static inline void
finalize_ssa_vuses (tree stmt)
{
! unsigned num;
! tree *vec;
stmt_ann_t ann;
vdef_optype vdefs;
#ifdef ENABLE_CHECKING
--- 312,363 ----
initial call to get_stmt_operands does not pass a pointer to a
statement). */
for (x = 0; x < num; x++)
! if (*(VARRAY_TREE_PTR (build_uses, x)) == stmt)
abort ();
}
#endif
+
+ use_ops = allocate_use_optype (num);
+ for (x = 0; x < num ; x++)
+ use_ops->uses[x] = VARRAY_TREE_PTR (build_uses, x);
+ VARRAY_POP_ALL (build_uses);
+
+ ann = stmt_ann (stmt);
+ ann->use_ops = use_ops;
}
static void
finalize_ssa_vdefs (tree stmt)
{
! unsigned num, x;
! vdef_optype vdef_ops;
stmt_ann_t ann;
num = VARRAY_ACTIVE_SIZE (build_vdefs);
if (num == 0)
return;
#ifdef ENABLE_CHECKING
/* VDEFs must be entered in pairs of result/uses. */
if (num % 2 != 0)
abort();
#endif
+ vdef_ops = allocate_vdef_optype (num / 2);
+ for (x = 0; x < num; x++)
+ vdef_ops->vdefs[x] = VARRAY_TREE (build_vdefs, x);
+ VARRAY_POP_ALL (build_vdefs);
+
ann = stmt_ann (stmt);
! ann->vdef_ops = vdef_ops;
}
static inline void
finalize_ssa_vuses (tree stmt)
{
! unsigned num, x;
stmt_ann_t ann;
+ vuse_optype vuse_ops;
vdef_optype vdefs;
#ifdef ENABLE_CHECKING
*************** finalize_ssa_vuses (tree stmt)
*** 511,522 ****
}
num = VARRAY_ACTIVE_SIZE (build_vuses);
! vec = finalize_new_ssa_virtual_operands (build_vuses);
! if (ann->vops == NULL)
! ann->vops = allocate_voperands_t ();
! ann->vops->vuse_ops.num_vuses = num;
! ann->vops->vuse_ops.vuses = vec;
}
extern void
--- 438,452 ----
}
num = VARRAY_ACTIVE_SIZE (build_vuses);
! /* We could have reduced the size to zero now, however. */
! if (num == 0)
! return;
! vuse_ops = allocate_vuse_optype (num);
! for (x = 0; x < num; x++)
! vuse_ops->vuses[x] = VARRAY_TREE (build_vuses, x);
! VARRAY_POP_ALL (build_vuses);
! ann->vuse_ops = vuse_ops;
}
extern void
*************** append_vdef (tree var, tree stmt, vopera
*** 616,629 ****
result = NULL_TREE;
source = NULL_TREE;
if (prev_vops)
! for (i = 0; i < NUM_VDEFS (&(prev_vops->vdef_ops)); i++)
{
! result = VDEF_RESULT (&(prev_vops->vdef_ops), i);
if (result == var
|| (TREE_CODE (result) == SSA_NAME
&& SSA_NAME_VAR (result) == var))
{
! source = VDEF_OP (&(prev_vops->vdef_ops), i);
break;
}
}
--- 546,559 ----
result = NULL_TREE;
source = NULL_TREE;
if (prev_vops)
! for (i = 0; i < NUM_VDEFS (prev_vops->vdef_ops); i++)
{
! result = VDEF_RESULT (prev_vops->vdef_ops, i);
if (result == var
|| (TREE_CODE (result) == SSA_NAME
&& SSA_NAME_VAR (result) == var))
{
! source = VDEF_OP (prev_vops->vdef_ops, i);
break;
}
}
*************** append_vuse (tree var, tree stmt, vopera
*** 676,684 ****
found = false;
vuse = NULL_TREE;
if (prev_vops)
! for (i = 0; i < NUM_VUSES (&(prev_vops->vuse_ops)); i++)
{
! vuse = VUSE_OP (&(prev_vops->vuse_ops), i);
if (vuse == var
|| (TREE_CODE (vuse) == SSA_NAME
&& SSA_NAME_VAR (vuse) == var))
--- 606,614 ----
found = false;
vuse = NULL_TREE;
if (prev_vops)
! for (i = 0; i < NUM_VUSES (prev_vops->vuse_ops); i++)
{
! vuse = VUSE_OP (prev_vops->vuse_ops, i);
if (vuse == var
|| (TREE_CODE (vuse) == SSA_NAME
&& SSA_NAME_VAR (vuse) == var))
*************** get_stmt_operands (tree stmt)
*** 731,737 ****
{
enum tree_code code;
stmt_ann_t ann;
! voperands_t prev_vops = NULL;
#if defined ENABLE_CHECKING
/* The optimizers cannot handle statements that are nothing but a
--- 661,667 ----
{
enum tree_code code;
stmt_ann_t ann;
! struct voperands_d prev_vops;
#if defined ENABLE_CHECKING
/* The optimizers cannot handle statements that are nothing but a
*************** get_stmt_operands (tree stmt)
*** 758,775 ****
}
/* Remove any existing operands as they will be scanned again. */
! if (ann->ops)
! {
! free_defs (&(ann->ops->def_ops));
! free_uses (&(ann->ops->use_ops));
! }
/* Before removing existing virtual operands, save them in PREV_VOPS so
that we can re-use their SSA versions. */
! if (ann->vops)
! prev_vops = ann->vops;
! ann->vops = NULL;
start_ssa_stmt_operands (stmt);
--- 688,704 ----
}
/* Remove any existing operands as they will be scanned again. */
! free_defs (&(ann->def_ops), true);
! free_uses (&(ann->use_ops), true);
/* Before removing existing virtual operands, save them in PREV_VOPS so
that we can re-use their SSA versions. */
! prev_vops.vdef_ops = VDEF_OPS (ann);
! prev_vops.vuse_ops = VUSE_OPS (ann);
! /* Dont free the previous values to memory since we're still using them. */
! free_vdefs (&(ann->vdef_ops), false);
! free_vuses (&(ann->vuse_ops), false);
start_ssa_stmt_operands (stmt);
*************** get_stmt_operands (tree stmt)
*** 777,792 ****
switch (code)
{
case MODIFY_EXPR:
! get_expr_operands (stmt, &TREE_OPERAND (stmt, 1), opf_none, prev_vops);
! get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def, prev_vops);
break;
case COND_EXPR:
! get_expr_operands (stmt, &COND_EXPR_COND (stmt), opf_none, prev_vops);
break;
case SWITCH_EXPR:
! get_expr_operands (stmt, &SWITCH_COND (stmt), opf_none, prev_vops);
break;
case ASM_EXPR:
--- 706,721 ----
switch (code)
{
case MODIFY_EXPR:
! get_expr_operands (stmt, &TREE_OPERAND (stmt, 1), opf_none, &prev_vops);
! get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def, &prev_vops);
break;
case COND_EXPR:
! get_expr_operands (stmt, &COND_EXPR_COND (stmt), opf_none, &prev_vops);
break;
case SWITCH_EXPR:
! get_expr_operands (stmt, &SWITCH_COND (stmt), opf_none, &prev_vops);
break;
case ASM_EXPR:
*************** get_stmt_operands (tree stmt)
*** 812,818 ****
if (!allows_reg && allows_mem)
note_addressable (TREE_VALUE (link), ann);
get_expr_operands (stmt, &TREE_VALUE (link), opf_is_def,
! prev_vops);
}
for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
{
--- 741,747 ----
if (!allows_reg && allows_mem)
note_addressable (TREE_VALUE (link), ann);
get_expr_operands (stmt, &TREE_VALUE (link), opf_is_def,
! &prev_vops);
}
for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
{
*************** get_stmt_operands (tree stmt)
*** 822,846 ****
oconstraints, &allows_mem, &allows_reg);
if (!allows_reg && allows_mem)
note_addressable (TREE_VALUE (link), ann);
! get_expr_operands (stmt, &TREE_VALUE (link), 0, prev_vops);
}
for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
if (!strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory")
&& num_call_clobbered_vars > 0)
! add_call_clobber_ops (stmt, prev_vops);
}
break;
case RETURN_EXPR:
! get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_none, prev_vops);
break;
case GOTO_EXPR:
! get_expr_operands (stmt, &GOTO_DESTINATION (stmt), opf_none, prev_vops);
break;
case LABEL_EXPR:
! get_expr_operands (stmt, &LABEL_EXPR_LABEL (stmt), opf_none, prev_vops);
break;
/* These nodes contain no variable references. */
--- 751,775 ----
oconstraints, &allows_mem, &allows_reg);
if (!allows_reg && allows_mem)
note_addressable (TREE_VALUE (link), ann);
! get_expr_operands (stmt, &TREE_VALUE (link), 0, &prev_vops);
}
for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
if (!strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory")
&& num_call_clobbered_vars > 0)
! add_call_clobber_ops (stmt, &prev_vops);
}
break;
case RETURN_EXPR:
! get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_none, &prev_vops);
break;
case GOTO_EXPR:
! get_expr_operands (stmt, &GOTO_DESTINATION (stmt), opf_none, &prev_vops);
break;
case LABEL_EXPR:
! get_expr_operands (stmt, &LABEL_EXPR_LABEL (stmt), opf_none, &prev_vops);
break;
/* These nodes contain no variable references. */
*************** get_stmt_operands (tree stmt)
*** 859,869 ****
append_use. This default will handle statements like empty statements,
CALL_EXPRs or VA_ARG_EXPRs that may appear on the RHS of a statement
or as statements themselves. */
! get_expr_operands (stmt, &stmt, opf_none, prev_vops);
break;
}
finalize_ssa_stmt_operands (stmt);
/* Clear the modified bit for STMT. Subsequent calls to
get_stmt_operands for this statement will do nothing until the
--- 788,802 ----
append_use. This default will handle statements like empty statements,
CALL_EXPRs or VA_ARG_EXPRs that may appear on the RHS of a statement
or as statements themselves. */
! get_expr_operands (stmt, &stmt, opf_none, &prev_vops);
break;
}
finalize_ssa_stmt_operands (stmt);
+
+ /* Now free the previous virtual ops to memory. */
+ free_vdefs (&(prev_vops.vdef_ops), true);
+ free_vuses (&(prev_vops.vuse_ops), true);
/* Clear the modified bit for STMT. Subsequent calls to
get_stmt_operands for this statement will do nothing until the
Index: tree-ssa-operands.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-operands.h,v
retrieving revision 1.1.2.1
diff -c -p -r1.1.2.1 tree-ssa-operands.h
*** tree-ssa-operands.h 15 Dec 2003 22:58:37 -0000 1.1.2.1
--- tree-ssa-operands.h 16 Dec 2003 20:52:35 -0000
*************** Software Foundation, 59 Temple Place - S
*** 26,32 ****
typedef struct def_optype_d GTY(())
{
unsigned num_defs;
! tree ** GTY((skip(""))) defs;
} def_optype_t;
typedef def_optype_t *def_optype;
--- 26,32 ----
typedef struct def_optype_d GTY(())
{
unsigned num_defs;
! tree * GTY((length("%h.num_defs"), skip(""))) defs[1];
} def_optype_t;
typedef def_optype_t *def_optype;
*************** typedef def_optype_t *def_optype;
*** 34,40 ****
typedef struct use_optype_d GTY(())
{
unsigned num_uses;
! tree ** GTY((skip(""))) uses;
} use_optype_t;
typedef use_optype_t *use_optype;
--- 34,40 ----
typedef struct use_optype_d GTY(())
{
unsigned num_uses;
! tree * GTY((length("%h.num_uses"), skip(""))) uses[1];
} use_optype_t;
typedef use_optype_t *use_optype;
*************** typedef use_optype_t *use_optype;
*** 42,48 ****
typedef struct vdef_optype_d GTY(())
{
unsigned num_vdefs;
! tree * GTY((length ("%h.num_vdefs * 2"))) vdefs;
} vdef_optype_t;
typedef vdef_optype_t *vdef_optype;
--- 42,48 ----
typedef struct vdef_optype_d GTY(())
{
unsigned num_vdefs;
! tree GTY((length ("%h.num_vdefs * 2"))) vdefs[1];
} vdef_optype_t;
typedef vdef_optype_t *vdef_optype;
*************** typedef vdef_optype_t *vdef_optype;
*** 50,56 ****
typedef struct vuse_optype_d GTY(())
{
unsigned num_vuses;
! tree * GTY((length ("%h.num_vuses"))) vuses;
} vuse_optype_t;
typedef vuse_optype_t *vuse_optype;
--- 50,56 ----
typedef struct vuse_optype_d GTY(())
{
unsigned num_vuses;
! tree GTY((length ("%h.num_vuses"))) vuses[1];
} vuse_optype_t;
typedef vuse_optype_t *vuse_optype;
*************** typedef vuse_optype_t *vuse_optype;
*** 85,117 ****
#define VUSE_OP(OPS, I) (*(VUSE_OP_PTR ((OPS), (I))))
- struct operands_d GTY(())
- {
- /* LHS of assignment statements. */
- struct def_optype_d GTY(()) def_ops;
-
- /* Array of pointers to each operand in the statement. */
- struct use_optype_d GTY(()) use_ops;
- };
-
- typedef struct operands_d *operands_t;
-
-
- struct voperands_d GTY(())
- {
- /* List of VDEF references in this statement. */
- struct vdef_optype_d GTY(()) vdef_ops;
-
- /* List of VUSE references in this statement. */
- struct vuse_optype_d GTY(()) vuse_ops;
- };
-
- typedef struct voperands_d *voperands_t;
extern void init_ssa_operands (void);
extern void fini_ssa_operands (void);
extern void verify_start_operands (tree);
extern void finalize_ssa_stmt_operands (tree);
void add_vuse (tree, tree);
extern void get_stmt_operands (tree);
#endif /* GCC_TREE_SSA_OPERANDS_H */
--- 85,97 ----
#define VUSE_OP(OPS, I) (*(VUSE_OP_PTR ((OPS), (I))))
extern void init_ssa_operands (void);
extern void fini_ssa_operands (void);
extern void verify_start_operands (tree);
extern void finalize_ssa_stmt_operands (tree);
void add_vuse (tree, tree);
extern void get_stmt_operands (tree);
+ extern void remove_vuses (tree);
+ extern void remove_vdefs (tree);
#endif /* GCC_TREE_SSA_OPERANDS_H */
Index: tree-ssa-pre.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-pre.c,v
retrieving revision 1.1.4.116
diff -c -p -r1.1.4.116 tree-ssa-pre.c
*** tree-ssa-pre.c 15 Dec 2003 22:58:35 -0000 1.1.4.116
--- tree-ssa-pre.c 16 Dec 2003 20:52:36 -0000
*************** subst_phis (struct expr_info *ei, tree Z
*** 1302,1308 ****
{
vuse_optype vuses = STMT_VUSE_OPS (Z);
! free_vuses (STMT_VUSE_OPS (stmt_copy));
start_ssa_stmt_operands (stmt_copy);
for (i = 0; i < NUM_VUSES (vuses); i++)
--- 1302,1308 ----
{
vuse_optype vuses = STMT_VUSE_OPS (Z);
! remove_vuses (stmt_copy);
start_ssa_stmt_operands (stmt_copy);
for (i = 0; i < NUM_VUSES (vuses); i++)
*************** subst_phis (struct expr_info *ei, tree Z
*** 1313,1320 ****
}
else
{
! free_vuses (STMT_VUSE_OPS (stmt_copy));
! free_vdefs (STMT_VDEF_OPS (stmt_copy));
}
if (j->index < n_phi_preds)
--- 1313,1320 ----
}
else
{
! remove_vuses (stmt_copy);
! remove_vdefs (stmt_copy);
}
if (j->index < n_phi_preds)