mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-30 17:25:21 +00:00
Take advantage of the recent improvements to the liveintervals set (tracking
instructions which define each value#) to simplify and improve the coallescer. In particular, this patch: 1. Implements iterative coallescing. 2. Reverts an unsafe hack from handlePhysRegDef, superceeding it with a better solution. 3. Implements PR865, "coallescing" away the second copy in code like: A = B ... B = A This also includes changes to symbolically print registers in intervals when possible. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29862 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -82,7 +82,7 @@ namespace llvm {
|
||||
|
||||
/// InstDefiningValue - This tracks the def index of the instruction that
|
||||
/// defines a particular value number in the interval. This may be ~0,
|
||||
/// which is treated as unknown.
|
||||
/// which is treated as unknown, or ~1, which is a deleted value number.
|
||||
SmallVector<unsigned, 4> InstDefiningValue;
|
||||
public:
|
||||
|
||||
@@ -116,10 +116,13 @@ namespace llvm {
|
||||
std::swap(weight, other.weight);
|
||||
std::swap(ranges, other.ranges);
|
||||
std::swap(NumValues, other.NumValues);
|
||||
std::swap(InstDefiningValue, other.InstDefiningValue);
|
||||
}
|
||||
|
||||
bool containsOneValue() const { return NumValues == 1; }
|
||||
|
||||
unsigned getNumValNums() const { return NumValues; }
|
||||
|
||||
/// getNextValue - Create a new value number and return it. MIIdx specifies
|
||||
/// the instruction that defines the value number.
|
||||
unsigned getNextValue(unsigned MIIdx) {
|
||||
@@ -138,6 +141,12 @@ namespace llvm {
|
||||
void setInstDefiningValNum(unsigned ValNo, unsigned MIIdx) {
|
||||
InstDefiningValue[ValNo] = MIIdx;
|
||||
}
|
||||
|
||||
/// MergeValueNumberInto - This method is called when two value nubmers
|
||||
/// are found to be equivalent. This eliminates V1, replacing all
|
||||
/// LiveRanges with the V1 value number with the V2 value number. This can
|
||||
/// cause merging of V1/V2 values numbers and compaction of the value space.
|
||||
void MergeValueNumberInto(unsigned V1, unsigned V2);
|
||||
|
||||
|
||||
bool empty() const { return ranges.empty(); }
|
||||
@@ -163,9 +172,19 @@ namespace llvm {
|
||||
|
||||
/// getLiveRangeContaining - Return the live range that contains the
|
||||
/// specified index, or null if there is none.
|
||||
const LiveRange *getLiveRangeContaining(unsigned Idx) const;
|
||||
const LiveRange *getLiveRangeContaining(unsigned Idx) const {
|
||||
const_iterator I = FindLiveRangeContaining(Idx);
|
||||
return I == end() ? 0 : &*I;
|
||||
}
|
||||
|
||||
/// FindLiveRangeContaining - Return an iterator to the live range that
|
||||
/// contains the specified index, or end() if there is none.
|
||||
const_iterator FindLiveRangeContaining(unsigned Idx) const;
|
||||
|
||||
/// FindLiveRangeContaining - Return an iterator to the live range that
|
||||
/// contains the specified index, or end() if there is none.
|
||||
iterator FindLiveRangeContaining(unsigned Idx);
|
||||
|
||||
/// joinable - Two intervals are joinable if the either don't overlap at all
|
||||
/// or if the destination of the copy is a single assignment value, and it
|
||||
/// only overlaps with one value in the source interval.
|
||||
|
@@ -53,8 +53,18 @@ namespace llvm {
|
||||
std::vector<bool> allocatableRegs_;
|
||||
|
||||
public:
|
||||
struct InstrSlots
|
||||
{
|
||||
struct CopyRec {
|
||||
MachineInstr *MI;
|
||||
unsigned SrcReg, DstReg;
|
||||
};
|
||||
CopyRec getCopyRec(MachineInstr *MI, unsigned SrcReg, unsigned DstReg) {
|
||||
CopyRec R;
|
||||
R.MI = MI;
|
||||
R.SrcReg = SrcReg;
|
||||
R.DstReg = DstReg;
|
||||
return R;
|
||||
}
|
||||
struct InstrSlots {
|
||||
enum {
|
||||
LOAD = 0,
|
||||
USE = 1,
|
||||
@@ -133,16 +143,37 @@ namespace llvm {
|
||||
virtual void print(std::ostream &O, const Module* = 0) const;
|
||||
|
||||
private:
|
||||
/// RemoveMachineInstrFromMaps - This marks the specified machine instr as
|
||||
/// deleted.
|
||||
void RemoveMachineInstrFromMaps(MachineInstr *MI) {
|
||||
// remove index -> MachineInstr and
|
||||
// MachineInstr -> index mappings
|
||||
Mi2IndexMap::iterator mi2i = mi2iMap_.find(MI);
|
||||
if (mi2i != mi2iMap_.end()) {
|
||||
i2miMap_[mi2i->second/InstrSlots::NUM] = 0;
|
||||
mi2iMap_.erase(mi2i);
|
||||
}
|
||||
}
|
||||
|
||||
/// computeIntervals - compute live intervals
|
||||
void computeIntervals();
|
||||
|
||||
/// joinIntervals - join compatible live intervals
|
||||
void joinIntervals();
|
||||
|
||||
/// joinIntervalsInMachineBB - Join intervals based on move
|
||||
/// instructions in the specified basic block.
|
||||
void joinIntervalsInMachineBB(MachineBasicBlock *MBB);
|
||||
/// CopyCoallesceInMBB - Coallsece copies in the specified MBB, putting
|
||||
/// copies that cannot yet be coallesced into the "TryAgain" list.
|
||||
void CopyCoallesceInMBB(MachineBasicBlock *MBB,
|
||||
std::vector<CopyRec> &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 coallesced away, or if it is never possible
|
||||
/// to coallesce these this copy, due to register constraints. It returns
|
||||
/// false if it is not currently possible to coallesce this interval, but
|
||||
/// it may be possible if other things get coallesced.
|
||||
bool JoinCopy(MachineInstr *CopyMI, unsigned SrcReg, unsigned DstReg);
|
||||
|
||||
/// handleRegisterDef - update intervals for a register def
|
||||
/// (calls handlePhysicalRegisterDef and
|
||||
/// handleVirtualRegisterDef)
|
||||
@@ -157,14 +188,10 @@ namespace llvm {
|
||||
LiveInterval& interval);
|
||||
|
||||
/// handlePhysicalRegisterDef - update intervals for a physical register
|
||||
/// def. If the defining instruction is a move instruction, SrcReg will be
|
||||
/// the input register, and DestReg will be the result. Note that Interval
|
||||
/// may not match DestReg (it might be an alias instead).
|
||||
///
|
||||
/// def.
|
||||
void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
|
||||
MachineBasicBlock::iterator mi,
|
||||
LiveInterval& interval,
|
||||
unsigned SrcReg, unsigned DestReg,
|
||||
bool isLiveIn = false);
|
||||
|
||||
/// Return true if the two specified registers belong to different
|
||||
@@ -172,9 +199,8 @@ namespace llvm {
|
||||
bool differingRegisterClasses(unsigned RegA, unsigned RegB) const;
|
||||
|
||||
|
||||
bool AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA,
|
||||
LiveInterval &IntB,
|
||||
unsigned CopyIdx);
|
||||
bool AdjustCopiesBackFrom(LiveInterval &IntA, LiveInterval &IntB,
|
||||
MachineInstr *CopyMI, unsigned CopyIdx);
|
||||
|
||||
bool overlapsAliases(const LiveInterval *lhs,
|
||||
const LiveInterval *rhs) const;
|
||||
|
Reference in New Issue
Block a user