const uint32_t *SubClassMask;
const uint16_t *SuperRegIndices;
const unsigned LaneMask;
+ /// Classes with a higher priority value are assigned first by register
+ /// allocators using a greedy heuristic. The value is in the range [0,63].
+ const uint8_t AllocationPriority;
+ /// Whether the class supports two (or more) disjunct subregister indices.
+ const bool HasDisjunctSubRegs;
const sc_iterator SuperClasses;
ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&);
///
/// then:
///
- /// getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B) != 0
+ /// (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.
unsigned getSubRegIndexLaneMask(unsigned SubIdx) const {
- // SubIdx == 0 is allowed, it has the lane mask ~0u.
assert(SubIdx < getNumSubRegIndices() && "This is not a subregister index");
return SubRegIndexLaneMasks[SubIdx];
}
/// closest to the incoming stack pointer if stack grows down, and vice versa.
///
virtual const MCPhysReg*
- getCalleeSavedRegs(const MachineFunction *MF = nullptr) const = 0;
+ getCalleeSavedRegs(const MachineFunction *MF) const = 0;
/// getCallPreservedMask - Return a mask of call-preserved registers for the
- /// given calling convention on the current sub-target. The mask should
+ /// given calling convention on the current function. The mask should
/// include all call-preserved aliases. This is used by the register
/// allocator to determine which registers can be live across a call.
///
/// instructions should use implicit-def operands to indicate call clobbered
/// registers.
///
- virtual const uint32_t *getCallPreservedMask(CallingConv::ID) const {
+ virtual const uint32_t *getCallPreservedMask(const MachineFunction &MF,
+ CallingConv::ID) const {
// The default mask clobbers everything. All targets should override.
return nullptr;
}
/// used by register scavenger to determine what registers are free.
virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
+ /// Prior to adding the live-out mask to a stackmap or patchpoint
+ /// instruction, provide the target the opportunity to adjust it (mainly to
+ /// remove pseudo-registers that should be ignored).
+ virtual void adjustStackMapLiveOutMask(uint32_t *Mask) const { }
+
/// getMatchingSuperReg - Return a super-register of the specified register
/// Reg so its sub-register of index SubIdx is Reg.
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
return composeSubRegIndicesImpl(a, b);
}
+ /// Transforms a LaneMask computed for one subregister to the lanemask that
+ /// would have been computed when composing the subsubregisters with IdxA
+ /// first. @sa composeSubRegIndices()
+ unsigned composeSubRegIndexLaneMask(unsigned IdxA, unsigned LaneMask) const {
+ if (!IdxA)
+ return LaneMask;
+ return composeSubRegIndexLaneMaskImpl(IdxA, LaneMask);
+ }
+
/// Debugging helper: dump register in human readable form to dbgs() stream.
static void dumpReg(unsigned Reg, unsigned SubRegIndex = 0,
const TargetRegisterInfo* TRI = nullptr);
llvm_unreachable("Target has no sub-registers");
}
+ /// Overridden by TableGen in targets that have sub-registers.
+ virtual unsigned
+ composeSubRegIndexLaneMaskImpl(unsigned, unsigned) const {
+ llvm_unreachable("Target has no sub-registers");
+ }
+
public:
/// getCommonSuperRegClass - Find a common super-register class if it exists.
///
/// legal to use in the current sub-target and has the same spill size.
/// The returned register class can be used to create virtual registers which
/// means that all its registers can be copied and spilled.
- virtual const TargetRegisterClass*
- getLargestLegalSuperClass(const TargetRegisterClass *RC) const {
+ virtual const TargetRegisterClass *
+ getLargestLegalSuperClass(const TargetRegisterClass *RC,
+ const MachineFunction &) const {
/// The default implementation is very conservative and doesn't allow the
/// register allocator to inflate register classes.
return RC;
/// Get the register unit pressure limit for this dimension.
/// This limit must be adjusted dynamically for reserved registers.
- virtual unsigned getRegPressureSetLimit(unsigned Idx) const = 0;
+ virtual unsigned getRegPressureSetLimit(const MachineFunction &MF,
+ unsigned Idx) const = 0;
/// Get the dimensions of register pressure impacted by this register class.
/// Returns a -1 terminated array of pressure set IDs.
const MachineFunction &MF,
const VirtRegMap *VRM = nullptr) const;
- /// avoidWriteAfterWrite - Return true if the register allocator should avoid
- /// writing a register from RC in two consecutive instructions.
- /// This can avoid pipeline stalls on certain architectures.
- /// It does cause increased register pressure, though.
- virtual bool avoidWriteAfterWrite(const TargetRegisterClass *RC) const {
- return false;
- }
-
- /// UpdateRegAllocHint - A callback to allow target a chance to update
+ /// updateRegAllocHint - A callback to allow target a chance to update
/// register allocation hints when a register is "changed" (e.g. coalesced)
/// to another register. e.g. On ARM, some virtual registers should target
/// register pairs, if one of pair is coalesced to another register, the
/// allocation hint of the other half of the pair should be changed to point
/// to the new register.
- virtual void UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
+ virtual void updateRegAllocHint(unsigned Reg, unsigned NewReg,
MachineFunction &MF) const {
// Do nothing.
}
llvm_unreachable("resolveFrameIndex does not exist on this target");
}
- /// isFrameOffsetLegal - Determine whether a given offset immediate is
- /// encodable to resolve a frame index.
- virtual bool isFrameOffsetLegal(const MachineInstr *MI,
+ /// isFrameOffsetLegal - Determine whether a given base register plus offset
+ /// immediate is encodable to resolve a frame index.
+ virtual bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
int64_t Offset) const {
llvm_unreachable("isFrameOffsetLegal does not exist on this target");
}