/// of AX.
///
struct TargetRegisterDesc {
- const char *AsmName; // Assembly language name for the register
const char *Name; // Printable name for the reg (for debugging)
const unsigned *AliasSet; // Register Alias Set, described above
const unsigned *SubRegs; // Sub-register set, described above
typedef const unsigned* iterator;
typedef const unsigned* const_iterator;
- typedef const MVT* vt_iterator;
+ typedef const EVT* vt_iterator;
typedef const TargetRegisterClass* const * sc_iterator;
private:
unsigned ID;
public:
TargetRegisterClass(unsigned id,
const char *name,
- const MVT *vts,
+ const EVT *vts,
const TargetRegisterClass * const *subcs,
const TargetRegisterClass * const *supcs,
const TargetRegisterClass * const *subregcs,
RegSet.insert(*I);
}
virtual ~TargetRegisterClass() {} // Allow subclasses
-
+
/// getID() - Return the register class ID number.
///
unsigned getID() const { return ID; }
/// hasType - return true if this TargetRegisterClass has the ValueType vt.
///
- bool hasType(MVT vt) const {
- for(int i = 0; VTs[i] != MVT::Other; ++i)
+ bool hasType(EVT vt) const {
+ for(int i = 0; VTs[i].getSimpleVT().SimpleTy != MVT::Other; ++i)
if (VTs[i] == vt)
return true;
return false;
}
-
+
/// vt_begin / vt_end - Loop over all of the value types that can be
/// represented by values in this register class.
vt_iterator vt_begin() const {
vt_iterator vt_end() const {
vt_iterator I = VTs;
- while (*I != MVT::Other) ++I;
+ while (I->getSimpleVT().SimpleTy != MVT::Other) ++I;
return I;
}
return I;
}
+ /// getSubRegisterRegClass - Return the register class of subregisters with
+ /// index SubIdx, or NULL if no such class exists.
+ const TargetRegisterClass* getSubRegisterRegClass(unsigned SubIdx) const {
+ assert(SubIdx>0 && "Invalid subregister index");
+ for (unsigned s = 0; s != SubIdx-1; ++s)
+ if (!SubRegClasses[s])
+ return NULL;
+ return SubRegClasses[SubIdx-1];
+ }
+
/// superregclasses_begin / superregclasses_end - Loop over all of
/// the superreg register classes of this register class.
sc_iterator superregclasses_begin() const {
/// hasSubClass - return true if the the specified TargetRegisterClass
/// is a proper subset of this TargetRegisterClass.
bool hasSubClass(const TargetRegisterClass *cs) const {
- for (int i = 0; SubClasses[i] != NULL; ++i)
+ for (int i = 0; SubClasses[i] != NULL; ++i)
if (SubClasses[i] == cs)
return true;
return false;
sc_iterator subclasses_begin() const {
return SubClasses;
}
-
+
sc_iterator subclasses_end() const {
sc_iterator I = SubClasses;
while (*I != NULL) ++I;
return I;
}
-
+
/// hasSuperClass - return true if the specified TargetRegisterClass is a
/// proper superset of this TargetRegisterClass.
bool hasSuperClass(const TargetRegisterClass *cs) const {
- for (int i = 0; SuperClasses[i] != NULL; ++i)
+ for (int i = 0; SuperClasses[i] != NULL; ++i)
if (SuperClasses[i] == cs)
return true;
return false;
sc_iterator superclasses_begin() const {
return SuperClasses;
}
-
+
sc_iterator superclasses_end() const {
sc_iterator I = SuperClasses;
while (*I != NULL) ++I;
bool isASubClass() const {
return SuperClasses[0] != 0;
}
-
+
/// allocation_order_begin/end - These methods define a range of registers
/// which specify the registers in this class that are valid to register
/// allocate, and the preferred order to allocate them in. For example,
return end();
}
-
-
/// getSize - Return the size of the register in bytes, which is also the size
/// of a stack slot allocated to hold a spilled copy of this register.
unsigned getSize() const { return RegSize; }
regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
int CallFrameSetupOpcode, CallFrameDestroyOpcode;
+
protected:
TargetRegisterInfo(const TargetRegisterDesc *D, unsigned NR,
regclass_iterator RegClassBegin,
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);
+ const unsigned* superregs = 0,
+ const unsigned superregsize = 0,
+ const unsigned* aliases = 0,
+ const unsigned aliasessize = 0);
virtual ~TargetRegisterInfo();
public:
}
/// getPhysicalRegisterRegClass - Returns the Register Class of a physical
- /// register of the given type. If type is MVT::Other, then just return any
+ /// 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, MVT VT = MVT::Other) const;
+ getPhysicalRegisterRegClass(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
/// specified, returns the subset for the class.
- BitVector getAllocatableSet(MachineFunction &MF,
+ BitVector getAllocatableSet(const MachineFunction &MF,
const TargetRegisterClass *RC = NULL) const;
const TargetRegisterDesc &operator[](unsigned RegNo) const {
return get(RegNo).SuperRegs;
}
- /// getAsmName - Return the symbolic target-specific name for the
- /// specified physical register.
- const char *getAsmName(unsigned RegNo) const {
- return get(RegNo).AsmName;
- }
-
/// getName - Return the human-readable symbolic target-specific name for the
/// specified physical register.
const char *getName(unsigned RegNo) const {
return NumRegs;
}
- /// areAliases - Returns true if the two registers alias each other, false
- /// otherwise
- bool areAliases(unsigned regA, unsigned regB) const {
+ /// regsOverlap - Returns true if the two registers are equal or alias each
+ /// other. The registers may be virtual register.
+ bool regsOverlap(unsigned regA, unsigned regB) const {
+ if (regA == regB)
+ return true;
+
+ if (isVirtualRegister(regA) || isVirtualRegister(regB))
+ return false;
+
+ // regA and regB are distinct physical registers. Do they alias?
size_t index = (regA + regB * 37) & (AliasesHashSize-1);
unsigned ProbeAmt = 0;
while (AliasesHash[index*2] != 0 &&
- AliasesHash[index*2+1] != 0) {
+ AliasesHash[index*2+1] != 0) {
if (AliasesHash[index*2] == regA && AliasesHash[index*2+1] == regB)
- return true;
+ return true;
index = (index + ProbeAmt) & (AliasesHashSize-1);
ProbeAmt += 2;
return false;
}
- /// regsOverlap - Returns true if the two registers are equal or alias each
- /// other. The registers may be virtual register.
- bool regsOverlap(unsigned regA, unsigned regB) const {
- if (regA == regB)
- return true;
-
- if (isVirtualRegister(regA) || isVirtualRegister(regB))
- return false;
- return areAliases(regA, regB);
- }
-
/// isSubRegister - Returns true if regB is a sub-register of regA.
///
bool isSubRegister(unsigned regA, unsigned regB) const {
SubregHash[index*2+1] != 0) {
if (SubregHash[index*2] == regA && SubregHash[index*2+1] == regB)
return true;
-
+
index = (index + ProbeAmt) & (SubregHashSize-1);
ProbeAmt += 2;
}
-
+
return false;
}
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;
}
/// exist.
virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0;
+ /// getSubRegIndex - For a given register pair, return the sub-register index
+ /// if they are second register is a sub-register of the second. Return zero
+ /// otherwise.
+ virtual unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const = 0;
+
+ /// 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,
+ const TargetRegisterClass *RC) const {
+ for (const unsigned *SRs = getSuperRegisters(Reg); unsigned SR = *SRs;++SRs)
+ if (Reg == getSubReg(SR, SubIdx) && RC->contains(SR))
+ return SR;
+ return 0;
+ }
+
+ /// getMatchingSuperRegClass - Return a subclass of the specified register
+ /// class A so that each register in it has a sub-register of the
+ /// specified sub-register index which is in the specified register class B.
+ virtual const TargetRegisterClass *
+ getMatchingSuperRegClass(const TargetRegisterClass *A,
+ const TargetRegisterClass *B, unsigned Idx) const {
+ return 0;
+ }
+
//===--------------------------------------------------------------------===//
// Register Class Information
//
unsigned getNumRegClasses() const {
return (unsigned)(regclass_end()-regclass_begin());
}
-
+
/// getRegClass - Returns the register class associated with the enumeration
/// value. See class TargetOperandInfo.
const TargetRegisterClass *getRegClass(unsigned i) const {
}
/// getPointerRegClass - Returns a TargetRegisterClass used for pointer
- /// values.
- virtual const TargetRegisterClass *getPointerRegClass() const {
+ /// values. If a target supports multiple different pointer register classes,
+ /// kind specifies which one is indicated.
+ virtual const TargetRegisterClass *getPointerRegClass(unsigned Kind=0) const {
assert(0 && "Target didn't implement getPointerRegClass!");
return 0; // Must return a value in order to compile with VS 2005
}
return NULL;
}
+ /// getAllocationOrder - Returns the register allocation order for a specified
+ /// register class in the form of a pair of TargetRegisterClass iterators.
+ virtual std::pair<TargetRegisterClass::iterator,TargetRegisterClass::iterator>
+ getAllocationOrder(const TargetRegisterClass *RC,
+ unsigned HintType, unsigned HintReg,
+ const MachineFunction &MF) const {
+ return std::make_pair(RC->allocation_order_begin(MF),
+ RC->allocation_order_end(MF));
+ }
+
+ /// ResolveRegAllocHint - Resolves the specified register allocation hint
+ /// to a physical register. Returns the physical register if it is successful.
+ virtual unsigned ResolveRegAllocHint(unsigned Type, unsigned Reg,
+ const MachineFunction &MF) const {
+ if (Type == 0 && Reg && isPhysicalRegister(Reg))
+ return Reg;
+ return 0;
+ }
+
+ /// 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,
+ MachineFunction &MF) const {
+ // Do nothing.
+ }
+
/// targetHandlesStackFrameRounding - Returns true if the target is
/// responsible for rounding up the stack frame (probably at emitPrologue
/// time).
virtual bool requiresRegisterScavenging(const MachineFunction &MF) const {
return false;
}
-
+
+ /// requiresFrameIndexScavenging - returns true if the target requires post
+ /// PEI scavenging of registers for materializing frame index constants.
+ virtual bool requiresFrameIndexScavenging(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.
+ /// 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);
}
- // needsStackRealignment - true if storage within the function requires the
- // stack pointer to be aligned more than the normal calling convention calls
- // for.
+ /// hasReservedSpillSlot - Return true if target has reserved a spill slot in
+ /// the stack frame of the given function for the specified register. e.g. On
+ /// x86, if the frame register is required, the first fixed stack object is
+ /// 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,
+ int &FrameIdx) const {
+ return false;
+ }
+
+ /// needsStackRealignment - true if storage within the function requires the
+ /// stack pointer to be aligned more than the normal calling convention calls
+ /// for.
virtual bool needsStackRealignment(const MachineFunction &MF) const {
return false;
}
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
+ /// otherwise. If this function does not spill the register, the scavenger
+ /// will instead spill it to the emergency spill slot.
+ ///
+ virtual bool saveScavengerRegister(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I,
+ MachineBasicBlock::iterator &UseMI,
+ const TargetRegisterClass *RC,
+ unsigned Reg) const {return false;}
+
/// eliminateFrameIndex - This method must be overriden to eliminate abstract
/// frame indices from instructions which may use them. The instruction
/// referenced by the iterator contains an MO_FrameIndex operand which must be
/// specified instruction, as long as it keeps the iterator pointing the the
/// finished product. SPAdj is the SP adjustment due to call frame setup
/// instruction.
- virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI,
- int SPAdj, RegScavenger *RS=NULL) const = 0;
+ ///
+ /// When -enable-frame-index-scavenging is enabled, the virtual register
+ /// allocated for this frame index is returned and its value is stored in
+ /// *Value.
+ virtual unsigned eliminateFrameIndex(MachineBasicBlock::iterator MI,
+ int SPAdj, int *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;
-
+
//===--------------------------------------------------------------------===//
/// Debug information queries.
-
+
/// getDwarfRegNum - Map a target register to an equivalent dwarf register
/// number. Returns -1 if there is no equivalent value. The second
/// parameter allows targets to use different numberings for EH info and
/// getFrameRegister - This method should return the register used as a base
/// for values allocated in the current stack frame.
- virtual unsigned getFrameRegister(MachineFunction &MF) const = 0;
+ 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(MachineFunction &MF, int FI) const;
-
+
/// 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;
};
+
// This is useful when building IndexedMaps keyed on virtual registers
-struct VirtReg2IndexFunctor : std::unary_function<unsigned, unsigned> {
+struct VirtReg2IndexFunctor : public std::unary_function<unsigned, unsigned> {
unsigned operator()(unsigned Reg) const {
return Reg - TargetRegisterInfo::FirstVirtualRegister;
}
};
+/// getCommonSubClass - find the largest common subclass of A and B. Return NULL
+/// if there is no common subclass.
+const TargetRegisterClass *getCommonSubClass(const TargetRegisterClass *A,
+ const TargetRegisterClass *B);
+
} // End llvm namespace
#endif