Skip to content

Commit da8e939

Browse files
committed
cmd/compile: thread Curfn through SSA
This is a first step towards eliminating the Curfn global in the backend. There's more to do. Passes toolstash -cmp. No compiler performance impact. Updates #15756 Change-Id: Ib09f550a001e279a5aeeed0f85698290f890939c Reviewed-on: https://go-review.googlesource.com/38232 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
1 parent ce584e5 commit da8e939

File tree

11 files changed

+86
-82
lines changed

11 files changed

+86
-82
lines changed

src/cmd/compile/internal/amd64/ggen.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ import (
1313
// no floating point in note handlers on Plan 9
1414
var isPlan9 = obj.GOOS == "plan9"
1515

16-
func defframe(ptxt *obj.Prog) {
16+
func defframe(ptxt *obj.Prog, fn *gc.Node) {
1717
// fill in argument size, stack size
1818
ptxt.To.Type = obj.TYPE_TEXTSIZE
1919

20-
ptxt.To.Val = int32(gc.Rnd(gc.Curfn.Type.ArgWidth(), int64(gc.Widthptr)))
20+
ptxt.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
2121
frame := uint32(gc.Rnd(gc.Stksize+gc.Maxarg, int64(gc.Widthreg)))
2222
ptxt.To.Offset = int64(frame)
2323

@@ -32,7 +32,7 @@ func defframe(ptxt *obj.Prog) {
3232
x0 := uint32(0)
3333

3434
// iterate through declarations - they are sorted in decreasing xoffset order.
35-
for _, n := range gc.Curfn.Func.Dcl {
35+
for _, n := range fn.Func.Dcl {
3636
if !n.Name.Needzero() {
3737
continue
3838
}

src/cmd/compile/internal/arm/ggen.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ import (
1010
"cmd/internal/obj/arm"
1111
)
1212

13-
func defframe(ptxt *obj.Prog) {
13+
func defframe(ptxt *obj.Prog, fn *gc.Node) {
1414
// fill in argument size, stack size
1515
ptxt.To.Type = obj.TYPE_TEXTSIZE
1616

17-
ptxt.To.Val = int32(gc.Rnd(gc.Curfn.Type.ArgWidth(), int64(gc.Widthptr)))
17+
ptxt.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
1818
frame := uint32(gc.Rnd(gc.Stksize+gc.Maxarg, int64(gc.Widthreg)))
1919
ptxt.To.Offset = int64(frame)
2020

@@ -26,7 +26,7 @@ func defframe(ptxt *obj.Prog) {
2626
hi := int64(0)
2727
lo := hi
2828
r0 := uint32(0)
29-
for _, n := range gc.Curfn.Func.Dcl {
29+
for _, n := range fn.Func.Dcl {
3030
if !n.Name.Needzero() {
3131
continue
3232
}

src/cmd/compile/internal/arm64/ggen.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ import (
1010
"cmd/internal/obj/arm64"
1111
)
1212

13-
func defframe(ptxt *obj.Prog) {
13+
func defframe(ptxt *obj.Prog, fn *gc.Node) {
1414
// fill in argument size, stack size
1515
ptxt.To.Type = obj.TYPE_TEXTSIZE
1616

17-
ptxt.To.Val = int32(gc.Rnd(gc.Curfn.Type.ArgWidth(), int64(gc.Widthptr)))
17+
ptxt.To.Val = int32(gc.Rnd(fn.Type.ArgWidth(), int64(gc.Widthptr)))
1818
frame := uint32(gc.Rnd(gc.Stksize+gc.Maxarg, int64(gc.Widthreg)))
1919

2020
// arm64 requires that the frame size (not counting saved LR)
@@ -34,7 +34,7 @@ func defframe(ptxt *obj.Prog) {
3434
lo := hi
3535

3636
// iterate through declarations - they are sorted in decreasing xoffset order.
37-
for _, n := range gc.Curfn.Func.Dcl {
37+
for _, n := range fn.Func.Dcl {
3838
if !n.Name.Needzero() {
3939
continue
4040
}

src/cmd/compile/internal/gc/go.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ type Arch struct {
365365
MAXWIDTH int64
366366
Use387 bool // should 386 backend use 387 FP instructions instead of sse2.
367367

368-
Defframe func(*obj.Prog)
368+
Defframe func(*obj.Prog, *Node)
369369
Ginsnop func()
370370
Proginfo func(*obj.Prog) ProgInfo
371371

src/cmd/compile/internal/gc/pgen.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,13 @@ func (s byStackVar) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
220220

221221
var scratchFpMem *Node
222222

223-
func (s *ssaExport) AllocFrame(f *ssa.Func) {
223+
func (s *ssafn) AllocFrame(f *ssa.Func) {
224224
Stksize = 0
225225
stkptrsize = 0
226+
fn := s.curfn.Func
226227

227228
// Mark the PAUTO's unused.
228-
for _, ln := range Curfn.Func.Dcl {
229+
for _, ln := range fn.Dcl {
229230
if ln.Class == PAUTO {
230231
ln.SetUsed(false)
231232
}
@@ -259,15 +260,15 @@ func (s *ssaExport) AllocFrame(f *ssa.Func) {
259260
scratchFpMem.SetUsed(scratchUsed)
260261
}
261262

262-
sort.Sort(byStackVar(Curfn.Func.Dcl))
263+
sort.Sort(byStackVar(fn.Dcl))
263264

264265
// Reassign stack offsets of the locals that are used.
265-
for i, n := range Curfn.Func.Dcl {
266+
for i, n := range fn.Dcl {
266267
if n.Op != ONAME || n.Class != PAUTO {
267268
continue
268269
}
269270
if !n.Used() {
270-
Curfn.Func.Dcl = Curfn.Func.Dcl[:i]
271+
fn.Dcl = fn.Dcl[:i]
271272
break
272273
}
273274

@@ -285,8 +286,7 @@ func (s *ssaExport) AllocFrame(f *ssa.Func) {
285286
Stksize = Rnd(Stksize, int64(Widthptr))
286287
}
287288
if Stksize >= 1<<31 {
288-
setlineno(Curfn)
289-
yyerror("stack frame too large (>2GB)")
289+
yyerrorl(s.curfn.Pos, "stack frame too large (>2GB)")
290290
}
291291

292292
n.Xoffset = -Stksize

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

+54-50
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
)
2020

2121
var ssaConfig *ssa.Config
22-
var ssaExp ssaExport
2322
var ssaCache *ssa.Cache
2423

2524
func initssaconfig() {
@@ -50,9 +49,12 @@ func buildssa(fn *Node) *ssa.Func {
5049
s.cgoUnsafeArgs = true
5150
}
5251

53-
ssaExp.log = printssa
52+
fe := ssafn{
53+
curfn: fn,
54+
log: printssa,
55+
}
5456

55-
s.f = ssa.NewFunc(&ssaExp)
57+
s.f = ssa.NewFunc(&fe)
5658
s.config = ssaConfig
5759
s.f.Config = ssaConfig
5860
s.f.Cache = ssaCache
@@ -4219,7 +4221,7 @@ func (s *SSAGenState) SetPos(pos src.XPos) {
42194221
func genssa(f *ssa.Func, ptxt *obj.Prog, gcargs, gclocals *Sym) {
42204222
var s SSAGenState
42214223

4222-
e := f.Frontend().(*ssaExport)
4224+
e := f.Frontend().(*ssafn)
42234225

42244226
// Remember where each block starts.
42254227
s.bstart = make([]*obj.Prog, f.NumBlocks())
@@ -4350,10 +4352,10 @@ func genssa(f *ssa.Func, ptxt *obj.Prog, gcargs, gclocals *Sym) {
43504352
}
43514353

43524354
// Generate gc bitmaps.
4353-
liveness(Curfn, ptxt, gcargs, gclocals)
4355+
liveness(e.curfn, ptxt, gcargs, gclocals)
43544356

43554357
// Add frame prologue. Zero ambiguously live variables.
4356-
thearch.Defframe(ptxt)
4358+
thearch.Defframe(ptxt, e.curfn)
43574359
if Debug['f'] != 0 {
43584360
frame(0)
43594361
}
@@ -4660,41 +4662,43 @@ func fieldIdx(n *Node) int {
46604662
// so we don't have to recompute it each time we need it.
46614663
}
46624664

4663-
// ssaExport exports a bunch of compiler services for the ssa backend.
4664-
type ssaExport struct {
4665-
log bool
4666-
}
4667-
4668-
func (s *ssaExport) TypeBool() ssa.Type { return Types[TBOOL] }
4669-
func (s *ssaExport) TypeInt8() ssa.Type { return Types[TINT8] }
4670-
func (s *ssaExport) TypeInt16() ssa.Type { return Types[TINT16] }
4671-
func (s *ssaExport) TypeInt32() ssa.Type { return Types[TINT32] }
4672-
func (s *ssaExport) TypeInt64() ssa.Type { return Types[TINT64] }
4673-
func (s *ssaExport) TypeUInt8() ssa.Type { return Types[TUINT8] }
4674-
func (s *ssaExport) TypeUInt16() ssa.Type { return Types[TUINT16] }
4675-
func (s *ssaExport) TypeUInt32() ssa.Type { return Types[TUINT32] }
4676-
func (s *ssaExport) TypeUInt64() ssa.Type { return Types[TUINT64] }
4677-
func (s *ssaExport) TypeFloat32() ssa.Type { return Types[TFLOAT32] }
4678-
func (s *ssaExport) TypeFloat64() ssa.Type { return Types[TFLOAT64] }
4679-
func (s *ssaExport) TypeInt() ssa.Type { return Types[TINT] }
4680-
func (s *ssaExport) TypeUintptr() ssa.Type { return Types[TUINTPTR] }
4681-
func (s *ssaExport) TypeString() ssa.Type { return Types[TSTRING] }
4682-
func (s *ssaExport) TypeBytePtr() ssa.Type { return ptrto(Types[TUINT8]) }
4665+
// ssafn holds frontend information about a function that the backend is processing.
4666+
// It also exports a bunch of compiler services for the ssa backend.
4667+
type ssafn struct {
4668+
curfn *Node
4669+
log bool
4670+
}
4671+
4672+
func (s *ssafn) TypeBool() ssa.Type { return Types[TBOOL] }
4673+
func (s *ssafn) TypeInt8() ssa.Type { return Types[TINT8] }
4674+
func (s *ssafn) TypeInt16() ssa.Type { return Types[TINT16] }
4675+
func (s *ssafn) TypeInt32() ssa.Type { return Types[TINT32] }
4676+
func (s *ssafn) TypeInt64() ssa.Type { return Types[TINT64] }
4677+
func (s *ssafn) TypeUInt8() ssa.Type { return Types[TUINT8] }
4678+
func (s *ssafn) TypeUInt16() ssa.Type { return Types[TUINT16] }
4679+
func (s *ssafn) TypeUInt32() ssa.Type { return Types[TUINT32] }
4680+
func (s *ssafn) TypeUInt64() ssa.Type { return Types[TUINT64] }
4681+
func (s *ssafn) TypeFloat32() ssa.Type { return Types[TFLOAT32] }
4682+
func (s *ssafn) TypeFloat64() ssa.Type { return Types[TFLOAT64] }
4683+
func (s *ssafn) TypeInt() ssa.Type { return Types[TINT] }
4684+
func (s *ssafn) TypeUintptr() ssa.Type { return Types[TUINTPTR] }
4685+
func (s *ssafn) TypeString() ssa.Type { return Types[TSTRING] }
4686+
func (s *ssafn) TypeBytePtr() ssa.Type { return ptrto(Types[TUINT8]) }
46834687

46844688
// StringData returns a symbol (a *Sym wrapped in an interface) which
46854689
// is the data component of a global string constant containing s.
4686-
func (*ssaExport) StringData(s string) interface{} {
4690+
func (*ssafn) StringData(s string) interface{} {
46874691
// TODO: is idealstring correct? It might not matter...
46884692
data := stringsym(s)
46894693
return &ssa.ExternSymbol{Typ: idealstring, Sym: data}
46904694
}
46914695

4692-
func (e *ssaExport) Auto(t ssa.Type) ssa.GCNode {
4696+
func (e *ssafn) Auto(t ssa.Type) ssa.GCNode {
46934697
n := temp(t.(*Type)) // Note: adds new auto to Curfn.Func.Dcl list
46944698
return n
46954699
}
46964700

4697-
func (e *ssaExport) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
4701+
func (e *ssafn) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
46984702
n := name.N.(*Node)
46994703
ptrType := ptrto(Types[TUINT8])
47004704
lenType := Types[TINT]
@@ -4708,7 +4712,7 @@ func (e *ssaExport) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlo
47084712
return ssa.LocalSlot{N: n, Type: ptrType, Off: name.Off}, ssa.LocalSlot{N: n, Type: lenType, Off: name.Off + int64(Widthptr)}
47094713
}
47104714

4711-
func (e *ssaExport) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
4715+
func (e *ssafn) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
47124716
n := name.N.(*Node)
47134717
t := ptrto(Types[TUINT8])
47144718
if n.Class == PAUTO && !n.Addrtaken() {
@@ -4725,7 +4729,7 @@ func (e *ssaExport) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.Local
47254729
return ssa.LocalSlot{N: n, Type: t, Off: name.Off}, ssa.LocalSlot{N: n, Type: t, Off: name.Off + int64(Widthptr)}
47264730
}
47274731

4728-
func (e *ssaExport) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot, ssa.LocalSlot) {
4732+
func (e *ssafn) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot, ssa.LocalSlot) {
47294733
n := name.N.(*Node)
47304734
ptrType := ptrto(name.Type.ElemType().(*Type))
47314735
lenType := Types[TINT]
@@ -4742,7 +4746,7 @@ func (e *ssaExport) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot
47424746
ssa.LocalSlot{N: n, Type: lenType, Off: name.Off + int64(2*Widthptr)}
47434747
}
47444748

4745-
func (e *ssaExport) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
4749+
func (e *ssafn) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
47464750
n := name.N.(*Node)
47474751
s := name.Type.Size() / 2
47484752
var t *Type
@@ -4761,7 +4765,7 @@ func (e *ssaExport) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSl
47614765
return ssa.LocalSlot{N: n, Type: t, Off: name.Off}, ssa.LocalSlot{N: n, Type: t, Off: name.Off + s}
47624766
}
47634767

4764-
func (e *ssaExport) SplitInt64(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
4768+
func (e *ssafn) SplitInt64(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
47654769
n := name.N.(*Node)
47664770
var t *Type
47674771
if name.Type.IsSigned() {
@@ -4782,7 +4786,7 @@ func (e *ssaExport) SplitInt64(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot
47824786
return ssa.LocalSlot{N: n, Type: t, Off: name.Off + 4}, ssa.LocalSlot{N: n, Type: Types[TUINT32], Off: name.Off}
47834787
}
47844788

4785-
func (e *ssaExport) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
4789+
func (e *ssafn) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
47864790
n := name.N.(*Node)
47874791
st := name.Type
47884792
ft := st.FieldType(i)
@@ -4796,7 +4800,7 @@ func (e *ssaExport) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
47964800
return ssa.LocalSlot{N: n, Type: ft, Off: name.Off + st.FieldOff(i)}
47974801
}
47984802

4799-
func (e *ssaExport) SplitArray(name ssa.LocalSlot) ssa.LocalSlot {
4803+
func (e *ssafn) SplitArray(name ssa.LocalSlot) ssa.LocalSlot {
48004804
n := name.N.(*Node)
48014805
at := name.Type
48024806
if at.NumElem() != 1 {
@@ -4810,13 +4814,13 @@ func (e *ssaExport) SplitArray(name ssa.LocalSlot) ssa.LocalSlot {
48104814
return ssa.LocalSlot{N: n, Type: et, Off: name.Off}
48114815
}
48124816

4813-
func (e *ssaExport) DerefItab(it *obj.LSym, offset int64) *obj.LSym {
4817+
func (e *ssafn) DerefItab(it *obj.LSym, offset int64) *obj.LSym {
48144818
return itabsym(it, offset)
48154819
}
48164820

48174821
// namedAuto returns a new AUTO variable with the given name and type.
48184822
// These are exposed to the debugger.
4819-
func (e *ssaExport) namedAuto(name string, typ ssa.Type) ssa.GCNode {
4823+
func (e *ssafn) namedAuto(name string, typ ssa.Type) ssa.GCNode {
48204824
t := typ.(*Type)
48214825
s := &Sym{Name: name, Pkg: localpkg}
48224826
n := nod(ONAME, nil, nil)
@@ -4828,62 +4832,62 @@ func (e *ssaExport) namedAuto(name string, typ ssa.Type) ssa.GCNode {
48284832
n.SetAddable(true)
48294833
n.Esc = EscNever
48304834
n.Xoffset = 0
4831-
n.Name.Curfn = Curfn
4832-
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
4835+
n.Name.Curfn = e.curfn
4836+
e.curfn.Func.Dcl = append(e.curfn.Func.Dcl, n)
48334837

48344838
dowidth(t)
48354839
return n
48364840
}
48374841

4838-
func (e *ssaExport) CanSSA(t ssa.Type) bool {
4842+
func (e *ssafn) CanSSA(t ssa.Type) bool {
48394843
return canSSAType(t.(*Type))
48404844
}
48414845

4842-
func (e *ssaExport) Line(pos src.XPos) string {
4846+
func (e *ssafn) Line(pos src.XPos) string {
48434847
return linestr(pos)
48444848
}
48454849

48464850
// Log logs a message from the compiler.
4847-
func (e *ssaExport) Logf(msg string, args ...interface{}) {
4851+
func (e *ssafn) Logf(msg string, args ...interface{}) {
48484852
if e.log {
48494853
fmt.Printf(msg, args...)
48504854
}
48514855
}
48524856

4853-
func (e *ssaExport) Log() bool {
4857+
func (e *ssafn) Log() bool {
48544858
return e.log
48554859
}
48564860

48574861
// Fatal reports a compiler error and exits.
4858-
func (e *ssaExport) Fatalf(pos src.XPos, msg string, args ...interface{}) {
4862+
func (e *ssafn) Fatalf(pos src.XPos, msg string, args ...interface{}) {
48594863
lineno = pos
48604864
Fatalf(msg, args...)
48614865
}
48624866

48634867
// Error reports a compiler error but keep going.
4864-
func (e *ssaExport) Error(pos src.XPos, msg string, args ...interface{}) {
4868+
func (e *ssafn) Error(pos src.XPos, msg string, args ...interface{}) {
48654869
yyerrorl(pos, msg, args...)
48664870
}
48674871

48684872
// Warnl reports a "warning", which is usually flag-triggered
48694873
// logging output for the benefit of tests.
4870-
func (e *ssaExport) Warnl(pos src.XPos, fmt_ string, args ...interface{}) {
4874+
func (e *ssafn) Warnl(pos src.XPos, fmt_ string, args ...interface{}) {
48714875
Warnl(pos, fmt_, args...)
48724876
}
48734877

4874-
func (e *ssaExport) Debug_checknil() bool {
4878+
func (e *ssafn) Debug_checknil() bool {
48754879
return Debug_checknil != 0
48764880
}
48774881

4878-
func (e *ssaExport) Debug_wb() bool {
4882+
func (e *ssafn) Debug_wb() bool {
48794883
return Debug_wb != 0
48804884
}
48814885

4882-
func (e *ssaExport) UseWriteBarrier() bool {
4886+
func (e *ssafn) UseWriteBarrier() bool {
48834887
return use_writebarrier
48844888
}
48854889

4886-
func (e *ssaExport) Syslook(name string) *obj.LSym {
4890+
func (e *ssafn) Syslook(name string) *obj.LSym {
48874891
return Linksym(syslook(name).Sym)
48884892
}
48894893

0 commit comments

Comments
 (0)