summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/LiveVariables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/LiveVariables.cpp')
-rw-r--r--lib/CodeGen/LiveVariables.cpp49
1 files changed, 48 insertions, 1 deletions
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp
index 96c655c..16a79bb 100644
--- a/lib/CodeGen/LiveVariables.cpp
+++ b/lib/CodeGen/LiveVariables.cpp
@@ -50,6 +50,14 @@ void LiveVariables::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
}
+MachineInstr *
+LiveVariables::VarInfo::findKill(const MachineBasicBlock *MBB) const {
+ for (unsigned i = 0, e = Kills.size(); i != e; ++i)
+ if (Kills[i]->getParent() == MBB)
+ return Kills[i];
+ return NULL;
+}
+
void LiveVariables::VarInfo::dump() const {
errs() << " Alive in blocks: ";
for (SparseBitVector<>::iterator I = AliveBlocks.begin(),
@@ -222,8 +230,9 @@ MachineInstr *LiveVariables::FindLastPartialDef(unsigned Reg,
/// implicit defs to a machine instruction if there was an earlier def of its
/// super-register.
void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
+ MachineInstr *LastDef = PhysRegDef[Reg];
// If there was a previous use or a "full" def all is well.
- if (!PhysRegDef[Reg] && !PhysRegUse[Reg]) {
+ if (!LastDef && !PhysRegUse[Reg]) {
// Otherwise, the last sub-register def implicitly defines this register.
// e.g.
// AH =
@@ -257,6 +266,11 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
}
}
}
+ else if (LastDef && !PhysRegUse[Reg] &&
+ !LastDef->findRegisterDefOperand(Reg))
+ // Last def defines the super register, add an implicit def of reg.
+ LastDef->addOperand(MachineOperand::CreateReg(Reg,
+ true/*IsDef*/, true/*IsImp*/));
// Remember this use.
PhysRegUse[Reg] = MI;
@@ -641,3 +655,36 @@ void LiveVariables::analyzePHINodes(const MachineFunction& Fn) {
PHIVarInfo[BBI->getOperand(i + 1).getMBB()->getNumber()]
.push_back(BBI->getOperand(i).getReg());
}
+
+/// addNewBlock - Add a new basic block BB as an empty succcessor to DomBB. All
+/// variables that are live out of DomBB will be marked as passing live through
+/// BB.
+void LiveVariables::addNewBlock(MachineBasicBlock *BB,
+ MachineBasicBlock *DomBB) {
+ const unsigned NumNew = BB->getNumber();
+ const unsigned NumDom = DomBB->getNumber();
+
+ // Update info for all live variables
+ for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister,
+ E = MRI->getLastVirtReg()+1; Reg != E; ++Reg) {
+ VarInfo &VI = getVarInfo(Reg);
+
+ // Anything live through DomBB is also live through BB.
+ if (VI.AliveBlocks.test(NumDom)) {
+ VI.AliveBlocks.set(NumNew);
+ continue;
+ }
+
+ // Variables not defined in DomBB cannot be live out.
+ const MachineInstr *Def = MRI->getVRegDef(Reg);
+ if (!Def || Def->getParent() != DomBB)
+ continue;
+
+ // Killed by DomBB?
+ if (VI.findKill(DomBB))
+ continue;
+
+ // This register is defined in DomBB and live out
+ VI.AliveBlocks.set(NumNew);
+ }
+}
OpenPOWER on IntegriCloud