This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Rewrite building of virtual operands


Hello,

currently, all operands are built in tree-ssa-opfinalize.h, that is
included and specialized for the appropriate operand type.  While this
solution avoids some amount code duplication, it has also disadvantages.
In addition to being hard to understand, debug, and modify,
all types of operands must be handled in (almost) the same way.
Most importantly, there is quite big difference between real operands
(that are really just references into the expression in the statement),
and the virtual operands (where the operands contain the trees
themselves).

At the moment, tree-ssa-opfinalize.h forces us to build virtual operands
in a way that is similar to that for virtual operands, i.e., to
accumulate them in a vector.  However, we know that for each DECL, there may be
only one virtual operand, and we want them to be sorted by decl_uid in
the list of virtual operands of the statement; achieving this is a bit
clumsy with the current representation -- bitmap is the appropriate type
for representing the object that satisfies these two properties.

This patch makes us use bitmaps for accumulating virtual operands of a
statement.  This prevents us from using tree-ssa-opfinalize.h, however,
the code duplication shows up to be surprisingly small.  Nevertheless,
the code is overall simpler (some pre- and post-processing of virtual
operands that was necessary before is not needed). This representation
also enables us to solve the problem discussed in
http://gcc.gnu.org/ml/gcc-patches/2006-02/msg01245.html and followups
(turning maydefs into mustdefs) in a natural way.

Bootstrapped & regtested on i686 and ia64.

Zdenek

	* tree-flow.h (struct var_ann_d): Remove in_vuse_list and
	 in_v_may_def_list fields.
	 * tree-ssa-operands.c (build_v_may_defs, build_v_must_defs,
	 build_vuses): Replaced with ...
	 (current_v_may_defs, current_v_must_defs, current_vuses): ... new
	 bitmaps. 
	 (init_ssa_operands, fini_ssa_operands, start_ssa_stmt_operands,
	 append_v_may_def, append_vuse, append_v_must_def,
	 copy_virtual_operands, create_ssa_artficial_load_stmt): Work with the
	 bitmaps instead of build vectors for virtual operands.
	 (get_name_decl): Renamed to ...
	 (get_decl_uid): ... this.
	 (operand_build_cmp, operand_build_sort_virtual,
	 finalize_ssa_v_may_def_ops, finalize_ssa_v_must_def_ops,
	 finalize_ssa_vuse_ops, cleanup_v_may_defs, finalize_ssa_vuses,
	 build_v_must_defs, finalize_ssa_v_must_defs): Removed.
	 (NEW_OPTYPE, INIT_USE, LINK_OPERAND, add_vuse, add_v_may_def,
	 add_v_must_def, MOVE_TO_FREELIST, finalize_virtual_operands): New.
	 (finalize_ssa_stmt_operands): Use finalize_virtual_operands.
	 (build_ssa_operands): Do not sort virtual operands.

Index: tree-flow.h
===================================================================
*** tree-flow.h	(revision 111468)
--- tree-flow.h	(working copy)
*************** struct var_ann_d GTY(())
*** 176,189 ****
       states.  */
    ENUM_BITFIELD (need_phi_state) need_phi_state : 2;
  
-   /* Used during operand processing to determine if this variable is already 
-      in the vuse list.  */
-   unsigned in_vuse_list : 1;
- 
-   /* Used during operand processing to determine if this variable is already 
-      in the v_may_def list.  */
-   unsigned in_v_may_def_list : 1;
- 
    /* An artificial variable representing the memory location pointed-to by
       all the pointers that TBAA (type-based alias analysis) considers
       to be aliased.  If the variable is not a pointer or if it is never
--- 176,181 ----
Index: tree-ssa-operands.c
===================================================================
*** tree-ssa-operands.c	(revision 111468)
--- tree-ssa-operands.c	(working copy)
*************** static VEC(tree,heap) *build_defs;
*** 110,124 ****
  /* Array for building all the use operands.  */
  static VEC(tree,heap) *build_uses;
  
! /* Array for building all the v_may_def operands.  */
! static VEC(tree,heap) *build_v_may_defs;
  
! /* Array for building all the vuse operands.  */
! static VEC(tree,heap) *build_vuses;
! 
! /* Array for building all the v_must_def operands.  */
! static VEC(tree,heap) *build_v_must_defs;
  
  
  /* These arrays are the cached operand vectors for call clobbered calls.  */
  static bool ops_active = false;
--- 110,123 ----
  /* Array for building all the use operands.  */
  static VEC(tree,heap) *build_uses;
  
! /* New V_MAY_DEF operands of the current statement.  */
! static bitmap current_v_may_defs;
  
! /* New V_MUST_DEF operands of the current statement.  */
! static bitmap current_v_must_defs;
  
+ /* New VUSE operands of the current statement.  */
+ static bitmap current_vuses;
  
  /* These arrays are the cached operand vectors for call clobbered calls.  */
  static bool ops_active = false;
*************** static mustdef_optype_p free_mustdefs = 
*** 154,160 ****
  /* Return the DECL_UID of the base variable of T.  */
  
  static inline unsigned
! get_name_decl (tree t)
  {
    if (TREE_CODE (t) != SSA_NAME)
      return DECL_UID (t);
--- 153,159 ----
  /* Return the DECL_UID of the base variable of T.  */
  
  static inline unsigned
! get_decl_uid (tree t)
  {
    if (TREE_CODE (t) != SSA_NAME)
      return DECL_UID (t);
*************** get_name_decl (tree t)
*** 162,215 ****
      return DECL_UID (SSA_NAME_VAR (t));
  }
  
- /* Comparison function for qsort used in operand_build_sort_virtual.  */
- 
- static int
- operand_build_cmp (const void *p, const void *q)
- {
-   tree e1 = *((const tree *)p);
-   tree e2 = *((const tree *)q);
-   unsigned int u1,u2;
- 
-   u1 = get_name_decl (e1);
-   u2 = get_name_decl (e2);
- 
-   /* We want to sort in ascending order.  They can never be equal.  */
- #ifdef ENABLE_CHECKING
-   gcc_assert (u1 != u2);
- #endif
-   return (u1 > u2 ? 1 : -1);
- }
- 
- /* Sort the virtual operands in LIST from lowest DECL_UID to highest.  */
- 
- static inline void
- operand_build_sort_virtual (VEC(tree,heap) *list)
- {
-   int num = VEC_length (tree, list);
-   if (num < 2)
-     return;
-   if (num == 2)
-     {
-       if (get_name_decl (VEC_index (tree, list, 0)) 
- 	  > get_name_decl (VEC_index (tree, list, 1)))
- 	{  
- 	  /* Swap elements if in the wrong order.  */
- 	  tree tmp = VEC_index (tree, list, 0);
- 	  VEC_replace (tree, list, 0, VEC_index (tree, list, 1));
- 	  VEC_replace (tree, list, 1, tmp);
- 	}
-       return;
-     }
-   /* There are 3 or more elements, call qsort.  */
-   qsort (VEC_address (tree, list), 
- 	 VEC_length (tree, list), 
- 	 sizeof (tree),
- 	 operand_build_cmp);
- }
- 
- 
- 
  /*  Return true if the ssa operands cache is active.  */
  
  bool
--- 161,166 ----
*************** init_ssa_operands (void)
*** 253,261 ****
  {
    build_defs = VEC_alloc (tree, heap, 5);
    build_uses = VEC_alloc (tree, heap, 10);
!   build_vuses = VEC_alloc (tree, heap, 25);
!   build_v_may_defs = VEC_alloc (tree, heap, 25);
!   build_v_must_defs = VEC_alloc (tree, heap, 25);
  
    gcc_assert (operand_memory == NULL);
    operand_memory_index = SSA_OPERAND_MEMORY_SIZE;
--- 204,212 ----
  {
    build_defs = VEC_alloc (tree, heap, 5);
    build_uses = VEC_alloc (tree, heap, 10);
!   current_v_may_defs = BITMAP_ALLOC (NULL);
!   current_v_must_defs = BITMAP_ALLOC (NULL);
!   current_vuses = BITMAP_ALLOC (NULL);
  
    gcc_assert (operand_memory == NULL);
    operand_memory_index = SSA_OPERAND_MEMORY_SIZE;
*************** fini_ssa_operands (void)
*** 273,281 ****
    struct ssa_operand_memory_d *ptr;
    VEC_free (tree, heap, build_defs);
    VEC_free (tree, heap, build_uses);
!   VEC_free (tree, heap, build_v_must_defs);
!   VEC_free (tree, heap, build_v_may_defs);
!   VEC_free (tree, heap, build_vuses);
    free_defs = NULL;
    free_uses = NULL;
    free_vuses = NULL;
--- 224,232 ----
    struct ssa_operand_memory_d *ptr;
    VEC_free (tree, heap, build_defs);
    VEC_free (tree, heap, build_uses);
!   BITMAP_FREE (current_v_may_defs);
!   BITMAP_FREE (current_v_must_defs);
!   BITMAP_FREE (current_vuses);
    free_defs = NULL;
    free_uses = NULL;
    free_vuses = NULL;
*************** finalize_ssa_uses (tree stmt)
*** 453,641 ****
    finalize_ssa_use_ops (stmt);
    VEC_truncate (tree, build_uses, 0);
  }
-                                                                               
-                                                                               
- /* Return a new v_may_def operand vector for STMT, comparing to OLD_OPS_P.  */                                                                                
- #define FINALIZE_OPBUILD	build_v_may_defs
- #define FINALIZE_OPBUILD_ELEM(I)	VEC_index (tree, build_v_may_defs, (I))
- #define FINALIZE_OPBUILD_BASE(I)	get_name_decl (VEC_index (tree,	\
- 							build_v_may_defs, (I)))
- #define FINALIZE_FUNC		finalize_ssa_v_may_def_ops
- #define FINALIZE_ALLOC		alloc_maydef
- #define FINALIZE_FREE		free_maydefs
- #define FINALIZE_TYPE		struct maydef_optype_d
- #define FINALIZE_ELEM(PTR)	MAYDEF_RESULT (PTR)
- #define FINALIZE_OPS		MAYDEF_OPS
- #define FINALIZE_USE_PTR(PTR)	MAYDEF_OP_PTR (PTR)
- #define FINALIZE_CORRECT_USE	set_virtual_use_link
- #define FINALIZE_BASE_ZERO	0
- #define FINALIZE_BASE(VAR)	get_name_decl (VAR)
- #define FINALIZE_BASE_TYPE	unsigned
- #define FINALIZE_INITIALIZE(PTR, VAL, STMT)				\
- 				(PTR)->def_var = (VAL);			\
- 				(PTR)->use_var = (VAL);			\
- 				(PTR)->use_ptr.use = &((PTR)->use_var);	\
- 				link_imm_use_stmt (&((PTR)->use_ptr),	\
- 						   (VAL), (STMT))
- #include "tree-ssa-opfinalize.h"
-                                                                               
-                                                                               
- static void
- finalize_ssa_v_may_defs (tree stmt)
- {
-   finalize_ssa_v_may_def_ops (stmt);
- }
-                                                                                
  
! /* Clear the in_list bits and empty the build array for v_may_defs.  */
  
! static inline void
! cleanup_v_may_defs (void)
  {
!   unsigned x, num;
!   num = VEC_length (tree, build_v_may_defs);
  
!   for (x = 0; x < num; x++)
!     {
!       tree t = VEC_index (tree, build_v_may_defs, x);
!       if (TREE_CODE (t) != SSA_NAME)
! 	{
! 	  var_ann_t ann = var_ann (t);
! 	  ann->in_v_may_def_list = 0;
! 	}
!     }
!   VEC_truncate (tree, build_v_may_defs, 0);
! }                                                                             
  
-                                                                               
- #define FINALIZE_OPBUILD	build_vuses
- #define FINALIZE_OPBUILD_ELEM(I)	VEC_index (tree, build_vuses, (I))
- #define FINALIZE_OPBUILD_BASE(I)	get_name_decl (VEC_index (tree,	\
- 							build_vuses, (I)))
- #define FINALIZE_FUNC		finalize_ssa_vuse_ops
- #define FINALIZE_ALLOC		alloc_vuse
- #define FINALIZE_FREE		free_vuses
- #define FINALIZE_TYPE		struct vuse_optype_d
- #define FINALIZE_ELEM(PTR)	VUSE_OP (PTR)
- #define FINALIZE_OPS		VUSE_OPS
- #define FINALIZE_USE_PTR(PTR)	VUSE_OP_PTR (PTR)
- #define FINALIZE_CORRECT_USE	set_virtual_use_link
- #define FINALIZE_BASE_ZERO	0
- #define FINALIZE_BASE(VAR)	get_name_decl (VAR)
- #define FINALIZE_BASE_TYPE	unsigned
- #define FINALIZE_INITIALIZE(PTR, VAL, STMT)				\
- 				(PTR)->use_var = (VAL);			\
- 				(PTR)->use_ptr.use = &((PTR)->use_var);	\
- 				link_imm_use_stmt (&((PTR)->use_ptr),	\
- 						   (VAL), (STMT))
- #include "tree-ssa-opfinalize.h"
  
  
! /* Return a new vuse operand vector, comparing to OLD_OPS_P.  */
!                                                                               
! static void
! finalize_ssa_vuses (tree stmt)
  {
!   unsigned num, num_v_may_defs;
!   unsigned vuse_index;
  
!   /* Remove superfluous VUSE operands.  If the statement already has a
!    V_MAY_DEF operation for a variable 'a', then a VUSE for 'a' is not
!    needed because V_MAY_DEFs imply a VUSE of the variable.  For instance,
!    suppose that variable 'a' is aliased:
  
! 	      # VUSE <a_2>
! 	      # a_3 = V_MAY_DEF <a_2>
! 	      a = a + 1;
  
!   The VUSE <a_2> is superfluous because it is implied by the V_MAY_DEF
!   operation.  */
  
!   num = VEC_length (tree, build_vuses);
!   num_v_may_defs = VEC_length (tree, build_v_may_defs);
  
!   if (num > 0 && num_v_may_defs > 0)
      {
!       for (vuse_index = 0; vuse_index < VEC_length (tree, build_vuses); )
!         {
! 	  tree vuse;
! 	  vuse = VEC_index (tree, build_vuses, vuse_index);
! 	  if (TREE_CODE (vuse) != SSA_NAME)
! 	    {
! 	      var_ann_t ann = var_ann (vuse);
! 	      ann->in_vuse_list = 0;
! 	      if (ann->in_v_may_def_list)
! 	        {
! 		  VEC_ordered_remove (tree, build_vuses, vuse_index);
! 		  continue;
! 		}
! 	    }
! 	  vuse_index++;
  	}
      }
-   else
-     /* Clear out the in_list bits.  */
-     for (vuse_index = 0;
- 	 vuse_index < VEC_length (tree, build_vuses);
- 	 vuse_index++)
-       {
- 	tree t = VEC_index (tree, build_vuses, vuse_index);
- 	if (TREE_CODE (t) != SSA_NAME)
- 	  {
- 	    var_ann_t ann = var_ann (t);
- 	    ann->in_vuse_list = 0;
- 	  }
-       }
  
!   finalize_ssa_vuse_ops (stmt);
!   /* The v_may_def build vector wasn't cleaned up because we needed it.  */
!   cleanup_v_may_defs ();
!                                                                               
!   /* Free the vuses build vector.  */
!   VEC_truncate (tree, build_vuses, 0);
! 
! }
!                                                                               
! /* Return a new v_must_def operand vector for STMT, comparing to OLD_OPS_P.  */
!                                                                               
! #define FINALIZE_OPBUILD	build_v_must_defs
! #define FINALIZE_OPBUILD_ELEM(I)	VEC_index (tree, build_v_must_defs, (I))
! #define FINALIZE_OPBUILD_BASE(I)	get_name_decl (VEC_index (tree,	\
! 							build_v_must_defs, (I)))
! #define FINALIZE_FUNC		finalize_ssa_v_must_def_ops
! #define FINALIZE_ALLOC		alloc_mustdef
! #define FINALIZE_FREE		free_mustdefs
! #define FINALIZE_TYPE		struct mustdef_optype_d
! #define FINALIZE_ELEM(PTR)	MUSTDEF_RESULT (PTR)
! #define FINALIZE_OPS		MUSTDEF_OPS
! #define FINALIZE_USE_PTR(PTR)	MUSTDEF_KILL_PTR (PTR)
! #define FINALIZE_CORRECT_USE	set_virtual_use_link
! #define FINALIZE_BASE_ZERO	0
! #define FINALIZE_BASE(VAR)	get_name_decl (VAR)
! #define FINALIZE_BASE_TYPE	unsigned
! #define FINALIZE_INITIALIZE(PTR, VAL, STMT)				\
! 				(PTR)->def_var = (VAL);			\
! 				(PTR)->kill_var = (VAL);		\
! 				(PTR)->use_ptr.use = &((PTR)->kill_var);\
! 				link_imm_use_stmt (&((PTR)->use_ptr),	\
! 						   (VAL), (STMT))
! #include "tree-ssa-opfinalize.h"
  
  
! static void
! finalize_ssa_v_must_defs (tree stmt)
! {
!   /* In the presence of subvars, there may be more than one V_MUST_DEF per
!      statement (one for each subvar).  It is a bit expensive to verify that
!      all must-defs in a statement belong to subvars if there is more than one
!      MUST-def, so we don't do it.  Suffice to say, if you reach here without
!      having subvars, and have num >1, you have hit a bug. */
  
!   finalize_ssa_v_must_def_ops (stmt);
!   VEC_truncate (tree, build_v_must_defs, 0);
  }
  
- 
  /* Finalize all the build vectors, fill the new ones into INFO.  */
                                                                                
  static inline void
--- 404,630 ----
    finalize_ssa_use_ops (stmt);
    VEC_truncate (tree, build_uses, 0);
  }
  
! /* Assigns a new operand with given TYPE to VAR.  Unless LIST is empty, the
!    element is taken from it, otherwise the element is allocated.  */
  
! #define NEW_OPTYPE(VAR, LIST, TYPE)			\
!   do							\
!     {							\
!       if (LIST)						\
! 	{						\
! 	  (VAR) = (LIST);				\
! 	  (LIST) = (LIST)->next;			\
! 	}						\
!       else						\
! 	(VAR) = ssa_operand_alloc (sizeof (TYPE));	\
!     } while (0)
! 
! /* Initializes use in operarand OP to USE.  Field to that use should be
!    placed is FIELD, and STMT is the current statement.  */
! 
! #define INIT_USE(STMT, OP, USE, FIELD)			\
!   do							\
!     {							\
!       (OP)->FIELD = (USE);				\
!       (OP)->use_ptr.use = &(OP)->FIELD;			\
!       link_imm_use_stmt (&(OP)->use_ptr, (USE), (STMT));\
!     } while (0)
! 
! /* Links operand OP to the list of operands in the field FIELD of the operands
!    structure in statement annotations ANN.  The list is kept sorted in
!    ascending order by DECL_UID of the operand, taken from its USE_VAR field.
!    If AFTER is not NULL, it is a hint on where we should start looking for
!    the suitable position for the operand.  TYPE is the type of the operand.  */
! 
! #define LINK_OPERAND(ANN, FIELD, TYPE, OP, USE_VAR, AFTER)	\
!   do								\
!     {								\
!       TYPE *at;							\
!       unsigned uid = get_decl_uid ((OP)->USE_VAR);		\
! 								\
!       if ((AFTER) && get_decl_uid ((AFTER)->USE_VAR) < uid)	\
! 	at = &(AFTER)->next;					\
!       else							\
! 	at = &(ANN)->operands.FIELD;				\
!       while (*at && get_decl_uid ((*at)->USE_VAR) < uid)	\
! 	at = &(*at)->next;					\
!       (OP)->next = *at;						\
!       *at = (OP);						\
!     } while (0)
! 
! /* Adds a vuse for USE to statement annotation ANN of statement STMT.  If AFTER
!    is not NULL, it gives the position where the last vuse was linked.  Returns
!    the position of the new operand.  */
! 
! static vuse_optype_p
! add_vuse (tree stmt, stmt_ann_t ann, tree use, vuse_optype_p after)
  {
!   vuse_optype_p op;
!   
!   NEW_OPTYPE (op, free_vuses, struct vuse_optype_d);
!   INIT_USE (stmt, op, use, use_var);
!   LINK_OPERAND (ann, vuse_ops, vuse_optype_p, op, use_var, after);
  
!   return op;
! }
  
  
+ /* Adds a vmaydef (DEF, USE) to statement annotation ANN of statment STMT.
+    If AFTER is not NULL, it gives the position where the last v_may_def
+    was linked.  Returns the position of the new operand.  */
  
! static maydef_optype_p
! add_v_may_def (tree stmt, stmt_ann_t ann, tree def, tree use,
! 	       maydef_optype_p after)
  {
!   maydef_optype_p op;
!   
!   NEW_OPTYPE (op, free_maydefs, struct maydef_optype_d);
!   INIT_USE (stmt, op, use, use_var);
!   op->def_var = def;
!   LINK_OPERAND (ann, maydef_ops, maydef_optype_p, op, use_var, after);
! 
!   return op;
! }
  
! /* Adds a vmustdef (DEF, USE) to statement annotation ANN of statement STMT.  */
  
! static mustdef_optype_p
! add_v_must_def (tree stmt, stmt_ann_t ann, tree def, tree use,
! 		mustdef_optype_p after)
! {
!   mustdef_optype_p op;
!   
!   NEW_OPTYPE (op, free_mustdefs, struct mustdef_optype_d);
!   INIT_USE (stmt, op, use, kill_var);
!   op->def_var = def;
!   LINK_OPERAND (ann, mustdef_ops, mustdef_optype_p, op, kill_var, after);
! 
!   return op;
! }
! 
! #define MOVE_TO_FREELIST(ELT, ELT_P, LIST)	\
!   do						\
!     {						\
!       delink_imm_use (&(ELT)->use_ptr);		\
!       *(ELT_P) = (ELT)->next;			\
!       (ELT)->next = (LIST);			\
!       (LIST) = (ELT);				\
!     } while (0)
  
! /* Creates the virtual operands for statement STMT, as previously scheduled by
!    parse_ssa_operands.  */
  
! static void
! finalize_virtual_operands (tree stmt)
! {
!   vuse_optype_p *act_vuse_p;
!   vuse_optype_p act_vuse, after_vuse = NULL;
!   mustdef_optype_p *act_mustdef_p;
!   mustdef_optype_p act_mustdef, after_mustdef = NULL;
!   maydef_optype_p *act_maydef_p;
!   maydef_optype_p act_maydef, after_maydef = NULL;
!   stmt_ann_t ann = get_stmt_ann (stmt);
!   unsigned uid;
!   bitmap_iterator bi;
!   tree op;
!   bitmap tmp = BITMAP_ALLOC (NULL);
  
!   /* vuse + vmustdef = vmaydef, e.g. in
!      structure = foo (structure).  */
!   bitmap_and (tmp, current_vuses, current_v_must_defs);
!   bitmap_and_compl_into (current_vuses, tmp);
!   bitmap_and_compl_into (current_v_must_defs, tmp);
!   bitmap_ior_into (current_v_may_defs, tmp);
!   BITMAP_FREE (tmp);
! 
!   /* If we have both vuse and vmaydef, the vuse is not neccessary.  */
!   bitmap_and_compl_into (current_vuses, current_v_may_defs);
! 
!   /* If we have both a mustdef and maydef, it is something like
!      structure = foo ();
!      where structure is call clobbered.  FOO may use value of
!      structure, therefore this is a maydef.  */
!   bitmap_and_compl_into (current_v_must_defs, current_v_may_defs);
! 
!   /* First we process the old virtual operands of the statement, find those
!      that we may reuse, and remove the rest.  Due to optimizations, it may
!      happen that V_MAY_DEF becomes a V_MUST_DEF, so convert the operand type
!      in this case.  */
!   for (act_vuse_p = &ann->operands.vuse_ops; *act_vuse_p; )
      {
!       act_vuse = *act_vuse_p;
!       uid = get_decl_uid (act_vuse->use_var);
!       
!       if (bitmap_bit_p (current_vuses, uid))
! 	{
! 	  bitmap_clear_bit (current_vuses, uid);
! 	  set_virtual_use_link (&act_vuse->use_ptr, stmt);
! 	  act_vuse_p = &act_vuse->next;
  	}
+       else
+ 	MOVE_TO_FREELIST (act_vuse, act_vuse_p, free_vuses);
      }
  
!   for (act_mustdef_p = &ann->operands.mustdef_ops; *act_mustdef_p; )
!     {
!       act_mustdef = *act_mustdef_p;
!       uid = get_decl_uid (act_mustdef->def_var);
!       
!       if (bitmap_bit_p (current_v_must_defs, uid))
! 	{
! 	  bitmap_clear_bit (current_v_must_defs, uid);
! 	  set_virtual_use_link (&act_mustdef->use_ptr, stmt);
! 	  act_mustdef_p = &act_mustdef->next;
! 	}
!       else
! 	MOVE_TO_FREELIST (act_mustdef, act_mustdef_p, free_mustdefs);
!     }
  
+   for (act_maydef_p = &ann->operands.maydef_ops; *act_maydef_p; )
+     {
+       act_maydef = *act_maydef_p;
+       uid = get_decl_uid (act_maydef->def_var);
+       
+       if (bitmap_bit_p (current_v_must_defs, uid))
+ 	{
+ 	  bitmap_clear_bit (current_v_must_defs, uid);
+ 	  after_mustdef = add_v_must_def (stmt, ann, act_maydef->def_var,
+ 					  act_maydef->use_var, after_mustdef);
+ 	  MOVE_TO_FREELIST (act_maydef, act_maydef_p, free_maydefs);
+ 	}
+       else if (bitmap_bit_p (current_v_may_defs, uid))
+ 	{
+ 	  bitmap_clear_bit (current_v_may_defs, uid);
+ 	  set_virtual_use_link (&act_maydef->use_ptr, stmt);
+ 	  act_maydef_p = &act_maydef->next;
+ 	}
+       else
+ 	MOVE_TO_FREELIST (act_maydef, act_maydef_p, free_maydefs);
+     }
  
!   /* Finally, create the virtual operands for the new vops.  */
!   EXECUTE_IF_SET_IN_BITMAP (current_vuses, 0, uid, bi)
!     {
!       after_vuse = add_vuse (stmt, ann, referenced_var (uid), after_vuse);
!     }
!   EXECUTE_IF_SET_IN_BITMAP (current_v_may_defs, 0, uid, bi)
!     {
!       op = referenced_var (uid);
!       after_maydef = add_v_may_def (stmt, ann, op, op, after_maydef);
!     }
!   EXECUTE_IF_SET_IN_BITMAP (current_v_must_defs, 0, uid, bi)
!     {
!       op = referenced_var (uid);
!       after_mustdef = add_v_must_def (stmt, ann, op, op, after_mustdef);
!     }
  
!   bitmap_clear (current_vuses);
!   bitmap_clear (current_v_may_defs);
!   bitmap_clear (current_v_must_defs);
  }
  
  /* Finalize all the build vectors, fill the new ones into INFO.  */
                                                                                
  static inline void
*************** finalize_ssa_stmt_operands (tree stmt)
*** 643,651 ****
  {
    finalize_ssa_defs (stmt);
    finalize_ssa_uses (stmt);
!   finalize_ssa_v_must_defs (stmt);
!   finalize_ssa_v_may_defs (stmt);
!   finalize_ssa_vuses (stmt);
  }
  
  
--- 632,638 ----
  {
    finalize_ssa_defs (stmt);
    finalize_ssa_uses (stmt);
!   finalize_virtual_operands (stmt);
  }
  
  
*************** start_ssa_stmt_operands (void)
*** 656,664 ****
  {
    gcc_assert (VEC_length (tree, build_defs) == 0);
    gcc_assert (VEC_length (tree, build_uses) == 0);
!   gcc_assert (VEC_length (tree, build_vuses) == 0);
!   gcc_assert (VEC_length (tree, build_v_may_defs) == 0);
!   gcc_assert (VEC_length (tree, build_v_must_defs) == 0);
  }
  
  
--- 643,651 ----
  {
    gcc_assert (VEC_length (tree, build_defs) == 0);
    gcc_assert (VEC_length (tree, build_uses) == 0);
!   gcc_assert (bitmap_empty_p (current_v_may_defs));
!   gcc_assert (bitmap_empty_p (current_v_must_defs));
!   gcc_assert (bitmap_empty_p (current_vuses));
  }
  
  
*************** append_use (tree *use_p)
*** 685,701 ****
  static inline void
  append_v_may_def (tree var)
  {
!   if (TREE_CODE (var) != SSA_NAME)
!     {
!       var_ann_t ann = get_var_ann (var);
! 
!       /* Don't allow duplicate entries.  */
!       if (ann->in_v_may_def_list)
! 	return;
!       ann->in_v_may_def_list = 1;
!     }
! 
!   VEC_safe_push (tree, heap, build_v_may_defs, (tree)var);
  }
  
  
--- 672,678 ----
  static inline void
  append_v_may_def (tree var)
  {
!   bitmap_set_bit (current_v_may_defs, get_decl_uid (var));
  }
  
  
*************** append_v_may_def (tree var)
*** 704,721 ****
  static inline void
  append_vuse (tree var)
  {
! 
!   /* Don't allow duplicate entries.  */
!   if (TREE_CODE (var) != SSA_NAME)
!     {
!       var_ann_t ann = get_var_ann (var);
! 
!       if (ann->in_vuse_list || ann->in_v_may_def_list)
!         return;
!       ann->in_vuse_list = 1;
!     }
! 
!   VEC_safe_push (tree, heap, build_vuses, (tree)var);
  }
  
  
--- 681,687 ----
  static inline void
  append_vuse (tree var)
  {
!   bitmap_set_bit (current_vuses, get_decl_uid (var));
  }
  
  
*************** append_vuse (tree var)
*** 724,737 ****
  static inline void
  append_v_must_def (tree var)
  {
!   unsigned i;
! 
!   /* Don't allow duplicate entries.  */
!   for (i = 0; i < VEC_length (tree, build_v_must_defs); i++)
!     if (var == VEC_index (tree, build_v_must_defs, i))
!       return;
! 
!   VEC_safe_push (tree, heap, build_v_must_defs, (tree)var);
  }
  
  
--- 690,696 ----
  static inline void
  append_v_must_def (tree var)
  {
!   bitmap_set_bit (current_v_must_defs, get_decl_uid (var));
  }
  
  
*************** build_ssa_operands (tree stmt)
*** 833,842 ****
    start_ssa_stmt_operands ();
  
    parse_ssa_operands (stmt);
-   operand_build_sort_virtual (build_vuses);
-   operand_build_sort_virtual (build_v_may_defs);
-   operand_build_sort_virtual (build_v_must_defs);
- 
    finalize_ssa_stmt_operands (stmt);
  }
  
--- 792,797 ----
*************** update_stmt_operands (tree stmt)
*** 889,951 ****
  void
  copy_virtual_operands (tree dest, tree src)
  {
!   tree t;
!   ssa_op_iter iter, old_iter;
!   use_operand_p use_p, u2;
!   def_operand_p def_p, d2;
! 
!   build_ssa_operands (dest);
! 
!   /* Copy all the virtual fields.  */
!   FOR_EACH_SSA_TREE_OPERAND (t, src, iter, SSA_OP_VUSE)
!     append_vuse (t);
!   FOR_EACH_SSA_TREE_OPERAND (t, src, iter, SSA_OP_VMAYDEF)
!     append_v_may_def (t);
!   FOR_EACH_SSA_TREE_OPERAND (t, src, iter, SSA_OP_VMUSTDEF)
!     append_v_must_def (t);
! 
!   if (VEC_length (tree, build_vuses) == 0
!       && VEC_length (tree, build_v_may_defs) == 0
!       && VEC_length (tree, build_v_must_defs) == 0)
!     return;
! 
!   /* Now commit the virtual operands to this stmt.  */
!   finalize_ssa_v_must_defs (dest);
!   finalize_ssa_v_may_defs (dest);
!   finalize_ssa_vuses (dest);
! 
!   /* Finally, set the field to the same values as then originals.  */
! 
!   
!   t = op_iter_init_tree (&old_iter, src, SSA_OP_VUSE);
!   FOR_EACH_SSA_USE_OPERAND (use_p, dest, iter, SSA_OP_VUSE)
!     {
!       gcc_assert (!op_iter_done (&old_iter));
!       SET_USE (use_p, t);
!       t = op_iter_next_tree (&old_iter);
!     }
!   gcc_assert (op_iter_done (&old_iter));
! 
!   op_iter_init_maydef (&old_iter, src, &u2, &d2);
!   FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, dest, iter)
!     {
!       gcc_assert (!op_iter_done (&old_iter));
!       SET_USE (use_p, USE_FROM_PTR (u2));
!       SET_DEF (def_p, DEF_FROM_PTR (d2));
!       op_iter_next_maymustdef (&u2, &d2, &old_iter);
!     }
!   gcc_assert (op_iter_done (&old_iter));
! 
!   op_iter_init_mustdef (&old_iter, src, &u2, &d2);
!   FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, use_p, dest, iter)
!     {
!       gcc_assert (!op_iter_done (&old_iter));
!       SET_USE (use_p, USE_FROM_PTR (u2));
!       SET_DEF (def_p, DEF_FROM_PTR (d2));
!       op_iter_next_maymustdef (&u2, &d2, &old_iter);
!     }
!   gcc_assert (op_iter_done (&old_iter));
! 
  }
  
  
--- 844,870 ----
  void
  copy_virtual_operands (tree dest, tree src)
  {
!   use_operand_p use;
!   def_operand_p def;
!   ssa_op_iter iter;
!   stmt_ann_t ann = get_stmt_ann (dest);
!   vuse_optype_p after_vuse = NULL;
!   mustdef_optype_p after_mustdef = NULL;
!   maydef_optype_p after_maydef = NULL;
! 
!   /* Clean up old virtual operands of DEST --  since current_... bitmaps are
!      now empty, finalize_virtual_operands has this effect.  */
!   finalize_virtual_operands (dest);
! 
!   /* Copy the virtual operands.  */
!   FOR_EACH_SSA_USE_OPERAND (use, src, iter, SSA_OP_VUSE)
!     after_vuse = add_vuse (dest, ann, USE_FROM_PTR (use), after_vuse);
!   FOR_EACH_SSA_MAYDEF_OPERAND (def, use, src, iter)
!     after_maydef = add_v_may_def (dest, ann, DEF_FROM_PTR (def),
! 				   USE_FROM_PTR (use), after_maydef);
!   FOR_EACH_SSA_MUSTDEF_OPERAND (def, use, src, iter)
!     after_mustdef = add_v_must_def (dest, ann, DEF_FROM_PTR (def),
! 				    USE_FROM_PTR (use), after_mustdef);
  }
  
  
*************** create_ssa_artficial_load_stmt (tree new
*** 962,968 ****
    tree op;
    ssa_op_iter iter;
    use_operand_p use_p;
!   unsigned x;
  
    ann = get_stmt_ann (new_stmt);
  
--- 881,887 ----
    tree op;
    ssa_op_iter iter;
    use_operand_p use_p;
!   vuse_optype_p after_vuse = NULL;
  
    ann = get_stmt_ann (new_stmt);
  
*************** create_ssa_artficial_load_stmt (tree new
*** 970,1006 ****
    start_ssa_stmt_operands ();
    parse_ssa_operands (new_stmt);
  
-   for (x = 0; x < VEC_length (tree, build_vuses); x++)
-     {
-       tree t = VEC_index (tree, build_vuses, x);
-       if (TREE_CODE (t) != SSA_NAME)
- 	{
- 	  var_ann_t ann = var_ann (t);
- 	  ann->in_vuse_list = 0;
- 	}
-     }
-    
-   for (x = 0; x < VEC_length (tree, build_v_may_defs); x++)
-     {
-       tree t = VEC_index (tree, build_v_may_defs, x);
-       if (TREE_CODE (t) != SSA_NAME)
- 	{
- 	  var_ann_t ann = var_ann (t);
- 	  ann->in_v_may_def_list = 0;
- 	}
-     }
    /* Remove any virtual operands that were found.  */
!   VEC_truncate (tree, build_v_may_defs, 0);
!   VEC_truncate (tree, build_v_must_defs, 0);
!   VEC_truncate (tree, build_vuses, 0);
  
    /* For each VDEF on the original statement, we want to create a
       VUSE of the V_MAY_DEF result or V_MUST_DEF op on the new 
       statement.  */
    FOR_EACH_SSA_TREE_OPERAND (op, old_stmt, iter, 
  			     (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF))
!     append_vuse (op);
!     
    /* Now build the operands for this new stmt.  */
    finalize_ssa_stmt_operands (new_stmt);
  
--- 889,909 ----
    start_ssa_stmt_operands ();
    parse_ssa_operands (new_stmt);
  
    /* Remove any virtual operands that were found.  */
!   bitmap_clear (current_v_may_defs);
!   bitmap_clear (current_v_must_defs);
!   bitmap_clear (current_vuses);
  
    /* For each VDEF on the original statement, we want to create a
       VUSE of the V_MAY_DEF result or V_MUST_DEF op on the new 
       statement.  */
    FOR_EACH_SSA_TREE_OPERAND (op, old_stmt, iter, 
  			     (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF))
!     {
!       after_vuse = add_vuse (new_stmt, ann, op, after_vuse);
!       bitmap_set_bit (current_vuses, get_decl_uid (op));
!     }
! 
    /* Now build the operands for this new stmt.  */
    finalize_ssa_stmt_operands (new_stmt);
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]