diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go index 2edf1ba463..bd90235682 100644 --- a/src/cmd/compile/internal/ssa/compile.go +++ b/src/cmd/compile/internal/ssa/compile.go @@ -342,7 +342,6 @@ var passes = [...]pass{ {name: "phiopt", fn: phiopt}, {name: "nilcheckelim", fn: nilcheckelim}, {name: "prove", fn: prove}, - {name: "loopbce", fn: loopbce}, {name: "decompose builtin", fn: decomposeBuiltIn, required: true}, {name: "softfloat", fn: softfloat, required: true}, {name: "late opt", fn: opt, required: true}, // TODO: split required rules and optimizing rules diff --git a/src/cmd/compile/internal/ssa/loopbce.go b/src/cmd/compile/internal/ssa/loopbce.go index 7f2da4870e..0ad274fc07 100644 --- a/src/cmd/compile/internal/ssa/loopbce.go +++ b/src/cmd/compile/internal/ssa/loopbce.go @@ -159,127 +159,6 @@ nextb: return iv } -// loopbce performs loop based bounds check elimination. -func loopbce(f *Func) { - ivList := findIndVar(f) - - m := make(map[*Value]indVar) - for _, iv := range ivList { - m[iv.ind] = iv - } - - removeBoundsChecks(f, m) -} - -// 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 - } - - v := b.Control - - // Simplify: - // (IsInBounds ind max) where 0 <= const == min <= ind < max. - // (IsSliceInBounds ind max) where 0 <= const == min <= ind < max. - // Found in: - // for i := range a { - // use a[i] - // use a[i:] - // use a[:i] - // } - if v.Op == OpIsInBounds || v.Op == OpIsSliceInBounds { - ind, add := dropAdd64(v.Args[0]) - if ind.Op != OpPhi { - goto skip1 - } - if v.Op == OpIsInBounds && add != 0 { - goto skip1 - } - if v.Op == OpIsSliceInBounds && (0 > add || add > 1) { - goto skip1 - } - - 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.Warnl(b.Pos, "Found redundant %s", v.Op) - } - goto simplify - } - } - } - skip1: - - // Simplify: - // (IsSliceInBounds ind (SliceCap a)) where 0 <= min <= ind < max == (SliceLen a) - // Found in: - // for i := range a { - // use a[:i] - // use a[:i+1] - // } - if v.Op == OpIsSliceInBounds { - ind, add := dropAdd64(v.Args[0]) - if ind.Op != OpPhi { - goto skip2 - } - if 0 > add || add > 1 { - goto skip2 - } - - 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.Warnl(b.Pos, "Found redundant %s (len promoted to cap)", v.Op) - } - goto simplify - } - } - } - skip2: - - // Simplify - // (IsInBounds (Add64 ind) (Const64 [c])) where 0 <= min <= ind < max <= (Const64 [c]) - // (IsSliceInBounds ind (Const64 [c])) where 0 <= min <= ind < max <= (Const64 [c]) - if v.Op == OpIsInBounds || v.Op == OpIsSliceInBounds { - ind, add := dropAdd64(v.Args[0]) - if ind.Op != OpPhi { - goto skip3 - } - - // ind + add >= 0 <-> min + add >= 0 <-> 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 - } - - limit := v.Args[1].AuxInt - if v.Op == OpIsSliceInBounds { - // If limit++ overflows signed integer then 0 <= max && max <= limit will be false. - limit++ - } - - if max := iv.max.AuxInt + add; 0 <= max && max <= limit { // handle overflow - if f.pass.debug > 0 { - f.Warnl(b.Pos, "Found redundant (%s ind %d), ind < %d", v.Op, v.Args[1].AuxInt, iv.max.AuxInt+add) - } - goto simplify - } - } - } - skip3: - - continue - - simplify: - f.Logf("removing bounds check %v at %v in %s\n", b.Control, b, f.Name) - b.Kind = BlockFirst - b.SetControl(nil) - } -} - func dropAdd64(v *Value) (*Value, int64) { if v.Op == OpAdd64 && v.Args[0].Op == OpConst64 { return v.Args[1], v.Args[0].AuxInt @@ -289,13 +168,3 @@ func dropAdd64(v *Value) (*Value, int64) { } return v, 0 } - -func isGreaterOrEqualThan(v *Value, c int64) bool { - if c == 0 { - return isNonNegative(v) - } - if v.isGenericIntConst() && v.AuxInt >= c { - return true - } - return false -}