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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128886 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2011-04-05 15:18:18 +00:00
parent 0286ca89f0
commit a2948ef5ac
3 changed files with 31 additions and 54 deletions

View File

@ -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();

View File

@ -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<bool>
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);
}

View File

@ -50,17 +50,9 @@ public:
const MachineLoopInfo &Loops;
const TargetInstrInfo &TII;
// Instructions using the the current register.
typedef SmallPtrSet<const MachineInstr*, 16> InstrPtrSet;
InstrPtrSet UsingInstrs;
// Sorted slot indexes of using instructions.
SmallVector<SlotIndex, 8> UseSlots;
// The number of instructions using CurLI in each basic block.
typedef DenseMap<const MachineBasicBlock*, unsigned> 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<const MachineBasicBlock*, 16> 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.