class MachineMove;
class RegScavenger;
template<class T> class SmallVectorImpl;
+class raw_ostream;
/// TargetRegisterDesc - This record contains all of the information known about
/// a particular register. The AliasSet field (if not null) contains a pointer
return RegSet.count(Reg);
}
+ /// contains - Return true if both registers are in this class.
+ bool contains(unsigned Reg1, unsigned Reg2) const {
+ return contains(Reg1) && contains(Reg2);
+ }
+
/// hasType - return true if this TargetRegisterClass has the ValueType vt.
///
bool hasType(EVT vt) const {
- for(int i = 0; VTs[i].getSimpleVT().SimpleTy != MVT::Other; ++i)
+ for(int i = 0; VTs[i] != MVT::Other; ++i)
if (VTs[i] == vt)
return true;
return false;
vt_iterator vt_end() const {
vt_iterator I = VTs;
- while (I->getSimpleVT().SimpleTy != MVT::Other) ++I;
+ while (*I != MVT::Other) ++I;
return I;
}
/// cheaper to allocate caller saved registers.
///
/// These methods take a MachineFunction argument, which can be used to tune
- /// the allocatable registers based on the characteristics of the function.
- /// One simple example is that the frame pointer register can be used if
- /// frame-pointer-elimination is performed.
+ /// the allocatable registers based on the characteristics of the function,
+ /// subtarget, or other criteria.
+ ///
+ /// Register allocators should account for the fact that an allocation
+ /// order iterator may return a reserved register and always check
+ /// if the register is allocatable (getAllocatableSet()) before using it.
///
/// By default, these methods return all registers in the class.
///
protected:
const unsigned* SubregHash;
const unsigned SubregHashSize;
- const unsigned* SuperregHash;
- const unsigned SuperregHashSize;
const unsigned* AliasesHash;
const unsigned AliasesHashSize;
public:
int CallFrameDestroyOpcode = -1,
const unsigned* subregs = 0,
const unsigned subregsize = 0,
- const unsigned* superregs = 0,
- const unsigned superregsize = 0,
const unsigned* aliases = 0,
const unsigned aliasessize = 0);
virtual ~TargetRegisterInfo();
/// considered to be a 'virtual' register, which is part of the SSA
/// namespace. This must be the same for all targets, which means that each
/// target is limited to this fixed number of registers.
- FirstVirtualRegister = 1024
+ FirstVirtualRegister = 16384
};
/// isPhysicalRegister - Return true if the specified register number is in
return Reg >= FirstVirtualRegister;
}
- /// getPhysicalRegisterRegClass - Returns the Register Class of a physical
- /// register of the given type. If type is EVT::Other, then just return any
- /// register class the register belongs to.
- virtual const TargetRegisterClass *
- getPhysicalRegisterRegClass(unsigned Reg, EVT VT = MVT::Other) const;
+ /// printReg - Print a virtual or physical register on OS.
+ void printReg(unsigned Reg, raw_ostream &OS) const;
+
+ /// getMinimalPhysRegClass - Returns the Register Class of a physical
+ /// register of the given type, picking the most sub register class of
+ /// the right type that contains this physreg.
+ const TargetRegisterClass *
+ getMinimalPhysRegClass(unsigned Reg, EVT VT = MVT::Other) const;
/// getAllocatableSet - Returns a bitset indexed by register number
/// indicating if a register is allocatable or not. If a register class is
/// isSuperRegister - Returns true if regB is a super-register of regA.
///
bool isSuperRegister(unsigned regA, unsigned regB) const {
- // SuperregHash is a simple quadratically probed hash table.
- size_t index = (regA + regB * 37) & (SuperregHashSize-1);
- unsigned ProbeAmt = 2;
- while (SuperregHash[index*2] != 0 &&
- SuperregHash[index*2+1] != 0) {
- if (SuperregHash[index*2] == regA && SuperregHash[index*2+1] == regB)
- return true;
-
- index = (index + ProbeAmt) & (SuperregHashSize-1);
- ProbeAmt += 2;
- }
-
- return false;
+ return isSubRegister(regB, regA);
}
/// getCalleeSavedRegs - Return a null-terminated list of all of the
virtual const unsigned* getCalleeSavedRegs(const MachineFunction *MF = 0)
const = 0;
- /// getCalleeSavedRegClasses - Return a null-terminated list of the preferred
- /// register classes to spill each callee saved register with. The order and
- /// length of this list match the getCalleeSaveRegs() list.
- virtual const TargetRegisterClass* const *getCalleeSavedRegClasses(
- const MachineFunction *MF) const =0;
/// getReservedRegs - Returns a bitset indexed by physical register number
/// indicating if a register is a special register that has particular uses
virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0;
/// getSubRegIndex - For a given register pair, return the sub-register index
- /// if the are second register is a sub-register of the first. Return zero
+ /// if the second register is a sub-register of the first. Return zero
/// otherwise.
virtual unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const = 0;
return 0;
}
- /// canCombinedSubRegIndex - Given a register class and a list of sub-register
- /// indices, return true if it's possible to combine the sub-register indices
- /// into one that corresponds to a larger sub-register. Return the new sub-
- /// register index by reference. Note the new index by be zero if the given
- /// sub-registers combined to form the whole register.
- virtual bool canCombinedSubRegIndex(const TargetRegisterClass *RC,
- SmallVectorImpl<unsigned> &SubIndices,
- unsigned &NewSubIdx) const {
+ /// canCombineSubRegIndices - Given a register class and a list of
+ /// subregister indices, return true if it's possible to combine the
+ /// subregister indices into one that corresponds to a larger
+ /// subregister. Return the new subregister index by reference. Note the
+ /// new index may be zero if the given subregisters can be combined to
+ /// form the whole register.
+ virtual bool canCombineSubRegIndices(const TargetRegisterClass *RC,
+ SmallVectorImpl<unsigned> &SubIndices,
+ unsigned &NewSubIdx) const {
return 0;
}
return 0;
}
+ /// composeSubRegIndices - Return the subregister index you get from composing
+ /// two subregister indices.
+ ///
+ /// If R:a:b is the same register as R:c, then composeSubRegIndices(a, b)
+ /// returns c. Note that composeSubRegIndices does not tell you about illegal
+ /// compositions. If R does not have a subreg a, or R:a does not have a subreg
+ /// b, composeSubRegIndices doesn't tell you.
+ ///
+ /// The ARM register Q0 has two D subregs dsub_0:D0 and dsub_1:D1. It also has
+ /// ssub_0:S0 - ssub_3:S3 subregs.
+ /// If you compose subreg indices dsub_1, ssub_0 you get ssub_2.
+ ///
+ virtual unsigned composeSubRegIndices(unsigned a, unsigned b) const {
+ // This default implementation is correct for most targets.
+ return b;
+ }
+
//===--------------------------------------------------------------------===//
// Register Class Information
//
/// getRegClass - Returns the register class associated with the enumeration
/// value. See class TargetOperandInfo.
const TargetRegisterClass *getRegClass(unsigned i) const {
- assert(i <= getNumRegClasses() && "Register Class ID out of range");
- return i ? RegClassBegin[i - 1] : NULL;
+ assert(i < getNumRegClasses() && "Register Class ID out of range");
+ return RegClassBegin[i];
}
/// getPointerRegClass - Returns a TargetRegisterClass used for pointer
// Do nothing.
}
- /// targetHandlesStackFrameRounding - Returns true if the target is
- /// responsible for rounding up the stack frame (probably at emitPrologue
- /// time).
- virtual bool targetHandlesStackFrameRounding() const {
- return false;
- }
-
/// requiresRegisterScavenging - returns true if the target requires (and can
/// make use of) the register scavenger.
virtual bool requiresRegisterScavenging(const MachineFunction &MF) const {
return false;
}
- /// hasFP - Return true if the specified function should have a dedicated
- /// frame pointer register. For most targets this is true only if the function
- /// has variable sized allocas or if frame pointer elimination is disabled.
- virtual bool hasFP(const MachineFunction &MF) const = 0;
-
- /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
- /// not required, we reserve argument space for call sites in the function
- /// immediately on entry to the current function. This eliminates the need for
- /// add/sub sp brackets around call sites. Returns true if the call frame is
- /// included as part of the stack frame.
- virtual bool hasReservedCallFrame(MachineFunction &MF) const {
- return !hasFP(MF);
- }
-
- /// canSimplifyCallFramePseudos - When possible, it's best to simplify the
- /// call frame pseudo ops before doing frame index elimination. This is
- /// possible only when frame index references between the pseudos won't
- /// need adjusted for the call frame adjustments. Normally, that's true
- /// if the function has a reserved call frame or a frame pointer. Some
- /// targets (Thumb2, for example) may have more complicated criteria,
- /// however, and can override this behavior.
- virtual bool canSimplifyCallFramePseudos(MachineFunction &MF) const {
- return hasReservedCallFrame(MF) || hasFP(MF);
+ /// requiresVirtualBaseRegisters - Returns true if the target wants the
+ /// LocalStackAllocation pass to be run and virtual base registers
+ /// used for more efficient stack access.
+ virtual bool requiresVirtualBaseRegisters(const MachineFunction &MF) const {
+ return false;
}
/// hasReservedSpillSlot - Return true if target has reserved a spill slot in
/// reserved as its spill slot. This tells PEI not to create a new stack frame
/// object for the given register. It should be called only after
/// processFunctionBeforeCalleeSavedScan().
- virtual bool hasReservedSpillSlot(MachineFunction &MF, unsigned Reg,
+ virtual bool hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg,
int &FrameIdx) const {
return false;
}
return false;
}
+ /// getFrameIndexInstrOffset - Get the offset from the referenced frame
+ /// index in the instruction, if the is one.
+ virtual int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
+ int Idx) const {
+ return 0;
+ }
+
+ /// needsFrameBaseReg - Returns true if the instruction's frame index
+ /// reference would be better served by a base register other than FP
+ /// or SP. Used by LocalStackFrameAllocation to determine which frame index
+ /// references it should create new base registers for.
+ virtual bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const {
+ return false;
+ }
+
+ /// materializeFrameBaseRegister - Insert defining instruction(s) for
+ /// BaseReg to be a pointer to FrameIdx before insertion point I.
+ virtual void materializeFrameBaseRegister(MachineBasicBlock::iterator I,
+ unsigned BaseReg, int FrameIdx,
+ int64_t Offset) const {
+ assert(0 && "materializeFrameBaseRegister does not exist on this target");
+ }
+
+ /// resolveFrameIndex - Resolve a frame index operand of an instruction
+ /// to reference the indicated base register plus offset instead.
+ virtual void resolveFrameIndex(MachineBasicBlock::iterator I,
+ unsigned BaseReg, int64_t Offset) const {
+ assert(0 && "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,
+ int64_t Offset) const {
+ assert(0 && "isFrameOffsetLegal does not exist on this target");
+ return false; // Must return a value in order to compile with VS 2005
+ }
+
/// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the
/// frame setup/destroy instructions if they exist (-1 otherwise). Some
/// targets use pseudo instructions in order to abstract away the difference
assert(0 && "Call Frame Pseudo Instructions do not exist on this target!");
}
- /// processFunctionBeforeCalleeSavedScan - This method is called immediately
- /// before PrologEpilogInserter scans the physical registers used to determine
- /// what callee saved registers should be spilled. This method is optional.
- virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
- RegScavenger *RS = NULL) const {
-
- }
-
- /// processFunctionBeforeFrameFinalized - This method is called immediately
- /// before the specified functions frame layout (MF.getFrameInfo()) is
- /// finalized. Once the frame is finalized, MO_FrameIndex operands are
- /// replaced with direct constants. This method is optional.
- ///
- virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
- }
/// saveScavengerRegister - Spill the register so it can be used by the
/// register scavenger. Return true if the register was spilled, false
/// specified instruction, as long as it keeps the iterator pointing at the
/// finished product. SPAdj is the SP adjustment due to call frame setup
/// instruction.
- ///
- /// When -enable-frame-index-scavenging is enabled, the virtual register
- /// allocated for this frame index is returned and its value is stored in
- /// *Value.
- typedef std::pair<unsigned, int> FrameIndexValue;
- virtual unsigned eliminateFrameIndex(MachineBasicBlock::iterator MI,
- int SPAdj, FrameIndexValue *Value = NULL,
- RegScavenger *RS=NULL) const = 0;
-
- /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
- /// the function.
- virtual void emitPrologue(MachineFunction &MF) const = 0;
- virtual void emitEpilogue(MachineFunction &MF,
- MachineBasicBlock &MBB) const = 0;
+ virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI,
+ int SPAdj, RegScavenger *RS=NULL) const = 0;
//===--------------------------------------------------------------------===//
/// Debug information queries.
/// for values allocated in the current stack frame.
virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0;
- /// getFrameIndexOffset - Returns the displacement from the frame register to
- /// the stack frame of the specified index.
- virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
-
- /// getFrameIndexReference - This method should return the base register
- /// and offset used to reference a frame index location. The offset is
- /// returned directly, and the base register is returned via FrameReg.
- virtual int getFrameIndexReference(const MachineFunction &MF, int FI,
- unsigned &FrameReg) const {
- // By default, assume all frame indices are referenced via whatever
- // getFrameRegister() says. The target can override this if it's doing
- // something different.
- FrameReg = getFrameRegister(MF);
- return getFrameIndexOffset(MF, FI);
- }
-
/// getRARegister - This method should return the register where the return
/// address can be found.
virtual unsigned getRARegister() const = 0;
-
- /// getInitialFrameState - Returns a list of machine moves that are assumed
- /// on entry to all functions. Note that LabelID is ignored (assumed to be
- /// the beginning of the function.)
- virtual void getInitialFrameState(std::vector<MachineMove> &Moves) const;
};