Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 232580) +++ gcc/common.opt (working copy) @@ -1025,6 +1025,10 @@ Common Var(flag_checking) Init(CHECKING_P) Perform internal consistency checkings. +fcollectible-pointers +Common Report Var(flag_collectible_pointers) Optimization +Ensure that pointers are always collectible by a garbage collector. + fcombine-stack-adjustments Common Report Var(flag_combine_stack_adjustments) Optimization Looks for opportunities to reduce stack adjustments and stack references. Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 232580) +++ gcc/doc/invoke.texi (working copy) @@ -6621,6 +6621,17 @@ If you use @option{-Wunsafe-loop-optimizations}, the compiler warns you if it finds this kind of loop. +@item -fcollectible-pointers +@opindex fcollectible-pointers +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: 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,14 @@ +/* { dg-options "-O2 -fdump-tree-ivopts -fcollectible-pointers" } */ + +/* No ivopts here when using -fcollectible-pointers. */ +void foo (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: gcc/tree-ssa-loop-ivopts.c =================================================================== --- gcc/tree-ssa-loop-ivopts.c (revision 232580) +++ gcc/tree-ssa-loop-ivopts.c (working copy) @@ -2956,6 +2956,17 @@ || !cst_and_fits_in_hwi (step)) return; + // -fcollectible-pointers 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_collectible_pointers && POINTER_TYPE_P (TREE_TYPE (base))) + return; + cstepi = int_cst_value (step); mem_mode = TYPE_MODE (TREE_TYPE (*use->op_p));