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:
Rafael Espindola 2011-06-26 22:34:10 +00:00
parent 655739de7b
commit 5b220213bf
11 changed files with 154 additions and 208 deletions

View File

@ -39,8 +39,6 @@ namespace {
(void) llvm::createGreedyRegisterAllocator();
(void) llvm::createDefaultPBQPRegisterAllocator();
(void) llvm::createSimpleRegisterCoalescer();
llvm::linkOcamlGC();
llvm::linkShadowStackGC();

View File

@ -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.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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

View File

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