@@ -19,7 +19,6 @@ import (
19
19
)
20
20
21
21
var ssaConfig * ssa.Config
22
- var ssaExp ssaExport
23
22
var ssaCache * ssa.Cache
24
23
25
24
func initssaconfig () {
@@ -50,9 +49,12 @@ func buildssa(fn *Node) *ssa.Func {
50
49
s .cgoUnsafeArgs = true
51
50
}
52
51
53
- ssaExp .log = printssa
52
+ fe := ssafn {
53
+ curfn : fn ,
54
+ log : printssa ,
55
+ }
54
56
55
- s .f = ssa .NewFunc (& ssaExp )
57
+ s .f = ssa .NewFunc (& fe )
56
58
s .config = ssaConfig
57
59
s .f .Config = ssaConfig
58
60
s .f .Cache = ssaCache
@@ -4219,7 +4221,7 @@ func (s *SSAGenState) SetPos(pos src.XPos) {
4219
4221
func genssa (f * ssa.Func , ptxt * obj.Prog , gcargs , gclocals * Sym ) {
4220
4222
var s SSAGenState
4221
4223
4222
- e := f .Frontend ().(* ssaExport )
4224
+ e := f .Frontend ().(* ssafn )
4223
4225
4224
4226
// Remember where each block starts.
4225
4227
s .bstart = make ([]* obj.Prog , f .NumBlocks ())
@@ -4350,10 +4352,10 @@ func genssa(f *ssa.Func, ptxt *obj.Prog, gcargs, gclocals *Sym) {
4350
4352
}
4351
4353
4352
4354
// Generate gc bitmaps.
4353
- liveness (Curfn , ptxt , gcargs , gclocals )
4355
+ liveness (e . curfn , ptxt , gcargs , gclocals )
4354
4356
4355
4357
// Add frame prologue. Zero ambiguously live variables.
4356
- thearch .Defframe (ptxt )
4358
+ thearch .Defframe (ptxt , e . curfn )
4357
4359
if Debug ['f' ] != 0 {
4358
4360
frame (0 )
4359
4361
}
@@ -4660,41 +4662,43 @@ func fieldIdx(n *Node) int {
4660
4662
// so we don't have to recompute it each time we need it.
4661
4663
}
4662
4664
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 ]) }
4683
4687
4684
4688
// StringData returns a symbol (a *Sym wrapped in an interface) which
4685
4689
// 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 {} {
4687
4691
// TODO: is idealstring correct? It might not matter...
4688
4692
data := stringsym (s )
4689
4693
return & ssa.ExternSymbol {Typ : idealstring , Sym : data }
4690
4694
}
4691
4695
4692
- func (e * ssaExport ) Auto (t ssa.Type ) ssa.GCNode {
4696
+ func (e * ssafn ) Auto (t ssa.Type ) ssa.GCNode {
4693
4697
n := temp (t .(* Type )) // Note: adds new auto to Curfn.Func.Dcl list
4694
4698
return n
4695
4699
}
4696
4700
4697
- func (e * ssaExport ) SplitString (name ssa.LocalSlot ) (ssa.LocalSlot , ssa.LocalSlot ) {
4701
+ func (e * ssafn ) SplitString (name ssa.LocalSlot ) (ssa.LocalSlot , ssa.LocalSlot ) {
4698
4702
n := name .N .(* Node )
4699
4703
ptrType := ptrto (Types [TUINT8 ])
4700
4704
lenType := Types [TINT ]
@@ -4708,7 +4712,7 @@ func (e *ssaExport) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlo
4708
4712
return ssa.LocalSlot {N : n , Type : ptrType , Off : name .Off }, ssa.LocalSlot {N : n , Type : lenType , Off : name .Off + int64 (Widthptr )}
4709
4713
}
4710
4714
4711
- func (e * ssaExport ) SplitInterface (name ssa.LocalSlot ) (ssa.LocalSlot , ssa.LocalSlot ) {
4715
+ func (e * ssafn ) SplitInterface (name ssa.LocalSlot ) (ssa.LocalSlot , ssa.LocalSlot ) {
4712
4716
n := name .N .(* Node )
4713
4717
t := ptrto (Types [TUINT8 ])
4714
4718
if n .Class == PAUTO && ! n .Addrtaken () {
@@ -4725,7 +4729,7 @@ func (e *ssaExport) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.Local
4725
4729
return ssa.LocalSlot {N : n , Type : t , Off : name .Off }, ssa.LocalSlot {N : n , Type : t , Off : name .Off + int64 (Widthptr )}
4726
4730
}
4727
4731
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 ) {
4729
4733
n := name .N .(* Node )
4730
4734
ptrType := ptrto (name .Type .ElemType ().(* Type ))
4731
4735
lenType := Types [TINT ]
@@ -4742,7 +4746,7 @@ func (e *ssaExport) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot
4742
4746
ssa.LocalSlot {N : n , Type : lenType , Off : name .Off + int64 (2 * Widthptr )}
4743
4747
}
4744
4748
4745
- func (e * ssaExport ) SplitComplex (name ssa.LocalSlot ) (ssa.LocalSlot , ssa.LocalSlot ) {
4749
+ func (e * ssafn ) SplitComplex (name ssa.LocalSlot ) (ssa.LocalSlot , ssa.LocalSlot ) {
4746
4750
n := name .N .(* Node )
4747
4751
s := name .Type .Size () / 2
4748
4752
var t * Type
@@ -4761,7 +4765,7 @@ func (e *ssaExport) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSl
4761
4765
return ssa.LocalSlot {N : n , Type : t , Off : name .Off }, ssa.LocalSlot {N : n , Type : t , Off : name .Off + s }
4762
4766
}
4763
4767
4764
- func (e * ssaExport ) SplitInt64 (name ssa.LocalSlot ) (ssa.LocalSlot , ssa.LocalSlot ) {
4768
+ func (e * ssafn ) SplitInt64 (name ssa.LocalSlot ) (ssa.LocalSlot , ssa.LocalSlot ) {
4765
4769
n := name .N .(* Node )
4766
4770
var t * Type
4767
4771
if name .Type .IsSigned () {
@@ -4782,7 +4786,7 @@ func (e *ssaExport) SplitInt64(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot
4782
4786
return ssa.LocalSlot {N : n , Type : t , Off : name .Off + 4 }, ssa.LocalSlot {N : n , Type : Types [TUINT32 ], Off : name .Off }
4783
4787
}
4784
4788
4785
- func (e * ssaExport ) SplitStruct (name ssa.LocalSlot , i int ) ssa.LocalSlot {
4789
+ func (e * ssafn ) SplitStruct (name ssa.LocalSlot , i int ) ssa.LocalSlot {
4786
4790
n := name .N .(* Node )
4787
4791
st := name .Type
4788
4792
ft := st .FieldType (i )
@@ -4796,7 +4800,7 @@ func (e *ssaExport) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
4796
4800
return ssa.LocalSlot {N : n , Type : ft , Off : name .Off + st .FieldOff (i )}
4797
4801
}
4798
4802
4799
- func (e * ssaExport ) SplitArray (name ssa.LocalSlot ) ssa.LocalSlot {
4803
+ func (e * ssafn ) SplitArray (name ssa.LocalSlot ) ssa.LocalSlot {
4800
4804
n := name .N .(* Node )
4801
4805
at := name .Type
4802
4806
if at .NumElem () != 1 {
@@ -4810,13 +4814,13 @@ func (e *ssaExport) SplitArray(name ssa.LocalSlot) ssa.LocalSlot {
4810
4814
return ssa.LocalSlot {N : n , Type : et , Off : name .Off }
4811
4815
}
4812
4816
4813
- func (e * ssaExport ) DerefItab (it * obj.LSym , offset int64 ) * obj.LSym {
4817
+ func (e * ssafn ) DerefItab (it * obj.LSym , offset int64 ) * obj.LSym {
4814
4818
return itabsym (it , offset )
4815
4819
}
4816
4820
4817
4821
// namedAuto returns a new AUTO variable with the given name and type.
4818
4822
// 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 {
4820
4824
t := typ .(* Type )
4821
4825
s := & Sym {Name : name , Pkg : localpkg }
4822
4826
n := nod (ONAME , nil , nil )
@@ -4828,62 +4832,62 @@ func (e *ssaExport) namedAuto(name string, typ ssa.Type) ssa.GCNode {
4828
4832
n .SetAddable (true )
4829
4833
n .Esc = EscNever
4830
4834
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 )
4833
4837
4834
4838
dowidth (t )
4835
4839
return n
4836
4840
}
4837
4841
4838
- func (e * ssaExport ) CanSSA (t ssa.Type ) bool {
4842
+ func (e * ssafn ) CanSSA (t ssa.Type ) bool {
4839
4843
return canSSAType (t .(* Type ))
4840
4844
}
4841
4845
4842
- func (e * ssaExport ) Line (pos src.XPos ) string {
4846
+ func (e * ssafn ) Line (pos src.XPos ) string {
4843
4847
return linestr (pos )
4844
4848
}
4845
4849
4846
4850
// 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 {}) {
4848
4852
if e .log {
4849
4853
fmt .Printf (msg , args ... )
4850
4854
}
4851
4855
}
4852
4856
4853
- func (e * ssaExport ) Log () bool {
4857
+ func (e * ssafn ) Log () bool {
4854
4858
return e .log
4855
4859
}
4856
4860
4857
4861
// 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 {}) {
4859
4863
lineno = pos
4860
4864
Fatalf (msg , args ... )
4861
4865
}
4862
4866
4863
4867
// 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 {}) {
4865
4869
yyerrorl (pos , msg , args ... )
4866
4870
}
4867
4871
4868
4872
// Warnl reports a "warning", which is usually flag-triggered
4869
4873
// 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 {}) {
4871
4875
Warnl (pos , fmt_ , args ... )
4872
4876
}
4873
4877
4874
- func (e * ssaExport ) Debug_checknil () bool {
4878
+ func (e * ssafn ) Debug_checknil () bool {
4875
4879
return Debug_checknil != 0
4876
4880
}
4877
4881
4878
- func (e * ssaExport ) Debug_wb () bool {
4882
+ func (e * ssafn ) Debug_wb () bool {
4879
4883
return Debug_wb != 0
4880
4884
}
4881
4885
4882
- func (e * ssaExport ) UseWriteBarrier () bool {
4886
+ func (e * ssafn ) UseWriteBarrier () bool {
4883
4887
return use_writebarrier
4884
4888
}
4885
4889
4886
- func (e * ssaExport ) Syslook (name string ) * obj.LSym {
4890
+ func (e * ssafn ) Syslook (name string ) * obj.LSym {
4887
4891
return Linksym (syslook (name ).Sym )
4888
4892
}
4889
4893
0 commit comments