On Tue, Jan 26, 2016 at 4:10 AM, Bernd Schmidt <[email protected]> wrote:
>
>>> On 01/23/2016 12:52 AM, Ian Lance Taylor wrote:
>>>
>>>> 2016-01-22 Ian Lance Taylor <[email protected]>
>>>>
>>>> * common.opt (fkeep-gc-roots-live): New 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.
>>>> * doc/invoke.texi (Optimize Options): Document
>>>> -fkeep-gc-roots-live.
>>>>
>>>> gcc/testsuite/ChangeLog:
>>>>
>>>> 2016-01-22 Ian Lance Taylor <[email protected]>
>>>>
>>>> * gcc.dg/tree-ssa/ivopt_5.c: New test.
>>>
>>>
>>>
>>> Patch not attached?
>>
>>
>> The patch is there in the mailing list. See the attachment on
>> https://gcc.gnu.org/ml/gcc-patches/2016-01/msg01781.html .
>
>
> That seems to be the old patch. At least it doesn't seem to match the
> ChangeLog quoted above.
I'm sorry, you're quite right. That's odd. Here is the actual patch.
Ian
Index: common.opt
===================================================================
--- common.opt (revision 232580)
+++ common.opt (working copy)
@@ -1380,6 +1380,10 @@
Enable hoisting adjacent loads to encourage generating conditional move
instructions.
+fkeep-gc-roots-live
+Common 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.
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi (revision 232580)
+++ doc/invoke.texi (working copy)
@@ -359,7 +359,7 @@
-fno-ira-share-spill-slots @gol
-fisolate-erroneous-paths-dereference -fisolate-erroneous-paths-attribute @gol
-fivopts -fkeep-inline-functions -fkeep-static-functions @gol
--fkeep-static-consts -flive-range-shrinkage @gol
+-fkeep-static-consts -fkeep-gc-roots-live -flive-range-shrinkage @gol
-floop-block -floop-interchange -floop-strip-mine @gol
-floop-unroll-and-jam -floop-nest-optimize @gol
-floop-parallelize-all -flra-remat -flto -flto-compression-level @gol
@@ -6621,6 +6621,17 @@
If you use @option{-Wunsafe-loop-optimizations}, the compiler warns you
if it finds this kind of loop.
+@item -fkeep-gc-roots-live
+@opindex fkeep-gc-roots-live
+This option tells the compiler that a garbage collector will be used,
+and that therefore the compiled code must retain a live pointer into
+all memory blocks. The compiler is permitted to construct a pointer
+that is outside the bounds of a memory block, but it must ensure that
+given a pointer into memory, some pointer into that memory remains
+live in the compiled code whenever it is live in the source code.
+This option is disabled by default for most languages, enabled by
+default for languages that use garbage collection.
+
@item -fcrossjumping
@opindex fcrossjumping
Perform cross-jumping transformation.
Index: testsuite/gcc.dg/tree-ssa/ivopt_5.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/ivopt_5.c (revision 0)
+++ testsuite/gcc.dg/tree-ssa/ivopt_5.c (working copy)
@@ -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"} } */
Index: tree-ssa-loop-ivopts.c
===================================================================
--- tree-ssa-loop-ivopts.c (revision 232580)
+++ tree-ssa-loop-ivopts.c (working copy)
@@ -2815,6 +2815,16 @@
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 @@
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);