if (RefsInMBB.empty() && !DefMI) {
MachineBasicBlock::iterator MII = MBB->begin();
MachineBasicBlock::iterator EndPt = MI;
+
+ if (MII == EndPt) return Pt;
+
do {
++MII;
unsigned Index = LIs->getInstructionIndex(MII);
unsigned Gap = LIs->findGapBeforeInstr(Index);
- if (Gap) {
- Pt = MII;
- SpillIndex = Gap;
- break;
// We can't insert the spill between the barrier (a call), and its
- // corresponding call frame setup.
- } else if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode() &&
- MII == MachineBasicBlock::iterator(MI))
+ // corresponding call frame setup/teardown.
+ if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) {
+ bool reachedBarrier = false;
+ do {
+ if (MII == EndPt) {
+ reachedBarrier = true;
+ break;
+ }
+ ++MII;
+ } while (MII->getOpcode() != TRI->getCallFrameDestroyOpcode());
+
+ if (reachedBarrier) break;
+ } else if (Gap) {
+ Pt = MII;
+ SpillIndex = Gap;
break;
+ }
} while (MII != EndPt);
} else {
MachineBasicBlock::iterator MII = MI;
MachineBasicBlock::iterator EndPt = DefMI
? MachineBasicBlock::iterator(DefMI) : MBB->begin();
- // We can't insert the spill between the barrier (a call), and its
- // corresponding call frame setup.
- if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) --MII;
while (MII != EndPt && !RefsInMBB.count(MII)) {
unsigned Index = LIs->getInstructionIndex(MII);
- if (LIs->hasGapBeforeInstr(Index)) {
+
+ // We can't insert the spill between the barrier (a call), and its
+ // corresponding call frame setup.
+ if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) {
+ --MII;
+ continue;
+ } if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) {
+ bool reachedBarrier = false;
+ while (MII->getOpcode() != TRI->getCallFrameSetupOpcode()) {
+ --MII;
+ if (MII == EndPt) {
+ reachedBarrier = true;
+ break;
+ }
+ }
+
+ if (reachedBarrier) break;
+ else continue;
+ } else if (LIs->hasGapBeforeInstr(Index)) {
Pt = MII;
SpillIndex = LIs->findGapBeforeInstr(Index, true);
}
if (RefsInMBB.empty() && LastIdx >= EndIdx) {
MachineBasicBlock::iterator MII = MBB->getFirstTerminator();
MachineBasicBlock::iterator EndPt = MI;
+
+ if (MII == EndPt) return Pt;
+
--MII;
do {
unsigned Index = LIs->getInstructionIndex(MII);
unsigned Gap = LIs->findGapBeforeInstr(Index);
- if (Gap) {
- Pt = MII;
- RestoreIndex = Gap;
- break;
// We can't insert a restore between the barrier (a call) and its
// corresponding call frame teardown.
- } else if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode() &&
- prior(MII) == MachineBasicBlock::iterator(MI))
+ if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) {
+ bool reachedBarrier = false;
+ while (MII->getOpcode() != TRI->getCallFrameSetupOpcode()) {
+ --MII;
+ if (MII == EndPt) {
+ reachedBarrier = true;
+ break;
+ }
+ }
+
+ if (reachedBarrier) break;
+ else continue;
+ } else if (Gap) {
+ Pt = MII;
+ RestoreIndex = Gap;
break;
+ }
+
--MII;
} while (MII != EndPt);
} else {
MachineBasicBlock::iterator MII = MI;
MII = ++MII;
- // We can't insert a restore between the barrier (a call) and its
- // corresponding call frame teardown.
- if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode())
- ++MII;
// FIXME: Limit the number of instructions to examine to reduce
// compile time?
if (Index > LastIdx)
break;
unsigned Gap = LIs->findGapBeforeInstr(Index);
- if (Gap) {
+
+ // We can't insert a restore between the barrier (a call) and its
+ // corresponding call frame teardown.
+ if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode()) {
+ ++MII;
+ continue;
+ } else if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) {
+ bool reachedBarrier = false;
+ do {
+ if (MII == MBB->getFirstTerminator() || RefsInMBB.count(MII)) {
+ reachedBarrier = true;
+ break;
+ }
+
+ ++MII;
+ } while (MII->getOpcode() != TRI->getCallFrameDestroyOpcode());
+
+ if (reachedBarrier) break;
+ } else if (Gap) {
Pt = MII;
RestoreIndex = Gap;
}
+
if (RefsInMBB.count(MII))
break;
++MII;
}
if (MBB->pred_size() == 1 && !RetVNI->hasPHIKill) {
- LI->MergeValueNumberInto(RetVNI, IncomingVNs.begin()->second);
- Phis[MBB] = RetVNI = IncomingVNs.begin()->second;
+ VNInfo* OldVN = RetVNI;
+ VNInfo* NewVN = IncomingVNs.begin()->second;
+ VNInfo* MergedVN = LI->MergeValueNumberInto(OldVN, NewVN);
+ if (MergedVN == OldVN) std::swap(OldVN, NewVN);
+
+ for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator LOI = LiveOut.begin(),
+ LOE = LiveOut.end(); LOI != LOE; ++LOI)
+ if (LOI->second == OldVN)
+ LOI->second = MergedVN;
+ for (DenseMap<MachineInstr*, VNInfo*>::iterator NVI = NewVNs.begin(),
+ NVE = NewVNs.end(); NVI != NVE; ++NVI)
+ if (NVI->second == OldVN)
+ NVI->second = MergedVN;
+ for (DenseMap<MachineBasicBlock*, VNInfo*>::iterator PI = Phis.begin(),
+ PE = Phis.end(); PI != PE; ++PI)
+ if (PI->second == OldVN)
+ PI->second = MergedVN;
+ RetVNI = MergedVN;
} else {
// Otherwise, merge the incoming VNInfos with a phi join. Create a new
// VNInfo to represent the joined value.
// by the current barrier.
SmallVector<LiveInterval*, 8> Intervals;
for (const TargetRegisterClass **RC = RCs; *RC; ++RC) {
- if (TII->IgnoreRegisterClassBarriers(*RC))
+ // FIXME: If it's not safe to move any instruction that defines the barrier
+ // register class, then it means there are some special dependencies which
+ // codegen is not modelling. Ignore these barriers for now.
+ if (!TII->isSafeToMoveRegClassDefs(*RC))
continue;
std::vector<unsigned> &VRs = MRI->getRegClassVirtRegs(*RC);
for (unsigned i = 0, e = VRs.size(); i != e; ++i) {