// allocated register is marked nospill so the assignment cannot be
// undone until the caller allows it by clearing nospill. Returns a
// *Value which is either v or a copy of v allocated to the chosen register.
-func (s *regAllocState) allocValToReg(v *Value, mask regMask, nospill bool) *Value {
+func (s *regAllocState) allocValToReg(v *Value, mask regMask, nospill bool, line int32) *Value {
vi := &s.values[v.ID]
// Check if v is already in a requested register.
if s.regs[r2].v != v {
panic("bad register state")
}
- c = s.curBlock.NewValue1(v.Line, OpCopy, v.Type, s.regs[r2].c)
+ c = s.curBlock.NewValue1(line, OpCopy, v.Type, s.regs[r2].c)
} else if v.rematerializeable() {
// Rematerialize instead of loading from the spill location.
c = v.copyInto(s.curBlock)
if logSpills {
fmt.Println("regalloc: load spill")
}
- c = s.curBlock.NewValue1(v.Line, OpLoadReg, v.Type, vi.spill)
+ c = s.curBlock.NewValue1(line, OpLoadReg, v.Type, vi.spill)
vi.spillUsed = true
default:
s.f.Fatalf("attempt to load unspilled value %v", v.LongString())
// TODO: remove flag input from regspec.inputs.
continue
}
- args[i.idx] = s.allocValToReg(v.Args[i.idx], i.regs, true)
+ args[i.idx] = s.allocValToReg(v.Args[i.idx], i.regs, true, v.Line)
}
// Now that all args are in regs, we're ready to issue the value itself.
// Load control value into reg.
// TODO: regspec for block control values, instead of using
// register set from the control op's output.
- s.allocValToReg(v, opcodeTable[v.Op].reg.outputs[0], false)
+ s.allocValToReg(v, opcodeTable[v.Op].reg.outputs[0], false, b.Line)
// Remove this use from the uses list.
vi := &s.values[v.ID]
u := vi.uses
// Figure out when that will be an improvement.
func tighten(f *Func) {
// For each value, the number of blocks in which it is used.
- uses := make([]int, f.NumValues())
+ uses := make([]int32, f.NumValues())
// For each value, whether that value is ever an arg to a phi value.
phi := make([]bool, f.NumValues())