import (
"cmd/internal/obj"
+ "cmd/internal/src"
"fmt"
)
n.Sym.Def.SetUsed(true)
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)
+}
"cmd/compile/internal/ssa"
"cmd/internal/dwarf"
"cmd/internal/obj"
+ "cmd/internal/src"
"cmd/internal/sys"
"fmt"
"sort"
}
if f.Config.NeedsFpScratch {
- scratchFpMem = temp(Types[TUINT64])
+ scratchFpMem = tempAt(src.NoXPos, s.curfn, Types[TUINT64])
scratchFpMem.SetUsed(scratchUsed)
}
curfn: fn,
log: printssa,
}
+ s.curfn = fn
s.f = ssa.NewFunc(&fe)
s.config = ssaConfig
// function we're building
f *ssa.Func
+ // Node for function
+ curfn *Node
+
// labels and labeled control flow nodes (OFOR, OFORUNTIL, OSWITCH, OSELECT) in f
labels map[string]*ssaLabel
labeledNodes map[*Node]*ssaLabel
if commaok && !canSSAType(n.Type) {
// unSSAable type, use temporary.
// 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)
s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, ssa.TypeMem, tmp, s.mem())
}
return aux
}
-func (e *ssafn) Auto(t ssa.Type) ssa.GCNode {
- n := temp(t.(*Type)) // Note: adds new auto to Curfn.Func.Dcl list
+func (e *ssafn) Auto(pos src.XPos, t ssa.Type) ssa.GCNode {
+ n := tempAt(pos, e.curfn, t.(*Type)) // Note: adds new auto to e.curfn.Func.Dcl list
return n
}
// Auto returns a Node for an auto variable of the given type.
// 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
// for the parts of that compound type.
func (DummyFrontend) StringData(s string) interface{} {
return nil
}
-func (DummyFrontend) Auto(t Type) GCNode {
+func (DummyFrontend) Auto(pos src.XPos, t Type) GCNode {
return &DummyAuto{t: t, s: "aDummyAuto"}
}
func (d DummyFrontend) SplitString(s LocalSlot) (LocalSlot, LocalSlot) {
package ssa
import (
+ "cmd/internal/src"
"testing"
)
Valu("mem", OpInitMem, TypeMem, 0, nil),
Valu("SP", OpSP, TypeUInt64, 0, nil),
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("startsum", OpConst64, TypeInt64, 0, nil),
Goto("b1")),
return &e.s.registers[pickReg(x)]
}
- // No register is available. 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.
- typ = types.Int64
- t := LocalSlot{e.s.f.fe.Auto(typ), typ, 0}
- // TODO: reuse these slots.
-
+ // No register is available.
// Pick a register to spill.
for _, vid := range e.cachedVals {
a := e.cache[vid]
if r, ok := e.s.f.getHome(c.ID).(*Register); ok && m>>uint(r.num)&1 != 0 {
if !c.rematerializeable() {
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)
if e.s.f.pass.debug > regDebug {
fmt.Printf(" SPILL %s->%s %s\n", r.Name(), t.Name(), x.LongString())
package ssa
-import "testing"
+import (
+ "cmd/internal/src"
+ "testing"
+)
func TestLiveControlOps(t *testing.T) {
c := testConfig(t)
f := c.Fun("entry",
Bloc("entry",
Valu("mem", OpInitMem, TypeMem, 0, nil),
- Valu("ptr", OpArg, TypeInt64Ptr, 0, c.Frontend().Auto(TypeInt64)),
- Valu("cond", OpArg, TypeBool, 0, c.Frontend().Auto(TypeBool)),
+ Valu("ptr", OpArg, TypeInt64Ptr, 0, c.Frontend().Auto(src.NoXPos, TypeInt64)),
+ Valu("cond", OpArg, TypeBool, 0, c.Frontend().Auto(src.NoXPos, TypeBool)),
Valu("ld", OpAMD64MOVQload, TypeInt64, 0, nil, "ptr", "mem"), // this value needs a spill
Goto("loop"),
),
// If there is no unused stack slot, allocate a new one.
if i == len(locs) {
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
}
// Use the stack variable at that index for v.
// a function call). Marshaling the args to typedmemmove might clobber the
// value we're trying to move.
t := val.Type.ElemType()
- tmp = b.Func.fe.Auto(t)
+ tmp = b.Func.fe.Auto(val.Pos, t)
aux := &AutoSymbol{Typ: t, Node: tmp}
mem = b.NewValue1A(pos, OpVarDef, TypeMem, tmp, mem)
tmpaddr := b.NewValue1A(pos, OpAddr, t.PtrTo(), aux, sp)