summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCameron Zwarich <zwarich@apple.com>2013-02-17 00:10:44 +0000
committerCameron Zwarich <zwarich@apple.com>2013-02-17 00:10:44 +0000
commitbfebb419844b1d9c63ad14d0cff51e19935a45a4 (patch)
tree5cbfba0678e3ff1f0b89273eed46a7cc6f6a17ec
parent23242098e7dc8b585f1a9e780f3932b40252ec62 (diff)
downloadbcm5719-llvm-bfebb419844b1d9c63ad14d0cff51e19935a45a4.tar.gz
bcm5719-llvm-bfebb419844b1d9c63ad14d0cff51e19935a45a4.zip
Add support for updating the LiveIntervals of registers used by 'exotic'
terminators that actually have register uses when splitting critical edges. This commit also introduces a method repairIntervalsInRange() on LiveIntervals, which allows for repairing LiveIntervals in a small range after an arbitrary target hook modifies, inserts, and removes instructions. It's pretty limited right now, but I hope to extend it to support all of the things that are done by the convertToThreeAddress() target hooks. llvm-svn: 175382
-rw-r--r--llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h15
-rw-r--r--llvm/lib/CodeGen/LiveIntervalAnalysis.cpp36
-rw-r--r--llvm/lib/CodeGen/MachineBasicBlock.cpp29
3 files changed, 80 insertions, 0 deletions
diff --git a/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h b/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h
index b6cc111b73c..f422a6f3e9b 100644
--- a/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -281,6 +281,21 @@ namespace llvm {
void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart,
bool UpdateFlags = false);
+ /// repairIntervalsInRange - Update live intervals for instructions in a
+ /// small range of reverse iterators. It is intended for use after target
+ /// hooks that may insert or remove instructions, and is only efficient for
+ /// a small number of instructions.
+ ///
+ /// OrigRegs is a vector of registers that were originally used by the
+ /// instructions in the range between the two iterators.
+ ///
+ /// Currently, the only only changes that are supported are simple removal
+ /// and addition of uses.
+ void repairIntervalsInRange(MachineBasicBlock *MBB,
+ MachineBasicBlock::reverse_iterator RBegin,
+ MachineBasicBlock::reverse_iterator REnd,
+ SmallVectorImpl<unsigned> &OrigRegs);
+
// Register mask functions.
//
// Machine instructions may use a register mask operand to indicate that a
diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
index 0d4ec11266e..3c67be5e8f6 100644
--- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -1032,3 +1032,39 @@ void LiveIntervals::handleMoveIntoBundle(MachineInstr* MI,
HMEditor HME(*this, *MRI, *TRI, OldIndex, NewIndex, UpdateFlags);
HME.updateAllRanges(MI);
}
+
+void
+LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
+ MachineBasicBlock::reverse_iterator RBegin,
+ MachineBasicBlock::reverse_iterator REnd,
+ SmallVectorImpl<unsigned> &OrigRegs) {
+ for (unsigned i = 0, e = OrigRegs.size(); i != e; ++i) {
+ unsigned Reg = OrigRegs[i];
+ if (!TargetRegisterInfo::isVirtualRegister(Reg))
+ continue;
+
+ LiveInterval &LI = getInterval(Reg);
+ SlotIndex startIdx = (REnd == MBB->rend()) ? getMBBStartIdx(MBB)
+ : getInstructionIndex(&*REnd);
+ for (MachineBasicBlock::reverse_iterator I = RBegin; I != REnd; ++I) {
+ MachineInstr *MI = &*I;
+ SlotIndex instrIdx = getInstructionIndex(MI);
+
+ for (MachineInstr::mop_iterator OI = MI->operands_begin(),
+ OE = MI->operands_end(); OI != OE; ++OI) {
+ const MachineOperand &MO = *OI;
+ if (!MO.isReg() || MO.getReg() != Reg)
+ continue;
+
+ assert(MO.isUse() && "Register defs are not yet supported.");
+
+ if (!LI.liveAt(instrIdx)) {
+ LiveRange *LR = LI.getLiveRangeContaining(startIdx.getRegSlot());
+ assert(LR && "Used registers must be live-in.");
+ LR->end = instrIdx.getRegSlot();
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index df1c7c2a66d..3d754366ee4 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -698,6 +698,24 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
}
}
+ SmallVector<unsigned, 4> UsedRegs;
+ if (LIS) {
+ for (instr_iterator I = getFirstInstrTerminator(), E = instr_end();
+ I != E; ++I) {
+ MachineInstr *MI = I;
+
+ for (MachineInstr::mop_iterator OI = MI->operands_begin(),
+ OE = MI->operands_end(); OI != OE; ++OI) {
+ if (!OI->isReg() || OI->getReg() == 0)
+ continue;
+
+ unsigned Reg = OI->getReg();
+ if (std::find(UsedRegs.begin(), UsedRegs.end(), Reg) == UsedRegs.end())
+ UsedRegs.push_back(Reg);
+ }
+ }
+ }
+
ReplaceUsesOfBlockWith(Succ, NMBB);
// If updateTerminator() removes instructions, we need to remove them from
@@ -830,6 +848,17 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) {
LI.removeRange(StartIndex, EndIndex);
}
}
+
+ // Update all intervals for registers whose uses may have been modified by
+ // updateTerminator().
+ iterator FirstTerminator = getFirstTerminator();
+ MachineInstr *FirstTerminatorMI = FirstTerminator;
+ if (FirstTerminatorMI->isBundled())
+ FirstTerminatorMI = getBundleStart(FirstTerminatorMI);
+ reverse_iterator PreTerminators =
+ (FirstTerminator == begin()) ? rend()
+ : reverse_iterator(FirstTerminatorMI);
+ LIS->repairIntervalsInRange(this, rbegin(), PreTerminators, UsedRegs);
}
if (MachineDominatorTree *MDT =
OpenPOWER on IntegriCloud