On Wed, Jan 27, 2016 at 7:24 AM, Bernd Schmidt <bschm...@redhat.com> wrote:
> On 01/27/2016 04:18 PM, Ian Lance Taylor wrote:
>>
>> On Wed, Jan 27, 2016 at 7:16 AM, Bernd Schmidt <bschm...@redhat.com>
>> wrote:
>>>
>>>
>>> Still, I feel uncomfortable about making a promise we don't really expect
>>> to
>>> fully keep yet, so I would prefer this option to be undocumented for now.
>>> I
>>> won't object if someone else wants to approve it as a normal option
>>> however.
>>
>>
>> Are you approving the patch if I change the option to be undocumented?
>
>
> Yes.

Committed as follows.

gcc/ChangeLog:

2016-01-27  Ian Lance Taylor  <i...@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.

gcc/testsuite/ChangeLog:

2016-01-27  Ian Lance Taylor  <i...@google.com>

* gcc.dg/tree-ssa/ivopt_5.c: New test.
Index: gcc/common.opt
===================================================================
--- gcc/common.opt      (revision 232580)
+++ gcc/common.opt      (working copy)
@@ -1380,6 +1380,10 @@
 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.
Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
--- gcc/tree-ssa-loop-ivopts.c  (revision 232580)
+++ gcc/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);
Index: gcc/testsuite/gcc.dg/tree-ssa/ivopt_5.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ivopt_5.c     (revision 0)
+++ gcc/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"} } */

Reply via email to