X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FTarget%2FTargetRegisterInfo.h;h=5dda8bd4b938c6b159b798579aff56946ee4edc4;hp=2a8ef98cc770d6e98da6653001ed08cdd05f4fcc;hb=96c909cc74e41dc26edcad3775b07fe317210821;hpb=0b8c9a80f20772c3793201ab5b251d3520b9cea3 diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 2a8ef98cc77..5dda8bd4b93 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -174,7 +174,7 @@ public: /// isASubClass - return true if this TargetRegisterClass is a subset /// class of at least one other TargetRegisterClass. bool isASubClass() const { - return SuperClasses[0] != 0; + return SuperClasses[0] != nullptr; } /// getRawAllocationOrder - Returns the preferred order for allocating @@ -226,13 +226,15 @@ private: const unsigned *SubRegIndexLaneMasks; regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses + unsigned CoveringLanes; protected: TargetRegisterInfo(const TargetRegisterInfoDesc *ID, regclass_iterator RegClassBegin, regclass_iterator RegClassEnd, const char *const *SRINames, - const unsigned *SRILaneMasks); + const unsigned *SRILaneMasks, + unsigned CoveringLanes); virtual ~TargetRegisterInfo(); public: @@ -315,7 +317,7 @@ public: /// indicating if a register is allocatable or not. If a register class is /// specified, returns the subset for the class. BitVector getAllocatableSet(const MachineFunction &MF, - const TargetRegisterClass *RC = NULL) const; + const TargetRegisterClass *RC = nullptr) const; /// getCostPerUse - Return the additional cost of using this register instead /// of other registers in its class. @@ -362,6 +364,31 @@ public: return SubRegIndexLaneMasks[SubIdx]; } + /// The lane masks returned by getSubRegIndexLaneMask() above can only be + /// used to determine if sub-registers overlap - they can't be used to + /// determine if a set of sub-registers completely cover another + /// sub-register. + /// + /// The X86 general purpose registers have two lanes corresponding to the + /// sub_8bit and sub_8bit_hi sub-registers. Both sub_32bit and sub_16bit have + /// lane masks '3', but the sub_16bit sub-register doesn't fully cover the + /// sub_32bit sub-register. + /// + /// On the other hand, the ARM NEON lanes fully cover their registers: The + /// dsub_0 sub-register is completely covered by the ssub_0 and ssub_1 lanes. + /// This is related to the CoveredBySubRegs property on register definitions. + /// + /// This function returns a bit mask of lanes that completely cover their + /// sub-registers. More precisely, given: + /// + /// Covering = getCoveringLanes(); + /// MaskA = getSubRegIndexLaneMask(SubA); + /// MaskB = getSubRegIndexLaneMask(SubB); + /// + /// If (MaskA & ~(MaskB & Covering)) == 0, then SubA is completely covered by + /// SubB. + unsigned getCoveringLanes() const { return CoveringLanes; } + /// 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 { @@ -393,8 +420,8 @@ public: /// order of desired callee-save stack frame offset. The first register is /// closest to the incoming stack pointer if stack grows down, and vice versa. /// - virtual const MCPhysReg* getCalleeSavedRegs(const MachineFunction *MF = 0) - const = 0; + virtual const MCPhysReg* + getCalleeSavedRegs(const MachineFunction *MF = nullptr) const = 0; /// getCallPreservedMask - Return a mask of call-preserved registers for the /// given calling convention on the current sub-target. The mask should @@ -416,7 +443,7 @@ public: /// virtual const uint32_t *getCallPreservedMask(CallingConv::ID) const { // The default mask clobbers everything. All targets should override. - return 0; + return nullptr; } /// getReservedRegs - Returns a bitset indexed by physical register number @@ -624,7 +651,7 @@ public: ArrayRef Order, SmallVectorImpl &Hints, const MachineFunction &MF, - const VirtRegMap *VRM = 0) const; + const VirtRegMap *VRM = nullptr) const; /// avoidWriteAfterWrite - Return true if the register allocator should avoid /// writing a register from RC in two consecutive instructions. @@ -645,6 +672,28 @@ public: // Do nothing. } + /// Allow the target to reverse allocation order of local live ranges. This + /// will generally allocate shorter local live ranges first. For targets with + /// many registers, this could reduce regalloc compile time by a large + /// factor. It is disabled by default for three reasons: + /// (1) Top-down allocation is simpler and easier to debug for targets that + /// don't benefit from reversing the order. + /// (2) Bottom-up allocation could result in poor evicition decisions on some + /// targets affecting the performance of compiled code. + /// (3) Bottom-up allocation is no longer guaranteed to optimally color. + virtual bool reverseLocalAssignment() const { return false; } + + /// Allow the target to override register assignment heuristics based on the + /// live range size. If this returns false, then local live ranges are always + /// assigned in order regardless of their size. This is a temporary hook for + /// debugging downstream codegen failures exposed by regalloc. + virtual bool mayOverrideLocalAssignment() const { return true; } + + /// Allow the target to override the cost of using a callee-saved register for + /// the first time. Default value of 0 means we will use a callee-saved + /// register if it is available. + virtual unsigned getCSRFirstUseCost() const { return 0; } + /// requiresRegisterScavenging - returns true if the target requires (and can /// make use of) the register scavenger. virtual bool requiresRegisterScavenging(const MachineFunction &MF) const { @@ -721,8 +770,8 @@ public: /// 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 { + virtual void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, + int64_t Offset) const { llvm_unreachable("resolveFrameIndex does not exist on this target"); } @@ -733,21 +782,6 @@ public: llvm_unreachable("isFrameOffsetLegal does not exist on this target"); } - /// eliminateCallFramePseudoInstr - This method is called during prolog/epilog - /// code insertion to eliminate call frame setup and destroy pseudo - /// instructions (but only if the Target is using them). It is responsible - /// for eliminating these instructions, replacing them with concrete - /// instructions. This method need only be implemented if using call frame - /// setup/destroy pseudo instructions. - /// - virtual void - eliminateCallFramePseudoInstr(MachineFunction &MF, - MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI) const { - llvm_unreachable("Call Frame Pseudo Instructions do not exist on this " - "target!"); - } - /// saveScavengerRegister - Spill the register so it can be used by the /// register scavenger. Return true if the register was spilled, false @@ -767,10 +801,23 @@ public: /// referenced by the iterator contains an MO_FrameIndex operand which must be /// eliminated by this method. This method may modify or replace the /// 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. + /// finished product. SPAdj is the SP adjustment due to call frame setup + /// instruction. FIOperandNum is the FI operand number. virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI, - int SPAdj, RegScavenger *RS=NULL) const = 0; + int SPAdj, unsigned FIOperandNum, + RegScavenger *RS = nullptr) const = 0; + + //===--------------------------------------------------------------------===// + /// Subtarget Hooks + + /// \brief SrcRC and DstRC will be morphed into NewRC if this returns true. + virtual bool shouldCoalesce(MachineInstr *MI, + const TargetRegisterClass *SrcRC, + unsigned SubReg, + const TargetRegisterClass *DstRC, + unsigned DstSubReg, + const TargetRegisterClass *NewRC) const + { return true; } //===--------------------------------------------------------------------===// /// Debug information queries. @@ -778,12 +825,6 @@ public: /// getFrameRegister - This method should return the register used as a base /// for values allocated in the current stack frame. virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0; - - /// getCompactUnwindRegNum - This function maps the register to the number for - /// compact unwind encoding. Return -1 if the register isn't valid. - virtual int getCompactUnwindRegNum(unsigned, bool) const { - return -1; - } }; @@ -839,7 +880,7 @@ public: Mask += RCMaskWords; SubReg = *Idx++; if (!SubReg) - Idx = 0; + Idx = nullptr; } }; @@ -867,7 +908,7 @@ class PrintReg { unsigned Reg; unsigned SubIdx; public: - explicit PrintReg(unsigned reg, const TargetRegisterInfo *tri = 0, + explicit PrintReg(unsigned reg, const TargetRegisterInfo *tri = nullptr, unsigned subidx = 0) : TRI(tri), Reg(reg), SubIdx(subidx) {} void print(raw_ostream&) const; @@ -888,6 +929,7 @@ static inline raw_ostream &operator<<(raw_ostream &OS, const PrintReg &PR) { /// Usage: OS << PrintRegUnit(Unit, TRI) << '\n'; /// class PrintRegUnit { +protected: const TargetRegisterInfo *TRI; unsigned Unit; public: @@ -901,6 +943,21 @@ static inline raw_ostream &operator<<(raw_ostream &OS, const PrintRegUnit &PR) { return OS; } +/// PrintVRegOrUnit - It is often convenient to track virtual registers and +/// physical register units in the same list. +class PrintVRegOrUnit : protected PrintRegUnit { +public: + PrintVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *tri) + : PrintRegUnit(VRegOrUnit, tri) {} + void print(raw_ostream&) const; +}; + +static inline raw_ostream &operator<<(raw_ostream &OS, + const PrintVRegOrUnit &PR) { + PR.print(OS); + return OS; +} + } // End llvm namespace #endif