summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCameron Zwarich <zwarich@apple.com>2013-02-20 06:46:48 +0000
committerCameron Zwarich <zwarich@apple.com>2013-02-20 06:46:48 +0000
commit9030fc22dd73684901ecb749c9688e289bd1a777 (patch)
tree80617332dbbc87af3474cc7a8ed7e7f375df0afe
parent6cf93d740a600024f2de924614a4d4d0dc1cb852 (diff)
downloadllvm-9030fc22dd73684901ecb749c9688e289bd1a777.tar.gz
llvm-9030fc22dd73684901ecb749c9688e289bd1a777.tar.bz2
llvm-9030fc22dd73684901ecb749c9688e289bd1a777.tar.xz
Add support to the two-address pass for updating LiveIntervals in many of the
common transformations. This includes updating repairIntervalsInRange() to handle more cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175604 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp51
-rw-r--r--lib/CodeGen/TwoAddressInstructionPass.cpp65
2 files changed, 102 insertions, 14 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 7b1eed2a34..8177db6194 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -1038,20 +1038,36 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
MachineBasicBlock::iterator Begin,
MachineBasicBlock::iterator End,
ArrayRef<unsigned> OrigRegs) {
- SlotIndex startIdx;
- if (Begin == MBB->begin())
- startIdx = getMBBStartIdx(MBB);
+ SlotIndex endIdx;
+ if (End == MBB->end())
+ endIdx = getMBBEndIdx(MBB).getPrevSlot();
else
- startIdx = getInstructionIndex(prior(Begin)).getRegSlot();
+ endIdx = getInstructionIndex(End);
Indexes->repairIndexesInRange(MBB, Begin, End);
+ for (MachineBasicBlock::iterator I = End; I != Begin;) {
+ --I;
+ MachineInstr *MI = I;
+ for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(),
+ MOE = MI->operands_end(); MOI != MOE; ++MOI) {
+ if (MOI->isReg() &&
+ TargetRegisterInfo::isVirtualRegister(MOI->getReg()) &&
+ !hasInterval(MOI->getReg())) {
+ LiveInterval &LI = getOrCreateInterval(MOI->getReg());
+ computeVirtRegInterval(&LI);
+ }
+ }
+ }
+
for (unsigned i = 0, e = OrigRegs.size(); i != e; ++i) {
unsigned Reg = OrigRegs[i];
if (!TargetRegisterInfo::isVirtualRegister(Reg))
continue;
LiveInterval &LI = getInterval(Reg);
+ LiveInterval::iterator LII = LI.FindLiveRangeContaining(endIdx);
+
for (MachineBasicBlock::iterator I = End; I != Begin;) {
--I;
MachineInstr *MI = I;
@@ -1063,13 +1079,26 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
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);
- assert(LR && "Used registers must be live-in.");
- LR->end = instrIdx.getRegSlot();
- break;
+ if (MO.isDef()) {
+ assert(LII != LI.end() &&
+ "Dead register defs are not yet supported.");
+ if (!Indexes->getInstructionFromIndex(LII->start)) {
+ LII->start = instrIdx.getRegSlot();
+ LII->valno->def = instrIdx.getRegSlot();
+ } else if (LII->start != instrIdx.getRegSlot()) {
+ VNInfo *VNI = LI.getNextValue(instrIdx.getRegSlot(), VNInfoAllocator);
+ LiveRange LR = LiveRange(instrIdx.getRegSlot(), LII->start, VNI);
+ LII = LI.addRange(LR);
+ }
+ } else if (MO.isUse()) {
+ if (LII == LI.end())
+ --LII;
+
+ assert(LII->start < instrIdx &&
+ "Registers with multiple used live ranges are not yet supported.");
+ SlotIndex endIdx = LII->end;
+ if (!endIdx.isBlock() && !Indexes->getInstructionFromIndex(endIdx))
+ LII->end = instrIdx.getRegSlot();
}
}
}
diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp
index cf14b4dea6..0da6662441 100644
--- a/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -1149,7 +1149,29 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
}
LV->addVirtualRegisterKilled(Reg, NewMIs[1]);
}
+
+ MachineBasicBlock::iterator Begin;
+ MachineBasicBlock::iterator End;
+ SmallVector<unsigned, 4> OrigRegs;
+ if (LIS) {
+ Begin = MachineBasicBlock::iterator(NewMIs[0]);
+ if (Begin != MBB->begin())
+ --Begin;
+ End = next(MachineBasicBlock::iterator(MI));
+
+ for (MachineInstr::const_mop_iterator MOI = MI.operands_begin(),
+ MOE = MI.operands_end(); MOI != MOE; ++MOI) {
+ if (MOI->isReg())
+ OrigRegs.push_back(MOI->getReg());
+ }
+ }
+
MI.eraseFromParent();
+
+ // Update LiveIntervals.
+ if (LIS)
+ LIS->repairIntervalsInRange(MBB, Begin, End, OrigRegs);
+
mi = NewMIs[1];
if (TransformSuccess)
return true;
@@ -1223,6 +1245,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
bool RemovedKillFlag = false;
bool AllUsesCopied = true;
unsigned LastCopiedReg = 0;
+ SlotIndex LastCopyIdx;
unsigned RegB = 0;
for (unsigned tpi = 0, tpe = TiedPairs.size(); tpi != tpe; ++tpi) {
unsigned SrcIdx = TiedPairs[tpi].first;
@@ -1267,9 +1290,17 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
DistanceMap.insert(std::make_pair(PrevMI, Dist));
DistanceMap[MI] = ++Dist;
- SlotIndex CopyIdx;
- if (Indexes)
- CopyIdx = Indexes->insertMachineInstrInMaps(PrevMI).getRegSlot();
+ if (LIS) {
+ LastCopyIdx = LIS->InsertMachineInstrInMaps(PrevMI).getRegSlot();
+
+ if (TargetRegisterInfo::isVirtualRegister(RegA)) {
+ LiveInterval &LI = LIS->getInterval(RegA);
+ VNInfo *VNI = LI.getNextValue(LastCopyIdx, LIS->getVNInfoAllocator());
+ SlotIndex endIdx =
+ LIS->getInstructionIndex(MI).getRegSlot(IsEarlyClobber);
+ LI.addRange(LiveRange(LastCopyIdx, endIdx, VNI));
+ }
+ }
DEBUG(dbgs() << "\t\tprepend:\t" << *PrevMI);
@@ -1315,6 +1346,18 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
LV->addVirtualRegisterKilled(RegB, PrevMI);
}
+ // Update LiveIntervals.
+ if (LIS) {
+ LiveInterval &LI = LIS->getInterval(RegB);
+ SlotIndex MIIdx = LIS->getInstructionIndex(MI);
+ LiveInterval::const_iterator I = LI.find(MIIdx);
+ assert(I != LI.end() && "RegB must be live-in to use.");
+
+ SlotIndex UseIdx = MIIdx.getRegSlot(IsEarlyClobber);
+ if (I->end == UseIdx)
+ LI.removeRange(LastCopyIdx, UseIdx);
+ }
+
} else if (RemovedKillFlag) {
// Some tied uses of regB matched their destination registers, so
// regB is still used in this instruction, but a kill flag was
@@ -1469,6 +1512,13 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) {
llvm_unreachable(0);
}
+ SmallVector<unsigned, 4> OrigRegs;
+ if (LIS) {
+ OrigRegs.push_back(MI->getOperand(0).getReg());
+ for (unsigned i = 1, e = MI->getNumOperands(); i < e; i += 2)
+ OrigRegs.push_back(MI->getOperand(i).getReg());
+ }
+
bool DefEmitted = false;
for (unsigned i = 1, e = MI->getNumOperands(); i < e; i += 2) {
MachineOperand &UseMO = MI->getOperand(i);
@@ -1512,6 +1562,8 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) {
DEBUG(dbgs() << "Inserted: " << *CopyMI);
}
+ MachineBasicBlock::iterator EndMBBI = next(MachineBasicBlock::iterator(MI));
+
if (!DefEmitted) {
DEBUG(dbgs() << "Turned: " << *MI << " into an IMPLICIT_DEF");
MI->setDesc(TII->get(TargetOpcode::IMPLICIT_DEF));
@@ -1521,4 +1573,11 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) {
DEBUG(dbgs() << "Eliminated: " << *MI);
MI->eraseFromParent();
}
+
+ // Udpate LiveIntervals.
+ if (LIS) {
+ if (MBBI != MBB->begin())
+ --MBBI;
+ LIS->repairIntervalsInRange(MBB, MBBI, EndMBBI, OrigRegs);
+ }
}