Skip to content

Commit 193510f

Browse files
committed
cmd/compile: evaluate config as needed in rewrite rules
Prior to this CL, config was an explicit argument to the SSA rewrite rules, and rules that needed a Frontend got at it via config. An upcoming CL moves Frontend from Config to Func, so rules can no longer reach Frontend via Config. Passing a Frontend as an argument to the rewrite rules causes a 2-3% regression in compile times. This CL takes a different approach: It treats the variable names "config" and "fe" as special and calculates them as needed. The "as needed part" is also important to performance: If they are calculated eagerly, the nilchecks themselves cause a regression. This introduces a little bit of magic into the rewrite generator. However, from the perspective of the rules, the config variable was already more or less magic. And it makes the upcoming changes much clearer. Passes toolstash -cmp. Change-Id: I173f2bcc124cba43d53138bfa3775e21316a9107 Reviewed-on: https://go-review.googlesource.com/38326 Run-TryBot: Josh Bleecher Snyder <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent 09272ae commit 193510f

25 files changed

+11847
-11995
lines changed

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

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,36 @@ import (
1515
// It is created once, early during compilation,
1616
// and shared across all compilations.
1717
type Config struct {
18-
arch string // "amd64", etc.
19-
IntSize int64 // 4 or 8
20-
PtrSize int64 // 4 or 8
21-
RegSize int64 // 4 or 8
22-
lowerBlock func(*Block, *Config) bool // lowering function
23-
lowerValue func(*Value, *Config) bool // lowering function
24-
registers []Register // machine registers
25-
gpRegMask regMask // general purpose integer register mask
26-
fpRegMask regMask // floating point register mask
27-
specialRegMask regMask // special register mask
28-
FPReg int8 // register number of frame pointer, -1 if not used
29-
LinkReg int8 // register number of link register if it is a general purpose register, -1 if not used
30-
hasGReg bool // has hardware g register
31-
fe Frontend // callbacks into compiler frontend
32-
ctxt *obj.Link // Generic arch information
33-
optimize bool // Do optimization
34-
noDuffDevice bool // Don't use Duff's device
35-
nacl bool // GOOS=nacl
36-
use387 bool // GO386=387
37-
OldArch bool // True for older versions of architecture, e.g. true for PPC64BE, false for PPC64LE
38-
NeedsFpScratch bool // No direct move between GP and FP register sets
39-
BigEndian bool //
40-
sparsePhiCutoff uint64 // Sparse phi location algorithm used above this #blocks*#variables score
18+
arch string // "amd64", etc.
19+
IntSize int64 // 4 or 8
20+
PtrSize int64 // 4 or 8
21+
RegSize int64 // 4 or 8
22+
lowerBlock blockRewriter // lowering function
23+
lowerValue valueRewriter // lowering function
24+
registers []Register // machine registers
25+
gpRegMask regMask // general purpose integer register mask
26+
fpRegMask regMask // floating point register mask
27+
specialRegMask regMask // special register mask
28+
FPReg int8 // register number of frame pointer, -1 if not used
29+
LinkReg int8 // register number of link register if it is a general purpose register, -1 if not used
30+
hasGReg bool // has hardware g register
31+
fe Frontend // callbacks into compiler frontend
32+
ctxt *obj.Link // Generic arch information
33+
optimize bool // Do optimization
34+
noDuffDevice bool // Don't use Duff's device
35+
nacl bool // GOOS=nacl
36+
use387 bool // GO386=387
37+
OldArch bool // True for older versions of architecture, e.g. true for PPC64BE, false for PPC64LE
38+
NeedsFpScratch bool // No direct move between GP and FP register sets
39+
BigEndian bool //
40+
sparsePhiCutoff uint64 // Sparse phi location algorithm used above this #blocks*#variables score
4141
}
4242

43+
type (
44+
blockRewriter func(*Block) bool
45+
valueRewriter func(*Value) bool
46+
)
47+
4348
type TypeSource interface {
4449
TypeBool() Type
4550
TypeInt8() Type

src/cmd/compile/internal/ssa/gen/386.rules

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@
6868
(Neg32 x) -> (NEGL x)
6969
(Neg16 x) -> (NEGL x)
7070
(Neg8 x) -> (NEGL x)
71-
(Neg32F x) && !config.use387 -> (PXOR x (MOVSSconst <config.Frontend().TypeFloat32()> [f2i(math.Copysign(0, -1))]))
72-
(Neg64F x) && !config.use387 -> (PXOR x (MOVSDconst <config.Frontend().TypeFloat64()> [f2i(math.Copysign(0, -1))]))
71+
(Neg32F x) && !config.use387 -> (PXOR x (MOVSSconst <fe.TypeFloat32()> [f2i(math.Copysign(0, -1))]))
72+
(Neg64F x) && !config.use387 -> (PXOR x (MOVSDconst <fe.TypeFloat64()> [f2i(math.Copysign(0, -1))]))
7373
(Neg32F x) && config.use387 -> (FCHS x)
7474
(Neg64F x) && config.use387 -> (FCHS x)
7575

src/cmd/compile/internal/ssa/gen/AMD64.rules

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@
7878
(Neg32 x) -> (NEGL x)
7979
(Neg16 x) -> (NEGL x)
8080
(Neg8 x) -> (NEGL x)
81-
(Neg32F x) -> (PXOR x (MOVSSconst <config.Frontend().TypeFloat32()> [f2i(math.Copysign(0, -1))]))
82-
(Neg64F x) -> (PXOR x (MOVSDconst <config.Frontend().TypeFloat64()> [f2i(math.Copysign(0, -1))]))
81+
(Neg32F x) -> (PXOR x (MOVSSconst <fe.TypeFloat32()> [f2i(math.Copysign(0, -1))]))
82+
(Neg64F x) -> (PXOR x (MOVSDconst <fe.TypeFloat64()> [f2i(math.Copysign(0, -1))]))
8383

8484
(Com64 x) -> (NOTQ x)
8585
(Com32 x) -> (NOTL x)
@@ -98,10 +98,10 @@
9898

9999
// Lowering other arithmetic
100100
(Ctz64 <t> x) -> (CMOVQEQ (Select0 <t> (BSFQ x)) (MOVQconst <t> [64]) (Select1 <TypeFlags> (BSFQ x)))
101-
(Ctz32 x) -> (Select0 (BSFQ (ORQ <config.Frontend().TypeUInt64()> (MOVQconst [1<<32]) x)))
101+
(Ctz32 x) -> (Select0 (BSFQ (ORQ <fe.TypeUInt64()> (MOVQconst [1<<32]) x)))
102102

103103
(BitLen64 <t> x) -> (ADDQconst [1] (CMOVQEQ <t> (Select0 <t> (BSRQ x)) (MOVQconst <t> [-1]) (Select1 <TypeFlags> (BSRQ x))))
104-
(BitLen32 x) -> (BitLen64 (MOVLQZX <config.Frontend().TypeUInt64()> x))
104+
(BitLen32 x) -> (BitLen64 (MOVLQZX <fe.TypeUInt64()> x))
105105

106106
(Bswap64 x) -> (BSWAPQ x)
107107
(Bswap32 x) -> (BSWAPL x)
@@ -472,10 +472,10 @@
472472

473473
// Atomic stores. We use XCHG to prevent the hardware reordering a subsequent load.
474474
// TODO: most runtime uses of atomic stores don't need that property. Use normal stores for those?
475-
(AtomicStore32 ptr val mem) -> (Select1 (XCHGL <MakeTuple(config.Frontend().TypeUInt32(),TypeMem)> val ptr mem))
476-
(AtomicStore64 ptr val mem) -> (Select1 (XCHGQ <MakeTuple(config.Frontend().TypeUInt64(),TypeMem)> val ptr mem))
477-
(AtomicStorePtrNoWB ptr val mem) && config.PtrSize == 8 -> (Select1 (XCHGQ <MakeTuple(config.Frontend().TypeBytePtr(),TypeMem)> val ptr mem))
478-
(AtomicStorePtrNoWB ptr val mem) && config.PtrSize == 4 -> (Select1 (XCHGL <MakeTuple(config.Frontend().TypeBytePtr(),TypeMem)> val ptr mem))
475+
(AtomicStore32 ptr val mem) -> (Select1 (XCHGL <MakeTuple(fe.TypeUInt32(),TypeMem)> val ptr mem))
476+
(AtomicStore64 ptr val mem) -> (Select1 (XCHGQ <MakeTuple(fe.TypeUInt64(),TypeMem)> val ptr mem))
477+
(AtomicStorePtrNoWB ptr val mem) && config.PtrSize == 8 -> (Select1 (XCHGQ <MakeTuple(fe.TypeBytePtr(),TypeMem)> val ptr mem))
478+
(AtomicStorePtrNoWB ptr val mem) && config.PtrSize == 4 -> (Select1 (XCHGL <MakeTuple(fe.TypeBytePtr(),TypeMem)> val ptr mem))
479479

480480
// Atomic exchanges.
481481
(AtomicExchange32 ptr val mem) -> (XCHGL val ptr mem)
@@ -553,8 +553,8 @@
553553
(NE (TESTB (SETNEF cmp) (SETNEF cmp)) yes no) -> (NEF cmp yes no)
554554

555555
// Disabled because it interferes with the pattern match above and makes worse code.
556-
// (SETNEF x) -> (ORQ (SETNE <config.Frontend().TypeInt8()> x) (SETNAN <config.Frontend().TypeInt8()> x))
557-
// (SETEQF x) -> (ANDQ (SETEQ <config.Frontend().TypeInt8()> x) (SETORD <config.Frontend().TypeInt8()> x))
556+
// (SETNEF x) -> (ORQ (SETNE <fe.TypeInt8()> x) (SETNAN <fe.TypeInt8()> x))
557+
// (SETEQF x) -> (ANDQ (SETEQ <fe.TypeInt8()> x) (SETORD <fe.TypeInt8()> x))
558558

559559
// fold constants into instructions
560560
(ADDQ x (MOVQconst [c])) && is32Bit(c) -> (ADDQconst [c] x)

src/cmd/compile/internal/ssa/gen/ARM.rules

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@
3434
(Mul32uhilo x y) -> (MULLU x y)
3535

3636
(Div32 x y) ->
37-
(SUB (XOR <config.fe.TypeUInt32()> // negate the result if one operand is negative
38-
(Select0 <config.fe.TypeUInt32()> (CALLudiv {config.ctxt.Lookup("udiv", 0)}
39-
(SUB <config.fe.TypeUInt32()> (XOR x <config.fe.TypeUInt32()> (Signmask x)) (Signmask x)) // negate x if negative
40-
(SUB <config.fe.TypeUInt32()> (XOR y <config.fe.TypeUInt32()> (Signmask y)) (Signmask y)))) // negate y if negative
41-
(Signmask (XOR <config.fe.TypeUInt32()> x y))) (Signmask (XOR <config.fe.TypeUInt32()> x y)))
42-
(Div32u x y) -> (Select0 <config.fe.TypeUInt32()> (CALLudiv {config.ctxt.Lookup("udiv", 0)} x y))
37+
(SUB (XOR <fe.TypeUInt32()> // negate the result if one operand is negative
38+
(Select0 <fe.TypeUInt32()> (CALLudiv {config.ctxt.Lookup("udiv", 0)}
39+
(SUB <fe.TypeUInt32()> (XOR x <fe.TypeUInt32()> (Signmask x)) (Signmask x)) // negate x if negative
40+
(SUB <fe.TypeUInt32()> (XOR y <fe.TypeUInt32()> (Signmask y)) (Signmask y)))) // negate y if negative
41+
(Signmask (XOR <fe.TypeUInt32()> x y))) (Signmask (XOR <fe.TypeUInt32()> x y)))
42+
(Div32u x y) -> (Select0 <fe.TypeUInt32()> (CALLudiv {config.ctxt.Lookup("udiv", 0)} x y))
4343
(Div16 x y) -> (Div32 (SignExt16to32 x) (SignExt16to32 y))
4444
(Div16u x y) -> (Div32u (ZeroExt16to32 x) (ZeroExt16to32 y))
4545
(Div8 x y) -> (Div32 (SignExt8to32 x) (SignExt8to32 y))
@@ -48,12 +48,12 @@
4848
(Div64F x y) -> (DIVD x y)
4949

5050
(Mod32 x y) ->
51-
(SUB (XOR <config.fe.TypeUInt32()> // negate the result if x is negative
52-
(Select1 <config.fe.TypeUInt32()> (CALLudiv {config.ctxt.Lookup("udiv", 0)}
53-
(SUB <config.fe.TypeUInt32()> (XOR <config.fe.TypeUInt32()> x (Signmask x)) (Signmask x)) // negate x if negative
54-
(SUB <config.fe.TypeUInt32()> (XOR <config.fe.TypeUInt32()> y (Signmask y)) (Signmask y)))) // negate y if negative
51+
(SUB (XOR <fe.TypeUInt32()> // negate the result if x is negative
52+
(Select1 <fe.TypeUInt32()> (CALLudiv {config.ctxt.Lookup("udiv", 0)}
53+
(SUB <fe.TypeUInt32()> (XOR <fe.TypeUInt32()> x (Signmask x)) (Signmask x)) // negate x if negative
54+
(SUB <fe.TypeUInt32()> (XOR <fe.TypeUInt32()> y (Signmask y)) (Signmask y)))) // negate y if negative
5555
(Signmask x)) (Signmask x))
56-
(Mod32u x y) -> (Select1 <config.fe.TypeUInt32()> (CALLudiv {config.ctxt.Lookup("udiv", 0)} x y))
56+
(Mod32u x y) -> (Select1 <fe.TypeUInt32()> (CALLudiv {config.ctxt.Lookup("udiv", 0)} x y))
5757
(Mod16 x y) -> (Mod32 (SignExt16to32 x) (SignExt16to32 y))
5858
(Mod16u x y) -> (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y))
5959
(Mod8 x y) -> (Mod32 (SignExt8to32 x) (SignExt8to32 y))
@@ -111,7 +111,7 @@
111111
// boolean ops -- booleans are represented with 0=false, 1=true
112112
(AndB x y) -> (AND x y)
113113
(OrB x y) -> (OR x y)
114-
(EqB x y) -> (XORconst [1] (XOR <config.fe.TypeBool()> x y))
114+
(EqB x y) -> (XORconst [1] (XOR <fe.TypeBool()> x y))
115115
(NeqB x y) -> (XOR x y)
116116
(Not x) -> (XORconst [1] x)
117117

@@ -160,11 +160,11 @@
160160
(Rsh32x64 x (Const64 [c])) && uint64(c) < 32 -> (SRAconst x [c])
161161
(Rsh32Ux64 x (Const64 [c])) && uint64(c) < 32 -> (SRLconst x [c])
162162
(Lsh16x64 x (Const64 [c])) && uint64(c) < 16 -> (SLLconst x [c])
163-
(Rsh16x64 x (Const64 [c])) && uint64(c) < 16 -> (SRAconst (SLLconst <config.fe.TypeUInt32()> x [16]) [c+16])
164-
(Rsh16Ux64 x (Const64 [c])) && uint64(c) < 16 -> (SRLconst (SLLconst <config.fe.TypeUInt32()> x [16]) [c+16])
163+
(Rsh16x64 x (Const64 [c])) && uint64(c) < 16 -> (SRAconst (SLLconst <fe.TypeUInt32()> x [16]) [c+16])
164+
(Rsh16Ux64 x (Const64 [c])) && uint64(c) < 16 -> (SRLconst (SLLconst <fe.TypeUInt32()> x [16]) [c+16])
165165
(Lsh8x64 x (Const64 [c])) && uint64(c) < 8 -> (SLLconst x [c])
166-
(Rsh8x64 x (Const64 [c])) && uint64(c) < 8 -> (SRAconst (SLLconst <config.fe.TypeUInt32()> x [24]) [c+24])
167-
(Rsh8Ux64 x (Const64 [c])) && uint64(c) < 8 -> (SRLconst (SLLconst <config.fe.TypeUInt32()> x [24]) [c+24])
166+
(Rsh8x64 x (Const64 [c])) && uint64(c) < 8 -> (SRAconst (SLLconst <fe.TypeUInt32()> x [24]) [c+24])
167+
(Rsh8Ux64 x (Const64 [c])) && uint64(c) < 8 -> (SRLconst (SLLconst <fe.TypeUInt32()> x [24]) [c+24])
168168

169169
// large constant shifts
170170
(Lsh32x64 _ (Const64 [c])) && uint64(c) >= 32 -> (Const32 [0])
@@ -176,8 +176,8 @@
176176

177177
// large constant signed right shift, we leave the sign bit
178178
(Rsh32x64 x (Const64 [c])) && uint64(c) >= 32 -> (SRAconst x [31])
179-
(Rsh16x64 x (Const64 [c])) && uint64(c) >= 16 -> (SRAconst (SLLconst <config.fe.TypeUInt32()> x [16]) [31])
180-
(Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 -> (SRAconst (SLLconst <config.fe.TypeUInt32()> x [24]) [31])
179+
(Rsh16x64 x (Const64 [c])) && uint64(c) >= 16 -> (SRAconst (SLLconst <fe.TypeUInt32()> x [16]) [31])
180+
(Rsh8x64 x (Const64 [c])) && uint64(c) >= 8 -> (SRAconst (SLLconst <fe.TypeUInt32()> x [24]) [31])
181181

182182
// constants
183183
(Const8 [val]) -> (MOVWconst [val])
@@ -204,7 +204,7 @@
204204
(SignExt16to32 x) -> (MOVHreg x)
205205

206206
(Signmask x) -> (SRAconst x [31])
207-
(Zeromask x) -> (SRAconst (RSBshiftRL <config.fe.TypeInt32()> x x [1]) [31]) // sign bit of uint32(x)>>1 - x
207+
(Zeromask x) -> (SRAconst (RSBshiftRL <fe.TypeInt32()> x x [1]) [31]) // sign bit of uint32(x)>>1 - x
208208
(Slicemask <t> x) -> (SRAconst (RSBconst <t> [0] x) [31])
209209

210210
// float <-> int conversion

src/cmd/compile/internal/ssa/gen/ARM64.rules

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727

2828
(Hmul64 x y) -> (MULH x y)
2929
(Hmul64u x y) -> (UMULH x y)
30-
(Hmul32 x y) -> (SRAconst (MULL <config.fe.TypeInt64()> x y) [32])
31-
(Hmul32u x y) -> (SRAconst (UMULL <config.fe.TypeUInt64()> x y) [32])
30+
(Hmul32 x y) -> (SRAconst (MULL <fe.TypeInt64()> x y) [32])
31+
(Hmul32u x y) -> (SRAconst (UMULL <fe.TypeUInt64()> x y) [32])
3232

3333
(Div64 x y) -> (DIV x y)
3434
(Div64u x y) -> (UDIV x y)
@@ -86,20 +86,20 @@
8686
(Ctz64 <t> x) -> (CLZ (RBIT <t> x))
8787
(Ctz32 <t> x) -> (CLZW (RBITW <t> x))
8888

89-
(BitLen64 x) -> (SUB (MOVDconst [64]) (CLZ <config.fe.TypeInt()> x))
89+
(BitLen64 x) -> (SUB (MOVDconst [64]) (CLZ <fe.TypeInt()> x))
9090

9191
(Bswap64 x) -> (REV x)
9292
(Bswap32 x) -> (REVW x)
9393

9494
(BitRev64 x) -> (RBIT x)
9595
(BitRev32 x) -> (RBITW x)
96-
(BitRev16 x) -> (SRLconst [48] (RBIT <config.fe.TypeUInt64()> x))
97-
(BitRev8 x) -> (SRLconst [56] (RBIT <config.fe.TypeUInt64()> x))
96+
(BitRev16 x) -> (SRLconst [48] (RBIT <fe.TypeUInt64()> x))
97+
(BitRev8 x) -> (SRLconst [56] (RBIT <fe.TypeUInt64()> x))
9898

9999
// boolean ops -- booleans are represented with 0=false, 1=true
100100
(AndB x y) -> (AND x y)
101101
(OrB x y) -> (OR x y)
102-
(EqB x y) -> (XOR (MOVDconst [1]) (XOR <config.fe.TypeBool()> x y))
102+
(EqB x y) -> (XOR (MOVDconst [1]) (XOR <fe.TypeBool()> x y))
103103
(NeqB x y) -> (XOR x y)
104104
(Not x) -> (XOR (MOVDconst [1]) x)
105105

0 commit comments

Comments
 (0)