172 lines
5.4 KiB
Diff
172 lines
5.4 KiB
Diff
|
|
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c
|
||
|
|
new file mode 100644
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c
|
||
|
|
@@ -0,0 +1,12 @@
|
||
|
|
+/* { dg-do compile } */
|
||
|
|
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
|
||
|
|
+
|
||
|
|
+unsigned test(unsigned k, unsigned b) {
|
||
|
|
+ unsigned a[2];
|
||
|
|
+ if (b < a[k]) {
|
||
|
|
+ a[k] = b;
|
||
|
|
+ }
|
||
|
|
+ return a[0]+a[1];
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
|
||
|
|
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c
|
||
|
|
new file mode 100644
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c
|
||
|
|
@@ -0,0 +1,14 @@
|
||
|
|
+/* { dg-do compile } */
|
||
|
|
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
|
||
|
|
+
|
||
|
|
+int c;
|
||
|
|
+unsigned test(unsigned k, unsigned b) {
|
||
|
|
+ unsigned a[2];
|
||
|
|
+ a[k] = c;
|
||
|
|
+ if (b < a[k]) {
|
||
|
|
+ a[k] = b;
|
||
|
|
+ }
|
||
|
|
+ return a[0]+a[1];
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
|
||
|
|
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c
|
||
|
|
new file mode 100644
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c
|
||
|
|
@@ -0,0 +1,12 @@
|
||
|
|
+/* { dg-do compile } */
|
||
|
|
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
|
||
|
|
+
|
||
|
|
+unsigned a[2];
|
||
|
|
+unsigned test(unsigned k, unsigned b) {
|
||
|
|
+ if (b < a[k]) {
|
||
|
|
+ a[k] = b;
|
||
|
|
+ }
|
||
|
|
+ return a[0]+a[1];
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+/* { dg-final { scan-tree-dump-not "Conditional store replacement" "cselim" } } */
|
||
|
|
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c
|
||
|
|
new file mode 100644
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c
|
||
|
|
@@ -0,0 +1,14 @@
|
||
|
|
+/* { dg-do compile } */
|
||
|
|
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
|
||
|
|
+
|
||
|
|
+int *p;
|
||
|
|
+unsigned test(unsigned k, unsigned b) {
|
||
|
|
+ unsigned a[2];
|
||
|
|
+ p = a;
|
||
|
|
+ if (b < a[k]) {
|
||
|
|
+ a[k] = b;
|
||
|
|
+ }
|
||
|
|
+ return a[0]+a[1];
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+/* { dg-final { scan-tree-dump-not "Conditional store replacement" "cselim" } } */
|
||
|
|
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c
|
||
|
|
new file mode 100644
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c
|
||
|
|
@@ -0,0 +1,16 @@
|
||
|
|
+/* { dg-do compile } */
|
||
|
|
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
|
||
|
|
+
|
||
|
|
+int test(int b, int k) {
|
||
|
|
+ struct {
|
||
|
|
+ int data[2];
|
||
|
|
+ } a;
|
||
|
|
+
|
||
|
|
+ if (b < a.data[k]) {
|
||
|
|
+ a.data[k] = b;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return a.data[0] + a.data[1];
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
|
||
|
|
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c
|
||
|
|
new file mode 100644
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c
|
||
|
|
@@ -0,0 +1,19 @@
|
||
|
|
+/* { dg-do compile } */
|
||
|
|
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
|
||
|
|
+
|
||
|
|
+int test(int b, int k) {
|
||
|
|
+ typedef struct {
|
||
|
|
+ int x;
|
||
|
|
+ } SS;
|
||
|
|
+ struct {
|
||
|
|
+ SS data[2];
|
||
|
|
+ } a;
|
||
|
|
+
|
||
|
|
+ if (b < a.data[k].x) {
|
||
|
|
+ a.data[k].x = b;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ return a.data[0].x + a.data[1].x;
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
|
||
|
|
diff -uprN a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
|
||
|
|
--- a/gcc/tree-ssa-phiopt.c
|
||
|
|
+++ b/gcc/tree-ssa-phiopt.c
|
||
|
|
@@ -2196,7 +2196,8 @@ get_non_trapping (void)
|
||
|
|
|
||
|
|
We check that MIDDLE_BB contains only one store, that that store
|
||
|
|
doesn't trap (not via NOTRAP, but via checking if an access to the same
|
||
|
|
- memory location dominates us) and that the store has a "simple" RHS. */
|
||
|
|
+ memory location dominates us, or the store is to a local addressable
|
||
|
|
+ object) and that the store has a "simple" RHS. */
|
||
|
|
|
||
|
|
static bool
|
||
|
|
cond_store_replacement (basic_block middle_bb, basic_block join_bb,
|
||
|
|
@@ -2218,8 +2219,9 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
|
||
|
|
locus = gimple_location (assign);
|
||
|
|
lhs = gimple_assign_lhs (assign);
|
||
|
|
rhs = gimple_assign_rhs1 (assign);
|
||
|
|
- if (TREE_CODE (lhs) != MEM_REF
|
||
|
|
- || TREE_CODE (TREE_OPERAND (lhs, 0)) != SSA_NAME
|
||
|
|
+ if ((TREE_CODE (lhs) != MEM_REF
|
||
|
|
+ && TREE_CODE (lhs) != ARRAY_REF
|
||
|
|
+ && TREE_CODE (lhs) != COMPONENT_REF)
|
||
|
|
|| !is_gimple_reg_type (TREE_TYPE (lhs)))
|
||
|
|
return false;
|
||
|
|
|
||
|
|
@@ -2227,7 +2229,13 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
|
||
|
|
TREE_THIS_NOTRAP here, but in that case we also could move stores,
|
||
|
|
whose value is not available readily, which we want to avoid. */
|
||
|
|
if (!nontrap->contains (lhs))
|
||
|
|
- return false;
|
||
|
|
+ {
|
||
|
|
+ /* If LHS is a local variable without address-taken, we could
|
||
|
|
+ always safely move down the store. */
|
||
|
|
+ tree base = get_base_address (lhs);
|
||
|
|
+ if (!auto_var_p (base) || TREE_ADDRESSABLE (base))
|
||
|
|
+ return false;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
/* Now we've checked the constraints, so do the transformation:
|
||
|
|
1) Remove the single store. */
|
||
|
|
@@ -2280,6 +2288,14 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
|
||
|
|
else
|
||
|
|
gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
|
||
|
|
|
||
|
|
+ if (dump_file && (dump_flags & TDF_DETAILS))
|
||
|
|
+ {
|
||
|
|
+ fprintf (dump_file, "\nConditional store replacement happened!");
|
||
|
|
+ fprintf (dump_file, "\nReplaced the store with a load.");
|
||
|
|
+ fprintf (dump_file, "\nInserted a new PHI statement in joint block:\n");
|
||
|
|
+ print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS);
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
return true;
|
||
|
|
}
|