mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-24 08:18:33 +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:
@@ -178,6 +178,11 @@ namespace llvm {
|
|||||||
return getIndex() >= other.getIndex();
|
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.
|
/// Return the distance from this index to the given one.
|
||||||
int distance(SlotIndex other) const {
|
int distance(SlotIndex other) const {
|
||||||
return other.getIndex() - getIndex();
|
return other.getIndex() - getIndex();
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
#include "llvm/CodeGen/MachineDominators.h"
|
#include "llvm/CodeGen/MachineDominators.h"
|
||||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
@@ -29,10 +28,6 @@
|
|||||||
|
|
||||||
using namespace llvm;
|
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(NumFinished, "Number of splits finished");
|
||||||
STATISTIC(NumSimple, "Number of splits that were simple");
|
STATISTIC(NumSimple, "Number of splits that were simple");
|
||||||
|
|
||||||
@@ -53,8 +48,6 @@ SplitAnalysis::SplitAnalysis(const VirtRegMap &vrm,
|
|||||||
|
|
||||||
void SplitAnalysis::clear() {
|
void SplitAnalysis::clear() {
|
||||||
UseSlots.clear();
|
UseSlots.clear();
|
||||||
UsingInstrs.clear();
|
|
||||||
UsingBlocks.clear();
|
|
||||||
LiveBlocks.clear();
|
LiveBlocks.clear();
|
||||||
CurLI = 0;
|
CurLI = 0;
|
||||||
}
|
}
|
||||||
@@ -96,21 +89,31 @@ SlotIndex SplitAnalysis::computeLastSplitPoint(unsigned Num) {
|
|||||||
|
|
||||||
/// analyzeUses - Count instructions, basic blocks, and loops using CurLI.
|
/// analyzeUses - Count instructions, basic blocks, and loops using CurLI.
|
||||||
void SplitAnalysis::analyzeUses() {
|
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();
|
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||||
for (MachineRegisterInfo::reg_iterator I = MRI.reg_begin(CurLI->reg),
|
for (MachineRegisterInfo::use_nodbg_iterator
|
||||||
E = MRI.reg_end(); I != E; ++I) {
|
I = MRI.use_nodbg_begin(CurLI->reg), E = MRI.use_nodbg_end(); I != E;
|
||||||
MachineOperand &MO = I.getOperand();
|
++I)
|
||||||
if (MO.isUse() && MO.isUndef())
|
if (!I.getOperand().isUndef())
|
||||||
continue;
|
UseSlots.push_back(LIS.getInstructionIndex(&*I).getDefIndex());
|
||||||
MachineInstr *MI = MO.getParent();
|
|
||||||
if (MI->isDebugValue() || !UsingInstrs.insert(MI))
|
|
||||||
continue;
|
|
||||||
UseSlots.push_back(LIS.getInstructionIndex(MI).getDefIndex());
|
|
||||||
MachineBasicBlock *MBB = MI->getParent();
|
|
||||||
UsingBlocks[MBB]++;
|
|
||||||
}
|
|
||||||
array_pod_sort(UseSlots.begin(), UseSlots.end());
|
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.
|
// Compute per-live block info.
|
||||||
if (!calcLiveBlockInfo()) {
|
if (!calcLiveBlockInfo()) {
|
||||||
// FIXME: calcLiveBlockInfo found inconsistencies in the live range.
|
// FIXME: calcLiveBlockInfo found inconsistencies in the live range.
|
||||||
@@ -125,8 +128,7 @@ void SplitAnalysis::analyzeUses() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(dbgs() << "Analyze counted "
|
DEBUG(dbgs() << "Analyze counted "
|
||||||
<< UsingInstrs.size() << " instrs, "
|
<< UseSlots.size() << " instrs, "
|
||||||
<< UsingBlocks.size() << " blocks, "
|
|
||||||
<< LiveBlocks.size() << " spanned.\n");
|
<< LiveBlocks.size() << " spanned.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,8 +159,8 @@ bool SplitAnalysis::calcLiveBlockInfo() {
|
|||||||
BI.Def = LVI->start;
|
BI.Def = LVI->start;
|
||||||
|
|
||||||
// Find the first and last uses in the block.
|
// Find the first and last uses in the block.
|
||||||
BI.Uses = hasUses(MFI);
|
BI.Uses = UseI != UseE && *UseI < Stop;
|
||||||
if (BI.Uses && UseI != UseE) {
|
if (BI.Uses) {
|
||||||
BI.FirstUse = *UseI;
|
BI.FirstUse = *UseI;
|
||||||
assert(BI.FirstUse >= Start);
|
assert(BI.FirstUse >= Start);
|
||||||
do ++UseI;
|
do ++UseI;
|
||||||
@@ -224,15 +226,6 @@ bool SplitAnalysis::isOriginalEndpoint(SlotIndex Idx) const {
|
|||||||
return I != Orig.begin() && (--I)->end == Idx;
|
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) {
|
void SplitAnalysis::analyze(const LiveInterval *li) {
|
||||||
clear();
|
clear();
|
||||||
CurLI = li;
|
CurLI = li;
|
||||||
@@ -918,12 +911,7 @@ bool SplitAnalysis::getMultiUseBlocks(BlockPtrSet &Blocks) {
|
|||||||
// Add blocks with multiple uses.
|
// Add blocks with multiple uses.
|
||||||
for (unsigned i = 0, e = LiveBlocks.size(); i != e; ++i) {
|
for (unsigned i = 0, e = LiveBlocks.size(); i != e; ++i) {
|
||||||
const BlockInfo &BI = LiveBlocks[i];
|
const BlockInfo &BI = LiveBlocks[i];
|
||||||
if (!BI.Uses)
|
if (!BI.Uses || BI.FirstUse == BI.LastUse)
|
||||||
continue;
|
|
||||||
unsigned Instrs = UsingBlocks.lookup(BI.MBB);
|
|
||||||
if (Instrs <= 1)
|
|
||||||
continue;
|
|
||||||
if (Instrs == 2 && BI.LiveIn && BI.LiveOut && !BI.LiveThrough)
|
|
||||||
continue;
|
continue;
|
||||||
Blocks.insert(BI.MBB);
|
Blocks.insert(BI.MBB);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,17 +50,9 @@ public:
|
|||||||
const MachineLoopInfo &Loops;
|
const MachineLoopInfo &Loops;
|
||||||
const TargetInstrInfo &TII;
|
const TargetInstrInfo &TII;
|
||||||
|
|
||||||
// Instructions using the the current register.
|
|
||||||
typedef SmallPtrSet<const MachineInstr*, 16> InstrPtrSet;
|
|
||||||
InstrPtrSet UsingInstrs;
|
|
||||||
|
|
||||||
// Sorted slot indexes of using instructions.
|
// Sorted slot indexes of using instructions.
|
||||||
SmallVector<SlotIndex, 8> UseSlots;
|
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
|
/// Additional information about basic blocks where the current variable is
|
||||||
/// live. Such a block will look like one of these templates:
|
/// live. Such a block will look like one of these templates:
|
||||||
///
|
///
|
||||||
@@ -130,11 +122,6 @@ public:
|
|||||||
return computeLastSplitPoint(Num);
|
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
|
/// 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,
|
/// (re-)defined at Idx. Idx should be the 'def' slot for a normal kill/def,
|
||||||
/// and 'use' for an early-clobber def.
|
/// and 'use' for an early-clobber def.
|
||||||
@@ -144,9 +131,6 @@ public:
|
|||||||
|
|
||||||
typedef SmallPtrSet<const MachineBasicBlock*, 16> BlockPtrSet;
|
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
|
/// getMultiUseBlocks - Add basic blocks to Blocks that may benefit from
|
||||||
/// having CurLI split to a new live interval. Return true if Blocks can be
|
/// having CurLI split to a new live interval. Return true if Blocks can be
|
||||||
/// passed to SplitEditor::splitSingleBlocks.
|
/// passed to SplitEditor::splitSingleBlocks.
|
||||||
|
|||||||
Reference in New Issue
Block a user