diff options
author | Keith Randall <khr@golang.org> | 2016-09-16 13:50:18 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2016-09-19 16:00:13 +0000 |
commit | 75ce89c20dab10857ab0b5102001b34767c45b6e (patch) | |
tree | b6d0086e53b0187137ca606d54e10d799d7f2761 /src/cmd/compile/internal/ssa/loopbce.go | |
parent | 2679282da4e437ee086ec791ab73181c39ae3463 (diff) | |
download | go-75ce89c20dab10857ab0b5102001b34767c45b6e.tar.gz go-75ce89c20dab10857ab0b5102001b34767c45b6e.zip |
cmd/compile: cache CFG-dependent computations
We compute a lot of stuff based off the CFG: postorder traversal,
dominators, dominator tree, loop nest. Multiple phases use this
information and we end up recomputing some of it. Add a cache
for this information so if the CFG hasn't changed, we can reuse
the previous computation.
Change-Id: I9b5b58af06830bd120afbee9cfab395a0a2f74b2
Reviewed-on: https://go-review.googlesource.com/29356
Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/loopbce.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/loopbce.go | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/ssa/loopbce.go b/src/cmd/compile/internal/ssa/loopbce.go index e94781b5b6..14d8834d7d 100644 --- a/src/cmd/compile/internal/ssa/loopbce.go +++ b/src/cmd/compile/internal/ssa/loopbce.go @@ -33,6 +33,7 @@ type indVar struct { // TODO: handle 32 bit operations func findIndVar(f *Func) []indVar { var iv []indVar + sdom := f.sdom() nextb: for _, b := range f.Blocks { @@ -110,7 +111,7 @@ nextb: // Second condition: b.Succs[entry] dominates nxt so that // nxt is computed when inc < max, meaning nxt <= max. - if !f.sdom.isAncestorEq(b.Succs[entry].b, nxt.Block) { + if !sdom.isAncestorEq(b.Succs[entry].b, nxt.Block) { // inc+ind can only be reached through the branch that enters the loop. continue } @@ -172,6 +173,7 @@ func loopbce(f *Func) { // removesBoundsChecks remove IsInBounds and IsSliceInBounds based on the induction variables. func removeBoundsChecks(f *Func, m map[*Value]indVar) { + sdom := f.sdom() for _, b := range f.Blocks { if b.Kind != BlockIf { continue @@ -200,7 +202,7 @@ func removeBoundsChecks(f *Func, m map[*Value]indVar) { goto skip1 } - if iv, has := m[ind]; has && f.sdom.isAncestorEq(iv.entry, b) && isNonNegative(iv.min) { + if iv, has := m[ind]; has && sdom.isAncestorEq(iv.entry, b) && isNonNegative(iv.min) { if v.Args[1] == iv.max { if f.pass.debug > 0 { f.Config.Warnl(b.Line, "Found redundant %s", v.Op) @@ -227,7 +229,7 @@ func removeBoundsChecks(f *Func, m map[*Value]indVar) { goto skip2 } - if iv, has := m[ind]; has && f.sdom.isAncestorEq(iv.entry, b) && isNonNegative(iv.min) { + if iv, has := m[ind]; has && sdom.isAncestorEq(iv.entry, b) && isNonNegative(iv.min) { if v.Args[1].Op == OpSliceCap && iv.max.Op == OpSliceLen && v.Args[1].Args[0] == iv.max.Args[0] { if f.pass.debug > 0 { f.Config.Warnl(b.Line, "Found redundant %s (len promoted to cap)", v.Op) @@ -248,7 +250,7 @@ func removeBoundsChecks(f *Func, m map[*Value]indVar) { } // ind + add >= 0 <-> min + add >= 0 <-> min >= -add - if iv, has := m[ind]; has && f.sdom.isAncestorEq(iv.entry, b) && isGreaterOrEqualThan(iv.min, -add) { + if iv, has := m[ind]; has && sdom.isAncestorEq(iv.entry, b) && isGreaterOrEqualThan(iv.min, -add) { if !v.Args[1].isGenericIntConst() || !iv.max.isGenericIntConst() { goto skip3 } |