destinations []dstRecord
extra []dstRecord
- usedRegs regMask // registers currently holding something
- uniqueRegs regMask // registers holding the only copy of a value
- finalRegs regMask // registers holding final target
+ usedRegs regMask // registers currently holding something
+ uniqueRegs regMask // registers holding the only copy of a value
+ finalRegs regMask // registers holding final target
+ rematerializeableRegs regMask // registers that hold rematerializeable values
}
type contentRecord struct {
e.usedRegs = 0
e.uniqueRegs = 0
e.finalRegs = 0
+ e.rematerializeableRegs = 0
// Live registers can be sources.
for _, x := range srcReg {
e.uniqueRegs &^= regMask(1) << uint(t.num)
}
}
+ if e.s.values[vid].rematerializeable {
+ e.rematerializeableRegs |= regMask(1) << uint(r.num)
+ }
}
if e.s.f.pass.debug > regDebug {
fmt.Printf("%s\n", c.LongString())
if cr.final {
e.finalRegs &^= regMask(1) << uint(r.num)
}
+ e.rematerializeableRegs &^= regMask(1) << uint(r.num)
}
if len(a) == 1 {
if r, ok := e.s.f.getHome(a[0].ID).(*Register); ok {
// 1) an unused register
// 2) a non-unique register not holding a final value
// 3) a non-unique register
- // 4) TODO: a register holding a rematerializeable value
+ // 4) a register holding a rematerializeable value
x := m &^ e.usedRegs
if x != 0 {
return &e.s.registers[pickReg(x)]
if x != 0 {
return &e.s.registers[pickReg(x)]
}
+ x = m & e.rematerializeableRegs
+ if x != 0 {
+ return &e.s.registers[pickReg(x)]
+ }
// No register is available.
// Pick a register to spill.
}
}
- fmt.Printf("m:%d unique:%d final:%d\n", m, e.uniqueRegs, e.finalRegs)
+ fmt.Printf("m:%d unique:%d final:%d rematerializable:%d\n", m, e.uniqueRegs, e.finalRegs, e.rematerializeableRegs)
for _, vid := range e.cachedVals {
a := e.cache[vid]
for _, c := range a {