From fe6e07fd8a678229f38abfaae465e2147caef8e8 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 5 Apr 2011 15:18:18 +0000 Subject: [PATCH] Use std::unique instead of a SmallPtrSet to ensure unique instructions in UseSlots. This allows us to always keep the smaller slot for an instruction which is what we want when a register has early clobber defines. Drop the UsingInstrs set and the UsingBlocks map. They are no longer needed. llvm-svn: 128886 --- llvm/include/llvm/CodeGen/SlotIndexes.h | 5 ++ llvm/lib/CodeGen/SplitKit.cpp | 64 ++++++++++--------------- llvm/lib/CodeGen/SplitKit.h | 16 ------- 3 files changed, 31 insertions(+), 54 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SlotIndexes.h b/llvm/include/llvm/CodeGen/SlotIndexes.h index 7cc31563b637..dc247132c8f2 100644 --- a/llvm/include/llvm/CodeGen/SlotIndexes.h +++ b/llvm/include/llvm/CodeGen/SlotIndexes.h @@ -178,6 +178,11 @@ namespace llvm { return getIndex() >= other.getIndex(); } + /// isSameInstr - Return true if A and B refer to the same instruction. + static bool isSameInstr(SlotIndex A, SlotIndex B) { + return A.lie.getPointer() == B.lie.getPointer(); + } + /// Return the distance from this index to the given one. int distance(SlotIndex other) const { return other.getIndex() - getIndex(); diff --git a/llvm/lib/CodeGen/SplitKit.cpp b/llvm/lib/CodeGen/SplitKit.cpp index 0b59a28c0617..4b642883d47a 100644 --- a/llvm/lib/CodeGen/SplitKit.cpp +++ b/llvm/lib/CodeGen/SplitKit.cpp @@ -21,7 +21,6 @@ #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" @@ -29,10 +28,6 @@ using namespace llvm; -static cl::opt -AllowSplit("spiller-splits-edges", - cl::desc("Allow critical edge splitting during spilling")); - STATISTIC(NumFinished, "Number of splits finished"); STATISTIC(NumSimple, "Number of splits that were simple"); @@ -53,8 +48,6 @@ SplitAnalysis::SplitAnalysis(const VirtRegMap &vrm, void SplitAnalysis::clear() { UseSlots.clear(); - UsingInstrs.clear(); - UsingBlocks.clear(); LiveBlocks.clear(); CurLI = 0; } @@ -96,21 +89,31 @@ SlotIndex SplitAnalysis::computeLastSplitPoint(unsigned Num) { /// analyzeUses - Count instructions, basic blocks, and loops using CurLI. void SplitAnalysis::analyzeUses() { + assert(UseSlots.empty() && "Call clear first"); + + // First get all the defs from the interval values. This provides the correct + // slots for early clobbers. + for (LiveInterval::const_vni_iterator I = CurLI->vni_begin(), + E = CurLI->vni_end(); I != E; ++I) + if (!(*I)->isPHIDef() && !(*I)->isUnused()) + UseSlots.push_back((*I)->def); + + // Get use slots form the use-def chain. const MachineRegisterInfo &MRI = MF.getRegInfo(); - for (MachineRegisterInfo::reg_iterator I = MRI.reg_begin(CurLI->reg), - E = MRI.reg_end(); I != E; ++I) { - MachineOperand &MO = I.getOperand(); - if (MO.isUse() && MO.isUndef()) - continue; - MachineInstr *MI = MO.getParent(); - if (MI->isDebugValue() || !UsingInstrs.insert(MI)) - continue; - UseSlots.push_back(LIS.getInstructionIndex(MI).getDefIndex()); - MachineBasicBlock *MBB = MI->getParent(); - UsingBlocks[MBB]++; - } + for (MachineRegisterInfo::use_nodbg_iterator + I = MRI.use_nodbg_begin(CurLI->reg), E = MRI.use_nodbg_end(); I != E; + ++I) + if (!I.getOperand().isUndef()) + UseSlots.push_back(LIS.getInstructionIndex(&*I).getDefIndex()); + array_pod_sort(UseSlots.begin(), UseSlots.end()); + // Remove duplicates, keeping the smaller slot for each instruction. + // That is what we want for early clobbers. + UseSlots.erase(std::unique(UseSlots.begin(), UseSlots.end(), + SlotIndex::isSameInstr), + UseSlots.end()); + // Compute per-live block info. if (!calcLiveBlockInfo()) { // FIXME: calcLiveBlockInfo found inconsistencies in the live range. @@ -125,8 +128,7 @@ void SplitAnalysis::analyzeUses() { } DEBUG(dbgs() << "Analyze counted " - << UsingInstrs.size() << " instrs, " - << UsingBlocks.size() << " blocks, " + << UseSlots.size() << " instrs, " << LiveBlocks.size() << " spanned.\n"); } @@ -157,8 +159,8 @@ bool SplitAnalysis::calcLiveBlockInfo() { BI.Def = LVI->start; // Find the first and last uses in the block. - BI.Uses = hasUses(MFI); - if (BI.Uses && UseI != UseE) { + BI.Uses = UseI != UseE && *UseI < Stop; + if (BI.Uses) { BI.FirstUse = *UseI; assert(BI.FirstUse >= Start); do ++UseI; @@ -224,15 +226,6 @@ bool SplitAnalysis::isOriginalEndpoint(SlotIndex Idx) const { return I != Orig.begin() && (--I)->end == Idx; } -void SplitAnalysis::print(const BlockPtrSet &B, raw_ostream &OS) const { - for (BlockPtrSet::const_iterator I = B.begin(), E = B.end(); I != E; ++I) { - unsigned count = UsingBlocks.lookup(*I); - OS << " BB#" << (*I)->getNumber(); - if (count) - OS << '(' << count << ')'; - } -} - void SplitAnalysis::analyze(const LiveInterval *li) { clear(); CurLI = li; @@ -918,12 +911,7 @@ bool SplitAnalysis::getMultiUseBlocks(BlockPtrSet &Blocks) { // Add blocks with multiple uses. for (unsigned i = 0, e = LiveBlocks.size(); i != e; ++i) { const BlockInfo &BI = LiveBlocks[i]; - if (!BI.Uses) - continue; - unsigned Instrs = UsingBlocks.lookup(BI.MBB); - if (Instrs <= 1) - continue; - if (Instrs == 2 && BI.LiveIn && BI.LiveOut && !BI.LiveThrough) + if (!BI.Uses || BI.FirstUse == BI.LastUse) continue; Blocks.insert(BI.MBB); } diff --git a/llvm/lib/CodeGen/SplitKit.h b/llvm/lib/CodeGen/SplitKit.h index 50f8dcfbd1eb..793989f7e375 100644 --- a/llvm/lib/CodeGen/SplitKit.h +++ b/llvm/lib/CodeGen/SplitKit.h @@ -50,17 +50,9 @@ public: const MachineLoopInfo &Loops; const TargetInstrInfo &TII; - // Instructions using the the current register. - typedef SmallPtrSet InstrPtrSet; - InstrPtrSet UsingInstrs; - // Sorted slot indexes of using instructions. SmallVector UseSlots; - // The number of instructions using CurLI in each basic block. - typedef DenseMap BlockCountMap; - BlockCountMap UsingBlocks; - /// Additional information about basic blocks where the current variable is /// live. Such a block will look like one of these templates: /// @@ -130,11 +122,6 @@ public: return computeLastSplitPoint(Num); } - /// hasUses - Return true if MBB has any uses of CurLI. - bool hasUses(const MachineBasicBlock *MBB) const { - return UsingBlocks.lookup(MBB); - } - /// isOriginalEndpoint - Return true if the original live range was killed or /// (re-)defined at Idx. Idx should be the 'def' slot for a normal kill/def, /// and 'use' for an early-clobber def. @@ -144,9 +131,6 @@ public: typedef SmallPtrSet BlockPtrSet; - // Print a set of blocks with use counts. - void print(const BlockPtrSet&, raw_ostream&) const; - /// getMultiUseBlocks - Add basic blocks to Blocks that may benefit from /// having CurLI split to a new live interval. Return true if Blocks can be /// passed to SplitEditor::splitSingleBlocks.