/// \brief Following the use-def chain, get the next available source
/// for the tracked value.
- /// \return A ValueTrackerResult containing the a set of registers
+ /// \return A ValueTrackerResult containing a set of registers
/// and sub registers with tracked values. A ValueTrackerResult with
/// an empty set of registers means no source was found.
ValueTrackerResult getNextSource();
SmallVector<TargetInstrInfo::RegSubRegPair, 4> SrcToLook;
TargetInstrInfo::RegSubRegPair CurSrcPair(Reg, SubReg);
SrcToLook.push_back(CurSrcPair);
- bool ShouldRewrite = false;
- unsigned PHILimit = RewritePHILimit;
- while (!SrcToLook.empty() && PHILimit) {
+ unsigned PHICount = 0;
+ while (!SrcToLook.empty() && PHICount < RewritePHILimit) {
TargetInstrInfo::RegSubRegPair Pair = SrcToLook.pop_back_val();
// As explained above, do not handle physical registers
if (TargetRegisterInfo::isPhysicalRegister(Pair.Reg))
ValueTracker ValTracker(CurSrcPair.Reg, CurSrcPair.SubReg, *MRI,
!DisableAdvCopyOpt, TII);
ValueTrackerResult Res;
+ bool ShouldRewrite = false;
do {
// Follow the chain of copies until we reach the top of the use-def chain
// a PHI instruction. Add the found PHI edges to be looked up further.
unsigned NumSrcs = Res.getNumSources();
if (NumSrcs > 1) {
- PHILimit--;
+ PHICount++;
for (unsigned i = 0; i < NumSrcs; ++i)
SrcToLook.push_back(TargetInstrInfo::RegSubRegPair(
Res.getSrcReg(i), Res.getSrcSubReg(i)));
if (Res.isValid())
continue;
- if (!PHILimit) {
- DEBUG(dbgs() << "findNextSource: PHI limit reached\n");
- return false;
- }
-
// Do not continue searching for a new source if the there's at least
// one use-def which cannot be rewritten.
if (!ShouldRewrite)
return false;
}
+ if (PHICount >= RewritePHILimit) {
+ DEBUG(dbgs() << "findNextSource: PHI limit reached\n");
+ return false;
+ }
+
// If we did not find a more suitable source, there is nothing to optimize.
if (CurSrcPair.Reg == Reg)
return false;
/// successfully traverse a PHI instruction and find suitable sources coming
/// from its edges. By inserting a new PHI, we provide a rewritten PHI def
/// suitable to be used in a new COPY instruction.
-MachineInstr *
+static MachineInstr *
insertPHI(MachineRegisterInfo *MRI, const TargetInstrInfo *TII,
const SmallVectorImpl<TargetInstrInfo::RegSubRegPair> &SrcRegs,
MachineInstr *OrigPHI) {
continue;
}
+ // TODO: remove once multiple srcs w/ coaslescable copies are supported.
if (!HandleMultipleSources)
break;
// Build the new PHI node and return its def register as the new source.
MachineInstr *OrigPHI = const_cast<MachineInstr *>(Res.getInst());
MachineInstr *NewPHI = insertPHI(MRI, TII, NewPHISrcs, OrigPHI);
+ DEBUG(dbgs() << "-- getNewSource\n");
+ DEBUG(dbgs() << " Replacing: " << *OrigPHI);
+ DEBUG(dbgs() << " With: " << *NewPHI);
const MachineOperand &MODef = NewPHI->getOperand(0);
return TargetInstrInfo::RegSubRegPair(MODef.getReg(), MODef.getSubReg());
if (Def.SubReg)
NewCopy->getOperand(0).setIsUndef();
+ DEBUG(dbgs() << "-- RewriteSource\n");
+ DEBUG(dbgs() << " Replacing: " << CopyLike);
+ DEBUG(dbgs() << " With: " << *NewCopy);
MRI.replaceRegWith(Def.Reg, NewVR);
MRI.clearKillFlags(NewVR);
TargetInstrInfo::RegSubRegPair TrackPair(TrackReg, TrackSubReg);
TargetInstrInfo::RegSubRegPair NewSrc = CpyRewriter->getNewSource(
MRI, TII, TrackPair, RewriteMap, false /* multiple sources */);
- if (SrcReg == NewSrc.Reg)
+ if (SrcReg == NewSrc.Reg || NewSrc.Reg == 0)
continue;
// Rewrite source.
if (MI->isDebugValue())
continue;
- // If there exists an instruction which belongs to the following
- // categories, we will discard the load candidates.
+ // If we run into an instruction we can't fold across, discard
+ // the load candidates.
+ if (MI->isLoadFoldBarrier())
+ FoldAsLoadDefCandidates.clear();
+
if (MI->isPosition() || MI->isPHI() || MI->isImplicitDef() ||
MI->isKill() || MI->isInlineAsm() ||
- MI->hasUnmodeledSideEffects()) {
- FoldAsLoadDefCandidates.clear();
+ MI->hasUnmodeledSideEffects())
continue;
- }
- if (MI->mayStore() || MI->isCall())
- FoldAsLoadDefCandidates.clear();
if ((isUncoalescableCopy(*MI) &&
optimizeUncoalescableCopy(MI, LocalMIs)) ||
Res.setInst(Def);
// If we can still move up in the use-def chain, move to the next
- // defintion.
+ // definition.
if (!TargetRegisterInfo::isPhysicalRegister(Reg) && OneRegSrc) {
Def = MRI.getVRegDef(Reg);
DefIdx = MRI.def_begin(Reg).getOperandNo();