summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/RegAllocFast.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/RegAllocFast.cpp')
-rw-r--r--llvm/lib/CodeGen/RegAllocFast.cpp28
1 files changed, 27 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp
index 4da0912508d..2ffa5e389f8 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -226,6 +226,7 @@ namespace {
MCPhysReg PhysReg);
bool mayLiveOut(unsigned VirtReg);
+ bool mayLiveIn(unsigned VirtReg);
void dumpState();
};
@@ -270,8 +271,10 @@ bool RegAllocFast::mayLiveOut(unsigned VirtReg) {
// If this block loops back to itself, it would be necessary to check whether
// the use comes after the def.
- if (MBB->isSuccessor(MBB))
+ if (MBB->isSuccessor(MBB)) {
+ MayLiveAcrossBlocks.set(TargetRegisterInfo::virtReg2Index(VirtReg));
return true;
+ }
// See if the first \p Limit uses of the register are all in the current
// block.
@@ -288,6 +291,24 @@ bool RegAllocFast::mayLiveOut(unsigned VirtReg) {
return false;
}
+/// Returns false if \p VirtReg is known to not be live into the current block.
+bool RegAllocFast::mayLiveIn(unsigned VirtReg) {
+ if (MayLiveAcrossBlocks.test(TargetRegisterInfo::virtReg2Index(VirtReg)))
+ return !MBB->pred_empty();
+
+ // See if the first \p Limit def of the register are all in the current block.
+ static const unsigned Limit = 8;
+ unsigned C = 0;
+ for (const MachineInstr &DefInst : MRI->def_instructions(VirtReg)) {
+ if (DefInst.getParent() != MBB || ++C >= Limit) {
+ MayLiveAcrossBlocks.set(TargetRegisterInfo::virtReg2Index(VirtReg));
+ return !MBB->pred_empty();
+ }
+ }
+
+ return false;
+}
+
/// Insert spill instruction for \p AssignedReg before \p Before. Update
/// DBG_VALUEs with \p VirtReg operands with the stack slot.
void RegAllocFast::spill(MachineBasicBlock::iterator Before, unsigned VirtReg,
@@ -1083,6 +1104,11 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
// There is no need to allocate a register for an undef use.
continue;
}
+
+ // Populate MayLiveAcrossBlocks in case the use block is allocated before
+ // the def block (removing the vreg uses).
+ mayLiveIn(Reg);
+
LiveReg &LR = reloadVirtReg(MI, I, Reg, CopyDstReg);
MCPhysReg PhysReg = LR.PhysReg;
CopySrcReg = (CopySrcReg == Reg || CopySrcReg == PhysReg) ? PhysReg : 0;
OpenPOWER on IntegriCloud