View | Details | Return to bug 70359
Collapse All | Expand All

(-)a/gcc/tree-outof-ssa.c (+93 lines)
Lines 43-48 along with GCC; see the file COPYING3. If not see Link Here
43
#include "tree-ssa-coalesce.h"
43
#include "tree-ssa-coalesce.h"
44
#include "tree-outof-ssa.h"
44
#include "tree-outof-ssa.h"
45
#include "dojump.h"
45
#include "dojump.h"
46
#include "fold-const.h"
47
#include "tree-ssa-loop-niter.h"
46
48
47
/* FIXME: A lot of code here deals with expanding to RTL.  All that code
49
/* FIXME: A lot of code here deals with expanding to RTL.  All that code
48
   should be in cfgexpand.c.  */
50
   should be in cfgexpand.c.  */
Lines 1035-1040 trivially_conflicts_p (basic_block bb, tree result, tree arg) Link Here
1035
  return false;
1037
  return false;
1036
}
1038
}
1037
1039
1040
/* Return TRUE if STMT is in the form: x_99 = SSA +p INT.  */
1041
// FIXME: Generalize this a bit more.  Perhaps handle PLUS/MINUS_EXPR too.
1042
static bool
1043
iv_plus_constant (gimple *stmt, tree ssa)
1044
{
1045
  return is_gimple_assign (stmt)
1046
    && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR
1047
    && gimple_assign_rhs1 (stmt) == ssa
1048
    && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST;
1049
}
1050
1051
/* If there is a use of a previous iteration of an IV outside of the
1052
   loop, see if we can rewrite the out-of-loop version in terms of IV.
1053
1054
   This undoes some of the damage done by forwprop creating
1055
   overlapping life-ranges for before and after values of an IV.
1056
1057
   We are looking for loops like this:
1058
1059
   LOOP:
1060
     # p_8 = PHI <p_16(2), p_INC(3)>
1061
     ...
1062
     p_INC = p_8 - 1;
1063
     goto LOOP;
1064
     x_123 = p_8 - 2;
1065
1066
   The outside use of p_8 can be rewritten as:
1067
     x_123 = p_INC - 1;
1068
   which can yield better auto inc/dec addressing.
1069
1070
   IV is the induction variable (p_8 above).
1071
   IV_INCR is the increment variable (p_INC above).  */
1072
1073
static void
1074
uncoalesce_ivs_outside_loop (tree iv, tree iv_incr)
1075
{
1076
  gimple *incr_stmt = SSA_NAME_DEF_STMT (iv_incr);
1077
  if (!iv_plus_constant (incr_stmt, iv))
1078
    return;
1079
1080
  gimple *use;
1081
  imm_use_iterator imm_iter;
1082
  tree curr_cst = gimple_assign_rhs2 (incr_stmt);
1083
  // FIXME: Generalize this.  Perhaps handle any multiple of CURR_CST.
1084
  tree prev_cst = fold_build2 (PLUS_EXPR, TREE_TYPE (curr_cst),
1085
			       curr_cst, curr_cst);
1086
  FOR_EACH_IMM_USE_STMT (use, imm_iter, iv)
1087
    {
1088
      if (is_gimple_debug (use)
1089
	  || use == incr_stmt
1090
	  || !iv_plus_constant (use, iv)
1091
	  || prev_cst != gimple_assign_rhs2 (use)
1092
	  || !stmt_dominates_stmt_p (incr_stmt, use))
1093
	// FIXME: bail if USE is not outside loop ??
1094
	continue;
1095
1096
      /* Rewrite:
1097
	   iv_incr = iv + 1
1098
	   ...
1099
	   x = iv + 2*CST
1100
	 into
1101
	   x = iv_incr + CST
1102
      */
1103
      gimple_assign_set_rhs1 (use, iv_incr);
1104
      gimple_assign_set_rhs2 (use, curr_cst);
1105
      update_stmt (use);
1106
1107
      /* If possible, rewrite MEM[iv_incr + CST] into *x.  */
1108
      gimple *u;
1109
      tree x = gimple_assign_lhs (use);
1110
      imm_use_iterator imm_iter2;
1111
      FOR_EACH_IMM_USE_STMT (u, imm_iter2, iv_incr)
1112
	{
1113
	  if (!is_gimple_assign (u)
1114
	      || TREE_CODE (gimple_assign_lhs (u)) != MEM_REF)
1115
	    continue;
1116
	  tree lhs = gimple_assign_lhs (u);
1117
	  if (TREE_OPERAND (lhs, 0) == iv_incr
1118
	      && TREE_CODE (TREE_OPERAND (lhs, 1)) == INTEGER_CST
1119
	      && tree_int_cst_equal (TREE_OPERAND (lhs, 1), curr_cst))
1120
	    {
1121
	      TREE_OPERAND (lhs, 0) = x;
1122
	      TREE_OPERAND (lhs, 1)
1123
		= build_int_cst (TREE_TYPE (TREE_OPERAND (lhs, 1)), 0);
1124
	      update_stmt (u);
1125
	    }
1126
	}
1127
    }
1128
}
1038
1129
1039
/* Search every PHI node for arguments associated with backedges which
1130
/* Search every PHI node for arguments associated with backedges which
1040
   we can trivially determine will need a copy (the argument is either
1131
   we can trivially determine will need a copy (the argument is either
Lines 1090-1095 insert_backedge_copies (void) Link Here
1090
		  if (!gsi_end_p (gsi2))
1181
		  if (!gsi_end_p (gsi2))
1091
		    last = gsi_stmt (gsi2);
1182
		    last = gsi_stmt (gsi2);
1092
1183
1184
		  uncoalesce_ivs_outside_loop (result, arg);
1185
1093
		  /* In theory the only way we ought to get back to the
1186
		  /* In theory the only way we ought to get back to the
1094
		     start of a loop should be with a COND_EXPR or GOTO_EXPR.
1187
		     start of a loop should be with a COND_EXPR or GOTO_EXPR.
1095
		     However, better safe than sorry.
1188
		     However, better safe than sorry.

Return to bug 70359