Patch RFA: Add option -fcollectible-pointers, use it in ivopts

Ian Lance Taylor iant@golang.org
Fri Jan 22 19:03:00 GMT 2016


Updated patch.

I've verified that I'm changing the only relevant place in
tree-ssa-loop-ivopts.c that creates a POINTER_PLUS_EXPR, so I do think
that this is the only changed to fix the problem for ivopts.

OK for mainline?

Ian

gcc/ChangeLog:

2016-01-22  Ian Lance Taylor  <iant@google.com>

* common.opt (fkeep-gc-roots-live): New option.
* tree-ssa-loop-ivopts.c (add_autoinc_candidates): If
-fkeep-gc-roots-live, skip pointers.
* doc/invoke.texi (Optimize Options): Document
-fkeep-gc-roots-live.

gcc/testsuite/ChangeLog:

2016-01-22  Ian Lance Taylor  <iant@google.com>

* gcc.dg/tree-ssa/ivopt_5.c: New test.
-------------- next part --------------
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" } */
+
+/* No 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 "ivopts"} } */
Index: tree-ssa-loop-ivopts.c
===================================================================
--- tree-ssa-loop-ivopts.c	(revision 232580)
+++ tree-ssa-loop-ivopts.c	(working copy)
@@ -2956,6 +2956,16 @@
       || !cst_and_fits_in_hwi (step))
     return;
 
+  /* -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;
+
   cstepi = int_cst_value (step);
 
   mem_mode = TYPE_MODE (TREE_TYPE (*use->op_p));


More information about the Gcc-patches mailing list