diff options
author | Austin Clements <austin@google.com> | 2018-03-23 17:38:55 -0400 |
---|---|---|
committer | Austin Clements <austin@google.com> | 2018-05-22 14:15:44 +0000 |
commit | b812eec928e89648df5ebc6a207ae2c156660be0 (patch) | |
tree | 339cc990c6a92271ac34d606e382f29175bfb7d3 /src/cmd/compile/internal/ssa/loopbce.go | |
parent | 4816eface10125bc915c8a0dfff7fe1489827b8c (diff) | |
download | go-b812eec928e89648df5ebc6a207ae2c156660be0.tar.gz go-b812eec928e89648df5ebc6a207ae2c156660be0.zip |
cmd/compile: detect OFORUNTIL inductive facts in prove
Currently, we compile range loops into for loops with the obvious
initialization and update of the index variable. In this form, the
prove pass can see that the body is dominated by an i < len condition,
and findIndVar can detect that i is an induction variable and that
0 <= i < len.
GOEXPERIMENT=preemptibleloops compiles range loops to OFORUNTIL and
we're preparing to unconditionally switch to a variation of this for
#24543. OFORUNTIL moves the increment and condition *after* the body,
which makes the bounds on the index variable much less obvious. With
OFORUNTIL, proving anything about the index variable requires
understanding the phi that joins the index values at the top of the
loop body block.
This interferes with both prove's ability to see that i < len (this is
true on both paths that enter the body, but from two different
conditional checks) and with findIndVar's ability to detect the
induction pattern.
Fix this by teaching prove to detect that the index in the pattern
constructed by OFORUNTIL is an induction variable and add both bounds
to the facts table. Currently this is done separately from findIndVar
because it depends on prove's factsTable, while findIndVar runs before
visiting blocks and building the factsTable.
Without any GOEXPERIMENT, this has no effect on std or cmd. However,
with GOEXPERIMENT=preemptibleloops, this change becomes necessary to
prove 90 conditions in std and cmd.
Change-Id: Ic025d669f81b53426309da5a6e8010e5ccaf4f49
Reviewed-on: https://go-review.googlesource.com/102603
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/ssa/loopbce.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/loopbce.go | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/src/cmd/compile/internal/ssa/loopbce.go b/src/cmd/compile/internal/ssa/loopbce.go index 692e55e17a..0c09de0bfc 100644 --- a/src/cmd/compile/internal/ssa/loopbce.go +++ b/src/cmd/compile/internal/ssa/loopbce.go @@ -165,30 +165,7 @@ nextb: } if f.pass.debug >= 1 { - mb1, mb2 := "[", "]" - if flags&indVarMinExc != 0 { - mb1 = "(" - } - if flags&indVarMaxInc == 0 { - mb2 = ")" - } - - mlim1, mlim2 := fmt.Sprint(min.AuxInt), fmt.Sprint(max.AuxInt) - if !min.isGenericIntConst() { - if f.pass.debug >= 2 { - mlim1 = fmt.Sprint(min) - } else { - mlim1 = "?" - } - } - if !max.isGenericIntConst() { - if f.pass.debug >= 2 { - mlim2 = fmt.Sprint(max) - } else { - mlim2 = "?" - } - } - b.Func.Warnl(b.Pos, "Induction variable: limits %v%v,%v%v, increment %d", mb1, mlim1, mlim2, mb2, inc.AuxInt) + printIndVar(b, ind, min, max, inc.AuxInt, flags) } iv = append(iv, indVar{ @@ -215,3 +192,34 @@ func dropAdd64(v *Value) (*Value, int64) { } return v, 0 } + +func printIndVar(b *Block, i, min, max *Value, inc int64, flags indVarFlags) { + mb1, mb2 := "[", "]" + if flags&indVarMinExc != 0 { + mb1 = "(" + } + if flags&indVarMaxInc == 0 { + mb2 = ")" + } + + mlim1, mlim2 := fmt.Sprint(min.AuxInt), fmt.Sprint(max.AuxInt) + if !min.isGenericIntConst() { + if b.Func.pass.debug >= 2 { + mlim1 = fmt.Sprint(min) + } else { + mlim1 = "?" + } + } + if !max.isGenericIntConst() { + if b.Func.pass.debug >= 2 { + mlim2 = fmt.Sprint(max) + } else { + mlim2 = "?" + } + } + extra := "" + if b.Func.pass.debug >= 2 { + extra = fmt.Sprintf(" (%s)", i) + } + b.Func.Warnl(b.Pos, "Induction variable: limits %v%v,%v%v, increment %d%s", mb1, mlim1, mlim2, mb2, inc, extra) +} |