summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-16 15:16:42 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-16 15:16:42 +0000
commit00ae4124e41f87be1459cbb37ead23b9c345bab1 (patch)
tree2b7b91ca00fdef0b86fd09f0e777db15991f100e
parent81012a4c7a37cd678d233e409cde1c760f9911e3 (diff)
downloadgcc-00ae4124e41f87be1459cbb37ead23b9c345bab1.tar.gz
2008-04-16 Richard Guenther <rguenther@suse.de>
* Makefile.in (tree-affine.o): Add $(FLAGS_H) dependency. * tree-affine.c (aff_combination_expand): Look through some conversions. * gcc.dg/tree-ssa/loop-35.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@134346 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-35.c64
-rw-r--r--gcc/tree-affine.c39
5 files changed, 111 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0295ec08d5e..a36a14accd5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2008-04-16 Richard Guenther <rguenther@suse.de>
+
+ * Makefile.in (tree-affine.o): Add $(FLAGS_H) dependency.
+ * tree-affine.c (aff_combination_expand): Look through some
+ conversions.
+
2008-04-15 Doug Kwan <dougkwan@google.com>
* dwarf2asm.c (dw2_assemble_integer): Cast to unsigned HOST_WIDE_INT
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index dc73bc59f68..4ea55fa32ba 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2191,7 +2191,7 @@ tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_FLOW_H) $(CONFIG_H) \
tree-chrec.h $(VARRAY_H) tree-affine.h pointer-set.h $(TARGET_H)
tree-affine.o : tree-affine.c tree-affine.h $(CONFIG_H) pointer-set.h \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(TREE_GIMPLE_H) \
- output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H)
+ output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(FLAGS_H)
tree-ssa-loop-manip.o : tree-ssa-loop-manip.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) \
output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 13167d6ef18..de3305ff0d3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2008-04-16 Richard Guenther <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/loop-35.c: New testcase.
+
2008-04-16 Samuel Tardieu <sam@rfc1149.net>
PR ada/29015
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-35.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-35.c
new file mode 100644
index 00000000000..ce6ba28d74a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-35.c
@@ -0,0 +1,64 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-lim-details" } */
+
+int x;
+int a[100];
+
+struct a
+{
+ int X;
+ int Y;
+};
+
+struct a arr[100];
+
+void test1(int b)
+{
+ unsigned i;
+
+ /* And here. */
+ for (i = 0; i < 100; i++)
+ {
+ arr[b+8].X += i;
+ arr[b+9].X += i;
+ }
+}
+
+void test2(struct a *A, int b)
+{
+ unsigned i;
+
+ /* And here as well. */
+ for (i = 0; i < 100; i++)
+ {
+ A[b].X += i;
+ A[b+1].Y += i;
+ }
+}
+
+void test3(unsigned long b)
+{
+ unsigned i;
+
+ /* And here. */
+ for (i = 0; i < 100; i++)
+ {
+ arr[b+8].X += i;
+ arr[b+9].X += i;
+ }
+}
+
+void test4(struct a *A, unsigned long b)
+{
+ unsigned i;
+
+ /* And here as well. */
+ for (i = 0; i < 100; i++)
+ {
+ A[b].X += i;
+ A[b+1].Y += i;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "Executing store motion of" 8 "lim" } } */
+/* { dg-final { cleanup-tree-dump "lim" } } */
diff --git a/gcc/tree-affine.c b/gcc/tree-affine.c
index 54f36b98135..8407df204a2 100644
--- a/gcc/tree-affine.c
+++ b/gcc/tree-affine.c
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "pointer-set.h"
#include "tree-affine.h"
#include "tree-gimple.h"
+#include "flags.h"
/* Extends CST as appropriate for the affine combinations COMB. */
@@ -578,12 +579,20 @@ aff_combination_expand (aff_tree *comb, struct pointer_map_t **cache)
aff_combination_zero (&to_add, comb->type);
for (i = 0; i < comb->n; i++)
{
+ tree type, name;
e = comb->elts[i].val;
- if (TREE_CODE (e) != SSA_NAME)
+ type = TREE_TYPE (e);
+ name = e;
+ /* Look through some conversions. */
+ if (TREE_CODE (e) == NOP_EXPR
+ && (TYPE_PRECISION (type)
+ >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (e, 0)))))
+ name = TREE_OPERAND (e, 0);
+ if (TREE_CODE (name) != SSA_NAME)
continue;
- def = SSA_NAME_DEF_STMT (e);
+ def = SSA_NAME_DEF_STMT (name);
if (TREE_CODE (def) != GIMPLE_MODIFY_STMT
- || GIMPLE_STMT_OPERAND (def, 0) != e)
+ || GIMPLE_STMT_OPERAND (def, 0) != name)
continue;
rhs = GIMPLE_STMT_OPERAND (def, 1);
@@ -607,6 +616,30 @@ aff_combination_expand (aff_tree *comb, struct pointer_map_t **cache)
exp = XNEW (struct name_expansion);
exp->in_progress = 1;
*slot = exp;
+ if (e != name)
+ {
+ /* In principle this is a generally valid folding, but
+ it is not unconditionally an optimization, so do it
+ here and not in fold_unary. */
+ /* Convert (T1)(X *+- CST) into (T1)X *+- (T1)CST if T1 is wider
+ than the type of X and overflow for the type of X is
+ undefined. */
+ if (INTEGRAL_TYPE_P (type)
+ && INTEGRAL_TYPE_P (TREE_TYPE (rhs))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs))
+ && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (rhs))
+ && (TREE_CODE (rhs) == PLUS_EXPR
+ || TREE_CODE (rhs) == MINUS_EXPR
+ || TREE_CODE (rhs) == MULT_EXPR)
+ && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
+ {
+ rhs = fold_build2 (TREE_CODE (rhs), type,
+ fold_convert (type, TREE_OPERAND (rhs, 0)),
+ fold_convert (type, TREE_OPERAND (rhs, 1)));
+ }
+ else
+ rhs = fold_convert (type, rhs);
+ }
tree_to_aff_combination_expand (rhs, comb->type, &current, cache);
exp->expansion = current;
exp->in_progress = 0;