forked from OSchip/llvm-project
TargetRegisterInfo: Add typedef unsigned LaneBitmask and use it where apropriate; NFC
llvm-svn: 248623
This commit is contained in:
parent
bbbf9a1a34
commit
e6a2485e1a
|
@ -25,6 +25,7 @@
|
||||||
#include "llvm/CodeGen/SlotIndexes.h"
|
#include "llvm/CodeGen/SlotIndexes.h"
|
||||||
#include "llvm/Support/AlignOf.h"
|
#include "llvm/Support/AlignOf.h"
|
||||||
#include "llvm/Support/Allocator.h"
|
#include "llvm/Support/Allocator.h"
|
||||||
|
#include "llvm/Target/TargetRegisterInfo.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -595,15 +596,15 @@ namespace llvm {
|
||||||
class SubRange : public LiveRange {
|
class SubRange : public LiveRange {
|
||||||
public:
|
public:
|
||||||
SubRange *Next;
|
SubRange *Next;
|
||||||
unsigned LaneMask;
|
LaneBitmask LaneMask;
|
||||||
|
|
||||||
/// Constructs a new SubRange object.
|
/// Constructs a new SubRange object.
|
||||||
SubRange(unsigned LaneMask)
|
SubRange(LaneBitmask LaneMask)
|
||||||
: Next(nullptr), LaneMask(LaneMask) {
|
: Next(nullptr), LaneMask(LaneMask) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new SubRange object by copying liveness from @p Other.
|
/// Constructs a new SubRange object by copying liveness from @p Other.
|
||||||
SubRange(unsigned LaneMask, const LiveRange &Other,
|
SubRange(LaneBitmask LaneMask, const LiveRange &Other,
|
||||||
BumpPtrAllocator &Allocator)
|
BumpPtrAllocator &Allocator)
|
||||||
: LiveRange(Other, Allocator), Next(nullptr), LaneMask(LaneMask) {
|
: LiveRange(Other, Allocator), Next(nullptr), LaneMask(LaneMask) {
|
||||||
}
|
}
|
||||||
|
@ -677,7 +678,8 @@ namespace llvm {
|
||||||
|
|
||||||
/// Creates a new empty subregister live range. The range is added at the
|
/// Creates a new empty subregister live range. The range is added at the
|
||||||
/// beginning of the subrange list; subrange iterators stay valid.
|
/// beginning of the subrange list; subrange iterators stay valid.
|
||||||
SubRange *createSubRange(BumpPtrAllocator &Allocator, unsigned LaneMask) {
|
SubRange *createSubRange(BumpPtrAllocator &Allocator,
|
||||||
|
LaneBitmask LaneMask) {
|
||||||
SubRange *Range = new (Allocator) SubRange(LaneMask);
|
SubRange *Range = new (Allocator) SubRange(LaneMask);
|
||||||
appendSubRange(Range);
|
appendSubRange(Range);
|
||||||
return Range;
|
return Range;
|
||||||
|
@ -685,7 +687,8 @@ namespace llvm {
|
||||||
|
|
||||||
/// Like createSubRange() but the new range is filled with a copy of the
|
/// Like createSubRange() but the new range is filled with a copy of the
|
||||||
/// liveness information in @p CopyFrom.
|
/// liveness information in @p CopyFrom.
|
||||||
SubRange *createSubRangeFrom(BumpPtrAllocator &Allocator, unsigned LaneMask,
|
SubRange *createSubRangeFrom(BumpPtrAllocator &Allocator,
|
||||||
|
LaneBitmask LaneMask,
|
||||||
const LiveRange &CopyFrom) {
|
const LiveRange &CopyFrom) {
|
||||||
SubRange *Range = new (Allocator) SubRange(LaneMask, CopyFrom, Allocator);
|
SubRange *Range = new (Allocator) SubRange(LaneMask, CopyFrom, Allocator);
|
||||||
appendSubRange(Range);
|
appendSubRange(Range);
|
||||||
|
|
|
@ -440,7 +440,7 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||||
void repairOldRegInRange(MachineBasicBlock::iterator Begin,
|
void repairOldRegInRange(MachineBasicBlock::iterator Begin,
|
||||||
MachineBasicBlock::iterator End,
|
MachineBasicBlock::iterator End,
|
||||||
const SlotIndex endIdx, LiveRange &LR,
|
const SlotIndex endIdx, LiveRange &LR,
|
||||||
unsigned Reg, unsigned LaneMask = ~0u);
|
unsigned Reg, LaneBitmask LaneMask = ~0u);
|
||||||
|
|
||||||
class HMEditor;
|
class HMEditor;
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,6 +32,9 @@ class StringRef;
|
||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
class MachineBranchProbabilityInfo;
|
class MachineBranchProbabilityInfo;
|
||||||
|
|
||||||
|
// Forward declaration to avoid circular include problem with TargetRegisterInfo
|
||||||
|
typedef unsigned LaneBitmask;
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> {
|
struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> {
|
||||||
private:
|
private:
|
||||||
|
@ -69,9 +72,9 @@ public:
|
||||||
struct RegisterMaskPair {
|
struct RegisterMaskPair {
|
||||||
public:
|
public:
|
||||||
MCPhysReg PhysReg;
|
MCPhysReg PhysReg;
|
||||||
unsigned LaneMask;
|
LaneBitmask LaneMask;
|
||||||
|
|
||||||
RegisterMaskPair(MCPhysReg PhysReg, unsigned LaneMask)
|
RegisterMaskPair(MCPhysReg PhysReg, LaneBitmask LaneMask)
|
||||||
: PhysReg(PhysReg), LaneMask(LaneMask) {}
|
: PhysReg(PhysReg), LaneMask(LaneMask) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -328,7 +331,7 @@ public:
|
||||||
/// Adds the specified register as a live in. Note that it is an error to add
|
/// Adds the specified register as a live in. Note that it is an error to add
|
||||||
/// the same register to the same set more than once unless the intention is
|
/// the same register to the same set more than once unless the intention is
|
||||||
/// to call sortUniqueLiveIns after all registers are added.
|
/// to call sortUniqueLiveIns after all registers are added.
|
||||||
void addLiveIn(MCPhysReg PhysReg, unsigned LaneMask = ~0u) {
|
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask = ~0u) {
|
||||||
LiveIns.push_back(RegisterMaskPair(PhysReg, LaneMask));
|
LiveIns.push_back(RegisterMaskPair(PhysReg, LaneMask));
|
||||||
}
|
}
|
||||||
void addLiveIn(const RegisterMaskPair &RegMaskPair) {
|
void addLiveIn(const RegisterMaskPair &RegMaskPair) {
|
||||||
|
@ -346,10 +349,10 @@ public:
|
||||||
unsigned addLiveIn(MCPhysReg PhysReg, const TargetRegisterClass *RC);
|
unsigned addLiveIn(MCPhysReg PhysReg, const TargetRegisterClass *RC);
|
||||||
|
|
||||||
/// Remove the specified register from the live in set.
|
/// Remove the specified register from the live in set.
|
||||||
void removeLiveIn(MCPhysReg Reg, unsigned LaneMask = ~0u);
|
void removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask = ~0u);
|
||||||
|
|
||||||
/// Return true if the specified register is in the live in set.
|
/// Return true if the specified register is in the live in set.
|
||||||
bool isLiveIn(MCPhysReg Reg, unsigned LaneMask = ~0u) const;
|
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask = ~0u) const;
|
||||||
|
|
||||||
// Iteration support for live in sets. These sets are kept in sorted
|
// Iteration support for live in sets. These sets are kept in sorted
|
||||||
// order by their register number.
|
// order by their register number.
|
||||||
|
|
|
@ -759,7 +759,7 @@ public:
|
||||||
|
|
||||||
/// Returns a mask covering all bits that can appear in lane masks of
|
/// Returns a mask covering all bits that can appear in lane masks of
|
||||||
/// subregisters of the virtual register @p Reg.
|
/// subregisters of the virtual register @p Reg.
|
||||||
unsigned getMaxLaneMaskForVReg(unsigned Reg) const;
|
LaneBitmask getMaxLaneMaskForVReg(unsigned Reg) const;
|
||||||
|
|
||||||
/// defusechain_iterator - This class provides iterator support for machine
|
/// defusechain_iterator - This class provides iterator support for machine
|
||||||
/// operands in the function that use or define a specific register. If
|
/// operands in the function that use or define a specific register. If
|
||||||
|
|
|
@ -152,7 +152,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tell the scavenger a register is used.
|
/// Tell the scavenger a register is used.
|
||||||
void setRegUsed(unsigned Reg, unsigned LaneMask = ~0u);
|
void setRegUsed(unsigned Reg, LaneBitmask LaneMask = ~0u);
|
||||||
private:
|
private:
|
||||||
/// Returns true if a register is reserved. It is never "unused".
|
/// Returns true if a register is reserved. It is never "unused".
|
||||||
bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); }
|
bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); }
|
||||||
|
|
|
@ -35,6 +35,26 @@ class VirtRegMap;
|
||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
class LiveRegMatrix;
|
class LiveRegMatrix;
|
||||||
|
|
||||||
|
/// A bitmask representing the parts of a register are alive.
|
||||||
|
///
|
||||||
|
/// Lane masks for sub-register indices are similar to register units for
|
||||||
|
/// physical registers. The individual bits in a lane mask can't be assigned
|
||||||
|
/// any specific meaning. They can be used to check if two sub-register
|
||||||
|
/// indices overlap.
|
||||||
|
///
|
||||||
|
/// If the target has a register such that:
|
||||||
|
///
|
||||||
|
/// getSubReg(Reg, A) overlaps getSubReg(Reg, B)
|
||||||
|
///
|
||||||
|
/// then:
|
||||||
|
///
|
||||||
|
/// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0
|
||||||
|
///
|
||||||
|
/// The converse is not necessarily true. If two lane masks have a common
|
||||||
|
/// bit, the corresponding sub-registers may not overlap, but it can be
|
||||||
|
/// assumed that they usually will.
|
||||||
|
typedef unsigned LaneBitmask;
|
||||||
|
|
||||||
class TargetRegisterClass {
|
class TargetRegisterClass {
|
||||||
public:
|
public:
|
||||||
typedef const MCPhysReg* iterator;
|
typedef const MCPhysReg* iterator;
|
||||||
|
@ -47,7 +67,7 @@ public:
|
||||||
const vt_iterator VTs;
|
const vt_iterator VTs;
|
||||||
const uint32_t *SubClassMask;
|
const uint32_t *SubClassMask;
|
||||||
const uint16_t *SuperRegIndices;
|
const uint16_t *SuperRegIndices;
|
||||||
const unsigned LaneMask;
|
const LaneBitmask LaneMask;
|
||||||
/// Classes with a higher priority value are assigned first by register
|
/// Classes with a higher priority value are assigned first by register
|
||||||
/// allocators using a greedy heuristic. The value is in the range [0,63].
|
/// allocators using a greedy heuristic. The value is in the range [0,63].
|
||||||
const uint8_t AllocationPriority;
|
const uint8_t AllocationPriority;
|
||||||
|
@ -202,7 +222,7 @@ public:
|
||||||
/// Returns the combination of all lane masks of register in this class.
|
/// Returns the combination of all lane masks of register in this class.
|
||||||
/// The lane masks of the registers are the combination of all lane masks
|
/// The lane masks of the registers are the combination of all lane masks
|
||||||
/// of their subregisters.
|
/// of their subregisters.
|
||||||
unsigned getLaneMask() const {
|
LaneBitmask getLaneMask() const {
|
||||||
return LaneMask;
|
return LaneMask;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -234,7 +254,7 @@ private:
|
||||||
const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen
|
const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen
|
||||||
const char *const *SubRegIndexNames; // Names of subreg indexes.
|
const char *const *SubRegIndexNames; // Names of subreg indexes.
|
||||||
// Pointer to array of lane masks, one per sub-reg index.
|
// Pointer to array of lane masks, one per sub-reg index.
|
||||||
const unsigned *SubRegIndexLaneMasks;
|
const LaneBitmask *SubRegIndexLaneMasks;
|
||||||
|
|
||||||
regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
|
regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
|
||||||
unsigned CoveringLanes;
|
unsigned CoveringLanes;
|
||||||
|
@ -244,7 +264,7 @@ protected:
|
||||||
regclass_iterator RegClassBegin,
|
regclass_iterator RegClassBegin,
|
||||||
regclass_iterator RegClassEnd,
|
regclass_iterator RegClassEnd,
|
||||||
const char *const *SRINames,
|
const char *const *SRINames,
|
||||||
const unsigned *SRILaneMasks,
|
const LaneBitmask *SRILaneMasks,
|
||||||
unsigned CoveringLanes);
|
unsigned CoveringLanes);
|
||||||
virtual ~TargetRegisterInfo();
|
virtual ~TargetRegisterInfo();
|
||||||
public:
|
public:
|
||||||
|
@ -350,27 +370,11 @@ public:
|
||||||
return SubRegIndexNames[SubIdx-1];
|
return SubRegIndexNames[SubIdx-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getSubRegIndexLaneMask - Return a bitmask representing the parts of a
|
/// Return a bitmask representing the parts of a register that are covered by
|
||||||
/// register that are covered by SubIdx.
|
/// SubIdx \see LaneBitmask.
|
||||||
///
|
///
|
||||||
/// Lane masks for sub-register indices are similar to register units for
|
|
||||||
/// physical registers. The individual bits in a lane mask can't be assigned
|
|
||||||
/// any specific meaning. They can be used to check if two sub-register
|
|
||||||
/// indices overlap.
|
|
||||||
///
|
|
||||||
/// If the target has a register such that:
|
|
||||||
///
|
|
||||||
/// getSubReg(Reg, A) overlaps getSubReg(Reg, B)
|
|
||||||
///
|
|
||||||
/// then:
|
|
||||||
///
|
|
||||||
/// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0
|
|
||||||
///
|
|
||||||
/// The converse is not necessarily true. If two lane masks have a common
|
|
||||||
/// bit, the corresponding sub-registers may not overlap, but it can be
|
|
||||||
/// assumed that they usually will.
|
|
||||||
/// SubIdx == 0 is allowed, it has the lane mask ~0u.
|
/// SubIdx == 0 is allowed, it has the lane mask ~0u.
|
||||||
unsigned getSubRegIndexLaneMask(unsigned SubIdx) const {
|
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const {
|
||||||
assert(SubIdx < getNumSubRegIndices() && "This is not a subregister index");
|
assert(SubIdx < getNumSubRegIndices() && "This is not a subregister index");
|
||||||
return SubRegIndexLaneMasks[SubIdx];
|
return SubRegIndexLaneMasks[SubIdx];
|
||||||
}
|
}
|
||||||
|
@ -384,7 +388,7 @@ public:
|
||||||
/// but we still have
|
/// but we still have
|
||||||
/// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0.
|
/// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0.
|
||||||
/// This function returns true in those cases.
|
/// This function returns true in those cases.
|
||||||
static bool isImpreciseLaneMask(unsigned LaneMask) {
|
static bool isImpreciseLaneMask(LaneBitmask LaneMask) {
|
||||||
return LaneMask & 0x80000000u;
|
return LaneMask & 0x80000000u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,7 +415,7 @@ public:
|
||||||
///
|
///
|
||||||
/// If (MaskA & ~(MaskB & Covering)) == 0, then SubA is completely covered by
|
/// If (MaskA & ~(MaskB & Covering)) == 0, then SubA is completely covered by
|
||||||
/// SubB.
|
/// SubB.
|
||||||
unsigned getCoveringLanes() const { return CoveringLanes; }
|
LaneBitmask getCoveringLanes() const { return CoveringLanes; }
|
||||||
|
|
||||||
/// regsOverlap - Returns true if the two registers are equal or alias each
|
/// regsOverlap - Returns true if the two registers are equal or alias each
|
||||||
/// other. The registers may be virtual register.
|
/// other. The registers may be virtual register.
|
||||||
|
@ -552,10 +556,11 @@ public:
|
||||||
/// Transforms a LaneMask computed for one subregister to the lanemask that
|
/// Transforms a LaneMask computed for one subregister to the lanemask that
|
||||||
/// would have been computed when composing the subsubregisters with IdxA
|
/// would have been computed when composing the subsubregisters with IdxA
|
||||||
/// first. @sa composeSubRegIndices()
|
/// first. @sa composeSubRegIndices()
|
||||||
unsigned composeSubRegIndexLaneMask(unsigned IdxA, unsigned LaneMask) const {
|
LaneBitmask composeSubRegIndexLaneMask(unsigned IdxA,
|
||||||
|
LaneBitmask Mask) const {
|
||||||
if (!IdxA)
|
if (!IdxA)
|
||||||
return LaneMask;
|
return Mask;
|
||||||
return composeSubRegIndexLaneMaskImpl(IdxA, LaneMask);
|
return composeSubRegIndexLaneMaskImpl(IdxA, Mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Debugging helper: dump register in human readable form to dbgs() stream.
|
/// Debugging helper: dump register in human readable form to dbgs() stream.
|
||||||
|
@ -569,8 +574,8 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Overridden by TableGen in targets that have sub-registers.
|
/// Overridden by TableGen in targets that have sub-registers.
|
||||||
virtual unsigned
|
virtual LaneBitmask
|
||||||
composeSubRegIndexLaneMaskImpl(unsigned, unsigned) const {
|
composeSubRegIndexLaneMaskImpl(unsigned, LaneBitmask) const {
|
||||||
llvm_unreachable("Target has no sub-registers");
|
llvm_unreachable("Target has no sub-registers");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -889,7 +889,7 @@ void LiveInterval::constructMainRangeFromSubranges(
|
||||||
Segment CurrentSegment;
|
Segment CurrentSegment;
|
||||||
bool ConstructingSegment = false;
|
bool ConstructingSegment = false;
|
||||||
bool NeedVNIFixup = false;
|
bool NeedVNIFixup = false;
|
||||||
unsigned ActiveMask = 0;
|
LaneBitmask ActiveMask = 0;
|
||||||
SlotIndex Pos = First;
|
SlotIndex Pos = First;
|
||||||
while (true) {
|
while (true) {
|
||||||
SlotIndex NextPos = Last;
|
SlotIndex NextPos = Last;
|
||||||
|
@ -899,7 +899,7 @@ void LiveInterval::constructMainRangeFromSubranges(
|
||||||
END_SEGMENT,
|
END_SEGMENT,
|
||||||
} Event = NOTHING;
|
} Event = NOTHING;
|
||||||
// Which subregister lanes are affected by the current event.
|
// Which subregister lanes are affected by the current event.
|
||||||
unsigned EventMask = 0;
|
LaneBitmask EventMask = 0;
|
||||||
// Whether a BEGIN_SEGMENT is also a valno definition point.
|
// Whether a BEGIN_SEGMENT is also a valno definition point.
|
||||||
bool IsDef = false;
|
bool IsDef = false;
|
||||||
// Find the next begin or end of a subrange segment. Combine masks if we
|
// Find the next begin or end of a subrange segment. Combine masks if we
|
||||||
|
@ -1101,8 +1101,8 @@ void LiveInterval::verify(const MachineRegisterInfo *MRI) const {
|
||||||
super::verify();
|
super::verify();
|
||||||
|
|
||||||
// Make sure SubRanges are fine and LaneMasks are disjunct.
|
// Make sure SubRanges are fine and LaneMasks are disjunct.
|
||||||
unsigned Mask = 0;
|
LaneBitmask Mask = 0;
|
||||||
unsigned MaxMask = MRI != nullptr ? MRI->getMaxLaneMaskForVReg(reg) : ~0u;
|
LaneBitmask MaxMask = MRI != nullptr ? MRI->getMaxLaneMaskForVReg(reg) : ~0u;
|
||||||
for (const SubRange &SR : subranges()) {
|
for (const SubRange &SR : subranges()) {
|
||||||
// Subrange lanemask should be disjunct to any previous subrange masks.
|
// Subrange lanemask should be disjunct to any previous subrange masks.
|
||||||
assert((Mask & SR.LaneMask) == 0);
|
assert((Mask & SR.LaneMask) == 0);
|
||||||
|
|
|
@ -531,8 +531,8 @@ void LiveIntervals::shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg)
|
||||||
// Maybe the operand is for a subregister we don't care about.
|
// Maybe the operand is for a subregister we don't care about.
|
||||||
unsigned SubReg = MO.getSubReg();
|
unsigned SubReg = MO.getSubReg();
|
||||||
if (SubReg != 0) {
|
if (SubReg != 0) {
|
||||||
unsigned SubRegMask = TRI->getSubRegIndexLaneMask(SubReg);
|
LaneBitmask LaneMask = TRI->getSubRegIndexLaneMask(SubReg);
|
||||||
if ((SubRegMask & SR.LaneMask) == 0)
|
if ((LaneMask & SR.LaneMask) == 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// We only need to visit each instruction once.
|
// We only need to visit each instruction once.
|
||||||
|
@ -731,7 +731,7 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
|
||||||
// assign R0L to %vreg1, and R0 to %vreg2 because the low 32bits of R0
|
// assign R0L to %vreg1, and R0 to %vreg2 because the low 32bits of R0
|
||||||
// are actually never written by %vreg2. After assignment the <kill>
|
// are actually never written by %vreg2. After assignment the <kill>
|
||||||
// flag at the read instruction is invalid.
|
// flag at the read instruction is invalid.
|
||||||
unsigned DefinedLanesMask;
|
LaneBitmask DefinedLanesMask;
|
||||||
if (!SRs.empty()) {
|
if (!SRs.empty()) {
|
||||||
// Compute a mask of lanes that are defined.
|
// Compute a mask of lanes that are defined.
|
||||||
DefinedLanesMask = 0;
|
DefinedLanesMask = 0;
|
||||||
|
@ -755,7 +755,7 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
|
||||||
continue;
|
continue;
|
||||||
if (MO.isUse()) {
|
if (MO.isUse()) {
|
||||||
// Reading any undefined lanes?
|
// Reading any undefined lanes?
|
||||||
unsigned UseMask = TRI->getSubRegIndexLaneMask(MO.getSubReg());
|
LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(MO.getSubReg());
|
||||||
if ((UseMask & ~DefinedLanesMask) != 0)
|
if ((UseMask & ~DefinedLanesMask) != 0)
|
||||||
goto CancelKill;
|
goto CancelKill;
|
||||||
} else if (MO.getSubReg() == 0) {
|
} else if (MO.getSubReg() == 0) {
|
||||||
|
@ -963,7 +963,7 @@ public:
|
||||||
LiveInterval &LI = LIS.getInterval(Reg);
|
LiveInterval &LI = LIS.getInterval(Reg);
|
||||||
if (LI.hasSubRanges()) {
|
if (LI.hasSubRanges()) {
|
||||||
unsigned SubReg = MO.getSubReg();
|
unsigned SubReg = MO.getSubReg();
|
||||||
unsigned LaneMask = TRI.getSubRegIndexLaneMask(SubReg);
|
LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubReg);
|
||||||
for (LiveInterval::SubRange &S : LI.subranges()) {
|
for (LiveInterval::SubRange &S : LI.subranges()) {
|
||||||
if ((S.LaneMask & LaneMask) == 0)
|
if ((S.LaneMask & LaneMask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -987,7 +987,7 @@ public:
|
||||||
private:
|
private:
|
||||||
/// Update a single live range, assuming an instruction has been moved from
|
/// Update a single live range, assuming an instruction has been moved from
|
||||||
/// OldIdx to NewIdx.
|
/// OldIdx to NewIdx.
|
||||||
void updateRange(LiveRange &LR, unsigned Reg, unsigned LaneMask) {
|
void updateRange(LiveRange &LR, unsigned Reg, LaneBitmask LaneMask) {
|
||||||
if (!Updated.insert(&LR).second)
|
if (!Updated.insert(&LR).second)
|
||||||
return;
|
return;
|
||||||
DEBUG({
|
DEBUG({
|
||||||
|
@ -1117,7 +1117,7 @@ private:
|
||||||
/// Hoist kill to NewIdx, then scan for last kill between NewIdx and
|
/// Hoist kill to NewIdx, then scan for last kill between NewIdx and
|
||||||
/// OldIdx.
|
/// OldIdx.
|
||||||
///
|
///
|
||||||
void handleMoveUp(LiveRange &LR, unsigned Reg, unsigned LaneMask) {
|
void handleMoveUp(LiveRange &LR, unsigned Reg, LaneBitmask LaneMask) {
|
||||||
// First look for a kill at OldIdx.
|
// First look for a kill at OldIdx.
|
||||||
LiveRange::iterator I = LR.find(OldIdx.getBaseIndex());
|
LiveRange::iterator I = LR.find(OldIdx.getBaseIndex());
|
||||||
LiveRange::iterator E = LR.end();
|
LiveRange::iterator E = LR.end();
|
||||||
|
@ -1194,7 +1194,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the last use of reg between NewIdx and OldIdx.
|
// Return the last use of reg between NewIdx and OldIdx.
|
||||||
SlotIndex findLastUseBefore(unsigned Reg, unsigned LaneMask) {
|
SlotIndex findLastUseBefore(unsigned Reg, LaneBitmask LaneMask) {
|
||||||
|
|
||||||
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
|
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
|
||||||
SlotIndex LastUse = NewIdx;
|
SlotIndex LastUse = NewIdx;
|
||||||
|
@ -1274,7 +1274,7 @@ void LiveIntervals::repairOldRegInRange(const MachineBasicBlock::iterator Begin,
|
||||||
const MachineBasicBlock::iterator End,
|
const MachineBasicBlock::iterator End,
|
||||||
const SlotIndex endIdx,
|
const SlotIndex endIdx,
|
||||||
LiveRange &LR, const unsigned Reg,
|
LiveRange &LR, const unsigned Reg,
|
||||||
const unsigned LaneMask) {
|
LaneBitmask LaneMask) {
|
||||||
LiveInterval::iterator LII = LR.find(endIdx);
|
LiveInterval::iterator LII = LR.find(endIdx);
|
||||||
SlotIndex lastUseIdx;
|
SlotIndex lastUseIdx;
|
||||||
if (LII != LR.end() && LII->start < endIdx)
|
if (LII != LR.end() && LII->start < endIdx)
|
||||||
|
@ -1301,7 +1301,7 @@ void LiveIntervals::repairOldRegInRange(const MachineBasicBlock::iterator Begin,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
unsigned SubReg = MO.getSubReg();
|
unsigned SubReg = MO.getSubReg();
|
||||||
unsigned Mask = TRI->getSubRegIndexLaneMask(SubReg);
|
LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubReg);
|
||||||
if ((Mask & LaneMask) == 0)
|
if ((Mask & LaneMask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -64,23 +64,23 @@ void LiveRangeCalc::calculate(LiveInterval &LI, bool TrackSubRegs) {
|
||||||
|
|
||||||
unsigned SubReg = MO.getSubReg();
|
unsigned SubReg = MO.getSubReg();
|
||||||
if (LI.hasSubRanges() || (SubReg != 0 && TrackSubRegs)) {
|
if (LI.hasSubRanges() || (SubReg != 0 && TrackSubRegs)) {
|
||||||
unsigned Mask = SubReg != 0 ? TRI.getSubRegIndexLaneMask(SubReg)
|
LaneBitmask Mask = SubReg != 0 ? TRI.getSubRegIndexLaneMask(SubReg)
|
||||||
: MRI->getMaxLaneMaskForVReg(Reg);
|
: MRI->getMaxLaneMaskForVReg(Reg);
|
||||||
|
|
||||||
// If this is the first time we see a subregister def, initialize
|
// If this is the first time we see a subregister def, initialize
|
||||||
// subranges by creating a copy of the main range.
|
// subranges by creating a copy of the main range.
|
||||||
if (!LI.hasSubRanges() && !LI.empty()) {
|
if (!LI.hasSubRanges() && !LI.empty()) {
|
||||||
unsigned ClassMask = MRI->getMaxLaneMaskForVReg(Reg);
|
LaneBitmask ClassMask = MRI->getMaxLaneMaskForVReg(Reg);
|
||||||
LI.createSubRangeFrom(*Alloc, ClassMask, LI);
|
LI.createSubRangeFrom(*Alloc, ClassMask, LI);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (LiveInterval::SubRange &S : LI.subranges()) {
|
for (LiveInterval::SubRange &S : LI.subranges()) {
|
||||||
// A Mask for subregs common to the existing subrange and current def.
|
// A Mask for subregs common to the existing subrange and current def.
|
||||||
unsigned Common = S.LaneMask & Mask;
|
LaneBitmask Common = S.LaneMask & Mask;
|
||||||
if (Common == 0)
|
if (Common == 0)
|
||||||
continue;
|
continue;
|
||||||
// A Mask for subregs covered by the subrange but not the current def.
|
// A Mask for subregs covered by the subrange but not the current def.
|
||||||
unsigned LRest = S.LaneMask & ~Mask;
|
LaneBitmask LRest = S.LaneMask & ~Mask;
|
||||||
LiveInterval::SubRange *CommonRange;
|
LiveInterval::SubRange *CommonRange;
|
||||||
if (LRest != 0) {
|
if (LRest != 0) {
|
||||||
// Split current subrange into Common and LRest ranges.
|
// Split current subrange into Common and LRest ranges.
|
||||||
|
@ -138,7 +138,8 @@ void LiveRangeCalc::createDeadDefs(LiveRange &LR, unsigned Reg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LiveRangeCalc::extendToUses(LiveRange &LR, unsigned Reg, unsigned Mask) {
|
void LiveRangeCalc::extendToUses(LiveRange &LR, unsigned Reg,
|
||||||
|
LaneBitmask Mask) {
|
||||||
// Visit all operands that read Reg. This may include partial defs.
|
// Visit all operands that read Reg. This may include partial defs.
|
||||||
const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
|
const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
|
||||||
for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
|
for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
|
||||||
|
@ -157,7 +158,7 @@ void LiveRangeCalc::extendToUses(LiveRange &LR, unsigned Reg, unsigned Mask) {
|
||||||
continue;
|
continue;
|
||||||
unsigned SubReg = MO.getSubReg();
|
unsigned SubReg = MO.getSubReg();
|
||||||
if (SubReg != 0) {
|
if (SubReg != 0) {
|
||||||
unsigned SubRegMask = TRI.getSubRegIndexLaneMask(SubReg);
|
LaneBitmask SubRegMask = TRI.getSubRegIndexLaneMask(SubReg);
|
||||||
// Ignore uses not covering the current subrange.
|
// Ignore uses not covering the current subrange.
|
||||||
if ((SubRegMask & Mask) == 0)
|
if ((SubRegMask & Mask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -129,7 +129,7 @@ class LiveRangeCalc {
|
||||||
///
|
///
|
||||||
/// All uses must be jointly dominated by existing liveness. PHI-defs are
|
/// All uses must be jointly dominated by existing liveness. PHI-defs are
|
||||||
/// inserted as needed to preserve SSA form.
|
/// inserted as needed to preserve SSA form.
|
||||||
void extendToUses(LiveRange &LR, unsigned Reg, unsigned LaneMask);
|
void extendToUses(LiveRange &LR, unsigned Reg, LaneBitmask LaneMask);
|
||||||
|
|
||||||
/// Reset Map and Seen fields.
|
/// Reset Map and Seen fields.
|
||||||
void resetLiveOutMap();
|
void resetLiveOutMap();
|
||||||
|
|
|
@ -226,7 +226,7 @@ bool LiveRangeEdit::useIsKill(const LiveInterval &LI,
|
||||||
return true;
|
return true;
|
||||||
const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
|
const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
|
||||||
unsigned SubReg = MO.getSubReg();
|
unsigned SubReg = MO.getSubReg();
|
||||||
unsigned LaneMask = TRI.getSubRegIndexLaneMask(SubReg);
|
LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubReg);
|
||||||
for (const LiveInterval::SubRange &S : LI.subranges()) {
|
for (const LiveInterval::SubRange &S : LI.subranges()) {
|
||||||
if ((S.LaneMask & LaneMask) != 0 && S.Query(Idx).isKill())
|
if ((S.LaneMask & LaneMask) != 0 && S.Query(Idx).isKill())
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -77,7 +77,7 @@ bool foreachUnit(const TargetRegisterInfo *TRI, LiveInterval &VRegInterval,
|
||||||
if (VRegInterval.hasSubRanges()) {
|
if (VRegInterval.hasSubRanges()) {
|
||||||
for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
|
for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
|
||||||
unsigned Unit = (*Units).first;
|
unsigned Unit = (*Units).first;
|
||||||
unsigned Mask = (*Units).second;
|
LaneBitmask Mask = (*Units).second;
|
||||||
for (LiveInterval::SubRange &S : VRegInterval.subranges()) {
|
for (LiveInterval::SubRange &S : VRegInterval.subranges()) {
|
||||||
if (S.LaneMask & Mask) {
|
if (S.LaneMask & Mask) {
|
||||||
if (Func(Unit, S))
|
if (Func(Unit, S))
|
||||||
|
|
|
@ -331,7 +331,7 @@ void MachineBasicBlock::printAsOperand(raw_ostream &OS,
|
||||||
OS << "BB#" << getNumber();
|
OS << "BB#" << getNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachineBasicBlock::removeLiveIn(MCPhysReg Reg, unsigned LaneMask) {
|
void MachineBasicBlock::removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask) {
|
||||||
LiveInVector::iterator I = std::find_if(
|
LiveInVector::iterator I = std::find_if(
|
||||||
LiveIns.begin(), LiveIns.end(),
|
LiveIns.begin(), LiveIns.end(),
|
||||||
[Reg] (const RegisterMaskPair &LI) { return LI.PhysReg == Reg; });
|
[Reg] (const RegisterMaskPair &LI) { return LI.PhysReg == Reg; });
|
||||||
|
@ -343,7 +343,7 @@ void MachineBasicBlock::removeLiveIn(MCPhysReg Reg, unsigned LaneMask) {
|
||||||
LiveIns.erase(I);
|
LiveIns.erase(I);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MachineBasicBlock::isLiveIn(MCPhysReg Reg, unsigned LaneMask) const {
|
bool MachineBasicBlock::isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask) const {
|
||||||
livein_iterator I = std::find_if(
|
livein_iterator I = std::find_if(
|
||||||
LiveIns.begin(), LiveIns.end(),
|
LiveIns.begin(), LiveIns.end(),
|
||||||
[Reg] (const RegisterMaskPair &LI) { return LI.PhysReg == Reg; });
|
[Reg] (const RegisterMaskPair &LI) { return LI.PhysReg == Reg; });
|
||||||
|
@ -361,7 +361,7 @@ void MachineBasicBlock::sortUniqueLiveIns() {
|
||||||
LiveInVector::iterator Out = LiveIns.begin();
|
LiveInVector::iterator Out = LiveIns.begin();
|
||||||
for (; I != LiveIns.end(); ++Out, I = J) {
|
for (; I != LiveIns.end(); ++Out, I = J) {
|
||||||
unsigned PhysReg = I->PhysReg;
|
unsigned PhysReg = I->PhysReg;
|
||||||
unsigned LaneMask = I->LaneMask;
|
LaneBitmask LaneMask = I->LaneMask;
|
||||||
for (J = std::next(I); J != LiveIns.end() && J->PhysReg == PhysReg; ++J)
|
for (J = std::next(I); J != LiveIns.end() && J->PhysReg == PhysReg; ++J)
|
||||||
LaneMask |= J->LaneMask;
|
LaneMask |= J->LaneMask;
|
||||||
Out->PhysReg = PhysReg;
|
Out->PhysReg = PhysReg;
|
||||||
|
|
|
@ -395,8 +395,7 @@ MachineRegisterInfo::EmitLiveInCopies(MachineBasicBlock *EntryMBB,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned MachineRegisterInfo::getMaxLaneMaskForVReg(unsigned Reg) const
|
LaneBitmask MachineRegisterInfo::getMaxLaneMaskForVReg(unsigned Reg) const {
|
||||||
{
|
|
||||||
// Lane masks are only defined for vregs.
|
// Lane masks are only defined for vregs.
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(Reg));
|
assert(TargetRegisterInfo::isVirtualRegister(Reg));
|
||||||
const TargetRegisterClass &TRC = *getRegClass(Reg);
|
const TargetRegisterClass &TRC = *getRegClass(Reg);
|
||||||
|
|
|
@ -213,9 +213,9 @@ namespace {
|
||||||
void report(const char *msg, const MachineBasicBlock *MBB,
|
void report(const char *msg, const MachineBasicBlock *MBB,
|
||||||
const LiveInterval &LI);
|
const LiveInterval &LI);
|
||||||
void report(const char *msg, const MachineFunction *MF,
|
void report(const char *msg, const MachineFunction *MF,
|
||||||
const LiveRange &LR, unsigned Reg, unsigned LaneMask);
|
const LiveRange &LR, unsigned Reg, LaneBitmask LaneMask);
|
||||||
void report(const char *msg, const MachineBasicBlock *MBB,
|
void report(const char *msg, const MachineBasicBlock *MBB,
|
||||||
const LiveRange &LR, unsigned Reg, unsigned LaneMask);
|
const LiveRange &LR, unsigned Reg, LaneBitmask LaneMask);
|
||||||
|
|
||||||
void verifyInlineAsm(const MachineInstr *MI);
|
void verifyInlineAsm(const MachineInstr *MI);
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ namespace {
|
||||||
void verifyLiveRangeSegment(const LiveRange&,
|
void verifyLiveRangeSegment(const LiveRange&,
|
||||||
const LiveRange::const_iterator I, unsigned,
|
const LiveRange::const_iterator I, unsigned,
|
||||||
unsigned);
|
unsigned);
|
||||||
void verifyLiveRange(const LiveRange&, unsigned, unsigned LaneMask = 0);
|
void verifyLiveRange(const LiveRange&, unsigned, LaneBitmask LaneMask = 0);
|
||||||
|
|
||||||
void verifyStackFrame();
|
void verifyStackFrame();
|
||||||
|
|
||||||
|
@ -442,7 +442,7 @@ void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB,
|
||||||
|
|
||||||
void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB,
|
void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB,
|
||||||
const LiveRange &LR, unsigned Reg,
|
const LiveRange &LR, unsigned Reg,
|
||||||
unsigned LaneMask) {
|
LaneBitmask LaneMask) {
|
||||||
report(msg, MBB);
|
report(msg, MBB);
|
||||||
errs() << "- liverange: " << LR << '\n';
|
errs() << "- liverange: " << LR << '\n';
|
||||||
errs() << "- register: " << PrintReg(Reg, TRI) << '\n';
|
errs() << "- register: " << PrintReg(Reg, TRI) << '\n';
|
||||||
|
@ -452,7 +452,7 @@ void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB,
|
||||||
|
|
||||||
void MachineVerifier::report(const char *msg, const MachineFunction *MF,
|
void MachineVerifier::report(const char *msg, const MachineFunction *MF,
|
||||||
const LiveRange &LR, unsigned Reg,
|
const LiveRange &LR, unsigned Reg,
|
||||||
unsigned LaneMask) {
|
LaneBitmask LaneMask) {
|
||||||
report(msg, MF);
|
report(msg, MF);
|
||||||
errs() << "- liverange: " << LR << '\n';
|
errs() << "- liverange: " << LR << '\n';
|
||||||
errs() << "- register: " << PrintReg(Reg, TRI) << '\n';
|
errs() << "- register: " << PrintReg(Reg, TRI) << '\n';
|
||||||
|
@ -1403,7 +1403,7 @@ void MachineVerifier::verifyLiveIntervals() {
|
||||||
|
|
||||||
void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
|
void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
|
||||||
const VNInfo *VNI, unsigned Reg,
|
const VNInfo *VNI, unsigned Reg,
|
||||||
unsigned LaneMask) {
|
LaneBitmask LaneMask) {
|
||||||
if (VNI->isUnused())
|
if (VNI->isUnused())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1494,7 +1494,8 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
|
||||||
|
|
||||||
void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
|
void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
|
||||||
const LiveRange::const_iterator I,
|
const LiveRange::const_iterator I,
|
||||||
unsigned Reg, unsigned LaneMask) {
|
unsigned Reg, LaneBitmask LaneMask)
|
||||||
|
{
|
||||||
const LiveRange::Segment &S = *I;
|
const LiveRange::Segment &S = *I;
|
||||||
const VNInfo *VNI = S.valno;
|
const VNInfo *VNI = S.valno;
|
||||||
assert(VNI && "Live segment has no valno");
|
assert(VNI && "Live segment has no valno");
|
||||||
|
@ -1667,7 +1668,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
|
||||||
}
|
}
|
||||||
|
|
||||||
void MachineVerifier::verifyLiveRange(const LiveRange &LR, unsigned Reg,
|
void MachineVerifier::verifyLiveRange(const LiveRange &LR, unsigned Reg,
|
||||||
unsigned LaneMask) {
|
LaneBitmask LaneMask) {
|
||||||
for (const VNInfo *VNI : LR.valnos)
|
for (const VNInfo *VNI : LR.valnos)
|
||||||
verifyLiveRangeValue(LR, VNI, Reg, LaneMask);
|
verifyLiveRangeValue(LR, VNI, Reg, LaneMask);
|
||||||
|
|
||||||
|
@ -1680,8 +1681,8 @@ void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) {
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(Reg));
|
assert(TargetRegisterInfo::isVirtualRegister(Reg));
|
||||||
verifyLiveRange(LI, Reg);
|
verifyLiveRange(LI, Reg);
|
||||||
|
|
||||||
unsigned Mask = 0;
|
LaneBitmask Mask = 0;
|
||||||
unsigned MaxMask = MRI->getMaxLaneMaskForVReg(Reg);
|
LaneBitmask MaxMask = MRI->getMaxLaneMaskForVReg(Reg);
|
||||||
for (const LiveInterval::SubRange &SR : LI.subranges()) {
|
for (const LiveInterval::SubRange &SR : LI.subranges()) {
|
||||||
if ((Mask & SR.LaneMask) != 0)
|
if ((Mask & SR.LaneMask) != 0)
|
||||||
report("Lane masks of sub ranges overlap in live interval", MF, LI);
|
report("Lane masks of sub ranges overlap in live interval", MF, LI);
|
||||||
|
|
|
@ -93,7 +93,7 @@ namespace {
|
||||||
|
|
||||||
/// A LaneMask to remember on which subregister live ranges we need to call
|
/// A LaneMask to remember on which subregister live ranges we need to call
|
||||||
/// shrinkToUses() later.
|
/// shrinkToUses() later.
|
||||||
unsigned ShrinkMask;
|
LaneBitmask ShrinkMask;
|
||||||
|
|
||||||
/// True if the main range of the currently coalesced intervals should be
|
/// True if the main range of the currently coalesced intervals should be
|
||||||
/// checked for smaller live intervals.
|
/// checked for smaller live intervals.
|
||||||
|
@ -166,13 +166,13 @@ namespace {
|
||||||
/// lanemasks already adjusted to the coalesced register.
|
/// lanemasks already adjusted to the coalesced register.
|
||||||
/// @returns false if live range conflicts couldn't get resolved.
|
/// @returns false if live range conflicts couldn't get resolved.
|
||||||
bool mergeSubRangeInto(LiveInterval &LI, const LiveRange &ToMerge,
|
bool mergeSubRangeInto(LiveInterval &LI, const LiveRange &ToMerge,
|
||||||
unsigned LaneMask, CoalescerPair &CP);
|
LaneBitmask LaneMask, CoalescerPair &CP);
|
||||||
|
|
||||||
/// Join the liveranges of two subregisters. Joins @p RRange into
|
/// Join the liveranges of two subregisters. Joins @p RRange into
|
||||||
/// @p LRange, @p RRange may be invalid afterwards.
|
/// @p LRange, @p RRange may be invalid afterwards.
|
||||||
/// @returns false if live range conflicts couldn't get resolved.
|
/// @returns false if live range conflicts couldn't get resolved.
|
||||||
bool joinSubRegRanges(LiveRange &LRange, LiveRange &RRange,
|
bool joinSubRegRanges(LiveRange &LRange, LiveRange &RRange,
|
||||||
unsigned LaneMask, const CoalescerPair &CP);
|
LaneBitmask LaneMask, const CoalescerPair &CP);
|
||||||
|
|
||||||
/// We found a non-trivially-coalescable copy. If the source value number is
|
/// 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
|
/// defined by a copy from the destination reg see if we can merge these two
|
||||||
|
@ -791,7 +791,7 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
|
||||||
BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
|
BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
|
||||||
if (IntB.hasSubRanges()) {
|
if (IntB.hasSubRanges()) {
|
||||||
if (!IntA.hasSubRanges()) {
|
if (!IntA.hasSubRanges()) {
|
||||||
unsigned Mask = MRI->getMaxLaneMaskForVReg(IntA.reg);
|
LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(IntA.reg);
|
||||||
IntA.createSubRangeFrom(Allocator, Mask, IntA);
|
IntA.createSubRangeFrom(Allocator, Mask, IntA);
|
||||||
}
|
}
|
||||||
SlotIndex AIdx = CopyIdx.getRegSlot(true);
|
SlotIndex AIdx = CopyIdx.getRegSlot(true);
|
||||||
|
@ -799,16 +799,16 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
|
||||||
VNInfo *ASubValNo = SA.getVNInfoAt(AIdx);
|
VNInfo *ASubValNo = SA.getVNInfoAt(AIdx);
|
||||||
assert(ASubValNo != nullptr);
|
assert(ASubValNo != nullptr);
|
||||||
|
|
||||||
unsigned AMask = SA.LaneMask;
|
LaneBitmask AMask = SA.LaneMask;
|
||||||
for (LiveInterval::SubRange &SB : IntB.subranges()) {
|
for (LiveInterval::SubRange &SB : IntB.subranges()) {
|
||||||
unsigned BMask = SB.LaneMask;
|
LaneBitmask BMask = SB.LaneMask;
|
||||||
unsigned Common = BMask & AMask;
|
LaneBitmask Common = BMask & AMask;
|
||||||
if (Common == 0)
|
if (Common == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
DEBUG(
|
DEBUG(
|
||||||
dbgs() << format("\t\tCopy+Merge %04X into %04X\n", BMask, Common));
|
dbgs() << format("\t\tCopy+Merge %04X into %04X\n", BMask, Common));
|
||||||
unsigned BRest = BMask & ~AMask;
|
LaneBitmask BRest = BMask & ~AMask;
|
||||||
LiveInterval::SubRange *CommonRange;
|
LiveInterval::SubRange *CommonRange;
|
||||||
if (BRest != 0) {
|
if (BRest != 0) {
|
||||||
SB.LaneMask = BRest;
|
SB.LaneMask = BRest;
|
||||||
|
@ -1094,7 +1094,7 @@ bool RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI) {
|
||||||
const LiveInterval &SrcLI = LIS->getInterval(SrcReg);
|
const LiveInterval &SrcLI = LIS->getInterval(SrcReg);
|
||||||
// CopyMI is undef iff SrcReg is not live before the instruction.
|
// CopyMI is undef iff SrcReg is not live before the instruction.
|
||||||
if (SrcSubIdx != 0 && SrcLI.hasSubRanges()) {
|
if (SrcSubIdx != 0 && SrcLI.hasSubRanges()) {
|
||||||
unsigned SrcMask = TRI->getSubRegIndexLaneMask(SrcSubIdx);
|
LaneBitmask SrcMask = TRI->getSubRegIndexLaneMask(SrcSubIdx);
|
||||||
for (const LiveInterval::SubRange &SR : SrcLI.subranges()) {
|
for (const LiveInterval::SubRange &SR : SrcLI.subranges()) {
|
||||||
if ((SR.LaneMask & SrcMask) == 0)
|
if ((SR.LaneMask & SrcMask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1115,7 +1115,7 @@ bool RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI) {
|
||||||
DstLI.MergeValueNumberInto(VNI, PrevVNI);
|
DstLI.MergeValueNumberInto(VNI, PrevVNI);
|
||||||
|
|
||||||
// The affected subregister segments can be removed.
|
// The affected subregister segments can be removed.
|
||||||
unsigned DstMask = TRI->getSubRegIndexLaneMask(DstSubIdx);
|
LaneBitmask DstMask = TRI->getSubRegIndexLaneMask(DstSubIdx);
|
||||||
for (LiveInterval::SubRange &SR : DstLI.subranges()) {
|
for (LiveInterval::SubRange &SR : DstLI.subranges()) {
|
||||||
if ((SR.LaneMask & DstMask) == 0)
|
if ((SR.LaneMask & DstMask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1134,7 +1134,7 @@ bool RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI) {
|
||||||
continue;
|
continue;
|
||||||
const MachineInstr &MI = *MO.getParent();
|
const MachineInstr &MI = *MO.getParent();
|
||||||
SlotIndex UseIdx = LIS->getInstructionIndex(&MI);
|
SlotIndex UseIdx = LIS->getInstructionIndex(&MI);
|
||||||
unsigned UseMask = TRI->getSubRegIndexLaneMask(MO.getSubReg());
|
LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(MO.getSubReg());
|
||||||
bool isLive;
|
bool isLive;
|
||||||
if (UseMask != ~0u && DstLI.hasSubRanges()) {
|
if (UseMask != ~0u && DstLI.hasSubRanges()) {
|
||||||
isLive = false;
|
isLive = false;
|
||||||
|
@ -1200,10 +1200,10 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg,
|
||||||
if (SubIdx != 0 && MO.isUse() && MRI->shouldTrackSubRegLiveness(DstReg)) {
|
if (SubIdx != 0 && MO.isUse() && MRI->shouldTrackSubRegLiveness(DstReg)) {
|
||||||
if (!DstInt->hasSubRanges()) {
|
if (!DstInt->hasSubRanges()) {
|
||||||
BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
|
BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
|
||||||
unsigned Mask = MRI->getMaxLaneMaskForVReg(DstInt->reg);
|
LaneBitmask Mask = MRI->getMaxLaneMaskForVReg(DstInt->reg);
|
||||||
DstInt->createSubRangeFrom(Allocator, Mask, *DstInt);
|
DstInt->createSubRangeFrom(Allocator, Mask, *DstInt);
|
||||||
}
|
}
|
||||||
unsigned Mask = TRI->getSubRegIndexLaneMask(SubIdx);
|
LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubIdx);
|
||||||
bool IsUndef = true;
|
bool IsUndef = true;
|
||||||
SlotIndex MIIdx = UseMI->isDebugValue()
|
SlotIndex MIIdx = UseMI->isDebugValue()
|
||||||
? LIS->getSlotIndexes()->getIndexBefore(UseMI)
|
? LIS->getSlotIndexes()->getIndexBefore(UseMI)
|
||||||
|
@ -1631,7 +1631,7 @@ class JoinVals {
|
||||||
const unsigned SubIdx;
|
const unsigned SubIdx;
|
||||||
/// The LaneMask that this liverange will occupy the coalesced register. May
|
/// The LaneMask that this liverange will occupy the coalesced register. May
|
||||||
/// be smaller than the lanemask produced by SubIdx when merging subranges.
|
/// be smaller than the lanemask produced by SubIdx when merging subranges.
|
||||||
const unsigned LaneMask;
|
const LaneBitmask LaneMask;
|
||||||
|
|
||||||
/// This is true when joining sub register ranges, false when joining main
|
/// This is true when joining sub register ranges, false when joining main
|
||||||
/// ranges.
|
/// ranges.
|
||||||
|
@ -1686,11 +1686,11 @@ class JoinVals {
|
||||||
ConflictResolution Resolution;
|
ConflictResolution Resolution;
|
||||||
|
|
||||||
/// Lanes written by this def, 0 for unanalyzed values.
|
/// Lanes written by this def, 0 for unanalyzed values.
|
||||||
unsigned WriteLanes;
|
LaneBitmask WriteLanes;
|
||||||
|
|
||||||
/// Lanes with defined values in this register. Other lanes are undef and
|
/// Lanes with defined values in this register. Other lanes are undef and
|
||||||
/// safe to clobber.
|
/// safe to clobber.
|
||||||
unsigned ValidLanes;
|
LaneBitmask ValidLanes;
|
||||||
|
|
||||||
/// Value in LI being redefined by this def.
|
/// Value in LI being redefined by this def.
|
||||||
VNInfo *RedefVNI;
|
VNInfo *RedefVNI;
|
||||||
|
@ -1731,7 +1731,7 @@ class JoinVals {
|
||||||
/// Compute the bitmask of lanes actually written by DefMI.
|
/// Compute the bitmask of lanes actually written by DefMI.
|
||||||
/// Set Redef if there are any partial register definitions that depend on the
|
/// Set Redef if there are any partial register definitions that depend on the
|
||||||
/// previous value of the register.
|
/// previous value of the register.
|
||||||
unsigned computeWriteLanes(const MachineInstr *DefMI, bool &Redef) const;
|
LaneBitmask computeWriteLanes(const MachineInstr *DefMI, bool &Redef) const;
|
||||||
|
|
||||||
/// Find the ultimate value that VNI was copied from.
|
/// Find the ultimate value that VNI was copied from.
|
||||||
std::pair<const VNInfo*,unsigned> followCopyChain(const VNInfo *VNI) const;
|
std::pair<const VNInfo*,unsigned> followCopyChain(const VNInfo *VNI) const;
|
||||||
|
@ -1767,12 +1767,12 @@ class JoinVals {
|
||||||
/// entry to TaintedVals.
|
/// entry to TaintedVals.
|
||||||
///
|
///
|
||||||
/// Returns false if the tainted lanes extend beyond the basic block.
|
/// Returns false if the tainted lanes extend beyond the basic block.
|
||||||
bool taintExtent(unsigned, unsigned, JoinVals&,
|
bool taintExtent(unsigned, LaneBitmask, JoinVals&,
|
||||||
SmallVectorImpl<std::pair<SlotIndex, unsigned> >&);
|
SmallVectorImpl<std::pair<SlotIndex, LaneBitmask> >&);
|
||||||
|
|
||||||
/// Return true if MI uses any of the given Lanes from Reg.
|
/// Return true if MI uses any of the given Lanes from Reg.
|
||||||
/// This does not include partial redefinitions of Reg.
|
/// This does not include partial redefinitions of Reg.
|
||||||
bool usesLanes(const MachineInstr *MI, unsigned, unsigned, unsigned) const;
|
bool usesLanes(const MachineInstr *MI, unsigned, unsigned, LaneBitmask) const;
|
||||||
|
|
||||||
/// Determine if ValNo is a copy of a value number in LR or Other.LR that will
|
/// Determine if ValNo is a copy of a value number in LR or Other.LR that will
|
||||||
/// be pruned:
|
/// be pruned:
|
||||||
|
@ -1783,7 +1783,7 @@ class JoinVals {
|
||||||
bool isPrunedValue(unsigned ValNo, JoinVals &Other);
|
bool isPrunedValue(unsigned ValNo, JoinVals &Other);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JoinVals(LiveRange &LR, unsigned Reg, unsigned SubIdx, unsigned LaneMask,
|
JoinVals(LiveRange &LR, unsigned Reg, unsigned SubIdx, LaneBitmask LaneMask,
|
||||||
SmallVectorImpl<VNInfo*> &newVNInfo, const CoalescerPair &cp,
|
SmallVectorImpl<VNInfo*> &newVNInfo, const CoalescerPair &cp,
|
||||||
LiveIntervals *lis, const TargetRegisterInfo *TRI, bool SubRangeJoin,
|
LiveIntervals *lis, const TargetRegisterInfo *TRI, bool SubRangeJoin,
|
||||||
bool TrackSubRegLiveness)
|
bool TrackSubRegLiveness)
|
||||||
|
@ -1810,7 +1810,7 @@ public:
|
||||||
/// Removes subranges starting at copies that get removed. This sometimes
|
/// Removes subranges starting at copies that get removed. This sometimes
|
||||||
/// happens when undefined subranges are copied around. These ranges contain
|
/// happens when undefined subranges are copied around. These ranges contain
|
||||||
/// no useful information and can be removed.
|
/// no useful information and can be removed.
|
||||||
void pruneSubRegValues(LiveInterval &LI, unsigned &ShrinkMask);
|
void pruneSubRegValues(LiveInterval &LI, LaneBitmask &ShrinkMask);
|
||||||
|
|
||||||
/// Erase any machine instructions that have been coalesced away.
|
/// Erase any machine instructions that have been coalesced away.
|
||||||
/// Add erased instructions to ErasedInstrs.
|
/// Add erased instructions to ErasedInstrs.
|
||||||
|
@ -1827,9 +1827,9 @@ public:
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
unsigned JoinVals::computeWriteLanes(const MachineInstr *DefMI, bool &Redef)
|
LaneBitmask JoinVals::computeWriteLanes(const MachineInstr *DefMI, bool &Redef)
|
||||||
const {
|
const {
|
||||||
unsigned L = 0;
|
LaneBitmask L = 0;
|
||||||
for (const MachineOperand &MO : DefMI->operands()) {
|
for (const MachineOperand &MO : DefMI->operands()) {
|
||||||
if (!MO.isReg() || MO.getReg() != Reg || !MO.isDef())
|
if (!MO.isReg() || MO.getReg() != Reg || !MO.isDef())
|
||||||
continue;
|
continue;
|
||||||
|
@ -1866,7 +1866,7 @@ std::pair<const VNInfo*, unsigned> JoinVals::followCopyChain(
|
||||||
ValueIn = nullptr;
|
ValueIn = nullptr;
|
||||||
for (const LiveInterval::SubRange &S : LI.subranges()) {
|
for (const LiveInterval::SubRange &S : LI.subranges()) {
|
||||||
// Transform lanemask to a mask in the joined live interval.
|
// Transform lanemask to a mask in the joined live interval.
|
||||||
unsigned SMask = TRI->composeSubRegIndexLaneMask(SubIdx, S.LaneMask);
|
LaneBitmask SMask = TRI->composeSubRegIndexLaneMask(SubIdx, S.LaneMask);
|
||||||
if ((SMask & LaneMask) == 0)
|
if ((SMask & LaneMask) == 0)
|
||||||
continue;
|
continue;
|
||||||
LiveQueryResult LRQ = S.Query(Def);
|
LiveQueryResult LRQ = S.Query(Def);
|
||||||
|
@ -1915,7 +1915,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
|
||||||
const MachineInstr *DefMI = nullptr;
|
const MachineInstr *DefMI = nullptr;
|
||||||
if (VNI->isPHIDef()) {
|
if (VNI->isPHIDef()) {
|
||||||
// Conservatively assume that all lanes in a PHI are valid.
|
// Conservatively assume that all lanes in a PHI are valid.
|
||||||
unsigned Lanes = SubRangeJoin ? 1 : TRI->getSubRegIndexLaneMask(SubIdx);
|
LaneBitmask Lanes = SubRangeJoin ? 1 : TRI->getSubRegIndexLaneMask(SubIdx);
|
||||||
V.ValidLanes = V.WriteLanes = Lanes;
|
V.ValidLanes = V.WriteLanes = Lanes;
|
||||||
} else {
|
} else {
|
||||||
DefMI = Indexes->getInstructionFromIndex(VNI->def);
|
DefMI = Indexes->getInstructionFromIndex(VNI->def);
|
||||||
|
@ -2177,8 +2177,8 @@ bool JoinVals::mapValues(JoinVals &Other) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JoinVals::
|
bool JoinVals::
|
||||||
taintExtent(unsigned ValNo, unsigned TaintedLanes, JoinVals &Other,
|
taintExtent(unsigned ValNo, LaneBitmask TaintedLanes, JoinVals &Other,
|
||||||
SmallVectorImpl<std::pair<SlotIndex, unsigned> > &TaintExtent) {
|
SmallVectorImpl<std::pair<SlotIndex, LaneBitmask> > &TaintExtent) {
|
||||||
VNInfo *VNI = LR.getValNumInfo(ValNo);
|
VNInfo *VNI = LR.getValNumInfo(ValNo);
|
||||||
MachineBasicBlock *MBB = Indexes->getMBBFromIndex(VNI->def);
|
MachineBasicBlock *MBB = Indexes->getMBBFromIndex(VNI->def);
|
||||||
SlotIndex MBBEnd = Indexes->getMBBEndIdx(MBB);
|
SlotIndex MBBEnd = Indexes->getMBBEndIdx(MBB);
|
||||||
|
@ -2217,7 +2217,7 @@ taintExtent(unsigned ValNo, unsigned TaintedLanes, JoinVals &Other,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JoinVals::usesLanes(const MachineInstr *MI, unsigned Reg, unsigned SubIdx,
|
bool JoinVals::usesLanes(const MachineInstr *MI, unsigned Reg, unsigned SubIdx,
|
||||||
unsigned Lanes) const {
|
LaneBitmask Lanes) const {
|
||||||
if (MI->isDebugValue())
|
if (MI->isDebugValue())
|
||||||
return false;
|
return false;
|
||||||
for (const MachineOperand &MO : MI->operands()) {
|
for (const MachineOperand &MO : MI->operands()) {
|
||||||
|
@ -2251,8 +2251,8 @@ bool JoinVals::resolveConflicts(JoinVals &Other) {
|
||||||
// VNI is known to clobber some lanes in OtherVNI. If we go ahead with the
|
// VNI is known to clobber some lanes in OtherVNI. If we go ahead with the
|
||||||
// join, those lanes will be tainted with a wrong value. Get the extent of
|
// join, those lanes will be tainted with a wrong value. Get the extent of
|
||||||
// the tainted lanes.
|
// the tainted lanes.
|
||||||
unsigned TaintedLanes = V.WriteLanes & OtherV.ValidLanes;
|
LaneBitmask TaintedLanes = V.WriteLanes & OtherV.ValidLanes;
|
||||||
SmallVector<std::pair<SlotIndex, unsigned>, 8> TaintExtent;
|
SmallVector<std::pair<SlotIndex, LaneBitmask>, 8> TaintExtent;
|
||||||
if (!taintExtent(i, TaintedLanes, Other, TaintExtent))
|
if (!taintExtent(i, TaintedLanes, Other, TaintExtent))
|
||||||
// Tainted lanes would extend beyond the basic block.
|
// Tainted lanes would extend beyond the basic block.
|
||||||
return false;
|
return false;
|
||||||
|
@ -2371,7 +2371,7 @@ void JoinVals::pruneValues(JoinVals &Other,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JoinVals::pruneSubRegValues(LiveInterval &LI, unsigned &ShrinkMask)
|
void JoinVals::pruneSubRegValues(LiveInterval &LI, LaneBitmask &ShrinkMask)
|
||||||
{
|
{
|
||||||
// Look for values being erased.
|
// Look for values being erased.
|
||||||
bool DidPrune = false;
|
bool DidPrune = false;
|
||||||
|
@ -2465,7 +2465,7 @@ void JoinVals::eraseInstrs(SmallPtrSetImpl<MachineInstr*> &ErasedInstrs,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RegisterCoalescer::joinSubRegRanges(LiveRange &LRange, LiveRange &RRange,
|
bool RegisterCoalescer::joinSubRegRanges(LiveRange &LRange, LiveRange &RRange,
|
||||||
unsigned LaneMask,
|
LaneBitmask LaneMask,
|
||||||
const CoalescerPair &CP) {
|
const CoalescerPair &CP) {
|
||||||
SmallVector<VNInfo*, 16> NewVNInfo;
|
SmallVector<VNInfo*, 16> NewVNInfo;
|
||||||
JoinVals RHSVals(RRange, CP.getSrcReg(), CP.getSrcIdx(), LaneMask,
|
JoinVals RHSVals(RRange, CP.getSrcReg(), CP.getSrcIdx(), LaneMask,
|
||||||
|
@ -2520,12 +2520,13 @@ bool RegisterCoalescer::joinSubRegRanges(LiveRange &LRange, LiveRange &RRange,
|
||||||
|
|
||||||
bool RegisterCoalescer::mergeSubRangeInto(LiveInterval &LI,
|
bool RegisterCoalescer::mergeSubRangeInto(LiveInterval &LI,
|
||||||
const LiveRange &ToMerge,
|
const LiveRange &ToMerge,
|
||||||
unsigned LaneMask, CoalescerPair &CP) {
|
LaneBitmask LaneMask,
|
||||||
|
CoalescerPair &CP) {
|
||||||
BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
|
BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
|
||||||
for (LiveInterval::SubRange &R : LI.subranges()) {
|
for (LiveInterval::SubRange &R : LI.subranges()) {
|
||||||
unsigned RMask = R.LaneMask;
|
LaneBitmask RMask = R.LaneMask;
|
||||||
// LaneMask of subregisters common to subrange R and ToMerge.
|
// LaneMask of subregisters common to subrange R and ToMerge.
|
||||||
unsigned Common = RMask & LaneMask;
|
LaneBitmask Common = RMask & LaneMask;
|
||||||
// There is nothing to do without common subregs.
|
// There is nothing to do without common subregs.
|
||||||
if (Common == 0)
|
if (Common == 0)
|
||||||
continue;
|
continue;
|
||||||
|
@ -2533,7 +2534,7 @@ bool RegisterCoalescer::mergeSubRangeInto(LiveInterval &LI,
|
||||||
DEBUG(dbgs() << format("\t\tCopy+Merge %04X into %04X\n", RMask, Common));
|
DEBUG(dbgs() << format("\t\tCopy+Merge %04X into %04X\n", RMask, Common));
|
||||||
// LaneMask of subregisters contained in the R range but not in ToMerge,
|
// LaneMask of subregisters contained in the R range but not in ToMerge,
|
||||||
// they have to split into their own subrange.
|
// they have to split into their own subrange.
|
||||||
unsigned LRest = RMask & ~LaneMask;
|
LaneBitmask LRest = RMask & ~LaneMask;
|
||||||
LiveInterval::SubRange *CommonRange;
|
LiveInterval::SubRange *CommonRange;
|
||||||
if (LRest != 0) {
|
if (LRest != 0) {
|
||||||
R.LaneMask = LRest;
|
R.LaneMask = LRest;
|
||||||
|
@ -2589,15 +2590,15 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
|
||||||
// create initial subranges if necessary.
|
// create initial subranges if necessary.
|
||||||
unsigned DstIdx = CP.getDstIdx();
|
unsigned DstIdx = CP.getDstIdx();
|
||||||
if (!LHS.hasSubRanges()) {
|
if (!LHS.hasSubRanges()) {
|
||||||
unsigned Mask = DstIdx == 0 ? CP.getNewRC()->getLaneMask()
|
LaneBitmask Mask = DstIdx == 0 ? CP.getNewRC()->getLaneMask()
|
||||||
: TRI->getSubRegIndexLaneMask(DstIdx);
|
: TRI->getSubRegIndexLaneMask(DstIdx);
|
||||||
// LHS must support subregs or we wouldn't be in this codepath.
|
// LHS must support subregs or we wouldn't be in this codepath.
|
||||||
assert(Mask != 0);
|
assert(Mask != 0);
|
||||||
LHS.createSubRangeFrom(Allocator, Mask, LHS);
|
LHS.createSubRangeFrom(Allocator, Mask, LHS);
|
||||||
} else if (DstIdx != 0) {
|
} else if (DstIdx != 0) {
|
||||||
// Transform LHS lanemasks to new register class if necessary.
|
// Transform LHS lanemasks to new register class if necessary.
|
||||||
for (LiveInterval::SubRange &R : LHS.subranges()) {
|
for (LiveInterval::SubRange &R : LHS.subranges()) {
|
||||||
unsigned Mask = TRI->composeSubRegIndexLaneMask(DstIdx, R.LaneMask);
|
LaneBitmask Mask = TRI->composeSubRegIndexLaneMask(DstIdx, R.LaneMask);
|
||||||
R.LaneMask = Mask;
|
R.LaneMask = Mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2608,14 +2609,14 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
|
||||||
unsigned SrcIdx = CP.getSrcIdx();
|
unsigned SrcIdx = CP.getSrcIdx();
|
||||||
bool Abort = false;
|
bool Abort = false;
|
||||||
if (!RHS.hasSubRanges()) {
|
if (!RHS.hasSubRanges()) {
|
||||||
unsigned Mask = SrcIdx == 0 ? CP.getNewRC()->getLaneMask()
|
LaneBitmask Mask = SrcIdx == 0 ? CP.getNewRC()->getLaneMask()
|
||||||
: TRI->getSubRegIndexLaneMask(SrcIdx);
|
: TRI->getSubRegIndexLaneMask(SrcIdx);
|
||||||
if (!mergeSubRangeInto(LHS, RHS, Mask, CP))
|
if (!mergeSubRangeInto(LHS, RHS, Mask, CP))
|
||||||
Abort = true;
|
Abort = true;
|
||||||
} else {
|
} else {
|
||||||
// Pair up subranges and merge.
|
// Pair up subranges and merge.
|
||||||
for (LiveInterval::SubRange &R : RHS.subranges()) {
|
for (LiveInterval::SubRange &R : RHS.subranges()) {
|
||||||
unsigned Mask = TRI->composeSubRegIndexLaneMask(SrcIdx, R.LaneMask);
|
LaneBitmask Mask = TRI->composeSubRegIndexLaneMask(SrcIdx, R.LaneMask);
|
||||||
if (!mergeSubRangeInto(LHS, R, Mask, CP)) {
|
if (!mergeSubRangeInto(LHS, R, Mask, CP)) {
|
||||||
Abort = true;
|
Abort = true;
|
||||||
break;
|
break;
|
||||||
|
@ -2969,7 +2970,7 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
|
||||||
DEBUG(dbgs() << PrintReg(Reg) << " inflated to "
|
DEBUG(dbgs() << PrintReg(Reg) << " inflated to "
|
||||||
<< TRI->getRegClassName(MRI->getRegClass(Reg)) << '\n');
|
<< TRI->getRegClassName(MRI->getRegClass(Reg)) << '\n');
|
||||||
LiveInterval &LI = LIS->getInterval(Reg);
|
LiveInterval &LI = LIS->getInterval(Reg);
|
||||||
unsigned MaxMask = MRI->getMaxLaneMaskForVReg(Reg);
|
LaneBitmask MaxMask = MRI->getMaxLaneMaskForVReg(Reg);
|
||||||
if (MaxMask == 0) {
|
if (MaxMask == 0) {
|
||||||
// If the inflated register class does not support subregisters anymore
|
// If the inflated register class does not support subregisters anymore
|
||||||
// remove the subranges.
|
// remove the subranges.
|
||||||
|
|
|
@ -31,9 +31,9 @@ using namespace llvm;
|
||||||
#define DEBUG_TYPE "reg-scavenging"
|
#define DEBUG_TYPE "reg-scavenging"
|
||||||
|
|
||||||
/// setUsed - Set the register units of this register as used.
|
/// setUsed - Set the register units of this register as used.
|
||||||
void RegScavenger::setRegUsed(unsigned Reg, unsigned LaneMask) {
|
void RegScavenger::setRegUsed(unsigned Reg, LaneBitmask LaneMask) {
|
||||||
for (MCRegUnitMaskIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) {
|
for (MCRegUnitMaskIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) {
|
||||||
unsigned UnitMask = (*RUI).second;
|
LaneBitmask UnitMask = (*RUI).second;
|
||||||
if (UnitMask == 0 || (LaneMask & UnitMask) != 0)
|
if (UnitMask == 0 || (LaneMask & UnitMask) != 0)
|
||||||
RegUnitsAvailable.reset((*RUI).first);
|
RegUnitsAvailable.reset((*RUI).first);
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,7 +263,7 @@ void VirtRegRewriter::addLiveInsForSubRanges(const LiveInterval &LI,
|
||||||
SlotIndex MBBBegin = MBBI->first;
|
SlotIndex MBBBegin = MBBI->first;
|
||||||
// Advance all subrange iterators so that their end position is just
|
// Advance all subrange iterators so that their end position is just
|
||||||
// behind MBBBegin (or the iterator is at the end).
|
// behind MBBBegin (or the iterator is at the end).
|
||||||
unsigned LaneMask = 0;
|
LaneBitmask LaneMask = 0;
|
||||||
for (auto &RangeIterPair : SubRanges) {
|
for (auto &RangeIterPair : SubRanges) {
|
||||||
const LiveInterval::SubRange *SR = RangeIterPair.first;
|
const LiveInterval::SubRange *SR = RangeIterPair.first;
|
||||||
LiveInterval::const_iterator &SRI = RangeIterPair.second;
|
LiveInterval::const_iterator &SRI = RangeIterPair.second;
|
||||||
|
@ -335,7 +335,7 @@ bool VirtRegRewriter::readsUndefSubreg(const MachineOperand &MO) const {
|
||||||
assert(LI.liveAt(BaseIndex) &&
|
assert(LI.liveAt(BaseIndex) &&
|
||||||
"Reads of completely dead register should be marked undef already");
|
"Reads of completely dead register should be marked undef already");
|
||||||
unsigned SubRegIdx = MO.getSubReg();
|
unsigned SubRegIdx = MO.getSubReg();
|
||||||
unsigned UseMask = TRI->getSubRegIndexLaneMask(SubRegIdx);
|
LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(SubRegIdx);
|
||||||
// See if any of the relevant subregister liveranges is defined at this point.
|
// See if any of the relevant subregister liveranges is defined at this point.
|
||||||
for (const LiveInterval::SubRange &SR : LI.subranges()) {
|
for (const LiveInterval::SubRange &SR : LI.subranges()) {
|
||||||
if ((SR.LaneMask & UseMask) != 0 && SR.liveAt(BaseIndex))
|
if ((SR.LaneMask & UseMask) != 0 && SR.liveAt(BaseIndex))
|
||||||
|
@ -405,7 +405,7 @@ void VirtRegRewriter::rewrite() {
|
||||||
// our subregister liveness tracking isn't precise and we can't
|
// our subregister liveness tracking isn't precise and we can't
|
||||||
// know what subregister parts are undefined, fall back to the
|
// know what subregister parts are undefined, fall back to the
|
||||||
// implicit super-register def then.
|
// implicit super-register def then.
|
||||||
unsigned LaneMask = TRI->getSubRegIndexLaneMask(SubReg);
|
LaneBitmask LaneMask = TRI->getSubRegIndexLaneMask(SubReg);
|
||||||
if (TargetRegisterInfo::isImpreciseLaneMask(LaneMask))
|
if (TargetRegisterInfo::isImpreciseLaneMask(LaneMask))
|
||||||
SuperDefs.push_back(PhysReg);
|
SuperDefs.push_back(PhysReg);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue