mirror of
https://github.com/golang/go
synced 2024-11-18 00:24:48 -07:00
cmd/compile: provide pos and curfn to temp
Concurrent compilation requires providing an explicit position and curfn to temp. This implementation of tempAt temporarily continues to use the globals lineno and Curfn, so as not to collide with mdempsky's work for #19683 eliminating the Curfn dependency from func nod. Updates #15756 Updates #19683 Change-Id: Ib3149ca4b0740e9f6eea44babc6f34cdd63028a9 Reviewed-on: https://go-review.googlesource.com/38592 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
34396adac1
commit
34975095d0
@ -8,6 +8,7 @@ package gc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
"cmd/internal/src"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -219,3 +220,10 @@ func temp(t *Type) *Node {
|
|||||||
n.Sym.Def.SetUsed(true)
|
n.Sym.Def.SetUsed(true)
|
||||||
return n.Orig
|
return n.Orig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tempAt(pos src.XPos, curfn *Node, t *Type) *Node {
|
||||||
|
// TODO(mdempsky/josharian): Remove all reads and writes of lineno and Curfn.
|
||||||
|
lineno = pos
|
||||||
|
Curfn = curfn
|
||||||
|
return temp(t)
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/internal/dwarf"
|
"cmd/internal/dwarf"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
|
"cmd/internal/src"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
@ -208,7 +209,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if f.Config.NeedsFpScratch {
|
if f.Config.NeedsFpScratch {
|
||||||
scratchFpMem = temp(Types[TUINT64])
|
scratchFpMem = tempAt(src.NoXPos, s.curfn, Types[TUINT64])
|
||||||
scratchFpMem.SetUsed(scratchUsed)
|
scratchFpMem.SetUsed(scratchUsed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ func buildssa(fn *Node) *ssa.Func {
|
|||||||
curfn: fn,
|
curfn: fn,
|
||||||
log: printssa,
|
log: printssa,
|
||||||
}
|
}
|
||||||
|
s.curfn = fn
|
||||||
|
|
||||||
s.f = ssa.NewFunc(&fe)
|
s.f = ssa.NewFunc(&fe)
|
||||||
s.config = ssaConfig
|
s.config = ssaConfig
|
||||||
@ -203,6 +204,9 @@ type state struct {
|
|||||||
// function we're building
|
// function we're building
|
||||||
f *ssa.Func
|
f *ssa.Func
|
||||||
|
|
||||||
|
// Node for function
|
||||||
|
curfn *Node
|
||||||
|
|
||||||
// labels and labeled control flow nodes (OFOR, OFORUNTIL, OSWITCH, OSELECT) in f
|
// labels and labeled control flow nodes (OFOR, OFORUNTIL, OSWITCH, OSELECT) in f
|
||||||
labels map[string]*ssaLabel
|
labels map[string]*ssaLabel
|
||||||
labeledNodes map[*Node]*ssaLabel
|
labeledNodes map[*Node]*ssaLabel
|
||||||
@ -4082,7 +4086,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
|
|||||||
if commaok && !canSSAType(n.Type) {
|
if commaok && !canSSAType(n.Type) {
|
||||||
// unSSAable type, use temporary.
|
// unSSAable type, use temporary.
|
||||||
// TODO: get rid of some of these temporaries.
|
// TODO: get rid of some of these temporaries.
|
||||||
tmp = temp(n.Type)
|
tmp = tempAt(n.Pos, s.curfn, n.Type)
|
||||||
addr = s.addr(tmp, false)
|
addr = s.addr(tmp, false)
|
||||||
s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, ssa.TypeMem, tmp, s.mem())
|
s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, ssa.TypeMem, tmp, s.mem())
|
||||||
}
|
}
|
||||||
@ -4713,8 +4717,8 @@ func (e *ssafn) StringData(s string) interface{} {
|
|||||||
return aux
|
return aux
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ssafn) Auto(t ssa.Type) ssa.GCNode {
|
func (e *ssafn) Auto(pos src.XPos, t ssa.Type) ssa.GCNode {
|
||||||
n := temp(t.(*Type)) // Note: adds new auto to Curfn.Func.Dcl list
|
n := tempAt(pos, e.curfn, t.(*Type)) // Note: adds new auto to e.curfn.Func.Dcl list
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ type Frontend interface {
|
|||||||
|
|
||||||
// Auto returns a Node for an auto variable of the given type.
|
// Auto returns a Node for an auto variable of the given type.
|
||||||
// The SSA compiler uses this function to allocate space for spills.
|
// The SSA compiler uses this function to allocate space for spills.
|
||||||
Auto(Type) GCNode
|
Auto(src.XPos, Type) GCNode
|
||||||
|
|
||||||
// Given the name for a compound type, returns the name we should use
|
// Given the name for a compound type, returns the name we should use
|
||||||
// for the parts of that compound type.
|
// for the parts of that compound type.
|
||||||
|
@ -76,7 +76,7 @@ func (d *DummyAuto) String() string {
|
|||||||
func (DummyFrontend) StringData(s string) interface{} {
|
func (DummyFrontend) StringData(s string) interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (DummyFrontend) Auto(t Type) GCNode {
|
func (DummyFrontend) Auto(pos src.XPos, t Type) GCNode {
|
||||||
return &DummyAuto{t: t, s: "aDummyAuto"}
|
return &DummyAuto{t: t, s: "aDummyAuto"}
|
||||||
}
|
}
|
||||||
func (d DummyFrontend) SplitString(s LocalSlot) (LocalSlot, LocalSlot) {
|
func (d DummyFrontend) SplitString(s LocalSlot) (LocalSlot, LocalSlot) {
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package ssa
|
package ssa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cmd/internal/src"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ func TestLoopConditionS390X(t *testing.T) {
|
|||||||
Valu("mem", OpInitMem, TypeMem, 0, nil),
|
Valu("mem", OpInitMem, TypeMem, 0, nil),
|
||||||
Valu("SP", OpSP, TypeUInt64, 0, nil),
|
Valu("SP", OpSP, TypeUInt64, 0, nil),
|
||||||
Valu("ret", OpAddr, TypeInt64Ptr, 0, nil, "SP"),
|
Valu("ret", OpAddr, TypeInt64Ptr, 0, nil, "SP"),
|
||||||
Valu("N", OpArg, TypeInt64, 0, c.Frontend().Auto(TypeInt64)),
|
Valu("N", OpArg, TypeInt64, 0, c.Frontend().Auto(src.NoXPos, TypeInt64)),
|
||||||
Valu("starti", OpConst64, TypeInt64, 0, nil),
|
Valu("starti", OpConst64, TypeInt64, 0, nil),
|
||||||
Valu("startsum", OpConst64, TypeInt64, 0, nil),
|
Valu("startsum", OpConst64, TypeInt64, 0, nil),
|
||||||
Goto("b1")),
|
Goto("b1")),
|
||||||
|
@ -2080,13 +2080,7 @@ func (e *edgeState) findRegFor(typ Type) Location {
|
|||||||
return &e.s.registers[pickReg(x)]
|
return &e.s.registers[pickReg(x)]
|
||||||
}
|
}
|
||||||
|
|
||||||
// No register is available. Allocate a temp location to spill a register to.
|
// No register is available.
|
||||||
// The type of the slot is immaterial - it will not be live across
|
|
||||||
// any safepoint. Just use a type big enough to hold any register.
|
|
||||||
typ = types.Int64
|
|
||||||
t := LocalSlot{e.s.f.fe.Auto(typ), typ, 0}
|
|
||||||
// TODO: reuse these slots.
|
|
||||||
|
|
||||||
// Pick a register to spill.
|
// Pick a register to spill.
|
||||||
for _, vid := range e.cachedVals {
|
for _, vid := range e.cachedVals {
|
||||||
a := e.cache[vid]
|
a := e.cache[vid]
|
||||||
@ -2094,6 +2088,11 @@ func (e *edgeState) findRegFor(typ Type) Location {
|
|||||||
if r, ok := e.s.f.getHome(c.ID).(*Register); ok && m>>uint(r.num)&1 != 0 {
|
if r, ok := e.s.f.getHome(c.ID).(*Register); ok && m>>uint(r.num)&1 != 0 {
|
||||||
if !c.rematerializeable() {
|
if !c.rematerializeable() {
|
||||||
x := e.p.NewValue1(c.Pos, OpStoreReg, c.Type, c)
|
x := e.p.NewValue1(c.Pos, OpStoreReg, c.Type, c)
|
||||||
|
// Allocate a temp location to spill a register to.
|
||||||
|
// The type of the slot is immaterial - it will not be live across
|
||||||
|
// any safepoint. Just use a type big enough to hold any register.
|
||||||
|
t := LocalSlot{e.s.f.fe.Auto(c.Pos, types.Int64), types.Int64, 0}
|
||||||
|
// TODO: reuse these slots.
|
||||||
e.set(t, vid, x, false, c.Pos)
|
e.set(t, vid, x, false, c.Pos)
|
||||||
if e.s.f.pass.debug > regDebug {
|
if e.s.f.pass.debug > regDebug {
|
||||||
fmt.Printf(" SPILL %s->%s %s\n", r.Name(), t.Name(), x.LongString())
|
fmt.Printf(" SPILL %s->%s %s\n", r.Name(), t.Name(), x.LongString())
|
||||||
|
@ -4,7 +4,10 @@
|
|||||||
|
|
||||||
package ssa
|
package ssa
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"cmd/internal/src"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func TestLiveControlOps(t *testing.T) {
|
func TestLiveControlOps(t *testing.T) {
|
||||||
c := testConfig(t)
|
c := testConfig(t)
|
||||||
@ -39,8 +42,8 @@ func TestSpillWithLoop(t *testing.T) {
|
|||||||
f := c.Fun("entry",
|
f := c.Fun("entry",
|
||||||
Bloc("entry",
|
Bloc("entry",
|
||||||
Valu("mem", OpInitMem, TypeMem, 0, nil),
|
Valu("mem", OpInitMem, TypeMem, 0, nil),
|
||||||
Valu("ptr", OpArg, TypeInt64Ptr, 0, c.Frontend().Auto(TypeInt64)),
|
Valu("ptr", OpArg, TypeInt64Ptr, 0, c.Frontend().Auto(src.NoXPos, TypeInt64)),
|
||||||
Valu("cond", OpArg, TypeBool, 0, c.Frontend().Auto(TypeBool)),
|
Valu("cond", OpArg, TypeBool, 0, c.Frontend().Auto(src.NoXPos, TypeBool)),
|
||||||
Valu("ld", OpAMD64MOVQload, TypeInt64, 0, nil, "ptr", "mem"), // this value needs a spill
|
Valu("ld", OpAMD64MOVQload, TypeInt64, 0, nil, "ptr", "mem"), // this value needs a spill
|
||||||
Goto("loop"),
|
Goto("loop"),
|
||||||
),
|
),
|
||||||
|
@ -246,7 +246,7 @@ func (s *stackAllocState) stackalloc() {
|
|||||||
// If there is no unused stack slot, allocate a new one.
|
// If there is no unused stack slot, allocate a new one.
|
||||||
if i == len(locs) {
|
if i == len(locs) {
|
||||||
s.nAuto++
|
s.nAuto++
|
||||||
locs = append(locs, LocalSlot{N: f.fe.Auto(v.Type), Type: v.Type, Off: 0})
|
locs = append(locs, LocalSlot{N: f.fe.Auto(v.Pos, v.Type), Type: v.Type, Off: 0})
|
||||||
locations[v.Type] = locs
|
locations[v.Type] = locs
|
||||||
}
|
}
|
||||||
// Use the stack variable at that index for v.
|
// Use the stack variable at that index for v.
|
||||||
|
@ -267,7 +267,7 @@ func wbcall(pos src.XPos, b *Block, fn *obj.LSym, typ interface{}, ptr, val, mem
|
|||||||
// a function call). Marshaling the args to typedmemmove might clobber the
|
// a function call). Marshaling the args to typedmemmove might clobber the
|
||||||
// value we're trying to move.
|
// value we're trying to move.
|
||||||
t := val.Type.ElemType()
|
t := val.Type.ElemType()
|
||||||
tmp = b.Func.fe.Auto(t)
|
tmp = b.Func.fe.Auto(val.Pos, t)
|
||||||
aux := &AutoSymbol{Typ: t, Node: tmp}
|
aux := &AutoSymbol{Typ: t, Node: tmp}
|
||||||
mem = b.NewValue1A(pos, OpVarDef, TypeMem, tmp, mem)
|
mem = b.NewValue1A(pos, OpVarDef, TypeMem, tmp, mem)
|
||||||
tmpaddr := b.NewValue1A(pos, OpAddr, t.PtrTo(), aux, sp)
|
tmpaddr := b.NewValue1A(pos, OpAddr, t.PtrTo(), aux, sp)
|
||||||
|
Loading…
Reference in New Issue
Block a user