aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/loopbce.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2016-09-16 13:50:18 -0700
committerKeith Randall <khr@golang.org>2016-09-19 16:00:13 +0000
commit75ce89c20dab10857ab0b5102001b34767c45b6e (patch)
treeb6d0086e53b0187137ca606d54e10d799d7f2761 /src/cmd/compile/internal/ssa/loopbce.go
parent2679282da4e437ee086ec791ab73181c39ae3463 (diff)
downloadgo-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.go10
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
}