aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ivopt_5.c23
-rw-r--r--gcc/tree-ssa-loop-ivopts.c17
5 files changed, 54 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ea59088..60322af 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2016-01-27 Ian Lance Taylor <iant@google.com>
+
+ * common.opt (fkeep-gc-roots-live): New undocumented option.
+ * tree-ssa-loop-ivopts.c (add_candidate_1): If
+ -fkeep-gc-roots-live, skip pointers.
+ (add_iv_candidate_for_biv): Handle add_candidate_1 returning
+ NULL.
+
2016-01-27 Uros Bizjak <ubizjak@gmail.com>
PR target/69512
diff --git a/gcc/common.opt b/gcc/common.opt
index 0f2587a..520fa9c 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1380,6 +1380,10 @@ Common Report Var(flag_hoist_adjacent_loads) Optimization
Enable hoisting adjacent loads to encourage generating conditional move
instructions.
+fkeep-gc-roots-live
+Common Undocumented Report Var(flag_keep_gc_roots_live) Optimization
+; Always keep a pointer to a live memory block
+
floop-parallelize-all
Common Report Var(flag_loop_parallelize_all) Optimization
Mark all loops as parallel.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 98bb775..b3af22c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2016-01-27 Ian Lance Taylor <iant@google.com>
+
+ * gcc.dg/tree-ssa/ivopt_5.c: New test.
+
2016-01-27 Ryan Burn <contact@rnburn.com>
PR cilkplus/69267
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ivopt_5.c b/gcc/testsuite/gcc.dg/tree-ssa/ivopt_5.c
new file mode 100644
index 0000000..b0d4166
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ivopt_5.c
@@ -0,0 +1,23 @@
+/* { dg-options "-O2 -fdump-tree-ivopts -fkeep-gc-roots-live" } */
+
+/* Only integer ivopts here when using -fkeep-gc-roots-live. */
+
+void foo (char *pstart, int n)
+{
+ char *p;
+ char *pend = pstart + n;
+
+ for (p = pstart; p < pend; p++)
+ *p = 1;
+}
+
+void foo1 (char *pstart, int n)
+{
+ char *p;
+ char *pend = pstart + n;
+
+ for (p = pstart; p != pend; p++)
+ *p = 1;
+}
+
+/* { dg-final { scan-tree-dump-times "ivtmp.\[0-9_\]* = PHI <\[^0\]" 0 "ivopts"} } */
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 3faed93..4026d28 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -2815,6 +2815,16 @@ add_candidate_1 (struct ivopts_data *data,
struct iv_cand *cand = NULL;
tree type, orig_type;
+ /* -fkeep-gc-roots-live means that we have to keep a real pointer
+ live, but the ivopts code may replace a real pointer with one
+ pointing before or after the memory block that is then adjusted
+ into the memory block during the loop. FIXME: It would likely be
+ better to actually force the pointer live and still use ivopts;
+ for example, it would be enough to write the pointer into memory
+ and keep it there until after the loop. */
+ if (flag_keep_gc_roots_live && POINTER_TYPE_P (TREE_TYPE (base)))
+ return NULL;
+
/* For non-original variables, make sure their values are computed in a type
that does not invoke undefined behavior on overflows (since in general,
we cannot prove that these induction variables are non-wrapping). */
@@ -3083,8 +3093,11 @@ add_iv_candidate_for_biv (struct ivopts_data *data, struct iv *iv)
cand = add_candidate_1 (data,
iv->base, iv->step, true, IP_ORIGINAL, NULL,
SSA_NAME_DEF_STMT (def));
- cand->var_before = iv->ssa_name;
- cand->var_after = def;
+ if (cand)
+ {
+ cand->var_before = iv->ssa_name;
+ cand->var_after = def;
+ }
}
else
gcc_assert (gimple_bb (phi) == data->current_loop->header);