EnableJoining("join-liveintervals",
cl::desc("Coallesce copies (default=true)"),
cl::init(true));
-
- static cl::opt<bool>
- EnableReMat("enable-rematerialization",
- cl::desc("Perform trivial re-materialization"),
- cl::init(false));
}
void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
unsigned reg = rep(mop.getReg());
mii->getOperand(i).setReg(reg);
- // If the definition instruction is re-materializable, its spill
- // weight is zero.
LiveInterval &RegInt = getInterval(reg);
- if (!RegInt.remat) {
- RegInt.weight +=
- (mop.isUse() + mop.isDef()) * pow(10.0F, (int)loopDepth);
- }
+ float w = (mop.isUse()+mop.isDef()) * powf(10.0F, (float)loopDepth);
+ // If the definition instruction is re-materializable, its spill
+ // weight is half of what it would have been normally unless it's
+ // a load from fixed stack slot.
+ int Dummy;
+ if (RegInt.remat && !tii_->isLoadFromStackSlot(RegInt.remat, Dummy))
+ w /= 2;
+ RegInt.weight += w;
}
}
++mii;
// done once for the vreg. We use an empty interval to detect the first
// time we see a vreg.
if (interval.empty()) {
- // Remember if the definition can be rematerialized.
- if (EnableReMat &&
- vi.DefInst && tii_->isReMaterializable(vi.DefInst->getOpcode()))
+ // Remember if the definition can be rematerialized. All load's from fixed
+ // stack slots are re-materializable.
+ int FrameIdx = 0;
+ if (vi.DefInst &&
+ (tii_->isReMaterializable(vi.DefInst->getOpcode()) ||
+ (tii_->isLoadFromStackSlot(vi.DefInst, FrameIdx) &&
+ mf_->getFrameInfo()->isFixedObjectIndex(FrameIdx))))
interval.remat = vi.DefInst;
// Get the Idx of the defining instructions.
}
} else {
- // Can't safely assume definition is rematierializable anymore.
+ // Can no longer safely assume definition is rematerializable.
interval.remat = NULL;
// If this is the second time we see a virtual register definition, it
// If the source instruction was killing the source register before the
// merge, unset the isKill marker given the live range has been extended.
- MachineOperand *MOK = ValLREndInst->findRegisterUseOperand(IntB.reg, true);
- if (MOK)
- MOK->unsetIsKill();
+ int UIdx = ValLREndInst->findRegisterUseOperand(IntB.reg, true);
+ if (UIdx != -1)
+ ValLREndInst->getOperand(UIdx).unsetIsKill();
// Finally, delete the copy instruction.
RemoveMachineInstrFromMaps(CopyMI);
// Check if it is necessary to propagate "isDead" property before intervals
// are joined.
+ MachineBasicBlock *CopyBB = CopyMI->getParent();
MachineOperand *mopd = CopyMI->findRegisterDefOperand(DstReg);
bool isDead = mopd->isDead();
bool isShorten = false;
// The instruction which defines the src is only truly dead if there are
// no intermediate uses and there isn't a use beyond the copy.
// FIXME: find the last use, mark is kill and shorten the live range.
- if (SrcEnd > getDefIndex(CopyIdx))
+ if (SrcEnd > getDefIndex(CopyIdx)) {
isDead = false;
- else {
+ } else {
MachineOperand *MOU;
MachineInstr *LastUse= lastRegisterUse(repSrcReg, SrcStart, CopyIdx, MOU);
if (LastUse) {
isShorten = true;
RemoveStart = getDefIndex(getInstructionIndex(LastUse));
RemoveEnd = SrcEnd;
+ } else {
+ MachineInstr *SrcMI = getInstructionFromIndex(SrcStart);
+ if (SrcMI) {
+ MachineOperand *mops = findDefOperand(SrcMI, repSrcReg);
+ if (mops)
+ // A dead def should have a single cycle interval.
+ ++RemoveStart;
+ }
}
}
}
LiveVariables::VarInfo& dvi = lv_->getVarInfo(repDstReg);
// Is the value used in the current BB or any immediate successroe BB?
- MachineBasicBlock *CopyBB = CopyMI->getParent();
if (dvi.UsedBlocks[CopyBB->getNumber()])
goto TryJoin;
for (MachineBasicBlock::succ_iterator SI = CopyBB->succ_begin(),
} else {
MachineInstr *SrcMI = getInstructionFromIndex(SrcStart);
if (SrcMI) {
- MachineOperand *mops = SrcMI->findRegisterDefOperand(SrcReg);
+ MachineOperand *mops = findDefOperand(SrcMI, repSrcReg);
if (mops)
- // FIXME: mops == NULL means SrcMI defines a subregister?
mops->setIsDead();
}
}
return NULL;
}
+
+/// findDefOperand - Returns the MachineOperand that is a def of the specific
+/// register. It returns NULL if the def is not found.
+MachineOperand *LiveIntervals::findDefOperand(MachineInstr *MI, unsigned Reg) {
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (MO.isReg() && MO.isDef() &&
+ mri_->regsOverlap(rep(MO.getReg()), Reg))
+ return &MO;
+ }
+ return NULL;
+}
+
/// unsetRegisterKill - Unset IsKill property of all uses of specific register
/// of the specific instruction.
void LiveIntervals::unsetRegisterKill(MachineInstr *MI, unsigned Reg) {