mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-22 02:05:01 +00:00
Allow the fast-path spilling code to attempt folding, but still leaving out remat and splitting.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55012 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1adf1b03af
commit
a41e47afc1
@ -1624,77 +1624,86 @@ addIntervalsForSpillsFast(const LiveInterval &li,
|
|||||||
|
|
||||||
const TargetRegisterClass* rc = mri_->getRegClass(li.reg);
|
const TargetRegisterClass* rc = mri_->getRegClass(li.reg);
|
||||||
|
|
||||||
DenseMap<MachineInstr*, unsigned> VRegMap;
|
|
||||||
DenseMap<MachineInstr*, VNInfo*> VNMap;
|
|
||||||
|
|
||||||
SSWeight = 0.0f;
|
SSWeight = 0.0f;
|
||||||
|
|
||||||
for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(li.reg),
|
MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(li.reg);
|
||||||
RE = mri_->reg_end(); RI != RE; ) {
|
while (RI != mri_->reg_end()) {
|
||||||
// Create a new virtual register for the spill interval.
|
MachineInstr* MI = &*RI;
|
||||||
MachineOperand& MO = RI.getOperand();
|
|
||||||
unsigned NewVReg = 0;
|
SmallVector<unsigned, 2> Indices;
|
||||||
bool newInt = false;
|
bool HasUse = false;
|
||||||
if (!VRegMap.count(MO.getParent())) {
|
bool HasDef = false;
|
||||||
VRegMap[MO.getParent()] = NewVReg = mri_->createVirtualRegister(rc);
|
|
||||||
|
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
|
||||||
|
MachineOperand& mop = MI->getOperand(i);
|
||||||
|
if (!mop.isReg() || mop.getReg() != li.reg) continue;
|
||||||
|
|
||||||
|
HasUse |= MI->getOperand(i).isUse();
|
||||||
|
HasDef |= MI->getOperand(i).isDef();
|
||||||
|
|
||||||
|
Indices.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tryFoldMemoryOperand(MI, vrm, NULL, getInstructionIndex(MI),
|
||||||
|
Indices, true, slot, li.reg)) {
|
||||||
|
unsigned NewVReg = mri_->createVirtualRegister(rc);
|
||||||
vrm.grow();
|
vrm.grow();
|
||||||
vrm.assignVirt2StackSlot(NewVReg, slot);
|
vrm.assignVirt2StackSlot(NewVReg, slot);
|
||||||
|
|
||||||
newInt = true;
|
// create a new register for this spill
|
||||||
} else
|
LiveInterval &nI = getOrCreateInterval(NewVReg);
|
||||||
NewVReg = VRegMap[MO.getParent()];
|
|
||||||
|
|
||||||
// Increment iterator to avoid invalidation.
|
|
||||||
++RI;
|
|
||||||
|
|
||||||
MO.setReg(NewVReg);
|
|
||||||
|
|
||||||
// create a new register for this spill
|
// the spill weight is now infinity as it
|
||||||
LiveInterval &nI = getOrCreateInterval(NewVReg);
|
// cannot be spilled again
|
||||||
|
nI.weight = HUGE_VALF;
|
||||||
// the spill weight is now infinity as it
|
|
||||||
// cannot be spilled again
|
// Rewrite register operands to use the new vreg.
|
||||||
nI.weight = HUGE_VALF;
|
for (SmallVectorImpl<unsigned>::iterator I = Indices.begin(),
|
||||||
|
E = Indices.end(); I != E; ++I) {
|
||||||
unsigned index = getInstructionIndex(MO.getParent());
|
MI->getOperand(*I).setReg(NewVReg);
|
||||||
bool HasUse = MO.isUse();
|
|
||||||
bool HasDef = MO.isDef();
|
if (MI->getOperand(*I).isUse())
|
||||||
if (!VNMap.count(MO.getParent()))
|
MI->getOperand(*I).setIsKill(true);
|
||||||
VNMap[MO.getParent()] = nI.getNextValue(~0U, 0, getVNInfoAllocator());
|
}
|
||||||
if (HasUse) {
|
|
||||||
LiveRange LR(getLoadIndex(index), getUseIndex(index),
|
// Fill in the new live interval.
|
||||||
VNMap[MO.getParent()]);
|
unsigned index = getInstructionIndex(MI);
|
||||||
DOUT << " +" << LR;
|
if (HasUse) {
|
||||||
nI.addRange(LR);
|
LiveRange LR(getLoadIndex(index), getUseIndex(index),
|
||||||
vrm.addRestorePoint(NewVReg, MO.getParent());
|
nI.getNextValue(~0U, 0, getVNInfoAllocator()));
|
||||||
MO.setIsKill(true);
|
DOUT << " +" << LR;
|
||||||
}
|
nI.addRange(LR);
|
||||||
if (HasDef) {
|
vrm.addRestorePoint(NewVReg, MI);
|
||||||
LiveRange LR(getDefIndex(index), getStoreIndex(index),
|
}
|
||||||
VNMap[MO.getParent()]);
|
if (HasDef) {
|
||||||
DOUT << " +" << LR;
|
LiveRange LR(getDefIndex(index), getStoreIndex(index),
|
||||||
nI.addRange(LR);
|
nI.getNextValue(~0U, 0, getVNInfoAllocator()));
|
||||||
vrm.addSpillPoint(NewVReg, true, MO.getParent());
|
DOUT << " +" << LR;
|
||||||
}
|
nI.addRange(LR);
|
||||||
|
vrm.addSpillPoint(NewVReg, true, MI);
|
||||||
if (newInt)
|
}
|
||||||
|
|
||||||
added.push_back(&nI);
|
added.push_back(&nI);
|
||||||
|
|
||||||
DOUT << "\t\t\t\tadded new interval: ";
|
DOUT << "\t\t\t\tadded new interval: ";
|
||||||
DEBUG(nI.dump());
|
DEBUG(nI.dump());
|
||||||
DOUT << '\n';
|
DOUT << '\n';
|
||||||
|
|
||||||
|
unsigned loopDepth = loopInfo->getLoopDepth(MI->getParent());
|
||||||
|
if (HasUse) {
|
||||||
|
if (HasDef)
|
||||||
|
SSWeight += getSpillWeight(true, true, loopDepth);
|
||||||
|
else
|
||||||
|
SSWeight += getSpillWeight(false, true, loopDepth);
|
||||||
|
} else
|
||||||
|
SSWeight += getSpillWeight(true, false, loopDepth);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned loopDepth = loopInfo->getLoopDepth(MO.getParent()->getParent());
|
|
||||||
if (HasUse) {
|
|
||||||
if (HasDef)
|
|
||||||
SSWeight += getSpillWeight(true, true, loopDepth);
|
|
||||||
else
|
|
||||||
SSWeight += getSpillWeight(false, true, loopDepth);
|
|
||||||
} else
|
|
||||||
SSWeight += getSpillWeight(true, false, loopDepth);
|
|
||||||
|
|
||||||
|
RI = mri_->reg_begin(li.reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clients expect the new intervals to be returned in sorted order.
|
||||||
std::sort(added.begin(), added.end(), LISorter());
|
std::sort(added.begin(), added.end(), LISorter());
|
||||||
|
|
||||||
return added;
|
return added;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user