[lno] Some bugfixes and improvements

Zdenek Dvorak rakdver@atrey.karlin.mff.cuni.cz
Thu May 13 21:20:00 GMT 2004


Hello,

this patch

-- prevents loss of aliasing information during strength reduction
   (by keeping the original reference for alias analysis)
-- makes chrec_contains_symbols_defined_in_loop not to fail on invariant
   addresses
-- makes tree_split_block not to mark statements moved to the newly
   created block as modified.

Zdenek

Index: ChangeLog.lno
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/ChangeLog.lno,v
retrieving revision 1.1.2.157
diff -c -3 -p -r1.1.2.157 ChangeLog.lno
*** ChangeLog.lno	12 May 2004 10:10:19 -0000	1.1.2.157
--- ChangeLog.lno	13 May 2004 21:07:59 -0000
***************
*** 1,3 ****
--- 1,20 ----
+ 2004-05-13  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
+ 
+ 	* expr.c (expand_expr_real_1): Use REF_ORIGINAL information
+ 	from INDIRECT_REFS.
+ 	* tree-flow.h (force_gimple_operand, rewrite_address_base): Declare.
+ 	* tree-ssa-loop-ivopts.c (force_gimple_operand): Expand.
+ 	(add_address_candidates): Add candidates with constant offset
+ 	stripped.
+ 	(idx_remove_ssa_names, unshare_and_remove_ssa_names,
+ 	rewrite_address_base): New.
+ 	(rewrite_use_address): Use rewrite_address_base.
+ 	* tree-into-ssa.c (register_new_def): Remove unused code.
+ 	* tree-scalar-evolution.c (chrec_contains_symbols_defined_in_loop):
+ 	Handle invariants correctly.
+ 	* tree-cfg.c (tree_split_block): Do not modify the statements.
+ 	* tree.h (REF_ORIGINAL): New macro.
+ 
  2004-05-12  Sebastian Pop  <pop@cri.ensmp.fr>
  
  	* tree-chrec.c (chrec_evaluate): Use the type of the chrec 
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.467.2.70.2.6
diff -c -3 -p -r1.467.2.70.2.6 expr.c
*** expr.c	25 Apr 2004 20:33:25 -0000	1.467.2.70.2.6
--- expr.c	13 May 2004 21:07:59 -0000
*************** expand_expr_real_1 (tree exp, rtx target
*** 6965,6970 ****
--- 6965,6971 ----
      case INDIRECT_REF:
        {
  	tree exp1 = TREE_OPERAND (exp, 0);
+ 	tree orig;
  
  	if (modifier != EXPAND_WRITE)
  	  {
*************** expand_expr_real_1 (tree exp, rtx target
*** 6978,6984 ****
  	op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
  	op0 = memory_address (mode, op0);
  	temp = gen_rtx_MEM (mode, op0);
! 	set_mem_attributes (temp, exp, 0);
  
  	/* If we are writing to this object and its type is a record with
  	   readonly fields, we must mark it as readonly so it will
--- 6979,6989 ----
  	op0 = expand_expr (exp1, NULL_RTX, VOIDmode, EXPAND_SUM);
  	op0 = memory_address (mode, op0);
  	temp = gen_rtx_MEM (mode, op0);
! 
! 	orig = REF_ORIGINAL (exp);
! 	if (!orig)
! 	  orig = exp;
! 	set_mem_attributes (temp, orig, 0);
  
  	/* If we are writing to this object and its type is a record with
  	   readonly fields, we must mark it as readonly so it will
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-cfg.c,v
retrieving revision 1.1.4.244.2.16
diff -c -3 -p -r1.1.4.244.2.16 tree-cfg.c
*** tree-cfg.c	25 Apr 2004 20:33:40 -0000	1.1.4.244.2.16
--- tree-cfg.c	13 May 2004 21:07:59 -0000
*************** tree_split_block (basic_block bb, void *
*** 4009,4017 ****
--- 4009,4022 ----
    bsi_tgt = bsi_start (new_bb);
    while (!bsi_end_p (bsi))
      {
+       bool was_modified;
+ 
        act = bsi_stmt (bsi);
+       was_modified = stmt_modified_p (act);
        bsi_remove (&bsi);
        bsi_insert_after (&bsi_tgt, act, BSI_NEW_STMT);
+       if (!was_modified)
+ 	unmodify_stmt (act);
      }
  
    return new_bb;
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow.h,v
retrieving revision 1.1.4.177.2.26
diff -c -3 -p -r1.1.4.177.2.26 tree-flow.h
*** tree-flow.h	30 Apr 2004 23:38:49 -0000	1.1.4.177.2.26
--- tree-flow.h	13 May 2004 21:07:59 -0000
*************** unsigned estimate_loop_size (struct loop
*** 635,640 ****
--- 635,643 ----
  void rewrite_into_loop_closed_ssa (void);
  void verify_loop_closed_ssa (void);
  void compute_phi_arg_on_exit (edge, tree, tree);
+ tree force_gimple_operand (tree, tree *, bool, tree);
+ void rewrite_address_base (block_stmt_iterator *, tree *, tree);
+ 
  
  /* Description of number of iterations of a loop.  */
  struct tree_niter_desc
Index: tree-into-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-into-ssa.c,v
retrieving revision 1.1.4.6
diff -c -3 -p -r1.1.4.6 tree-into-ssa.c
*** tree-into-ssa.c	25 Apr 2004 20:33:42 -0000	1.1.4.6
--- tree-into-ssa.c	13 May 2004 21:07:59 -0000
*************** register_new_def (tree def, varray_type 
*** 1277,1287 ****
    if (! *block_defs_p)
      VARRAY_TREE_INIT (*block_defs_p, 20, "block_defs");
  
-   /* If we are rewriting ssa names, record the variable whose value must be
-      be restored.  */
-   if (TREE_CODE (var) == SSA_NAME)
-     VARRAY_PUSH_TREE (*block_defs_p, var);
- 
    /* Push the current reaching definition into *BLOCK_DEFS_P.  This stack is
       later used by the dominator tree callbacks to restore the reaching
       definitions for all the variables defined in the block after a recursive
--- 1277,1282 ----
Index: tree-scalar-evolution.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-scalar-evolution.c,v
retrieving revision 1.1.2.46
diff -c -3 -p -r1.1.2.46 tree-scalar-evolution.c
*** tree-scalar-evolution.c	12 May 2004 10:10:19 -0000	1.1.2.46
--- tree-scalar-evolution.c	13 May 2004 21:07:59 -0000
*************** chrec_contains_symbols_defined_in_loop (
*** 401,406 ****
--- 401,409 ----
    if (chrec == NULL_TREE)
      return false;
  
+   if (TREE_INVARIANT (chrec))
+     return false;
+ 
    if (TREE_CODE (chrec) == VAR_DECL
        || TREE_CODE (chrec) == PARM_DECL
        || TREE_CODE (chrec) == FUNCTION_DECL
Index: tree-ssa-loop-ivopts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-loop-ivopts.c,v
retrieving revision 1.1.2.32
diff -c -3 -p -r1.1.2.32 tree-ssa-loop-ivopts.c
*** tree-ssa-loop-ivopts.c	30 Apr 2004 23:38:49 -0000	1.1.2.32
--- tree-ssa-loop-ivopts.c	13 May 2004 21:07:59 -0000
*************** static unsigned spill_cost;	/* The cost 
*** 243,250 ****
  
  static varray_type decl_rtl_to_reset;
  
- static tree force_gimple_operand (tree, tree *, bool, tree);
- 
  /* Number of uses recorded in DATA.  */
  
  static inline unsigned
--- 243,248 ----
*************** update_addressable_flag (tree expr)
*** 632,638 ****
     to be either ssa_name or integer constant.  If VAR is not NULL, make the
     base variable of the final destination be VAR if possible.  */
  
! static tree
  force_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
  {
    enum tree_code code;
--- 630,636 ----
     to be either ssa_name or integer constant.  If VAR is not NULL, make the
     base variable of the final destination be VAR if possible.  */
  
! tree
  force_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
  {
    enum tree_code code;
*************** static void
*** 1959,1965 ****
  add_address_candidates (struct ivopts_data *data,
  			struct iv *iv, struct iv_use *use)
  {
!   tree base, type;
  
    /* First, the trivial choices.  */
    add_iv_value_candidates (data, iv, use);
--- 1957,1963 ----
  add_address_candidates (struct ivopts_data *data,
  			struct iv *iv, struct iv_use *use)
  {
!   tree base, type, abase, tmp, *act;
  
    /* First, the trivial choices.  */
    add_iv_value_candidates (data, iv, use);
*************** add_address_candidates (struct ivopts_da
*** 1983,1988 ****
--- 1981,2009 ----
  	  add_candidate (data, base, iv->step, false, use);
  	}
      }
+ 
+   /* Third, try removing the constant offset.  */
+   abase = iv->base;
+   while (TREE_CODE (abase) == PLUS_EXPR
+ 	 && TREE_CODE (TREE_OPERAND (abase, 1)) != INTEGER_CST)
+     abase = TREE_OPERAND (abase, 0);
+   /* We found the offset, so make the copy of the non-shared part and
+      remove it.  */
+   if (TREE_CODE (abase) == PLUS_EXPR)
+     {
+       tmp = iv->base;
+       act = &base;
+ 
+       for (tmp = iv->base; tmp != abase; tmp = TREE_OPERAND (tmp, 0))
+ 	{
+ 	  *act = build (PLUS_EXPR, TREE_TYPE (tmp),
+ 			NULL_TREE, TREE_OPERAND (tmp, 1));
+ 	  act = &TREE_OPERAND (*act, 0);
+ 	}
+       *act = TREE_OPERAND (tmp, 0);
+ 
+       add_candidate (data, base, iv->step, false, use);
+     }
  }
  
  /* Possibly adds pseudocandidate for replacing the final value of USE by
*************** rewrite_use_nonlinear_expr (struct ivopt
*** 4113,4118 ****
--- 4134,4221 ----
      }
  }
  
+ /* Replaces ssa name in index IDX by its basic variable.  Callback for
+    for_each_index.  */
+ 
+ static bool
+ idx_remove_ssa_names (tree base ATTRIBUTE_UNUSED, tree *idx,
+ 		      void *data ATTRIBUTE_UNUSED)
+ {
+   if (TREE_CODE (*idx) == SSA_NAME)
+     *idx = SSA_NAME_VAR (*idx);
+   return true;
+ }
+ 
+ /* Unshares REF and replaces ssa names inside it by their basic variables.  */
+ 
+ static tree
+ unshare_and_remove_ssa_names (tree ref)
+ {
+   ref = unshare_expr (ref);
+   for_each_index (&ref, idx_remove_ssa_names, NULL);
+ 
+   return ref;
+ }
+ 
+ /* Rewrites base of memory access OP with expression WITH in statement
+    pointed to by BSI.  */
+ 
+ void
+ rewrite_address_base (block_stmt_iterator *bsi, tree *op, tree with)
+ {
+   tree var = get_base_address (*op), new_var, new_name, copy, name;
+   tree orig;
+ 
+   if (!var || TREE_CODE (with) != SSA_NAME)
+     goto do_rewrite;
+ 
+   if (TREE_CODE (var) == INDIRECT_REF)
+     var = TREE_OPERAND (var, 0);
+   if (TREE_CODE (var) == SSA_NAME)
+     {
+       name = var;
+       var = SSA_NAME_VAR (var);
+     }
+   else if (DECL_P (var))
+     name = NULL_TREE;
+   else
+     goto do_rewrite;
+     
+   if (var_ann (var)->type_mem_tag)
+     var = var_ann (var)->type_mem_tag;
+ 
+   /* We need to add a memory tag for the variable.  But we do not want
+      to add it to the temporary used for the computations, since this leads
+      to problems in redundancy elimination when there are common parts
+      in two computations refering to the different arrays.  So we copy
+      the variable to a new temporary.  */
+   copy = build (MODIFY_EXPR, void_type_node, NULL_TREE, with);
+   if (name)
+     new_name = duplicate_ssa_name (name, copy);
+   else
+     {
+       new_var = create_tmp_var (TREE_TYPE (with), "ruatmp");
+       add_referenced_tmp_var (new_var);
+       var_ann (new_var)->type_mem_tag = var;
+       new_name = make_ssa_name (new_var, copy);
+     }
+   TREE_OPERAND (copy, 0) = new_name;
+   bsi_insert_before (bsi, copy, BSI_SAME_STMT);
+   with = new_name;
+ 
+ do_rewrite:
+ 
+   orig = NULL_TREE;
+   if (TREE_CODE (*op) == INDIRECT_REF)
+     orig = REF_ORIGINAL (*op);
+   if (!orig)
+     orig = unshare_and_remove_ssa_names (*op);
+ 
+   *op = build1 (INDIRECT_REF, TREE_TYPE (*op), with);
+   /* Record the original reference, for purposes of alias analysis.  */
+   REF_ORIGINAL (*op) = orig;
+ }
+ 
  /* Rewrites USE (address that is an iv) using candidate CAND.  */
  
  static void
*************** rewrite_use_address (struct ivopts_data 
*** 4124,4170 ****
    block_stmt_iterator bsi = stmt_bsi (use->stmt);
    tree stmts;
    tree op = force_gimple_operand (comp, &stmts, false, NULL_TREE);
-   tree var, new_var, new_name, copy, name;
  
    if (stmts)
      bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
  
!   if (TREE_CODE (op) == SSA_NAME)
!     {
!       var = get_base_address (*use->op_p);
!       if (TREE_CODE (var) == INDIRECT_REF)
! 	var = TREE_OPERAND (var, 0);
!       if (TREE_CODE (var) == SSA_NAME)
! 	{
! 	  name = var;
! 	  var = SSA_NAME_VAR (var);
! 	}
!       else
! 	name = NULL_TREE;
!       if (var_ann (var)->type_mem_tag)
! 	var = var_ann (var)->type_mem_tag;
! 
!       /* We need to add a memory tag for the variable.  But we do not want
! 	 to add it to the temporary used for the computations, since this leads
! 	 to problems in redundancy elimination when there are common parts
! 	 in two computations refering to the different arrays.  So we copy
! 	 the variable to a new temporary.  */
!       copy = build (MODIFY_EXPR, void_type_node, NULL_TREE, op);
!       if (name)
! 	new_name = duplicate_ssa_name (name, copy);
!       else
! 	{
! 	  new_var = create_tmp_var (TREE_TYPE (op), "ruatmp");
! 	  add_referenced_tmp_var (new_var);
! 	  var_ann (new_var)->type_mem_tag = var;
! 	  new_name = make_ssa_name (new_var, copy);
! 	}
!       TREE_OPERAND (copy, 0) = new_name;
!       bsi_insert_before (&bsi, copy, BSI_SAME_STMT);
!       op = new_name;
!     }
! 
!   *use->op_p = build1 (INDIRECT_REF, TREE_TYPE (*use->op_p), op);
  }
  
  /* Rewrites USE (the condition such that one of the arguments is an iv) using
--- 4227,4237 ----
    block_stmt_iterator bsi = stmt_bsi (use->stmt);
    tree stmts;
    tree op = force_gimple_operand (comp, &stmts, false, NULL_TREE);
  
    if (stmts)
      bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
  
!   rewrite_address_base (&bsi, use->op_p, op);
  }
  
  /* Rewrites USE (the condition such that one of the arguments is an iv) using
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.154.2.12
diff -c -3 -p -r1.342.2.154.2.12 tree.h
*** tree.h	27 Apr 2004 14:10:15 -0000	1.342.2.154.2.12
--- tree.h	13 May 2004 21:07:59 -0000
*************** struct tree_vec GTY(())
*** 1042,1047 ****
--- 1042,1050 ----
  #define TREE_OPERAND(NODE, I) TREE_OPERAND_CHECK (NODE, I)
  #define TREE_COMPLEXITY(NODE) (EXPR_CHECK (NODE)->exp.complexity)
  
+ /* In INDIRECT_REF.  */
+ #define REF_ORIGINAL(NODE) TREE_CHAIN (TREE_CHECK (NODE, INDIRECT_REF))
+ 
  /* In a LABELED_BLOCK_EXPR node.  */
  #define LABELED_BLOCK_LABEL(NODE) \
    TREE_OPERAND_CHECK_CODE (NODE, LABELED_BLOCK_EXPR, 0)



More information about the Gcc-patches mailing list