Skip to content

Commit 802d056

Browse files
committed
cmd/compile: move ppc64 over to new bounds check strategy
Change-Id: I25a9bbc247b2490e7e37ed843386f53a71822146 Reviewed-on: https://go-review.googlesource.com/c/go/+/682498 Reviewed-by: Paul Murphy <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent a3295df commit 802d056

File tree

6 files changed

+233
-149
lines changed

6 files changed

+233
-149
lines changed

src/cmd/compile/internal/ppc64/ssa.go

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"cmd/compile/internal/types"
1515
"cmd/internal/obj"
1616
"cmd/internal/obj/ppc64"
17+
"internal/abi"
1718
"internal/buildcfg"
1819
"math"
1920
"strings"
@@ -1913,12 +1914,90 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
19131914
// AuxInt encodes how many buffer entries we need.
19141915
p.To.Sym = ir.Syms.GCWriteBarrier[v.AuxInt-1]
19151916

1916-
case ssa.OpPPC64LoweredPanicBoundsA, ssa.OpPPC64LoweredPanicBoundsB, ssa.OpPPC64LoweredPanicBoundsC:
1917-
p := s.Prog(obj.ACALL)
1917+
case ssa.OpPPC64LoweredPanicBoundsRR, ssa.OpPPC64LoweredPanicBoundsRC, ssa.OpPPC64LoweredPanicBoundsCR, ssa.OpPPC64LoweredPanicBoundsCC:
1918+
// Compute the constant we put in the PCData entry for this call.
1919+
code, signed := ssa.BoundsKind(v.AuxInt).Code()
1920+
xIsReg := false
1921+
yIsReg := false
1922+
xVal := 0
1923+
yVal := 0
1924+
switch v.Op {
1925+
case ssa.OpPPC64LoweredPanicBoundsRR:
1926+
xIsReg = true
1927+
xVal = int(v.Args[0].Reg() - ppc64.REG_R3)
1928+
yIsReg = true
1929+
yVal = int(v.Args[1].Reg() - ppc64.REG_R3)
1930+
case ssa.OpPPC64LoweredPanicBoundsRC:
1931+
xIsReg = true
1932+
xVal = int(v.Args[0].Reg() - ppc64.REG_R3)
1933+
c := v.Aux.(ssa.PanicBoundsC).C
1934+
if c >= 0 && c <= abi.BoundsMaxConst {
1935+
yVal = int(c)
1936+
} else {
1937+
// Move constant to a register
1938+
yIsReg = true
1939+
if yVal == xVal {
1940+
yVal = 1
1941+
}
1942+
p := s.Prog(ppc64.AMOVD)
1943+
p.From.Type = obj.TYPE_CONST
1944+
p.From.Offset = c
1945+
p.To.Type = obj.TYPE_REG
1946+
p.To.Reg = ppc64.REG_R3 + int16(yVal)
1947+
}
1948+
case ssa.OpPPC64LoweredPanicBoundsCR:
1949+
yIsReg = true
1950+
yVal := int(v.Args[0].Reg() - ppc64.REG_R3)
1951+
c := v.Aux.(ssa.PanicBoundsC).C
1952+
if c >= 0 && c <= abi.BoundsMaxConst {
1953+
xVal = int(c)
1954+
} else {
1955+
// Move constant to a register
1956+
if xVal == yVal {
1957+
xVal = 1
1958+
}
1959+
p := s.Prog(ppc64.AMOVD)
1960+
p.From.Type = obj.TYPE_CONST
1961+
p.From.Offset = c
1962+
p.To.Type = obj.TYPE_REG
1963+
p.To.Reg = ppc64.REG_R3 + int16(xVal)
1964+
}
1965+
case ssa.OpPPC64LoweredPanicBoundsCC:
1966+
c := v.Aux.(ssa.PanicBoundsCC).Cx
1967+
if c >= 0 && c <= abi.BoundsMaxConst {
1968+
xVal = int(c)
1969+
} else {
1970+
// Move constant to a register
1971+
xIsReg = true
1972+
p := s.Prog(ppc64.AMOVD)
1973+
p.From.Type = obj.TYPE_CONST
1974+
p.From.Offset = c
1975+
p.To.Type = obj.TYPE_REG
1976+
p.To.Reg = ppc64.REG_R3 + int16(xVal)
1977+
}
1978+
c = v.Aux.(ssa.PanicBoundsCC).Cy
1979+
if c >= 0 && c <= abi.BoundsMaxConst {
1980+
yVal = int(c)
1981+
} else {
1982+
// Move constant to a register
1983+
yIsReg = true
1984+
yVal = 1
1985+
p := s.Prog(ppc64.AMOVD)
1986+
p.From.Type = obj.TYPE_CONST
1987+
p.From.Offset = c
1988+
p.To.Type = obj.TYPE_REG
1989+
p.To.Reg = ppc64.REG_R3 + int16(yVal)
1990+
}
1991+
}
1992+
c := abi.BoundsEncode(code, signed, xIsReg, yIsReg, xVal, yVal)
1993+
1994+
p := s.Prog(obj.APCDATA)
1995+
p.From.SetConst(abi.PCDATA_PanicBounds)
1996+
p.To.SetConst(int64(c))
1997+
p = s.Prog(obj.ACALL)
19181998
p.To.Type = obj.TYPE_MEM
19191999
p.To.Name = obj.NAME_EXTERN
1920-
p.To.Sym = ssagen.BoundsCheckFunc[v.AuxInt]
1921-
s.UseArgs(16) // space used in callee args area by assembly stubs
2000+
p.To.Sym = ir.Syms.PanicBounds
19222001

19232002
case ssa.OpPPC64LoweredNilCheck:
19242003
if buildcfg.GOOS == "aix" {

src/cmd/compile/internal/ssa/_gen/PPC64.rules

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -553,9 +553,11 @@
553553
// Publication barrier as intrinsic
554554
(PubBarrier ...) => (LoweredPubBarrier ...)
555555

556-
(PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem)
557-
(PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem)
558-
(PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem)
556+
(PanicBounds ...) => (LoweredPanicBoundsRR ...)
557+
(LoweredPanicBoundsRR [kind] x (MOVDconst [c]) mem) => (LoweredPanicBoundsRC [kind] x {PanicBoundsC{C:c}} mem)
558+
(LoweredPanicBoundsRR [kind] (MOVDconst [c]) y mem) => (LoweredPanicBoundsCR [kind] {PanicBoundsC{C:c}} y mem)
559+
(LoweredPanicBoundsRC [kind] {p} (MOVDconst [c]) mem) => (LoweredPanicBoundsCC [kind] {PanicBoundsCC{Cx:c, Cy:p.C}} mem)
560+
(LoweredPanicBoundsCR [kind] {p} (MOVDconst [c]) mem) => (LoweredPanicBoundsCC [kind] {PanicBoundsCC{Cx:p.C, Cy:c}} mem)
559561

560562
// Optimizations
561563
// Note that PPC "logical" immediates come in 0:15 and 16:31 unsigned immediate forms,

src/cmd/compile/internal/ssa/_gen/PPC64Ops.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,7 @@ func init() {
171171
fpstore = regInfo{inputs: []regMask{gp | sp | sb, fp}}
172172
fpstoreidx = regInfo{inputs: []regMask{gp | sp | sb, gp | sp | sb, fp}}
173173
callerSave = regMask(gp | fp | gr | xer)
174-
r3 = buildReg("R3")
175-
r4 = buildReg("R4")
176-
r5 = buildReg("R5")
177-
r6 = buildReg("R6")
174+
first8 = buildReg("R3 R4 R5 R6 R7 R8 R9 R10")
178175
)
179176
ops := []opData{
180177
{name: "ADD", argLength: 2, reg: gp21, asm: "ADD", commutative: true}, // arg0 + arg1
@@ -706,12 +703,16 @@ func init() {
706703
{name: "LoweredWB", argLength: 1, reg: regInfo{clobbers: (callerSave &^ buildReg("R0 R3 R4 R5 R6 R7 R8 R9 R10 R14 R15 R16 R17 R20 R21 g")) | buildReg("R31"), outputs: []regMask{buildReg("R29")}}, clobberFlags: true, aux: "Int64"},
707704

708705
{name: "LoweredPubBarrier", argLength: 1, asm: "LWSYNC", hasSideEffects: true}, // Do data barrier. arg0=memory
709-
// There are three of these functions so that they can have three different register inputs.
710-
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
711-
// default registers to match so we don't need to copy registers around unnecessarily.
712-
{name: "LoweredPanicBoundsA", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r5, r6}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
713-
{name: "LoweredPanicBoundsB", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r4, r5}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
714-
{name: "LoweredPanicBoundsC", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{r3, r4}}, typ: "Mem", call: true}, // arg0=idx, arg1=len, arg2=mem, returns memory. AuxInt contains report code (see PanicBounds in genericOps.go).
706+
707+
// LoweredPanicBoundsRR takes x and y, two values that caused a bounds check to fail.
708+
// the RC and CR versions are used when one of the arguments is a constant. CC is used
709+
// when both are constant (normally both 0, as prove derives the fact that a [0] bounds
710+
// failure means the length must have also been 0).
711+
// AuxInt contains a report code (see PanicBounds in genericOps.go).
712+
{name: "LoweredPanicBoundsRR", argLength: 3, aux: "Int64", reg: regInfo{inputs: []regMask{first8, first8}}, typ: "Mem", call: true}, // arg0=x, arg1=y, arg2=mem, returns memory.
713+
{name: "LoweredPanicBoundsRC", argLength: 2, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{first8}}, typ: "Mem", call: true}, // arg0=x, arg1=mem, returns memory.
714+
{name: "LoweredPanicBoundsCR", argLength: 2, aux: "PanicBoundsC", reg: regInfo{inputs: []regMask{first8}}, typ: "Mem", call: true}, // arg0=y, arg1=mem, returns memory.
715+
{name: "LoweredPanicBoundsCC", argLength: 1, aux: "PanicBoundsCC", reg: regInfo{}, typ: "Mem", call: true}, // arg0=mem, returns memory.
715716

716717
// (InvertFlags (CMP a b)) == (CMP b a)
717718
// So if we want (LessThan (CMP a b)) but we can't do that because a is a constant,

src/cmd/compile/internal/ssa/opGen.go

Lines changed: 22 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/ssa/rewritePPC64.go

Lines changed: 88 additions & 55 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)