mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 02:29:18 +00:00
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:
parent
0286ca89f0
commit
a2948ef5ac
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user