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"} } */