mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 00:32:55 +00:00
There is only one register coalescer. Merge it into the base class and
remove the analysis group. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133899 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
655739de7b
commit
5b220213bf
@ -39,8 +39,6 @@ namespace {
|
||||
(void) llvm::createGreedyRegisterAllocator();
|
||||
(void) llvm::createDefaultPBQPRegisterAllocator();
|
||||
|
||||
(void) llvm::createSimpleRegisterCoalescer();
|
||||
|
||||
llvm::linkOcamlGC();
|
||||
llvm::linkShadowStackGC();
|
||||
|
||||
|
@ -78,11 +78,6 @@ namespace llvm {
|
||||
/// LiveStacks pass. An analysis keeping track of the liveness of stack slots.
|
||||
extern char &LiveStacksID;
|
||||
|
||||
/// SimpleRegisterCoalescing pass. Aggressively coalesces every register
|
||||
/// copy it can.
|
||||
///
|
||||
extern char &SimpleRegisterCoalescingID;
|
||||
|
||||
/// TwoAddressInstruction pass - This pass reduces two-address instructions to
|
||||
/// use two operands. This destroys SSA information but it is desired by
|
||||
/// register allocators.
|
||||
@ -132,10 +127,10 @@ namespace llvm {
|
||||
///
|
||||
FunctionPass *createDefaultPBQPRegisterAllocator();
|
||||
|
||||
/// SimpleRegisterCoalescing Pass - Coalesce all copies possible. Can run
|
||||
/// RegisterCoalescer Pass - Coalesce all copies possible. Can run
|
||||
/// independently of the register allocator.
|
||||
///
|
||||
RegisterCoalescer *createSimpleRegisterCoalescer();
|
||||
RegisterCoalescer *createRegisterCoalescer();
|
||||
|
||||
/// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code,
|
||||
/// and eliminates abstract frame references.
|
||||
|
@ -198,7 +198,6 @@ void initializeRegionOnlyPrinterPass(PassRegistry&);
|
||||
void initializeRegionOnlyViewerPass(PassRegistry&);
|
||||
void initializeRegionPrinterPass(PassRegistry&);
|
||||
void initializeRegionViewerPass(PassRegistry&);
|
||||
void initializeRegisterCoalescerAnalysisGroup(PassRegistry&);
|
||||
void initializeRenderMachineFunctionPass(PassRegistry&);
|
||||
void initializeSCCPPass(PassRegistry&);
|
||||
void initializeSROA_DTPass(PassRegistry&);
|
||||
@ -206,7 +205,7 @@ void initializeSROA_SSAUpPass(PassRegistry&);
|
||||
void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&);
|
||||
void initializeScalarEvolutionPass(PassRegistry&);
|
||||
void initializeSimpleInlinerPass(PassRegistry&);
|
||||
void initializeSimpleRegisterCoalescingPass(PassRegistry&);
|
||||
void initializeRegisterCoalescerPass(PassRegistry&);
|
||||
void initializeSimplifyLibCallsPass(PassRegistry&);
|
||||
void initializeSingleLoopExtractorPass(PassRegistry&);
|
||||
void initializeSinkingPass(PassRegistry&);
|
||||
|
@ -41,9 +41,8 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
|
||||
initializeProcessImplicitDefsPass(Registry);
|
||||
initializePEIPass(Registry);
|
||||
initializeRALinScanPass(Registry);
|
||||
initializeRegisterCoalescerAnalysisGroup(Registry);
|
||||
initializeRegisterCoalescerPass(Registry);
|
||||
initializeRenderMachineFunctionPass(Registry);
|
||||
initializeSimpleRegisterCoalescingPass(Registry);
|
||||
initializeSlotIndexesPass(Registry);
|
||||
initializeLoopSplitterPass(Registry);
|
||||
initializeStackProtectorPass(Registry);
|
||||
|
@ -141,7 +141,7 @@ RABasic::RABasic(): MachineFunctionPass(ID) {
|
||||
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
|
||||
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
|
||||
initializeStrongPHIEliminationPass(*PassRegistry::getPassRegistry());
|
||||
initializeRegisterCoalescerAnalysisGroup(*PassRegistry::getPassRegistry());
|
||||
initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
|
||||
initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
|
||||
initializeLiveStacksPass(*PassRegistry::getPassRegistry());
|
||||
initializeMachineDominatorTreePass(*PassRegistry::getPassRegistry());
|
||||
|
@ -234,7 +234,7 @@ RAGreedy::RAGreedy(): MachineFunctionPass(ID), LRStage(RS_New) {
|
||||
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
|
||||
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
|
||||
initializeStrongPHIEliminationPass(*PassRegistry::getPassRegistry());
|
||||
initializeRegisterCoalescerAnalysisGroup(*PassRegistry::getPassRegistry());
|
||||
initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
|
||||
initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
|
||||
initializeLiveStacksPass(*PassRegistry::getPassRegistry());
|
||||
initializeMachineDominatorTreePass(*PassRegistry::getPassRegistry());
|
||||
|
@ -101,7 +101,7 @@ namespace {
|
||||
initializeLiveDebugVariablesPass(*PassRegistry::getPassRegistry());
|
||||
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
|
||||
initializeStrongPHIEliminationPass(*PassRegistry::getPassRegistry());
|
||||
initializeRegisterCoalescerAnalysisGroup(
|
||||
initializeRegisterCoalescerPass(
|
||||
*PassRegistry::getPassRegistry());
|
||||
initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
|
||||
initializePreAllocSplittingPass(*PassRegistry::getPassRegistry());
|
||||
@ -405,7 +405,7 @@ INITIALIZE_PASS_DEPENDENCY(PreAllocSplitting)
|
||||
INITIALIZE_PASS_DEPENDENCY(LiveStacks)
|
||||
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
|
||||
INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
|
||||
INITIALIZE_AG_DEPENDENCY(RegisterCoalescer)
|
||||
INITIALIZE_PASS_DEPENDENCY(RegisterCoalescer)
|
||||
INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
|
||||
INITIALIZE_PASS_END(RALinScan, "linearscan-regalloc",
|
||||
"Linear Scan Register Allocator", false, false)
|
||||
|
@ -88,7 +88,7 @@ public:
|
||||
: MachineFunctionPass(ID), builder(b), customPassID(cPassID) {
|
||||
initializeSlotIndexesPass(*PassRegistry::getPassRegistry());
|
||||
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
|
||||
initializeRegisterCoalescerAnalysisGroup(*PassRegistry::getPassRegistry());
|
||||
initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
|
||||
initializeCalculateSpillWeightsPass(*PassRegistry::getPassRegistry());
|
||||
initializeLiveStacksPass(*PassRegistry::getPassRegistry());
|
||||
initializeMachineLoopInfoPass(*PassRegistry::getPassRegistry());
|
||||
|
@ -55,7 +55,6 @@ STATISTIC(NumReMats , "Number of instructions re-materialized");
|
||||
STATISTIC(numPeep , "Number of identity moves eliminated after coalescing");
|
||||
STATISTIC(numAborts , "Number of times interval joining aborted");
|
||||
|
||||
char SimpleRegisterCoalescing::ID = 0;
|
||||
static cl::opt<bool>
|
||||
EnableJoining("join-liveintervals",
|
||||
cl::desc("Coalesce copies (default=true)"),
|
||||
@ -76,9 +75,8 @@ VerifyCoalescing("verify-coalescing",
|
||||
cl::desc("Verify machine instrs before and after register coalescing"),
|
||||
cl::Hidden);
|
||||
|
||||
INITIALIZE_AG_PASS_BEGIN(SimpleRegisterCoalescing, RegisterCoalescer,
|
||||
"simple-register-coalescing", "Simple Register Coalescing",
|
||||
false, false, true)
|
||||
INITIALIZE_PASS_BEGIN(RegisterCoalescer, "simple-register-coalescing",
|
||||
"Simple Register Coalescing", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
|
||||
INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
|
||||
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
|
||||
@ -87,25 +85,11 @@ INITIALIZE_PASS_DEPENDENCY(StrongPHIElimination)
|
||||
INITIALIZE_PASS_DEPENDENCY(PHIElimination)
|
||||
INITIALIZE_PASS_DEPENDENCY(TwoAddressInstructionPass)
|
||||
INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
|
||||
INITIALIZE_AG_PASS_END(SimpleRegisterCoalescing, RegisterCoalescer,
|
||||
"simple-register-coalescing", "Simple Register Coalescing",
|
||||
false, false, true)
|
||||
INITIALIZE_PASS_END(RegisterCoalescer, "simple-register-coalescing",
|
||||
"Simple Register Coalescing", false, false)
|
||||
|
||||
char &llvm::SimpleRegisterCoalescingID = SimpleRegisterCoalescing::ID;
|
||||
|
||||
// Register the RegisterCoalescer interface, providing a nice name to refer to.
|
||||
INITIALIZE_ANALYSIS_GROUP(RegisterCoalescer, "Register Coalescer",
|
||||
SimpleRegisterCoalescing)
|
||||
char RegisterCoalescer::ID = 0;
|
||||
|
||||
// RegisterCoalescer destructor: DO NOT move this to the header file
|
||||
// for RegisterCoalescer or else clients of the RegisterCoalescer
|
||||
// class may not depend on the RegisterCoalescer.o file in the current
|
||||
// .a file, causing alias analysis support to not be included in the
|
||||
// tool correctly!
|
||||
//
|
||||
RegisterCoalescer::~RegisterCoalescer() {}
|
||||
|
||||
unsigned CoalescerPair::compose(unsigned a, unsigned b) const {
|
||||
if (!a) return b;
|
||||
if (!b) return a;
|
||||
@ -259,14 +243,7 @@ bool CoalescerPair::isCoalescable(const MachineInstr *MI) const {
|
||||
}
|
||||
}
|
||||
|
||||
// Because of the way .a files work, we must force the SimpleRC
|
||||
// implementation to be pulled in if the RegisterCoalescer classes are
|
||||
// pulled in. Otherwise we run the risk of RegisterCoalescer being
|
||||
// used, but the default implementation not being linked into the tool
|
||||
// that uses it.
|
||||
DEFINING_FILE_FOR(RegisterCoalescer)
|
||||
|
||||
void SimpleRegisterCoalescing::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
void RegisterCoalescer::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<AliasAnalysis>();
|
||||
AU.addRequired<LiveIntervals>();
|
||||
@ -283,7 +260,7 @@ void SimpleRegisterCoalescing::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
void SimpleRegisterCoalescing::markAsJoined(MachineInstr *CopyMI) {
|
||||
void RegisterCoalescer::markAsJoined(MachineInstr *CopyMI) {
|
||||
/// Joined copies are not deleted immediately, but kept in JoinedCopies.
|
||||
JoinedCopies.insert(CopyMI);
|
||||
|
||||
@ -310,7 +287,7 @@ void SimpleRegisterCoalescing::markAsJoined(MachineInstr *CopyMI) {
|
||||
///
|
||||
/// This returns true if an interval was modified.
|
||||
///
|
||||
bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(const CoalescerPair &CP,
|
||||
bool RegisterCoalescer::AdjustCopiesBackFrom(const CoalescerPair &CP,
|
||||
MachineInstr *CopyMI) {
|
||||
// Bail if there is no dst interval - can happen when merging physical subreg
|
||||
// operations.
|
||||
@ -464,7 +441,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(const CoalescerPair &CP,
|
||||
|
||||
/// HasOtherReachingDefs - Return true if there are definitions of IntB
|
||||
/// other than BValNo val# that can reach uses of AValno val# of IntA.
|
||||
bool SimpleRegisterCoalescing::HasOtherReachingDefs(LiveInterval &IntA,
|
||||
bool RegisterCoalescer::HasOtherReachingDefs(LiveInterval &IntA,
|
||||
LiveInterval &IntB,
|
||||
VNInfo *AValNo,
|
||||
VNInfo *BValNo) {
|
||||
@ -510,7 +487,7 @@ bool SimpleRegisterCoalescing::HasOtherReachingDefs(LiveInterval &IntA,
|
||||
///
|
||||
/// This returns true if an interval was modified.
|
||||
///
|
||||
bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(const CoalescerPair &CP,
|
||||
bool RegisterCoalescer::RemoveCopyByCommutingDef(const CoalescerPair &CP,
|
||||
MachineInstr *CopyMI) {
|
||||
// FIXME: For now, only eliminate the copy by commuting its def when the
|
||||
// source register is a virtual register. We want to guard against cases
|
||||
@ -693,7 +670,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(const CoalescerPair &CP,
|
||||
|
||||
/// ReMaterializeTrivialDef - If the source of a copy is defined by a trivial
|
||||
/// computation, replace the copy by rematerialize the definition.
|
||||
bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
|
||||
bool RegisterCoalescer::ReMaterializeTrivialDef(LiveInterval &SrcInt,
|
||||
bool preserveSrcInt,
|
||||
unsigned DstReg,
|
||||
unsigned DstSubIdx,
|
||||
@ -788,7 +765,7 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt,
|
||||
/// being updated is not zero, make sure to set it to the correct physical
|
||||
/// subregister.
|
||||
void
|
||||
SimpleRegisterCoalescing::UpdateRegDefsUses(const CoalescerPair &CP) {
|
||||
RegisterCoalescer::UpdateRegDefsUses(const CoalescerPair &CP) {
|
||||
bool DstIsPhys = CP.isPhys();
|
||||
unsigned SrcReg = CP.getSrcReg();
|
||||
unsigned DstReg = CP.getDstReg();
|
||||
@ -879,7 +856,7 @@ static bool removeIntervalIfEmpty(LiveInterval &li, LiveIntervals *li_,
|
||||
|
||||
/// RemoveDeadDef - If a def of a live interval is now determined dead, remove
|
||||
/// the val# it defines. If the live interval becomes empty, remove it as well.
|
||||
bool SimpleRegisterCoalescing::RemoveDeadDef(LiveInterval &li,
|
||||
bool RegisterCoalescer::RemoveDeadDef(LiveInterval &li,
|
||||
MachineInstr *DefMI) {
|
||||
SlotIndex DefIdx = li_->getInstructionIndex(DefMI).getDefIndex();
|
||||
LiveInterval::iterator MLR = li.FindLiveRangeContaining(DefIdx);
|
||||
@ -889,7 +866,7 @@ bool SimpleRegisterCoalescing::RemoveDeadDef(LiveInterval &li,
|
||||
return removeIntervalIfEmpty(li, li_, tri_);
|
||||
}
|
||||
|
||||
void SimpleRegisterCoalescing::RemoveCopyFlag(unsigned DstReg,
|
||||
void RegisterCoalescer::RemoveCopyFlag(unsigned DstReg,
|
||||
const MachineInstr *CopyMI) {
|
||||
SlotIndex DefIdx = li_->getInstructionIndex(CopyMI).getDefIndex();
|
||||
if (li_->hasInterval(DstReg)) {
|
||||
@ -915,7 +892,7 @@ void SimpleRegisterCoalescing::RemoveCopyFlag(unsigned DstReg,
|
||||
/// virtual register. Once the coalescing is done, it cannot be broken and these
|
||||
/// are not spillable! If the destination interval uses are far away, think
|
||||
/// twice about coalescing them!
|
||||
bool SimpleRegisterCoalescing::shouldJoinPhys(CoalescerPair &CP) {
|
||||
bool RegisterCoalescer::shouldJoinPhys(CoalescerPair &CP) {
|
||||
bool Allocatable = li_->isAllocatable(CP.getDstReg());
|
||||
LiveInterval &JoinVInt = li_->getInterval(CP.getSrcReg());
|
||||
|
||||
@ -966,8 +943,8 @@ bool SimpleRegisterCoalescing::shouldJoinPhys(CoalescerPair &CP) {
|
||||
/// isWinToJoinCrossClass - Return true if it's profitable to coalesce
|
||||
/// two virtual registers from different register classes.
|
||||
bool
|
||||
SimpleRegisterCoalescing::isWinToJoinCrossClass(unsigned SrcReg,
|
||||
unsigned DstReg,
|
||||
RegisterCoalescer::isWinToJoinCrossClass(unsigned SrcReg,
|
||||
unsigned DstReg,
|
||||
const TargetRegisterClass *SrcRC,
|
||||
const TargetRegisterClass *DstRC,
|
||||
const TargetRegisterClass *NewRC) {
|
||||
@ -1019,7 +996,7 @@ SimpleRegisterCoalescing::isWinToJoinCrossClass(unsigned SrcReg,
|
||||
/// if the copy was successfully coalesced away. If it is not currently
|
||||
/// possible to coalesce this interval, but it may be possible if other
|
||||
/// things get coalesced, then it returns true by reference in 'Again'.
|
||||
bool SimpleRegisterCoalescing::JoinCopy(MachineInstr *CopyMI, bool &Again) {
|
||||
bool RegisterCoalescer::JoinCopy(MachineInstr *CopyMI, bool &Again) {
|
||||
|
||||
Again = false;
|
||||
if (JoinedCopies.count(CopyMI) || ReMatCopies.count(CopyMI))
|
||||
@ -1211,7 +1188,7 @@ static unsigned ComputeUltimateVN(VNInfo *VNI,
|
||||
|
||||
/// JoinIntervals - Attempt to join these two intervals. On failure, this
|
||||
/// returns false.
|
||||
bool SimpleRegisterCoalescing::JoinIntervals(CoalescerPair &CP) {
|
||||
bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) {
|
||||
LiveInterval &RHS = li_->getInterval(CP.getSrcReg());
|
||||
DEBUG({ dbgs() << "\t\tRHS = "; RHS.print(dbgs(), tri_); dbgs() << "\n"; });
|
||||
|
||||
@ -1446,7 +1423,7 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB,
|
||||
void RegisterCoalescer::CopyCoalesceInMBB(MachineBasicBlock *MBB,
|
||||
std::vector<MachineInstr*> &TryAgain) {
|
||||
DEBUG(dbgs() << MBB->getName() << ":\n");
|
||||
|
||||
@ -1504,7 +1481,7 @@ void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB,
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleRegisterCoalescing::joinIntervals() {
|
||||
void RegisterCoalescer::joinIntervals() {
|
||||
DEBUG(dbgs() << "********** JOINING INTERVALS ***********\n");
|
||||
|
||||
std::vector<MachineInstr*> TryAgainList;
|
||||
@ -1555,13 +1532,13 @@ void SimpleRegisterCoalescing::joinIntervals() {
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleRegisterCoalescing::releaseMemory() {
|
||||
void RegisterCoalescer::releaseMemory() {
|
||||
JoinedCopies.clear();
|
||||
ReMatCopies.clear();
|
||||
ReMatDefs.clear();
|
||||
}
|
||||
|
||||
bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
|
||||
bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
|
||||
mf_ = &fn;
|
||||
mri_ = &fn.getRegInfo();
|
||||
tm_ = &fn.getTarget();
|
||||
@ -1706,13 +1683,10 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
|
||||
}
|
||||
|
||||
/// print - Implement the dump method.
|
||||
void SimpleRegisterCoalescing::print(raw_ostream &O, const Module* m) const {
|
||||
void RegisterCoalescer::print(raw_ostream &O, const Module* m) const {
|
||||
li_->print(O, m);
|
||||
}
|
||||
|
||||
RegisterCoalescer* llvm::createSimpleRegisterCoalescer() {
|
||||
return new SimpleRegisterCoalescing();
|
||||
RegisterCoalescer *llvm::createRegisterCoalescer() {
|
||||
return new RegisterCoalescer();
|
||||
}
|
||||
|
||||
// Make sure that anything that uses RegisterCoalescer pulls in this file...
|
||||
DEFINING_FILE_FOR(SimpleRegisterCoalescing)
|
||||
|
@ -29,24 +29,126 @@ namespace llvm {
|
||||
class TargetRegisterInfo;
|
||||
class TargetRegisterClass;
|
||||
class TargetInstrInfo;
|
||||
class SimpleRegisterCoalescing;
|
||||
class LiveDebugVariables;
|
||||
class VirtRegMap;
|
||||
class MachineLoopInfo;
|
||||
|
||||
class CoalescerPair;
|
||||
|
||||
/// An abstract interface for register coalescers. Coalescers must
|
||||
/// implement this interface to be part of the coalescer analysis
|
||||
/// group.
|
||||
class RegisterCoalescer {
|
||||
class RegisterCoalescer : public MachineFunctionPass {
|
||||
MachineFunction* mf_;
|
||||
MachineRegisterInfo* mri_;
|
||||
const TargetMachine* tm_;
|
||||
const TargetRegisterInfo* tri_;
|
||||
const TargetInstrInfo* tii_;
|
||||
LiveIntervals *li_;
|
||||
LiveDebugVariables *ldv_;
|
||||
const MachineLoopInfo* loopInfo;
|
||||
AliasAnalysis *AA;
|
||||
RegisterClassInfo RegClassInfo;
|
||||
|
||||
/// JoinedCopies - Keep track of copies eliminated due to coalescing.
|
||||
///
|
||||
SmallPtrSet<MachineInstr*, 32> JoinedCopies;
|
||||
|
||||
/// ReMatCopies - Keep track of copies eliminated due to remat.
|
||||
///
|
||||
SmallPtrSet<MachineInstr*, 32> ReMatCopies;
|
||||
|
||||
/// ReMatDefs - Keep track of definition instructions which have
|
||||
/// been remat'ed.
|
||||
SmallPtrSet<MachineInstr*, 8> ReMatDefs;
|
||||
|
||||
/// joinIntervals - join compatible live intervals
|
||||
void joinIntervals();
|
||||
|
||||
/// CopyCoalesceInMBB - Coalesce copies in the specified MBB, putting
|
||||
/// copies that cannot yet be coalesced into the "TryAgain" list.
|
||||
void CopyCoalesceInMBB(MachineBasicBlock *MBB,
|
||||
std::vector<MachineInstr*> &TryAgain);
|
||||
|
||||
/// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
|
||||
/// which are the src/dst of the copy instruction CopyMI. This returns true
|
||||
/// if the copy was successfully coalesced away. If it is not currently
|
||||
/// possible to coalesce this interval, but it may be possible if other
|
||||
/// things get coalesced, then it returns true by reference in 'Again'.
|
||||
bool JoinCopy(MachineInstr *TheCopy, bool &Again);
|
||||
|
||||
/// JoinIntervals - Attempt to join these two intervals. On failure, this
|
||||
/// returns false. The output "SrcInt" will not have been modified, so we can
|
||||
/// use this information below to update aliases.
|
||||
bool JoinIntervals(CoalescerPair &CP);
|
||||
|
||||
/// AdjustCopiesBackFrom - We found a non-trivially-coalescable copy. If
|
||||
/// the source value number is defined by a copy from the destination reg
|
||||
/// see if we can merge these two destination reg valno# into a single
|
||||
/// value number, eliminating a copy.
|
||||
bool AdjustCopiesBackFrom(const CoalescerPair &CP, MachineInstr *CopyMI);
|
||||
|
||||
/// HasOtherReachingDefs - Return true if there are definitions of IntB
|
||||
/// other than BValNo val# that can reach uses of AValno val# of IntA.
|
||||
bool HasOtherReachingDefs(LiveInterval &IntA, LiveInterval &IntB,
|
||||
VNInfo *AValNo, VNInfo *BValNo);
|
||||
|
||||
/// RemoveCopyByCommutingDef - We found a non-trivially-coalescable copy.
|
||||
/// If the source value number is defined by a commutable instruction and
|
||||
/// its other operand is coalesced to the copy dest register, see if we
|
||||
/// can transform the copy into a noop by commuting the definition.
|
||||
bool RemoveCopyByCommutingDef(const CoalescerPair &CP,MachineInstr *CopyMI);
|
||||
|
||||
/// ReMaterializeTrivialDef - If the source of a copy is defined by a trivial
|
||||
/// computation, replace the copy by rematerialize the definition.
|
||||
/// If PreserveSrcInt is true, make sure SrcInt is valid after the call.
|
||||
bool ReMaterializeTrivialDef(LiveInterval &SrcInt, bool PreserveSrcInt,
|
||||
unsigned DstReg, unsigned DstSubIdx,
|
||||
MachineInstr *CopyMI);
|
||||
|
||||
/// shouldJoinPhys - Return true if a physreg copy should be joined.
|
||||
bool shouldJoinPhys(CoalescerPair &CP);
|
||||
|
||||
/// isWinToJoinCrossClass - Return true if it's profitable to coalesce
|
||||
/// two virtual registers from different register classes.
|
||||
bool isWinToJoinCrossClass(unsigned SrcReg,
|
||||
unsigned DstReg,
|
||||
const TargetRegisterClass *SrcRC,
|
||||
const TargetRegisterClass *DstRC,
|
||||
const TargetRegisterClass *NewRC);
|
||||
|
||||
/// UpdateRegDefsUses - Replace all defs and uses of SrcReg to DstReg and
|
||||
/// update the subregister number if it is not zero. If DstReg is a
|
||||
/// physical register and the existing subregister number of the def / use
|
||||
/// being updated is not zero, make sure to set it to the correct physical
|
||||
/// subregister.
|
||||
void UpdateRegDefsUses(const CoalescerPair &CP);
|
||||
|
||||
/// RemoveDeadDef - If a def of a live interval is now determined dead,
|
||||
/// remove the val# it defines. If the live interval becomes empty, remove
|
||||
/// it as well.
|
||||
bool RemoveDeadDef(LiveInterval &li, MachineInstr *DefMI);
|
||||
|
||||
/// RemoveCopyFlag - If DstReg is no longer defined by CopyMI, clear the
|
||||
/// VNInfo copy flag for DstReg and all aliases.
|
||||
void RemoveCopyFlag(unsigned DstReg, const MachineInstr *CopyMI);
|
||||
|
||||
/// markAsJoined - Remember that CopyMI has already been joined.
|
||||
void markAsJoined(MachineInstr *CopyMI);
|
||||
|
||||
public:
|
||||
static char ID; // Class identification, replacement for typeinfo
|
||||
RegisterCoalescer() {}
|
||||
virtual ~RegisterCoalescer(); // We want to be subclassed
|
||||
RegisterCoalescer() : MachineFunctionPass(ID) {
|
||||
initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
/// Run the coalescer on this function, providing interference
|
||||
/// data to query. Return whether we removed any copies.
|
||||
virtual bool coalesceFunction(MachineFunction &mf,
|
||||
RegallocQuery &ifd) = 0;
|
||||
RegallocQuery &ifd) {
|
||||
// This runs as an independent pass, so don't do anything.
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Reset state. Can be used to allow a coalescer run by
|
||||
/// PassManager to be run again by the register allocator.
|
||||
@ -59,8 +161,16 @@ namespace llvm {
|
||||
/// which to invalidate when running the register allocator or any
|
||||
/// pass that might call coalescing. The long-term solution is to
|
||||
/// allow hierarchies of PassManagers.
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {}
|
||||
};
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
||||
virtual void releaseMemory();
|
||||
|
||||
/// runOnMachineFunction - pass entry point
|
||||
virtual bool runOnMachineFunction(MachineFunction&);
|
||||
|
||||
/// print - Implement the dump method.
|
||||
virtual void print(raw_ostream &O, const Module* = 0) const;
|
||||
};
|
||||
|
||||
/// An abstract interface for register allocators to interact with
|
||||
/// coalescers
|
||||
@ -82,7 +192,7 @@ namespace llvm {
|
||||
/// /// allocation doesn't pre-compute interference information it's
|
||||
/// /// the best we can do. Coalescers are always free to ignore this
|
||||
/// /// and implement their own discovery strategy. See
|
||||
/// /// SimpleRegisterCoalescing for an example.
|
||||
/// /// RegisterCoalescer for an example.
|
||||
/// void getInterferences(IntervalSet &interferences,
|
||||
/// const LiveInterval &a) const {
|
||||
/// for(LiveIntervals::const_iterator iv = li.begin(),
|
||||
@ -236,135 +346,6 @@ namespace llvm {
|
||||
/// getNewRC - Return the register class of the coalesced register.
|
||||
const TargetRegisterClass *getNewRC() const { return newRC_; }
|
||||
};
|
||||
|
||||
class SimpleRegisterCoalescing : public MachineFunctionPass,
|
||||
public RegisterCoalescer {
|
||||
MachineFunction* mf_;
|
||||
MachineRegisterInfo* mri_;
|
||||
const TargetMachine* tm_;
|
||||
const TargetRegisterInfo* tri_;
|
||||
const TargetInstrInfo* tii_;
|
||||
LiveIntervals *li_;
|
||||
LiveDebugVariables *ldv_;
|
||||
const MachineLoopInfo* loopInfo;
|
||||
AliasAnalysis *AA;
|
||||
RegisterClassInfo RegClassInfo;
|
||||
|
||||
/// JoinedCopies - Keep track of copies eliminated due to coalescing.
|
||||
///
|
||||
SmallPtrSet<MachineInstr*, 32> JoinedCopies;
|
||||
|
||||
/// ReMatCopies - Keep track of copies eliminated due to remat.
|
||||
///
|
||||
SmallPtrSet<MachineInstr*, 32> ReMatCopies;
|
||||
|
||||
/// ReMatDefs - Keep track of definition instructions which have
|
||||
/// been remat'ed.
|
||||
SmallPtrSet<MachineInstr*, 8> ReMatDefs;
|
||||
|
||||
public:
|
||||
static char ID; // Pass identifcation, replacement for typeid
|
||||
SimpleRegisterCoalescing() : MachineFunctionPass(ID) {
|
||||
initializeSimpleRegisterCoalescingPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
virtual void releaseMemory();
|
||||
|
||||
/// runOnMachineFunction - pass entry point
|
||||
virtual bool runOnMachineFunction(MachineFunction&);
|
||||
|
||||
bool coalesceFunction(MachineFunction &mf, RegallocQuery &) {
|
||||
// This runs as an independent pass, so don't do anything.
|
||||
return false;
|
||||
}
|
||||
|
||||
/// print - Implement the dump method.
|
||||
virtual void print(raw_ostream &O, const Module* = 0) const;
|
||||
|
||||
private:
|
||||
/// joinIntervals - join compatible live intervals
|
||||
void joinIntervals();
|
||||
|
||||
/// CopyCoalesceInMBB - Coalesce copies in the specified MBB, putting
|
||||
/// copies that cannot yet be coalesced into the "TryAgain" list.
|
||||
void CopyCoalesceInMBB(MachineBasicBlock *MBB,
|
||||
std::vector<MachineInstr*> &TryAgain);
|
||||
|
||||
/// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
|
||||
/// which are the src/dst of the copy instruction CopyMI. This returns true
|
||||
/// if the copy was successfully coalesced away. If it is not currently
|
||||
/// possible to coalesce this interval, but it may be possible if other
|
||||
/// things get coalesced, then it returns true by reference in 'Again'.
|
||||
bool JoinCopy(MachineInstr *TheCopy, bool &Again);
|
||||
|
||||
/// JoinIntervals - Attempt to join these two intervals. On failure, this
|
||||
/// returns false. The output "SrcInt" will not have been modified, so we can
|
||||
/// use this information below to update aliases.
|
||||
bool JoinIntervals(CoalescerPair &CP);
|
||||
|
||||
/// AdjustCopiesBackFrom - We found a non-trivially-coalescable copy. If
|
||||
/// the source value number is defined by a copy from the destination reg
|
||||
/// see if we can merge these two destination reg valno# into a single
|
||||
/// value number, eliminating a copy.
|
||||
bool AdjustCopiesBackFrom(const CoalescerPair &CP, MachineInstr *CopyMI);
|
||||
|
||||
/// HasOtherReachingDefs - Return true if there are definitions of IntB
|
||||
/// other than BValNo val# that can reach uses of AValno val# of IntA.
|
||||
bool HasOtherReachingDefs(LiveInterval &IntA, LiveInterval &IntB,
|
||||
VNInfo *AValNo, VNInfo *BValNo);
|
||||
|
||||
/// RemoveCopyByCommutingDef - We found a non-trivially-coalescable copy.
|
||||
/// If the source value number is defined by a commutable instruction and
|
||||
/// its other operand is coalesced to the copy dest register, see if we
|
||||
/// can transform the copy into a noop by commuting the definition.
|
||||
bool RemoveCopyByCommutingDef(const CoalescerPair &CP,MachineInstr *CopyMI);
|
||||
|
||||
/// ReMaterializeTrivialDef - If the source of a copy is defined by a trivial
|
||||
/// computation, replace the copy by rematerialize the definition.
|
||||
/// If PreserveSrcInt is true, make sure SrcInt is valid after the call.
|
||||
bool ReMaterializeTrivialDef(LiveInterval &SrcInt, bool PreserveSrcInt,
|
||||
unsigned DstReg, unsigned DstSubIdx,
|
||||
MachineInstr *CopyMI);
|
||||
|
||||
/// shouldJoinPhys - Return true if a physreg copy should be joined.
|
||||
bool shouldJoinPhys(CoalescerPair &CP);
|
||||
|
||||
/// isWinToJoinCrossClass - Return true if it's profitable to coalesce
|
||||
/// two virtual registers from different register classes.
|
||||
bool isWinToJoinCrossClass(unsigned SrcReg,
|
||||
unsigned DstReg,
|
||||
const TargetRegisterClass *SrcRC,
|
||||
const TargetRegisterClass *DstRC,
|
||||
const TargetRegisterClass *NewRC);
|
||||
|
||||
/// UpdateRegDefsUses - Replace all defs and uses of SrcReg to DstReg and
|
||||
/// update the subregister number if it is not zero. If DstReg is a
|
||||
/// physical register and the existing subregister number of the def / use
|
||||
/// being updated is not zero, make sure to set it to the correct physical
|
||||
/// subregister.
|
||||
void UpdateRegDefsUses(const CoalescerPair &CP);
|
||||
|
||||
/// RemoveDeadDef - If a def of a live interval is now determined dead,
|
||||
/// remove the val# it defines. If the live interval becomes empty, remove
|
||||
/// it as well.
|
||||
bool RemoveDeadDef(LiveInterval &li, MachineInstr *DefMI);
|
||||
|
||||
/// RemoveCopyFlag - If DstReg is no longer defined by CopyMI, clear the
|
||||
/// VNInfo copy flag for DstReg and all aliases.
|
||||
void RemoveCopyFlag(unsigned DstReg, const MachineInstr *CopyMI);
|
||||
|
||||
/// markAsJoined - Remember that CopyMI has already been joined.
|
||||
void markAsJoined(MachineInstr *CopyMI);
|
||||
};
|
||||
} // End llvm namespace
|
||||
|
||||
// Because of the way .a files work, we must force the SimpleRC
|
||||
// implementation to be pulled in if the RegisterCoalescing header is
|
||||
// included. Otherwise we run the risk of RegisterCoalescing being
|
||||
// used, but the default implementation not being linked into the tool
|
||||
// that uses it.
|
||||
FORCE_DEFINING_FILE_TO_BE_LINKED(RegisterCoalescer)
|
||||
FORCE_DEFINING_FILE_TO_BE_LINKED(SimpleRegisterCoalescing)
|
||||
|
||||
#endif
|
||||
|
@ -122,7 +122,7 @@ void SplitAnalysis::analyzeUses() {
|
||||
// Compute per-live block info.
|
||||
if (!calcLiveBlockInfo()) {
|
||||
// FIXME: calcLiveBlockInfo found inconsistencies in the live range.
|
||||
// I am looking at you, SimpleRegisterCoalescing!
|
||||
// I am looking at you, RegisterCoalescer!
|
||||
DidRepairRange = true;
|
||||
++NumRepairs;
|
||||
DEBUG(dbgs() << "*** Fixing inconsistent live interval! ***\n");
|
||||
@ -165,7 +165,7 @@ bool SplitAnalysis::calcLiveBlockInfo() {
|
||||
tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(BI.MBB);
|
||||
|
||||
// If the block contains no uses, the range must be live through. At one
|
||||
// point, SimpleRegisterCoalescing could create dangling ranges that ended
|
||||
// point, RegisterCoalescer could create dangling ranges that ended
|
||||
// mid-block.
|
||||
if (UseI == UseE || *UseI >= Stop) {
|
||||
++NumThroughBlocks;
|
||||
|
Loading…
x
Reference in New Issue
Block a user