X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FInlineSpiller.cpp;h=b63611b94c1c1d403d38d9160a6dac9fe77d837e;hb=cccfd194ecf8e1c6fb203ec3f96aca8cfe9e0484;hp=0c46aeb6aa1c8f15646bf776c08eae555f209252;hpb=6b6e32d954233ddeeae7f99e358ff85059f1176a;p=oota-llvm.git diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp index 0c46aeb6aa1..b63611b94c1 100644 --- a/lib/CodeGen/InlineSpiller.cpp +++ b/lib/CodeGen/InlineSpiller.cpp @@ -28,22 +28,26 @@ #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; STATISTIC(NumSpilledRanges, "Number of spilled live ranges"); -STATISTIC(NumSnippets, "Number of snippets included in spills"); +STATISTIC(NumSnippets, "Number of spilled snippets"); STATISTIC(NumSpills, "Number of spills inserted"); +STATISTIC(NumSpillsRemoved, "Number of spills removed"); STATISTIC(NumReloads, "Number of reloads inserted"); +STATISTIC(NumReloadsRemoved, "Number of reloads removed"); STATISTIC(NumFolded, "Number of folded stack accesses"); STATISTIC(NumFoldedLoads, "Number of folded loads"); STATISTIC(NumRemats, "Number of rematerialized defs for spilling"); -STATISTIC(NumOmitReloadSpill, "Number of omitted spills after reloads"); -STATISTIC(NumHoistLocal, "Number of locally hoisted spills"); -STATISTIC(NumHoistGlobal, "Number of globally hoisted spills"); -STATISTIC(NumRedundantSpills, "Number of redundant spills identified"); +STATISTIC(NumOmitReloadSpill, "Number of omitted spills of reloads"); +STATISTIC(NumHoists, "Number of hoisted spills"); + +static cl::opt DisableHoisting("disable-spill-hoist", cl::Hidden, + cl::desc("Disable inline spill hoisting")); namespace { class InlineSpiller : public Spiller { @@ -86,6 +90,9 @@ public: // True when value is defined by an original PHI not from splitting. bool DefByOrigPHI; + // True when the COPY defining this value killed its source. + bool KillsSource; + // The preferred register to spill. unsigned SpillReg; @@ -108,7 +115,7 @@ public: TinyPtrVector Deps; SibValueInfo(unsigned Reg, VNInfo *VNI) - : AllDefsAreReloads(true), DefByOrigPHI(false), + : AllDefsAreReloads(true), DefByOrigPHI(false), KillsSource(false), SpillReg(Reg), SpillVNI(VNI), SpillMBB(0), DefMI(0) {} // Returns true when a def has been found. @@ -315,6 +322,8 @@ static raw_ostream &operator<<(raw_ostream &OS, OS << " all-reloads"; if (SVI.DefByOrigPHI) OS << " orig-phi"; + if (SVI.KillsSource) + OS << " kill"; OS << " deps["; for (unsigned i = 0, e = SVI.Deps.size(); i != e; ++i) OS << ' ' << SVI.Deps[i]->id << '@' << SVI.Deps[i]->def; @@ -367,7 +376,7 @@ void InlineSpiller::propagateSiblingValue(SibValueMap::iterator SVI, // Should this value be propagated as a preferred spill candidate? We don't // propagate values of registers that are about to spill. - bool PropSpill = !isRegToSpill(SV.SpillReg); + bool PropSpill = !DisableHoisting && !isRegToSpill(SV.SpillReg); unsigned SpillDepth = ~0u; for (TinyPtrVector::iterator DepI = Deps->begin(), @@ -398,7 +407,7 @@ void InlineSpiller::propagateSiblingValue(SibValueMap::iterator SVI, if (PropSpill && SV.SpillVNI != DepSV.SpillVNI) { if (SV.SpillMBB == DepSV.SpillMBB) { // DepSV is in the same block. Hoist when dominated. - if (SV.SpillVNI->def < DepSV.SpillVNI->def) { + if (DepSV.KillsSource && SV.SpillVNI->def < DepSV.SpillVNI->def) { // This is an alternative def earlier in the same MBB. // Hoist the spill as far as possible in SpillMBB. This can ease // register pressure: @@ -414,6 +423,7 @@ void InlineSpiller::propagateSiblingValue(SibValueMap::iterator SVI, // spill x // y = use x // + // This hoist only helps when the DepSV copy kills its source. Changed = true; DepSV.SpillReg = SV.SpillReg; DepSV.SpillVNI = SV.SpillVNI; @@ -568,10 +578,14 @@ MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI, if (unsigned SrcReg = isFullCopyOf(MI, Reg)) { if (isSibling(SrcReg)) { LiveInterval &SrcLI = LIS.getInterval(SrcReg); - VNInfo *SrcVNI = SrcLI.getVNInfoAt(VNI->def.getUseIndex()); - assert(SrcVNI && "Copy from non-existing value"); + LiveRange *SrcLR = SrcLI.getLiveRangeContaining(VNI->def.getUseIndex()); + assert(SrcLR && "Copy from non-existing value"); + // Check if this COPY kills its source. + SVI->second.KillsSource = (SrcLR->end == VNI->def); + VNInfo *SrcVNI = SrcLR->valno; DEBUG(dbgs() << "copy of " << PrintReg(SrcReg) << ':' - << SrcVNI->id << '@' << SrcVNI->def << '\n'); + << SrcVNI->id << '@' << SrcVNI->def + << " kill=" << unsigned(SVI->second.KillsSource) << '\n'); // Known sibling source value? Try an insertion. tie(SVI, Inserted) = SibValues.insert(std::make_pair(SrcVNI, SibValueInfo(SrcReg, SrcVNI))); @@ -715,10 +729,8 @@ bool InlineSpiller::hoistSpill(LiveInterval &SpillLI, MachineInstr *CopyMI) { VRM.addSpillSlotUse(StackSlot, MII); DEBUG(dbgs() << "\thoisted: " << SVI.SpillVNI->def << '\t' << *MII); - if (MBB == CopyMI->getParent()) - ++NumHoistLocal; - else - ++NumHoistGlobal; + ++NumSpills; + ++NumHoists; return true; } @@ -773,7 +785,8 @@ void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, VNInfo *VNI) { // eliminateDeadDefs won't normally remove stores, so switch opcode. MI->setDesc(TII.get(TargetOpcode::KILL)); DeadDefs.push_back(MI); - ++NumRedundantSpills; + ++NumSpillsRemoved; + --NumSpills; } } } while (!WorkList.empty()); @@ -971,10 +984,10 @@ void InlineSpiller::reMaterializeAll() { /// If MI is a load or store of StackSlot, it can be removed. bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, unsigned Reg) { int FI = 0; - unsigned InstrReg; - if (!(InstrReg = TII.isLoadFromStackSlot(MI, FI)) && - !(InstrReg = TII.isStoreToStackSlot(MI, FI))) - return false; + unsigned InstrReg = TII.isLoadFromStackSlot(MI, FI); + bool IsLoad = InstrReg; + if (!IsLoad) + InstrReg = TII.isStoreToStackSlot(MI, FI); // We have a stack access. Is it the right register and slot? if (InstrReg != Reg || FI != StackSlot) @@ -983,6 +996,15 @@ bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, unsigned Reg) { DEBUG(dbgs() << "Coalescing stack access: " << *MI); LIS.RemoveMachineInstrFromMaps(MI); MI->eraseFromParent(); + + if (IsLoad) { + ++NumReloadsRemoved; + --NumReloads; + } else { + ++NumSpillsRemoved; + --NumSpills; + } + return true; } @@ -994,6 +1016,7 @@ bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, unsigned Reg) { bool InlineSpiller::foldMemoryOperand(MachineBasicBlock::iterator MI, const SmallVectorImpl &Ops, MachineInstr *LoadMI) { + bool WasCopy = MI->isCopy(); // TargetInstrInfo::foldMemoryOperand only expects explicit, non-tied // operands. SmallVector FoldOps; @@ -1023,7 +1046,12 @@ bool InlineSpiller::foldMemoryOperand(MachineBasicBlock::iterator MI, VRM.addSpillSlotUse(StackSlot, FoldMI); MI->eraseFromParent(); DEBUG(dbgs() << "\tfolded: " << *FoldMI); - ++NumFolded; + if (!WasCopy) + ++NumFolded; + else if (Ops.front() == 0) + ++NumSpills; + else + ++NumReloads; return true; }