summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp35
-rw-r--r--lib/CodeGen/BranchFolding.cpp20
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp137
-rw-r--r--lib/CodeGen/MachineVerifier.cpp177
-rw-r--r--lib/CodeGen/PHIElimination.cpp34
-rw-r--r--lib/CodeGen/PHIElimination.h3
-rw-r--r--lib/CodeGen/RegAllocLinearScan.cpp21
-rw-r--r--lib/CodeGen/Spiller.cpp287
-rw-r--r--lib/CodeGen/Spiller.h12
-rw-r--r--lib/CodeGen/TwoAddressInstructionPass.cpp17
-rw-r--r--lib/CodeGen/VirtRegRewriter.cpp31
11 files changed, 325 insertions, 449 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index 1c8b8f4..fcdcfd3 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -727,7 +727,8 @@ void DwarfException::EmitExceptionTable() {
// somewhere. This predicate should be moved to a shared location that is
// in target-independent code.
//
- if (LSDASection->getKind().isWriteable() ||
+ if ((LSDASection->getKind().isWriteable() &&
+ !LSDASection->getKind().isReadOnlyWithRel()) ||
Asm->TM.getRelocationModel() == Reloc::Static)
TTypeFormat = dwarf::DW_EH_PE_absptr;
else
@@ -917,14 +918,36 @@ void DwarfException::EmitExceptionTable() {
}
// Emit the Catch TypeInfos.
+ const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
+ unsigned Index = 1;
+
for (std::vector<GlobalVariable *>::const_reverse_iterator
I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
- const GlobalVariable *GV = *I;
- PrintRelDirective();
-
- if (GV) {
- O << Asm->Mang->getMangledName(GV);
+ const GlobalVariable *TI = *I;
+
+ if (TI) {
+ if (!LSDASection->getKind().isReadOnlyWithRel() &&
+ (TTypeFormat == dwarf::DW_EH_PE_absptr ||
+ TI->getLinkage() == GlobalValue::InternalLinkage)) {
+ // Print out the unadorned name of the type info.
+ PrintRelDirective();
+ O << Asm->Mang->getMangledName(TI);
+ } else {
+ bool IsTypeInfoIndirect = false, IsTypeInfoPCRel = false;
+ const MCExpr *TypeInfoRef =
+ TLOF.getSymbolForDwarfGlobalReference(TI, Asm->Mang, Asm->MMI,
+ IsTypeInfoIndirect,
+ IsTypeInfoPCRel);
+
+ if (!IsTypeInfoPCRel)
+ TypeInfoRef = CreateLabelDiff(TypeInfoRef, "typeinforef_addr",
+ Index++);
+
+ O << MAI->getData32bitsDirective();
+ TypeInfoRef->print(O, MAI);
+ }
} else {
+ PrintRelDirective();
O << "0x0";
}
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index 94bfb72..f807e8f 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -41,8 +41,12 @@ using namespace llvm;
STATISTIC(NumDeadBlocks, "Number of dead blocks removed");
STATISTIC(NumBranchOpts, "Number of branches optimized");
STATISTIC(NumTailMerge , "Number of block tails merged");
+STATISTIC(NumTailDups , "Number of tail duplicated blocks");
+STATISTIC(NumInstrDups , "Additional instructions due to tail duplication");
+
static cl::opt<cl::boolOrDefault> FlagEnableTailMerge("enable-tail-merge",
cl::init(cl::BOU_UNSET), cl::Hidden);
+
// Throttle for huge numbers of predecessors (compile speed problems)
static cl::opt<unsigned>
TailMergeThreshold("tail-merge-threshold",
@@ -193,7 +197,6 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF,
MadeChange |= OptimizeImpDefsBlock(MBB);
}
-
bool MadeChangeThisIteration = true;
while (MadeChangeThisIteration) {
MadeChangeThisIteration = false;
@@ -202,10 +205,15 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF,
MadeChange |= MadeChangeThisIteration;
}
- // Do tail duplication once after tail merging is done. Otherwise it is
+ // Do tail duplication after tail merging is done. Otherwise it is
// tough to avoid situations where tail duplication and tail merging undo
// each other's transformations ad infinitum.
- MadeChange |= TailDuplicateBlocks(MF);
+ MadeChangeThisIteration = true;
+ while (MadeChangeThisIteration) {
+ MadeChangeThisIteration = false;
+ MadeChangeThisIteration |= TailDuplicateBlocks(MF);
+ MadeChange |= MadeChangeThisIteration;
+ }
// See if any jump tables have become mergable or dead as the code generator
// did its thing.
@@ -1003,9 +1011,6 @@ static bool IsBetterFallthrough(MachineBasicBlock *MBB1,
bool BranchFolder::TailDuplicateBlocks(MachineFunction &MF) {
bool MadeChange = false;
- // Make sure blocks are numbered in order
- MF.RenumberBlocks();
-
for (MachineFunction::iterator I = ++MF.begin(), E = MF.end(); I != E; ) {
MachineBasicBlock *MBB = I++;
@@ -1017,6 +1022,7 @@ bool BranchFolder::TailDuplicateBlocks(MachineFunction &MF) {
// If it is dead, remove it.
if (MBB->pred_empty()) {
+ NumInstrDups -= MBB->size();
RemoveDeadBlock(MBB);
MadeChange = true;
++NumDeadBlocks;
@@ -1097,6 +1103,7 @@ bool BranchFolder::TailDuplicate(MachineBasicBlock *TailBB,
MachineInstr *NewMI = MF.CloneMachineInstr(I);
PredBB->insert(PredBB->end(), NewMI);
}
+ NumInstrDups += TailBB->size() - 1; // subtract one for removed branch
// Update the CFG.
PredBB->removeSuccessor(PredBB->succ_begin());
@@ -1107,6 +1114,7 @@ bool BranchFolder::TailDuplicate(MachineBasicBlock *TailBB,
PredBB->addSuccessor(*I);
Changed = true;
+ ++NumTailDups;
}
// If TailBB was duplicated into all its predecessors except for the prior
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index a60d34f..bbfc82b 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -53,16 +53,9 @@ static cl::opt<bool> DisableReMat("disable-rematerialization",
static cl::opt<bool> EnableFastSpilling("fast-spill",
cl::init(false), cl::Hidden);
-static cl::opt<bool> EarlyCoalescing("early-coalescing",
- cl::init(false), cl::Hidden);
-
-static cl::opt<int> CoalescingLimit("early-coalescing-limit",
- cl::init(-1), cl::Hidden);
-
STATISTIC(numIntervals , "Number of original intervals");
STATISTIC(numFolds , "Number of loads/stores folded into instructions");
STATISTIC(numSplits , "Number of intervals split");
-STATISTIC(numCoalescing, "Number of early coalescing performed");
char LiveIntervals::ID = 0;
static RegisterPass<LiveIntervals> X("liveintervals", "Live Interval Analysis");
@@ -96,7 +89,6 @@ void LiveIntervals::releaseMemory() {
delete I->second;
r2iMap_.clear();
- phiJoinCopies.clear();
// Release VNInfo memroy regions after all VNInfo objects are dtor'd.
VNInfoAllocator.Reset();
@@ -121,7 +113,6 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
allocatableRegs_ = tri_->getAllocatableSet(fn);
computeIntervals();
- performEarlyCoalescing();
numIntervals += getNumIntervals();
@@ -409,7 +400,6 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
// Remove the old range that we now know has an incorrect number.
VNInfo *VNI = interval.getValNumInfo(0);
MachineInstr *Killer = vi.Kills[0];
- phiJoinCopies.push_back(Killer);
SlotIndex Start = getMBBStartIdx(Killer->getParent());
SlotIndex End = getInstructionIndex(Killer).getDefIndex();
DEBUG({
@@ -653,133 +643,6 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
DEBUG(errs() << " +" << LR << '\n');
}
-bool LiveIntervals::
-isSafeAndProfitableToCoalesce(LiveInterval &DstInt,
- LiveInterval &SrcInt,
- SmallVector<MachineInstr*,16> &IdentCopies,
- SmallVector<MachineInstr*,16> &OtherCopies) {
- unsigned NumIdent = 0;
- for (MachineRegisterInfo::def_iterator ri = mri_->def_begin(SrcInt.reg),
- re = mri_->def_end(); ri != re; ++ri) {
- MachineInstr *MI = &*ri;
- unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
- if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
- return false;
- if (SrcReg != DstInt.reg) {
- // Non-identity copy - we cannot handle overlapping intervals
- if (DstInt.liveAt(getInstructionIndex(MI)))
- return false;
- OtherCopies.push_back(MI);
- } else {
- IdentCopies.push_back(MI);
- ++NumIdent;
- }
- }
-
- return IdentCopies.size() > OtherCopies.size();
-}
-
-void LiveIntervals::performEarlyCoalescing() {
- if (!EarlyCoalescing)
- return;
-
- /// Perform early coalescing: eliminate copies which feed into phi joins
- /// and whose sources are defined by the phi joins.
- for (unsigned i = 0, e = phiJoinCopies.size(); i != e; ++i) {
- MachineInstr *Join = phiJoinCopies[i];
- if (CoalescingLimit != -1 && (int)numCoalescing == CoalescingLimit)
- break;
-
- unsigned PHISrc, PHIDst, SrcSubReg, DstSubReg;
- bool isMove= tii_->isMoveInstr(*Join, PHISrc, PHIDst, SrcSubReg, DstSubReg);
-#ifndef NDEBUG
- assert(isMove && "PHI join instruction must be a move!");
-#else
- isMove = isMove;
-#endif
-
- LiveInterval &DstInt = getInterval(PHIDst);
- LiveInterval &SrcInt = getInterval(PHISrc);
- SmallVector<MachineInstr*, 16> IdentCopies;
- SmallVector<MachineInstr*, 16> OtherCopies;
- if (!isSafeAndProfitableToCoalesce(DstInt, SrcInt,
- IdentCopies, OtherCopies))
- continue;
-
- DEBUG(errs() << "PHI Join: " << *Join);
- assert(DstInt.containsOneValue() && "PHI join should have just one val#!");
- assert(std::distance(mri_->use_begin(PHISrc), mri_->use_end()) == 1 &&
- "PHI join src should not be used elsewhere");
- VNInfo *VNI = DstInt.getValNumInfo(0);
-
- // Change the non-identity copies to directly target the phi destination.
- for (unsigned i = 0, e = OtherCopies.size(); i != e; ++i) {
- MachineInstr *PHICopy = OtherCopies[i];
- SlotIndex MIIndex = getInstructionIndex(PHICopy);
- DEBUG(errs() << "Moving: " << MIIndex << ' ' << *PHICopy);
- SlotIndex DefIndex = MIIndex.getDefIndex();
- LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex);
- SlotIndex StartIndex = SLR->start;
- SlotIndex EndIndex = SLR->end;
-
- // Delete val# defined by the now identity copy and add the range from
- // beginning of the mbb to the end of the range.
- SrcInt.removeValNo(SLR->valno);
- DEBUG(errs() << " added range [" << StartIndex << ','
- << EndIndex << "] to reg" << DstInt.reg << '\n');
- assert (!DstInt.liveAt(StartIndex) && "Cannot coalesce when dst live!");
- VNInfo *NewVNI = DstInt.getNextValue(DefIndex, PHICopy, true,
- VNInfoAllocator);
- NewVNI->setHasPHIKill(true);
- DstInt.addRange(LiveRange(StartIndex, EndIndex, NewVNI));
- for (unsigned j = 0, ee = PHICopy->getNumOperands(); j != ee; ++j) {
- MachineOperand &MO = PHICopy->getOperand(j);
- if (!MO.isReg() || MO.getReg() != PHISrc)
- continue;
- MO.setReg(PHIDst);
- }
- }
-
- // Now let's eliminate all the would-be identity copies.
- for (unsigned i = 0, e = IdentCopies.size(); i != e; ++i) {
- MachineInstr *PHICopy = IdentCopies[i];
- DEBUG(errs() << "Coalescing: " << *PHICopy);
-
- SlotIndex MIIndex = getInstructionIndex(PHICopy);
- SlotIndex DefIndex = MIIndex.getDefIndex();
- LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex);
- SlotIndex StartIndex = SLR->start;
- SlotIndex EndIndex = SLR->end;
-
- // Delete val# defined by the now identity copy and add the range from
- // beginning of the mbb to the end of the range.
- SrcInt.removeValNo(SLR->valno);
- RemoveMachineInstrFromMaps(PHICopy);
- PHICopy->eraseFromParent();
- DEBUG(errs() << " added range [" << StartIndex << ','
- << EndIndex << "] to reg" << DstInt.reg << '\n');
- DstInt.addRange(LiveRange(StartIndex, EndIndex, VNI));
- }
-
- // Remove the phi join and update the phi block liveness.
- SlotIndex MIIndex = getInstructionIndex(Join);
- SlotIndex UseIndex = MIIndex.getUseIndex();
- SlotIndex DefIndex = MIIndex.getDefIndex();
- LiveRange *SLR = SrcInt.getLiveRangeContaining(UseIndex);
- LiveRange *DLR = DstInt.getLiveRangeContaining(DefIndex);
- DLR->valno->setCopy(0);
- DLR->valno->setIsDefAccurate(false);
- DstInt.addRange(LiveRange(SLR->start, SLR->end, DLR->valno));
- SrcInt.removeRange(SLR->start, SLR->end);
- assert(SrcInt.empty());
- removeInterval(PHISrc);
- RemoveMachineInstrFromMaps(Join);
- Join->eraseFromParent();
-
- ++numCoalescing;
- }
-}
-
/// computeIntervals - computes the live intervals for virtual
/// registers. for some ordering of the machine instructions [1,N] a
/// live interval is an interval [i, j) where 1 <= i <= j < N for
diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp
index be9f68f..a1c74c0 100644
--- a/lib/CodeGen/MachineVerifier.cpp
+++ b/lib/CodeGen/MachineVerifier.cpp
@@ -42,23 +42,18 @@
using namespace llvm;
namespace {
- struct MachineVerifier : public MachineFunctionPass {
- static char ID; // Pass ID, replacement for typeid
+ struct MachineVerifier {
- MachineVerifier(bool allowDoubleDefs = false) :
- MachineFunctionPass(&ID),
+ MachineVerifier(Pass *pass, bool allowDoubleDefs) :
+ PASS(pass),
allowVirtDoubleDefs(allowDoubleDefs),
allowPhysDoubleDefs(allowDoubleDefs),
OutFileName(getenv("LLVM_VERIFY_MACHINEINSTRS"))
- {}
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
+ {}
bool runOnMachineFunction(MachineFunction &MF);
+ Pass *const PASS;
const bool allowVirtDoubleDefs;
const bool allowPhysDoubleDefs;
@@ -112,6 +107,10 @@ namespace {
// regsKilled and regsLiveOut.
RegSet vregsPassed;
+ // Vregs that must pass through MBB because they are needed by a successor
+ // block. This set is disjoint from regsLiveOut.
+ RegSet vregsRequired;
+
BBInfo() : reachable(false) {}
// Add register to vregsPassed if it belongs there. Return true if
@@ -133,6 +132,34 @@ namespace {
return changed;
}
+ // Add register to vregsRequired if it belongs there. Return true if
+ // anything changed.
+ bool addRequired(unsigned Reg) {
+ if (!TargetRegisterInfo::isVirtualRegister(Reg))
+ return false;
+ if (regsLiveOut.count(Reg))
+ return false;
+ return vregsRequired.insert(Reg).second;
+ }
+
+ // Same for a full set.
+ bool addRequired(const RegSet &RS) {
+ bool changed = false;
+ for (RegSet::const_iterator I = RS.begin(), E = RS.end(); I != E; ++I)
+ if (addRequired(*I))
+ changed = true;
+ return changed;
+ }
+
+ // Same for a full map.
+ bool addRequired(const RegMap &RM) {
+ bool changed = false;
+ for (RegMap::const_iterator I = RM.begin(), E = RM.end(); I != E; ++I)
+ if (addRequired(I->first))
+ changed = true;
+ return changed;
+ }
+
// Live-out registers are either in regsLiveOut or vregsPassed.
bool isLiveOut(unsigned Reg) const {
return regsLiveOut.count(Reg) || vregsPassed.count(Reg);
@@ -146,6 +173,9 @@ namespace {
return Reg < regsReserved.size() && regsReserved.test(Reg);
}
+ // Analysis information if available
+ LiveVariables *LiveVars;
+
void visitMachineFunctionBefore();
void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB);
void visitMachineInstrBefore(const MachineInstr *MI);
@@ -163,20 +193,44 @@ namespace {
void calcMaxRegsPassed();
void calcMinRegsPassed();
void checkPHIOps(const MachineBasicBlock *MBB);
+
+ void calcRegsRequired();
+ void verifyLiveVariables();
+ };
+
+ struct MachineVerifierPass : public MachineFunctionPass {
+ static char ID; // Pass ID, replacement for typeid
+ bool AllowDoubleDefs;
+
+ explicit MachineVerifierPass(bool allowDoubleDefs = false)
+ : MachineFunctionPass(&ID),
+ AllowDoubleDefs(allowDoubleDefs) {}
+
+ void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) {
+ MF.verify(this, AllowDoubleDefs);
+ return false;
+ }
};
+
}
-char MachineVerifier::ID = 0;
-static RegisterPass<MachineVerifier>
+char MachineVerifierPass::ID = 0;
+static RegisterPass<MachineVerifierPass>
MachineVer("machineverifier", "Verify generated machine code");
static const PassInfo *const MachineVerifyID = &MachineVer;
FunctionPass *llvm::createMachineVerifierPass(bool allowPhysDoubleDefs) {
- return new MachineVerifier(allowPhysDoubleDefs);
+ return new MachineVerifierPass(allowPhysDoubleDefs);
}
-void MachineFunction::verify() const {
- MachineVerifier().runOnMachineFunction(const_cast<MachineFunction&>(*this));
+void MachineFunction::verify(Pass *p, bool allowDoubleDefs) const {
+ MachineVerifier(p, allowDoubleDefs)
+ .runOnMachineFunction(const_cast<MachineFunction&>(*this));
}
bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
@@ -202,6 +256,12 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
TRI = TM->getRegisterInfo();
MRI = &MF.getRegInfo();
+ if (PASS) {
+ LiveVars = PASS->getAnalysisIfAvailable<LiveVariables>();
+ } else {
+ LiveVars = NULL;
+ }
+
visitMachineFunctionBefore();
for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end();
MFI!=MFE; ++MFI) {
@@ -518,8 +578,9 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
} else if (MO->isUse()) {
regsLiveInButUnused.erase(Reg);
+ bool isKill = false;
if (MO->isKill()) {
- addRegWithSubRegs(regsKilled, Reg);
+ isKill = true;
// Tied operands on two-address instuctions MUST NOT have a <kill> flag.
if (MI->isRegTiedToDefOperand(MONum))
report("Illegal kill flag on two-address instruction operand",
@@ -529,8 +590,20 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
unsigned defIdx;
if (MI->isRegTiedToDefOperand(MONum, &defIdx) &&
MI->getOperand(defIdx).getReg() == Reg)
- addRegWithSubRegs(regsKilled, Reg);
+ isKill = true;
+ }
+ if (isKill) {
+ addRegWithSubRegs(regsKilled, Reg);
+
+ // Check that LiveVars knows this kill
+ if (LiveVars && TargetRegisterInfo::isVirtualRegister(Reg)) {
+ LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg);
+ if (std::find(VI.Kills.begin(),
+ VI.Kills.end(), MI) == VI.Kills.end())
+ report("Kill missing from LiveVariables", MO, MONum);
+ }
}
+
// Use of a dead register.
if (!regsLive.count(Reg)) {
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
@@ -734,6 +807,41 @@ void MachineVerifier::calcMinRegsPassed() {
}
}
+// Calculate the set of virtual registers that must be passed through each basic
+// block in order to satisfy the requirements of successor blocks. This is very
+// similar to calcMaxRegsPassed, only backwards.
+void MachineVerifier::calcRegsRequired() {
+ // First push live-in regs to predecessors' vregsRequired.
+ DenseSet<const MachineBasicBlock*> todo;
+ for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end();
+ MFI != MFE; ++MFI) {
+ const MachineBasicBlock &MBB(*MFI);
+ BBInfo &MInfo = MBBInfoMap[&MBB];
+ for (MachineBasicBlock::const_pred_iterator PrI = MBB.pred_begin(),
+ PrE = MBB.pred_end(); PrI != PrE; ++PrI) {
+ BBInfo &PInfo = MBBInfoMap[*PrI];
+ if (PInfo.addRequired(MInfo.vregsLiveIn))
+ todo.insert(*PrI);
+ }
+ }
+
+ // Iteratively push vregsRequired to predecessors. This will converge to the
+ // same final state regardless of DenseSet iteration order.
+ while (!todo.empty()) {
+ const MachineBasicBlock *MBB = *todo.begin();
+ todo.erase(MBB);
+ BBInfo &MInfo = MBBInfoMap[MBB];
+ for (MachineBasicBlock::const_pred_iterator PrI = MBB->pred_begin(),
+ PrE = MBB->pred_end(); PrI != PrE; ++PrI) {
+ if (*PrI == MBB)
+ continue;
+ BBInfo &SInfo = MBBInfoMap[*PrI];
+ if (SInfo.addRequired(MInfo.vregsRequired))
+ todo.insert(*PrI);
+ }
+ }
+}
+
// Check PHI instructions at the beginning of MBB. It is assumed that
// calcMinRegsPassed has been run so BBInfo::isLiveOut is valid.
void MachineVerifier::checkPHIOps(const MachineBasicBlock *MBB) {
@@ -849,4 +957,39 @@ void MachineVerifier::visitMachineFunctionAfter() {
}
}
}
+
+ // Now check LiveVariables info if available
+ if (LiveVars) {
+ calcRegsRequired();
+ verifyLiveVariables();
+ }
}
+
+void MachineVerifier::verifyLiveVariables() {
+ assert(LiveVars && "Don't call verifyLiveVariables without LiveVars");
+ for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister,
+ RegE = MRI->getLastVirtReg()-1; Reg != RegE; ++Reg) {
+ LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg);
+ for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end();
+ MFI != MFE; ++MFI) {
+ BBInfo &MInfo = MBBInfoMap[MFI];
+
+ // Our vregsRequired should be identical to LiveVariables' AliveBlocks
+ if (MInfo.vregsRequired.count(Reg)) {
+ if (!VI.AliveBlocks.test(MFI->getNumber())) {
+ report("LiveVariables: Block missing from AliveBlocks", MFI);
+ *OS << "Virtual register %reg" << Reg
+ << " must be live through the block.\n";
+ }
+ } else {
+ if (VI.AliveBlocks.test(MFI->getNumber())) {
+ report("LiveVariables: Block should not be in AliveBlocks", MFI);
+ *OS << "Virtual register %reg" << Reg
+ << " is not needed live through the block.\n";
+ }
+ }
+ }
+ }
+}
+
+
diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp
index cd38dd1..b3802ed 100644
--- a/lib/CodeGen/PHIElimination.cpp
+++ b/lib/CodeGen/PHIElimination.cpp
@@ -21,7 +21,6 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/Function.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -37,37 +36,17 @@ using namespace llvm;
STATISTIC(NumAtomic, "Number of atomic phis lowered");
STATISTIC(NumSplits, "Number of critical edges split on demand");
-static cl::opt<bool>
-SplitEdges("split-phi-edges",
- cl::desc("Split critical edges during phi elimination"),
- cl::init(false), cl::Hidden);
-
char PHIElimination::ID = 0;
static RegisterPass<PHIElimination>
X("phi-node-elimination", "Eliminate PHI nodes for register allocation");
const PassInfo *const llvm::PHIEliminationID = &X;
-namespace llvm { FunctionPass *createLocalRegisterAllocator(); }
-
-// Should we run edge splitting?
-static bool shouldSplitEdges() {
- // Edge splitting breaks the local register allocator. It cannot tolerate
- // LiveVariables being run.
- if (RegisterRegAlloc::getDefault() == createLocalRegisterAllocator)
- return false;
- return SplitEdges;
-}
-
void llvm::PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addPreserved<LiveVariables>();
AU.addPreserved<MachineDominatorTree>();
- if (shouldSplitEdges()) {
- AU.addRequired<LiveVariables>();
- } else {
- AU.setPreservesCFG();
- AU.addPreservedID(MachineLoopInfoID);
- }
+ // rdar://7401784 This would be nice:
+ // AU.addPreservedID(MachineLoopInfoID);
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -79,9 +58,9 @@ bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &Fn) {
bool Changed = false;
// Split critical edges to help the coalescer
- if (shouldSplitEdges())
+ if (LiveVariables *LV = getAnalysisIfAvailable<LiveVariables>())
for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
- Changed |= SplitPHIEdges(Fn, *I);
+ Changed |= SplitPHIEdges(Fn, *I, *LV);
// Populate VRegPHIUseCount
analyzePHINodes(Fn);
@@ -361,10 +340,11 @@ void llvm::PHIElimination::analyzePHINodes(const MachineFunction& Fn) {
}
bool llvm::PHIElimination::SplitPHIEdges(MachineFunction &MF,
- MachineBasicBlock &MBB) {
+ MachineBasicBlock &MBB,
+ LiveVariables &LV) {
if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI)
return false; // Quick exit for basic blocks without PHIs.
- LiveVariables &LV = getAnalysis<LiveVariables>();
+
for (MachineBasicBlock::const_iterator BBI = MBB.begin(), BBE = MBB.end();
BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI) {
for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) {
diff --git a/lib/CodeGen/PHIElimination.h b/lib/CodeGen/PHIElimination.h
index 94716ee..f8c9fe7 100644
--- a/lib/CodeGen/PHIElimination.h
+++ b/lib/CodeGen/PHIElimination.h
@@ -90,7 +90,8 @@ namespace llvm {
void analyzePHINodes(const MachineFunction& Fn);
/// Split critical edges where necessary for good coalescer performance.
- bool SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB);
+ bool SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB,
+ LiveVariables &LV);
/// isLiveOut - Determine if Reg is live out from MBB, when not
/// considering PHI nodes. This means that Reg is either killed by
diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp
index 6930abf..fff50da 100644
--- a/lib/CodeGen/RegAllocLinearScan.cpp
+++ b/lib/CodeGen/RegAllocLinearScan.cpp
@@ -59,11 +59,6 @@ PreSplitIntervals("pre-alloc-split",
cl::desc("Pre-register allocation live interval splitting"),
cl::init(false), cl::Hidden);
-static cl::opt<bool>
-NewSpillFramework("new-spill-framework",
- cl::desc("New spilling framework"),
- cl::init(false), cl::Hidden);
-
static RegisterRegAlloc
linearscanRegAlloc("linearscan", "linear scan register allocator",
createLinearScanRegisterAllocator);
@@ -441,9 +436,7 @@ bool RALinScan::runOnMachineFunction(MachineFunction &fn) {
vrm_ = &getAnalysis<VirtRegMap>();
if (!rewriter_.get()) rewriter_.reset(createVirtRegRewriter());
- if (NewSpillFramework) {
- spiller_.reset(createSpiller(mf_, li_, ls_, vrm_));
- }
+ spiller_.reset(createSpiller(mf_, li_, ls_, loopInfo, vrm_));
initIntervalSets();
@@ -1157,11 +1150,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) {
SmallVector<LiveInterval*, 8> spillIs;
std::vector<LiveInterval*> added;
- if (!NewSpillFramework) {
- added = li_->addIntervalsForSpills(*cur, spillIs, loopInfo, *vrm_);
- } else {
- added = spiller_->spill(cur);
- }
+ added = spiller_->spill(cur, spillIs);
std::sort(added.begin(), added.end(), LISorter());
addStackInterval(cur, ls_, li_, mri_, *vrm_);
@@ -1241,11 +1230,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) {
earliestStartInterval : sli;
std::vector<LiveInterval*> newIs;
- if (!NewSpillFramework) {
- newIs = li_->addIntervalsForSpills(*sli, spillIs, loopInfo, *vrm_);
- } else {
- newIs = spiller_->spill(sli);
- }
+ newIs = spiller_->spill(sli, spillIs);
addStackInterval(sli, ls_, li_, mri_, *vrm_);
std::copy(newIs.begin(), newIs.end(), std::back_inserter(added));
spilled.insert(sli->reg);
diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp
index 9107325..20c4a28 100644
--- a/lib/CodeGen/Spiller.cpp
+++ b/lib/CodeGen/Spiller.cpp
@@ -18,11 +18,25 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+namespace {
+ enum SpillerName { trivial, standard };
+}
+
+static cl::opt<SpillerName>
+spillerOpt("spiller",
+ cl::desc("Spiller to use: (default: standard)"),
+ cl::Prefix,
+ cl::values(clEnumVal(trivial, "trivial spiller"),
+ clEnumVal(standard, "default spiller"),
+ clEnumValEnd),
+ cl::init(standard));
+
Spiller::~Spiller() {}
namespace {
@@ -49,153 +63,9 @@ protected:
tii = mf->getTarget().getInstrInfo();
}
- /// Ensures there is space before the given machine instruction, returns the
- /// instruction's new number.
- SlotIndex makeSpaceBefore(MachineInstr *mi) {
- //if (!lis->hasGapBeforeInstr(lis->getInstructionIndex(mi))) {
- // FIXME: Should be updated to use rewrite-in-place methods when they're
- // introduced. Currently broken.
- //lis->scaleNumbering(2);
- //ls->scaleNumbering(2);
- //}
-
- SlotIndex miIdx = lis->getInstructionIndex(mi);
-
- //assert(lis->hasGapBeforeInstr(miIdx));
-
- return miIdx;
- }
-
- /// Ensure there is space after the given machine instruction, returns the
- /// instruction's new number.
- SlotIndex makeSpaceAfter(MachineInstr *mi) {
- //if (!lis->hasGapAfterInstr(lis->getInstructionIndex(mi))) {
- // FIXME: Should be updated to use rewrite-in-place methods when they're
- // introduced. Currently broken.
- // lis->scaleNumbering(2);
- // ls->scaleNumbering(2);
- //}
-
- SlotIndex miIdx = lis->getInstructionIndex(mi);
-
- //assert(lis->hasGapAfterInstr(miIdx));
-
- return miIdx;
- }
-
- /// Insert a store of the given vreg to the given stack slot immediately
- /// after the given instruction. Returns the base index of the inserted
- /// instruction. The caller is responsible for adding an appropriate
- /// LiveInterval to the LiveIntervals analysis.
- SlotIndex insertStoreAfter(MachineInstr *mi, unsigned ss,
- unsigned vreg,
- const TargetRegisterClass *trc) {
-
- MachineBasicBlock::iterator nextInstItr(next(mi));
-
- SlotIndex miIdx = makeSpaceAfter(mi);
-
- tii->storeRegToStackSlot(*mi->getParent(), nextInstItr, vreg,
- true, ss, trc);
- MachineBasicBlock::iterator storeInstItr(next(mi));
- MachineInstr *storeInst = &*storeInstItr;
-
- return lis->InsertMachineInstrInMaps(storeInst);
- }
-
- /// Insert a store of the given vreg to the given stack slot immediately
- /// before the given instructnion. Returns the base index of the inserted
- /// Instruction.
- SlotIndex insertStoreBefore(MachineInstr *mi, unsigned ss,
- unsigned vreg,
- const TargetRegisterClass *trc) {
- SlotIndex miIdx = makeSpaceBefore(mi);
-
- tii->storeRegToStackSlot(*mi->getParent(), mi, vreg, true, ss, trc);
- MachineBasicBlock::iterator storeInstItr(prior(mi));
- MachineInstr *storeInst = &*storeInstItr;
-
- return lis->InsertMachineInstrInMaps(storeInst);
- }
-
- void insertStoreAfterInstOnInterval(LiveInterval *li,
- MachineInstr *mi, unsigned ss,
- unsigned vreg,
- const TargetRegisterClass *trc) {
-
- SlotIndex storeInstIdx = insertStoreAfter(mi, ss, vreg, trc);
- SlotIndex start = lis->getInstructionIndex(mi).getDefIndex(),
- end = storeInstIdx.getUseIndex();
-
- VNInfo *vni =
- li->getNextValue(storeInstIdx, 0, true, lis->getVNInfoAllocator());
- vni->addKill(storeInstIdx);
- DEBUG(errs() << " Inserting store range: [" << start
- << ", " << end << ")\n");
- LiveRange lr(start, end, vni);
-
- li->addRange(lr);
- }
-
- /// Insert a load of the given vreg from the given stack slot immediately
- /// after the given instruction. Returns the base index of the inserted
- /// instruction. The caller is responsibel for adding/removing an appropriate
- /// range vreg's LiveInterval.
- SlotIndex insertLoadAfter(MachineInstr *mi, unsigned ss,
- unsigned vreg,
- const TargetRegisterClass *trc) {
-
- MachineBasicBlock::iterator nextInstItr(next(mi));
-
- SlotIndex miIdx = makeSpaceAfter(mi);
-
- tii->loadRegFromStackSlot(*mi->getParent(), nextInstItr, vreg, ss, trc);
- MachineBasicBlock::iterator loadInstItr(next(mi));
- MachineInstr *loadInst = &*loadInstItr;
-
- return lis->InsertMachineInstrInMaps(loadInst);
- }
-
- /// Insert a load of the given vreg from the given stack slot immediately
- /// before the given instruction. Returns the base index of the inserted
- /// instruction. The caller is responsible for adding an appropriate
- /// LiveInterval to the LiveIntervals analysis.
- SlotIndex insertLoadBefore(MachineInstr *mi, unsigned ss,
- unsigned vreg,
- const TargetRegisterClass *trc) {
- SlotIndex miIdx = makeSpaceBefore(mi);
-
- tii->loadRegFromStackSlot(*mi->getParent(), mi, vreg, ss, trc);
- MachineBasicBlock::iterator loadInstItr(prior(mi));
- MachineInstr *loadInst = &*loadInstItr;
-
- return lis->InsertMachineInstrInMaps(loadInst);
- }
-
- void insertLoadBeforeInstOnInterval(LiveInterval *li,
- MachineInstr *mi, unsigned ss,
- unsigned vreg,
- const TargetRegisterClass *trc) {
-
- SlotIndex loadInstIdx = insertLoadBefore(mi, ss, vreg, trc);
- SlotIndex start = loadInstIdx.getDefIndex(),
- end = lis->getInstructionIndex(mi).getUseIndex();
-
- VNInfo *vni =
- li->getNextValue(loadInstIdx, 0, true, lis->getVNInfoAllocator());
- vni->addKill(lis->getInstructionIndex(mi));
- DEBUG(errs() << " Intserting load range: [" << start
- << ", " << end << ")\n");
- LiveRange lr(start, end, vni);
-
- li->addRange(lr);
- }
-
-
-
/// Add spill ranges for every use/def of the live interval, inserting loads
- /// immediately before each use, and stores after each def. No folding is
- /// attempted.
+ /// immediately before each use, and stores after each def. No folding or
+ /// remat is attempted.
std::vector<LiveInterval*> trivialSpillEverywhere(LiveInterval *li) {
DEBUG(errs() << "Spilling everywhere " << *li << "\n");
@@ -212,56 +82,77 @@ protected:
const TargetRegisterClass *trc = mri->getRegClass(li->reg);
unsigned ss = vrm->assignVirt2StackSlot(li->reg);
+ // Iterate over reg uses/defs.
for (MachineRegisterInfo::reg_iterator
regItr = mri->reg_begin(li->reg); regItr != mri->reg_end();) {
+ // Grab the use/def instr.
MachineInstr *mi = &*regItr;
DEBUG(errs() << " Processing " << *mi);
+ // Step regItr to the next use/def instr.
do {
++regItr;
} while (regItr != mri->reg_end() && (&*regItr == mi));
+ // Collect uses & defs for this instr.
SmallVector<unsigned, 2> indices;
bool hasUse = false;
bool hasDef = false;
-
for (unsigned i = 0; i != mi->getNumOperands(); ++i) {
MachineOperand &op = mi->getOperand(i);
-
if (!op.isReg() || op.getReg() != li->reg)
continue;
-
hasUse |= mi->getOperand(i).isUse();
hasDef |= mi->getOperand(i).isDef();
-
indices.push_back(i);
}
+ // Create a new vreg & interval for this instr.
unsigned newVReg = mri->createVirtualRegister(trc);
vrm->grow();
vrm->assignVirt2StackSlot(newVReg, ss);
-
LiveInterval *newLI = &lis->getOrCreateInterval(newVReg);
newLI->weight = HUGE_VALF;
+ // Update the reg operands & kill flags.
for (unsigned i = 0; i < indices.size(); ++i) {
- mi->getOperand(indices[i]).setReg(newVReg);
-
- if (mi->getOperand(indices[i]).isUse()) {
- mi->getOperand(indices[i]).setIsKill(true);
+ unsigned mopIdx = indices[i];
+ MachineOperand &mop = mi->getOperand(mopIdx);
+ mop.setReg(newVReg);
+ if (mop.isUse() && !mi->isRegTiedToDefOperand(mopIdx)) {
+ mop.setIsKill(true);
}
}
-
assert(hasUse || hasDef);
+ // Insert reload if necessary.
+ MachineBasicBlock::iterator miItr(mi);
if (hasUse) {
- insertLoadBeforeInstOnInterval(newLI, mi, ss, newVReg, trc);
+ tii->loadRegFromStackSlot(*mi->getParent(), miItr, newVReg, ss, trc);
+ MachineInstr *loadInstr(prior(miItr));
+ SlotIndex loadIndex =
+ lis->InsertMachineInstrInMaps(loadInstr).getDefIndex();
+ SlotIndex endIndex = loadIndex.getNextIndex();
+ VNInfo *loadVNI =
+ newLI->getNextValue(loadIndex, 0, true, lis->getVNInfoAllocator());
+ loadVNI->addKill(endIndex);
+ newLI->addRange(LiveRange(loadIndex, endIndex, loadVNI));
}
+ // Insert store if necessary.
if (hasDef) {
- insertStoreAfterInstOnInterval(newLI, mi, ss, newVReg, trc);
+ tii->storeRegToStackSlot(*mi->getParent(), next(miItr), newVReg, true,
+ ss, trc);
+ MachineInstr *storeInstr(next(miItr));
+ SlotIndex storeIndex =
+ lis->InsertMachineInstrInMaps(storeInstr).getDefIndex();
+ SlotIndex beginIndex = storeIndex.getPrevIndex();
+ VNInfo *storeVNI =
+ newLI->getNextValue(beginIndex, 0, true, lis->getVNInfoAllocator());
+ storeVNI->addKill(storeIndex);
+ newLI->addRange(LiveRange(beginIndex, storeIndex, storeVNI));
}
added.push_back(newLI);
@@ -279,60 +170,32 @@ class TrivialSpiller : public SpillerBase {
public:
TrivialSpiller(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls,
- VirtRegMap *vrm) :
- SpillerBase(mf, lis, ls, vrm) {}
+ VirtRegMap *vrm)
+ : SpillerBase(mf, lis, ls, vrm) {}
- std::vector<LiveInterval*> spill(LiveInterval *li) {
+ std::vector<LiveInterval*> spill(LiveInterval *li,
+ SmallVectorImpl<LiveInterval*> &spillIs) {
+ // Ignore spillIs - we don't use it.
return trivialSpillEverywhere(li);
}
- std::vector<LiveInterval*> intraBlockSplit(LiveInterval *li, VNInfo *valno) {
- std::vector<LiveInterval*> spillIntervals;
-
- if (!valno->isDefAccurate() && !valno->isPHIDef()) {
- // Early out for values which have no well defined def point.
- return spillIntervals;
- }
-
- // Ok.. we should be able to proceed...
- const TargetRegisterClass *trc = mri->getRegClass(li->reg);
- unsigned ss = vrm->assignVirt2StackSlot(li->reg);
- vrm->grow();
- vrm->assignVirt2StackSlot(li->reg, ss);
-
- MachineInstr *mi = 0;
- SlotIndex storeIdx = SlotIndex();
-
- if (valno->isDefAccurate()) {
- // If we have an accurate def we can just grab an iterator to the instr
- // after the def.
- mi = lis->getInstructionFromIndex(valno->def);
- storeIdx = insertStoreAfter(mi, ss, li->reg, trc).getDefIndex();
- } else {
- // if we get here we have a PHI def.
- mi = &lis->getMBBFromIndex(valno->def)->front();
- storeIdx = insertStoreBefore(mi, ss, li->reg, trc).getDefIndex();
- }
-
- MachineBasicBlock *defBlock = mi->getParent();
- SlotIndex loadIdx = SlotIndex();
-
- // Now we need to find the load...
- MachineBasicBlock::iterator useItr(mi);
- for (; !useItr->readsRegister(li->reg); ++useItr) {}
-
- if (useItr != defBlock->end()) {
- MachineInstr *loadInst = useItr;
- loadIdx = insertLoadBefore(loadInst, ss, li->reg, trc).getUseIndex();
- }
- else {
- MachineInstr *loadInst = &defBlock->back();
- loadIdx = insertLoadAfter(loadInst, ss, li->reg, trc).getUseIndex();
- }
-
- li->removeRange(storeIdx, loadIdx, true);
+};
- return spillIntervals;
+/// Falls back on LiveIntervals::addIntervalsForSpills.
+class StandardSpiller : public Spiller {
+private:
+ LiveIntervals *lis;
+ const MachineLoopInfo *loopInfo;
+ VirtRegMap *vrm;
+public:
+ StandardSpiller(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls,
+ const MachineLoopInfo *loopInfo, VirtRegMap *vrm)
+ : lis(lis), loopInfo(loopInfo), vrm(vrm) {}
+
+ /// Falls back on LiveIntervals::addIntervalsForSpills.
+ std::vector<LiveInterval*> spill(LiveInterval *li,
+ SmallVectorImpl<LiveInterval*> &spillIs) {
+ return lis->addIntervalsForSpills(*li, spillIs, loopInfo, *vrm);
}
};
@@ -340,6 +203,12 @@ public:
}
llvm::Spiller* llvm::createSpiller(MachineFunction *mf, LiveIntervals *lis,
- LiveStacks *ls, VirtRegMap *vrm) {
- return new TrivialSpiller(mf, lis, ls, vrm);
+ LiveStacks *ls,
+ const MachineLoopInfo *loopInfo,
+ VirtRegMap *vrm) {
+ switch (spillerOpt) {
+ case trivial: return new TrivialSpiller(mf, lis, ls, vrm); break;
+ case standard: return new StandardSpiller(mf, lis, ls, loopInfo, vrm); break;
+ default: llvm_unreachable("Unreachable!"); break;
+ }
}
diff --git a/lib/CodeGen/Spiller.h b/lib/CodeGen/Spiller.h
index 9c3900d..7ec8e6d 100644
--- a/lib/CodeGen/Spiller.h
+++ b/lib/CodeGen/Spiller.h
@@ -10,6 +10,7 @@
#ifndef LLVM_CODEGEN_SPILLER_H
#define LLVM_CODEGEN_SPILLER_H
+#include "llvm/ADT/SmallVector.h"
#include <vector>
namespace llvm {
@@ -19,6 +20,7 @@ namespace llvm {
class LiveStacks;
class MachineFunction;
class MachineInstr;
+ class MachineLoopInfo;
class VirtRegMap;
class VNInfo;
@@ -32,17 +34,15 @@ namespace llvm {
/// Spill the given live range. The method used will depend on the Spiller
/// implementation selected.
- virtual std::vector<LiveInterval*> spill(LiveInterval *li) = 0;
-
- /// Intra-block split.
- virtual std::vector<LiveInterval*> intraBlockSplit(LiveInterval *li,
- VNInfo *valno) = 0;
+ virtual std::vector<LiveInterval*> spill(LiveInterval *li,
+ SmallVectorImpl<LiveInterval*> &spillIs) = 0;
};
/// Create and return a spiller object, as specified on the command line.
Spiller* createSpiller(MachineFunction *mf, LiveIntervals *li,
- LiveStacks *ls, VirtRegMap *vrm);
+ LiveStacks *ls, const MachineLoopInfo *loopInfo,
+ VirtRegMap *vrm);
}
#endif
diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp
index 84467ed..5fa690b 100644
--- a/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -112,8 +112,7 @@ namespace {
MachineBasicBlock *MBB, unsigned Dist);
bool DeleteUnusedInstr(MachineBasicBlock::iterator &mi,
MachineBasicBlock::iterator &nmi,
- MachineFunction::iterator &mbbi,
- unsigned regB, unsigned regBIdx, unsigned Dist);
+ MachineFunction::iterator &mbbi, unsigned Dist);
bool TryInstructionTransform(MachineBasicBlock::iterator &mi,
MachineBasicBlock::iterator &nmi,
@@ -730,7 +729,7 @@ void TwoAddressInstructionPass::ProcessCopy(MachineInstr *MI,
/// isSafeToDelete - If the specified instruction does not produce any side
/// effects and all of its defs are dead, then it's safe to delete.
-static bool isSafeToDelete(MachineInstr *MI, unsigned Reg,
+static bool isSafeToDelete(MachineInstr *MI,
const TargetInstrInfo *TII,
SmallVector<unsigned, 4> &Kills) {
const TargetInstrDesc &TID = MI->getDesc();
@@ -745,10 +744,9 @@ static bool isSafeToDelete(MachineInstr *MI, unsigned Reg,
continue;
if (MO.isDef() && !MO.isDead())
return false;
- if (MO.isUse() && MO.getReg() != Reg && MO.isKill())
+ if (MO.isUse() && MO.isKill())
Kills.push_back(MO.getReg());
}
-
return true;
}
@@ -783,11 +781,10 @@ bool
TwoAddressInstructionPass::DeleteUnusedInstr(MachineBasicBlock::iterator &mi,
MachineBasicBlock::iterator &nmi,
MachineFunction::iterator &mbbi,
- unsigned regB, unsigned regBIdx,
unsigned Dist) {
// Check if the instruction has no side effects and if all its defs are dead.
SmallVector<unsigned, 4> Kills;
- if (!isSafeToDelete(mi, regB, TII, Kills))
+ if (!isSafeToDelete(mi, TII, Kills))
return false;
// If this instruction kills some virtual registers, we need to
@@ -810,10 +807,6 @@ TwoAddressInstructionPass::DeleteUnusedInstr(MachineBasicBlock::iterator &mi,
LV->addVirtualRegisterKilled(Kill, NewKill);
}
}
-
- // If regB was marked as a kill, update its Kills list.
- if (mi->getOperand(regBIdx).isKill())
- LV->removeVirtualRegisterKilled(regB, mi);
}
mbbi->erase(mi); // Nuke the old inst.
@@ -842,7 +835,7 @@ TryInstructionTransform(MachineBasicBlock::iterator &mi,
// it so it doesn't clobber regB.
bool regBKilled = isKilled(*mi, regB, MRI, TII);
if (!regBKilled && mi->getOperand(DstIdx).isDead() &&
- DeleteUnusedInstr(mi, nmi, mbbi, regB, SrcIdx, Dist)) {
+ DeleteUnusedInstr(mi, nmi, mbbi, Dist)) {
++NumDeletes;
return true; // Done with this instruction.
}
diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp
index ec0abd1..c836286 100644
--- a/lib/CodeGen/VirtRegRewriter.cpp
+++ b/lib/CodeGen/VirtRegRewriter.cpp
@@ -77,27 +77,38 @@ struct TrivialRewriter : public VirtRegRewriter {
DEBUG(MF.dump());
MachineRegisterInfo *mri = &MF.getRegInfo();
+ const TargetRegisterInfo *tri = MF.getTarget().getRegisterInfo();
bool changed = false;
for (LiveIntervals::iterator liItr = LIs->begin(), liEnd = LIs->end();
liItr != liEnd; ++liItr) {
- if (TargetRegisterInfo::isVirtualRegister(liItr->first)) {
- if (VRM.hasPhys(liItr->first)) {
- unsigned preg = VRM.getPhys(liItr->first);
- mri->replaceRegWith(liItr->first, preg);
- mri->setPhysRegUsed(preg);
- changed = true;
- }
+ const LiveInterval *li = liItr->second;
+ unsigned reg = li->reg;
+
+ if (TargetRegisterInfo::isPhysicalRegister(reg)) {
+ if (!li->empty())
+ mri->setPhysRegUsed(reg);
}
else {
- if (!liItr->second->empty()) {
- mri->setPhysRegUsed(liItr->first);
+ if (!VRM.hasPhys(reg))
+ continue;
+ unsigned pReg = VRM.getPhys(reg);
+ mri->setPhysRegUsed(pReg);
+ for (MachineRegisterInfo::reg_iterator regItr = mri->reg_begin(reg),
+ regEnd = mri->reg_end(); regItr != regEnd;) {
+ MachineOperand &mop = regItr.getOperand();
+ assert(mop.isReg() && mop.getReg() == reg && "reg_iterator broken?");
+ ++regItr;
+ unsigned subRegIdx = mop.getSubReg();
+ unsigned pRegOp = subRegIdx ? tri->getSubReg(pReg, subRegIdx) : pReg;
+ mop.setReg(pRegOp);
+ mop.setSubReg(0);
+ changed = true;
}
}
}
-
DEBUG(errs() << "**** Post Machine Instrs ****\n");
DEBUG(MF.dump());
OpenPOWER on IntegriCloud