diff options
Diffstat (limited to 'include/llvm/CodeGen')
| -rw-r--r-- | include/llvm/CodeGen/FastISel.h | 5 | ||||
| -rw-r--r-- | include/llvm/CodeGen/ISDOpcodes.h | 5 | ||||
| -rw-r--r-- | include/llvm/CodeGen/LiveInterval.h | 57 | ||||
| -rw-r--r-- | include/llvm/CodeGen/LiveIntervalAnalysis.h | 18 | ||||
| -rw-r--r-- | include/llvm/CodeGen/MachineBasicBlock.h | 8 | ||||
| -rw-r--r-- | include/llvm/CodeGen/MachineBranchProbabilityInfo.h | 9 | ||||
| -rw-r--r-- | include/llvm/CodeGen/MachineInstr.h | 34 | ||||
| -rw-r--r-- | include/llvm/CodeGen/MachineInstrBuilder.h | 6 | ||||
| -rw-r--r-- | include/llvm/CodeGen/MachineOperand.h | 53 | ||||
| -rw-r--r-- | include/llvm/CodeGen/MachineRegisterInfo.h | 86 | ||||
| -rw-r--r-- | include/llvm/CodeGen/Passes.h | 8 | ||||
| -rw-r--r-- | include/llvm/CodeGen/SelectionDAG.h | 2 | ||||
| -rw-r--r-- | include/llvm/CodeGen/SelectionDAGNodes.h | 33 | ||||
| -rw-r--r-- | include/llvm/CodeGen/ValueTypes.h | 107 | ||||
| -rw-r--r-- | include/llvm/CodeGen/ValueTypes.td | 30 |
15 files changed, 289 insertions, 172 deletions
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 9fe743e..7cb9695 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -34,6 +34,7 @@ class MachineFrameInfo; class MachineRegisterInfo; class TargetData; class TargetInstrInfo; +class TargetLibraryInfo; class TargetLowering; class TargetMachine; class TargetRegisterClass; @@ -57,6 +58,7 @@ protected: const TargetInstrInfo &TII; const TargetLowering &TLI; const TargetRegisterInfo &TRI; + const TargetLibraryInfo *LibInfo; /// The position of the last instruction for materializing constants /// for use in the current block. It resets to EmitStartPt when it @@ -144,7 +146,8 @@ public: virtual ~FastISel(); protected: - explicit FastISel(FunctionLoweringInfo &funcInfo); + explicit FastISel(FunctionLoweringInfo &funcInfo, + const TargetLibraryInfo *libInfo); /// TargetSelectInstruction - This method is called by target-independent /// code when the normal FastISel process fails to select an instruction. diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index 83a848c..f387bd5 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -126,6 +126,11 @@ namespace ISD { TargetExternalSymbol, TargetBlockAddress, + /// TargetIndex - Like a constant pool entry, but with completely + /// target-dependent semantics. Holds target flags, a 32-bit index, and a + /// 64-bit index. Targets can use this however they like. + TargetIndex, + /// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) /// This node represents a target intrinsic function with no side effects. /// The first operand is the ID number of the intrinsic from the diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 3fe7c8d..a3ce47c 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -40,15 +40,6 @@ namespace llvm { /// definition and use points. /// class VNInfo { - private: - enum { - HAS_PHI_KILL = 1, - IS_PHI_DEF = 1 << 1, - IS_UNUSED = 1 << 2 - }; - - unsigned char flags; - public: typedef BumpPtrAllocator Allocator; @@ -60,60 +51,30 @@ namespace llvm { /// VNInfo constructor. VNInfo(unsigned i, SlotIndex d) - : flags(0), id(i), def(d) + : id(i), def(d) { } /// VNInfo construtor, copies values from orig, except for the value number. VNInfo(unsigned i, const VNInfo &orig) - : flags(orig.flags), id(i), def(orig.def) + : id(i), def(orig.def) { } /// Copy from the parameter into this VNInfo. void copyFrom(VNInfo &src) { - flags = src.flags; def = src.def; } - /// Used for copying value number info. - unsigned getFlags() const { return flags; } - void setFlags(unsigned flags) { this->flags = flags; } - - /// Merge flags from another VNInfo - void mergeFlags(const VNInfo *VNI) { - flags = (flags | VNI->flags) & ~IS_UNUSED; - } - - /// Returns true if one or more kills are PHI nodes. - /// Obsolete, do not use! - bool hasPHIKill() const { return flags & HAS_PHI_KILL; } - /// Set the PHI kill flag on this value. - void setHasPHIKill(bool hasKill) { - if (hasKill) - flags |= HAS_PHI_KILL; - else - flags &= ~HAS_PHI_KILL; - } - /// Returns true if this value is defined by a PHI instruction (or was, /// PHI instrucions may have been eliminated). - bool isPHIDef() const { return flags & IS_PHI_DEF; } - /// Set the "phi def" flag on this value. - void setIsPHIDef(bool phiDef) { - if (phiDef) - flags |= IS_PHI_DEF; - else - flags &= ~IS_PHI_DEF; - } + /// PHI-defs begin at a block boundary, all other defs begin at register or + /// EC slots. + bool isPHIDef() const { return def.isBlock(); } /// Returns true if this value is unused. - bool isUnused() const { return flags & IS_UNUSED; } - /// Set the "is unused" flag on this value. - void setIsUnused(bool unused) { - if (unused) - flags |= IS_UNUSED; - else - flags &= ~IS_UNUSED; - } + bool isUnused() const { return !def.isValid(); } + + /// Mark this value as unused. + void markUnused() { def = SlotIndex(); } }; /// LiveRange structure - This represents a simple register range in the diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index a344b1f..da521db 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -241,18 +241,15 @@ namespace llvm { /// print - Implement the dump method. virtual void print(raw_ostream &O, const Module* = 0) const; - /// isReMaterializable - Returns true if every definition of MI of every - /// val# of the specified interval is re-materializable. Also returns true - /// by reference if all of the defs are load instructions. - bool isReMaterializable(const LiveInterval &li, - const SmallVectorImpl<LiveInterval*> *SpillIs, - bool &isLoad); - /// intervalIsInOneMBB - If LI is confined to a single basic block, return /// a pointer to that block. If LI is live in to or out of any block, /// return NULL. MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const; + /// Returns true if VNI is killed by any PHI-def values in LI. + /// This may conservatively return true to avoid expensive computations. + bool hasPHIKill(const LiveInterval &LI, const VNInfo *VNI) const; + /// addKillFlags - Add kill flags to any instruction that kills a virtual /// register. void addKillFlags(); @@ -347,6 +344,12 @@ namespace llvm { /// computeIntervals - Compute live intervals. void computeIntervals(); + /// Compute live intervals for all virtual registers. + void computeVirtRegs(); + + /// Compute RegMaskSlots and RegMaskBits. + void computeRegMasks(); + /// handleRegisterDef - update intervals for a register def /// (calls handleVirtualRegisterDef) void handleRegisterDef(MachineBasicBlock *MBB, @@ -375,6 +378,7 @@ namespace llvm { void computeLiveInRegUnits(); void computeRegUnitInterval(LiveInterval*); + void computeVirtRegInterval(LiveInterval*); class HMEditor; }; diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 4371aa5..77ea4d0 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -351,6 +351,8 @@ public: /// parameter is stored in Weights list and it may be used by /// MachineBranchProbabilityInfo analysis to calculate branch probability. /// + /// Note that duplicate Machine CFG edges are not allowed. + /// void addSuccessor(MachineBasicBlock *succ, uint32_t weight = 0); /// removeSuccessor - Remove successor from the successors list of this @@ -379,6 +381,10 @@ public: /// which refer to fromMBB to refer to this. void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *fromMBB); + /// isPredecessor - Return true if the specified MBB is a predecessor of this + /// block. + bool isPredecessor(const MachineBasicBlock *MBB) const; + /// isSuccessor - Return true if the specified MBB is a successor of this /// block. bool isSuccessor(const MachineBasicBlock *MBB) const; @@ -568,7 +574,7 @@ private: /// getSuccWeight - Return weight of the edge from this block to MBB. This /// method should NOT be called directly, but by using getEdgeWeight method /// from MachineBranchProbabilityInfo class. - uint32_t getSuccWeight(const MachineBasicBlock *succ) const; + uint32_t getSuccWeight(const_succ_iterator Succ) const; // Methods used to maintain doubly linked list of blocks... diff --git a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h index af4db7d..12189ce 100644 --- a/include/llvm/CodeGen/MachineBranchProbabilityInfo.h +++ b/include/llvm/CodeGen/MachineBranchProbabilityInfo.h @@ -16,14 +16,12 @@ #define LLVM_CODEGEN_MACHINEBRANCHPROBABILITYINFO_H #include "llvm/Pass.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/Support/BranchProbability.h" #include <climits> namespace llvm { -class raw_ostream; -class MachineBasicBlock; - class MachineBranchProbabilityInfo : public ImmutablePass { virtual void anchor(); @@ -52,6 +50,11 @@ public: uint32_t getEdgeWeight(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const; + // Same thing, but using a const_succ_iterator from Src. This is faster when + // the iterator is already available. + uint32_t getEdgeWeight(const MachineBasicBlock *Src, + MachineBasicBlock::const_succ_iterator Dst) const; + // Get sum of the block successors' weights, potentially scaling them to fit // within 32-bits. If scaling is required, sets Scale based on the necessary // adjustment. Any edge weights used with the sum should be divided by Scale. diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 65093d7..27756ab 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -420,6 +420,12 @@ public: return hasProperty(MCID::Bitcast, Type); } + /// isSelect - Return true if this instruction is a select instruction. + /// + bool isSelect(QueryType Type = IgnoreBundle) const { + return hasProperty(MCID::Select, Type); + } + /// isNotDuplicable - Return true if this instruction cannot be safely /// duplicated. For example, if the instruction has a unique labels attached /// to it, duplicating it would cause multiple definition errors. @@ -635,6 +641,30 @@ public: getOperand(0).getSubReg() == getOperand(1).getSubReg(); } + /// isTransient - Return true if this is a transient instruction that is + /// either very likely to be eliminated during register allocation (such as + /// copy-like instructions), or if this instruction doesn't have an + /// execution-time cost. + bool isTransient() const { + switch(getOpcode()) { + default: return false; + // Copy-like instructions are usually eliminated during register allocation. + case TargetOpcode::PHI: + case TargetOpcode::COPY: + case TargetOpcode::INSERT_SUBREG: + case TargetOpcode::SUBREG_TO_REG: + case TargetOpcode::REG_SEQUENCE: + // Pseudo-instructions that don't produce any real output. + case TargetOpcode::IMPLICIT_DEF: + case TargetOpcode::KILL: + case TargetOpcode::PROLOG_LABEL: + case TargetOpcode::EH_LABEL: + case TargetOpcode::GC_LABEL: + case TargetOpcode::DBG_VALUE: + return true; + } + } + /// getBundleSize - Return the number of instructions inside the MI bundle. unsigned getBundleSize() const; @@ -912,12 +942,12 @@ private: /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in /// this instruction from their respective use lists. This requires that the /// operands already be on their use lists. - void RemoveRegOperandsFromUseLists(); + void RemoveRegOperandsFromUseLists(MachineRegisterInfo&); /// AddRegOperandsToUseLists - Add all of the register operands in /// this instruction from their respective use lists. This requires that the /// operands not be on their use lists yet. - void AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo); + void AddRegOperandsToUseLists(MachineRegisterInfo&); /// hasPropertyInBundle - Slow path for hasProperty when we're dealing with a /// bundle. diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h index 9192474..654361f 100644 --- a/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/include/llvm/CodeGen/MachineInstrBuilder.h @@ -108,6 +108,12 @@ public: return *this; } + const MachineInstrBuilder &addTargetIndex(unsigned Idx, int64_t Offset = 0, + unsigned char TargetFlags = 0) const { + MI->addOperand(MachineOperand::CreateTargetIndex(Idx, Offset, TargetFlags)); + return *this; + } + const MachineInstrBuilder &addJumpTableIndex(unsigned Idx, unsigned char TargetFlags = 0) const { MI->addOperand(MachineOperand::CreateJTI(Idx, TargetFlags)); diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index c3b4f7c..37d42b3 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -45,6 +45,7 @@ public: MO_MachineBasicBlock, ///< MachineBasicBlock reference MO_FrameIndex, ///< Abstract Stack Frame Index MO_ConstantPoolIndex, ///< Address of indexed Constant in Constant Pool + MO_TargetIndex, ///< Target-dependent index+offset operand. MO_JumpTableIndex, ///< Address of indexed Jump Table for switch MO_ExternalSymbol, ///< Name of external global symbol MO_GlobalAddress, ///< Address of a global value @@ -149,7 +150,7 @@ private: struct { // For MO_Register. // Register number is in SmallContents.RegNo. - MachineOperand **Prev; // Access list for register. + MachineOperand *Prev; // Access list for register. See MRI. MachineOperand *Next; } Reg; @@ -215,6 +216,8 @@ public: bool isFI() const { return OpKind == MO_FrameIndex; } /// isCPI - Tests if this is a MO_ConstantPoolIndex operand. bool isCPI() const { return OpKind == MO_ConstantPoolIndex; } + /// isTargetIndex - Tests if this is a MO_TargetIndex operand. + bool isTargetIndex() const { return OpKind == MO_TargetIndex; } /// isJTI - Tests if this is a MO_JumpTableIndex operand. bool isJTI() const { return OpKind == MO_JumpTableIndex; } /// isGlobal - Tests if this is a MO_GlobalAddress operand. @@ -302,13 +305,6 @@ public: return !isUndef() && !isInternalRead() && (isUse() || getSubReg()); } - /// getNextOperandForReg - Return the next MachineOperand in the function that - /// uses or defines this register. - MachineOperand *getNextOperandForReg() const { - assert(isReg() && "This is not a register operand!"); - return Contents.Reg.Next; - } - //===--------------------------------------------------------------------===// // Mutators for Register Operands //===--------------------------------------------------------------------===// @@ -335,17 +331,9 @@ public: /// void substPhysReg(unsigned Reg, const TargetRegisterInfo&); - void setIsUse(bool Val = true) { - assert(isReg() && "Wrong MachineOperand accessor"); - assert((Val || !isDebug()) && "Marking a debug operation as def"); - IsDef = !Val; - } + void setIsUse(bool Val = true) { setIsDef(!Val); } - void setIsDef(bool Val = true) { - assert(isReg() && "Wrong MachineOperand accessor"); - assert((!Val || !isDebug()) && "Marking a debug operation as def"); - IsDef = Val; - } + void setIsDef(bool Val = true); void setImplicit(bool Val = true) { assert(isReg() && "Wrong MachineOperand accessor"); @@ -408,7 +396,7 @@ public: } int getIndex() const { - assert((isFI() || isCPI() || isJTI()) && + assert((isFI() || isCPI() || isTargetIndex() || isJTI()) && "Wrong MachineOperand accessor"); return Contents.OffsetedInfo.Val.Index; } @@ -431,8 +419,8 @@ public: /// getOffset - Return the offset from the symbol in this operand. This always /// returns 0 for ExternalSymbol operands. int64_t getOffset() const { - assert((isGlobal() || isSymbol() || isCPI() || isBlockAddress()) && - "Wrong MachineOperand accessor"); + assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() || + isBlockAddress()) && "Wrong MachineOperand accessor"); return (int64_t(Contents.OffsetedInfo.OffsetHi) << 32) | SmallContents.OffsetLo; } @@ -479,14 +467,14 @@ public: } void setOffset(int64_t Offset) { - assert((isGlobal() || isSymbol() || isCPI() || isBlockAddress()) && - "Wrong MachineOperand accessor"); + assert((isGlobal() || isSymbol() || isCPI() || isTargetIndex() || + isBlockAddress()) && "Wrong MachineOperand accessor"); SmallContents.OffsetLo = unsigned(Offset); Contents.OffsetedInfo.OffsetHi = int(Offset >> 32); } void setIndex(int Idx) { - assert((isFI() || isCPI() || isJTI()) && + assert((isFI() || isCPI() || isTargetIndex() || isJTI()) && "Wrong MachineOperand accessor"); Contents.OffsetedInfo.Val.Index = Idx; } @@ -587,6 +575,14 @@ public: Op.setTargetFlags(TargetFlags); return Op; } + static MachineOperand CreateTargetIndex(unsigned Idx, int64_t Offset, + unsigned char TargetFlags = 0) { + MachineOperand Op(MachineOperand::MO_TargetIndex); + Op.setIndex(Idx); + Op.setOffset(Offset); + Op.setTargetFlags(TargetFlags); + return Op; + } static MachineOperand CreateJTI(unsigned Idx, unsigned char TargetFlags = 0) { MachineOperand Op(MachineOperand::MO_JumpTableIndex); @@ -662,15 +658,6 @@ private: assert(isReg() && "Can only add reg operand to use lists"); return Contents.Reg.Prev != 0; } - - /// AddRegOperandToRegInfo - Add this register operand to the specified - /// MachineRegisterInfo. If it is null, then the next/prev fields should be - /// explicitly nulled out. - void AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo); - - /// RemoveRegOperandFromRegInfo - Remove this register operand from the - /// MachineRegisterInfo it is linked with. - void RemoveRegOperandFromRegInfo(); }; inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand& MO) { diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 2bcd1c7..42a8aa4 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -57,6 +57,26 @@ class MachineRegisterInfo { /// physical registers. MachineOperand **PhysRegUseDefLists; + /// getRegUseDefListHead - Return the head pointer for the register use/def + /// list for the specified virtual or physical register. + MachineOperand *&getRegUseDefListHead(unsigned RegNo) { + if (TargetRegisterInfo::isVirtualRegister(RegNo)) + return VRegInfo[RegNo].second; + return PhysRegUseDefLists[RegNo]; + } + + MachineOperand *getRegUseDefListHead(unsigned RegNo) const { + if (TargetRegisterInfo::isVirtualRegister(RegNo)) + return VRegInfo[RegNo].second; + return PhysRegUseDefLists[RegNo]; + } + + /// Get the next element in the use-def chain. + static MachineOperand *getNextOperandForReg(const MachineOperand *MO) { + assert(MO && MO->isReg() && "This is not a register operand!"); + return MO->Contents.Reg.Next; + } + /// UsedPhysRegs - This is a bit vector that is computed and set by the /// register allocator, and must be kept up to date by passes that run after /// register allocation (though most don't modify this). This is used @@ -129,12 +149,21 @@ public: // Register Info //===--------------------------------------------------------------------===// + // Strictly for use by MachineInstr.cpp. + void addRegOperandToUseList(MachineOperand *MO); + + // Strictly for use by MachineInstr.cpp. + void removeRegOperandFromUseList(MachineOperand *MO); + /// reg_begin/reg_end - Provide iteration support to walk over all definitions /// and uses of a register within the MachineFunction that corresponds to this /// MachineRegisterInfo object. template<bool Uses, bool Defs, bool SkipDebug> class defusechain_iterator; + // Make it a friend so it can access getNextOperandForReg(). + template<bool, bool, bool> friend class defusechain_iterator; + /// reg_iterator/reg_begin/reg_end - Walk all defs and uses of the specified /// register. typedef defusechain_iterator<true,true,false> reg_iterator; @@ -172,6 +201,15 @@ public: /// specified register (it may be live-in). bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); } + /// hasOneDef - Return true if there is exactly one instruction defining the + /// specified register. + bool hasOneDef(unsigned RegNo) const { + def_iterator DI = def_begin(RegNo); + if (DI == def_end()) + return false; + return ++DI == def_end(); + } + /// use_iterator/use_begin/use_end - Walk all uses of the specified register. typedef defusechain_iterator<true,false,false> use_iterator; use_iterator use_begin(unsigned RegNo) const { @@ -185,7 +223,12 @@ public: /// hasOneUse - Return true if there is exactly one instruction using the /// specified register. - bool hasOneUse(unsigned RegNo) const; + bool hasOneUse(unsigned RegNo) const { + use_iterator UI = use_begin(RegNo); + if (UI == use_end()) + return false; + return ++UI == use_end(); + } /// use_nodbg_iterator/use_nodbg_begin/use_nodbg_end - Walk all uses of the /// specified register, skipping those marked as Debug. @@ -218,20 +261,6 @@ public: /// constraints. void replaceRegWith(unsigned FromReg, unsigned ToReg); - /// getRegUseDefListHead - Return the head pointer for the register use/def - /// list for the specified virtual or physical register. - MachineOperand *&getRegUseDefListHead(unsigned RegNo) { - if (TargetRegisterInfo::isVirtualRegister(RegNo)) - return VRegInfo[RegNo].second; - return PhysRegUseDefLists[RegNo]; - } - - MachineOperand *getRegUseDefListHead(unsigned RegNo) const { - if (TargetRegisterInfo::isVirtualRegister(RegNo)) - return VRegInfo[RegNo].second; - return PhysRegUseDefLists[RegNo]; - } - /// getVRegDef - Return the machine instr that defines the specified virtual /// register or null if none is found. This assumes that the code is in SSA /// form, so there should only be one definition. @@ -439,10 +468,6 @@ public: const TargetRegisterInfo &TRI, const TargetInstrInfo &TII); -private: - void HandleVRegListReallocation(); - -public: /// defusechain_iterator - This class provides iterator support for machine /// operands in the function that use or define a specific register. If /// ReturnUses is true it returns uses of registers, if ReturnDefs is true it @@ -486,13 +511,22 @@ public: // Iterator traversal: forward iteration only defusechain_iterator &operator++() { // Preincrement assert(Op && "Cannot increment end iterator!"); - Op = Op->getNextOperandForReg(); - - // If this is an operand we don't care about, skip it. - while (Op && ((!ReturnUses && Op->isUse()) || - (!ReturnDefs && Op->isDef()) || - (SkipDebug && Op->isDebug()))) - Op = Op->getNextOperandForReg(); + Op = getNextOperandForReg(Op); + + // All defs come before the uses, so stop def_iterator early. + if (!ReturnUses) { + if (Op) { + if (Op->isUse()) + Op = 0; + else + assert(!Op->isDebug() && "Can't have debug defs"); + } + } else { + // If this is an operand we don't care about, skip it. + while (Op && ((!ReturnDefs && Op->isDef()) || + (SkipDebug && Op->isDebug()))) + Op = getNextOperandForReg(Op); + } return *this; } diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index c80f6dc..07b3b45 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -315,6 +315,10 @@ namespace llvm { /// This pass is still in development extern char &StrongPHIEliminationID; + /// LiveIntervals - This analysis keeps track of the live ranges of virtual + /// and physical registers. + extern char &LiveIntervalsID; + /// LiveStacks pass. An analysis keeping track of the liveness of stack slots. extern char &LiveStacksID; @@ -392,6 +396,10 @@ namespace llvm { /// into tails of their predecessors. extern char &TailDuplicateID; + /// MachineTraceMetrics - This pass computes critical path and CPU resource + /// usage in an ensemble of traces. + extern char &MachineTraceMetricsID; + /// EarlyIfConverter - This pass performs if-conversion on SSA form by /// inserting cmov instructions. extern char &EarlyIfConverterID; diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index a5a912a..1ccfe54 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -422,6 +422,8 @@ public: int Offset = 0, unsigned char TargetFlags=0) { return getConstantPool(C, VT, Align, Offset, true, TargetFlags); } + SDValue getTargetIndex(int Index, EVT VT, int64_t Offset = 0, + unsigned char TargetFlags = 0); // When generating a branch to a BB, we don't in general know enough // to provide debug info for the BB at that time, so keep this one around. SDValue getBasicBlock(MachineBasicBlock *MBB); diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 41407f1..db361ee 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -146,7 +146,8 @@ public: inline bool isMachineOpcode() const; inline unsigned getMachineOpcode() const; inline const DebugLoc getDebugLoc() const; - + inline void dump() const; + inline void dumpr() const; /// reachesChainWithoutSideEffects - Return true if this operand (which must /// be a chain) reaches the specified operand without crossing any @@ -806,7 +807,12 @@ inline bool SDValue::hasOneUse() const { inline const DebugLoc SDValue::getDebugLoc() const { return Node->getDebugLoc(); } - +inline void SDValue::dump() const { + return Node->dump(); +} +inline void SDValue::dumpr() const { + return Node->dumpr(); +} // Define inline functions from the SDUse class. inline void SDUse::set(const SDValue &V) { @@ -1343,6 +1349,29 @@ public: } }; +/// Completely target-dependent object reference. +class TargetIndexSDNode : public SDNode { + unsigned char TargetFlags; + int Index; + int64_t Offset; + friend class SelectionDAG; +public: + + TargetIndexSDNode(int Idx, EVT VT, int64_t Ofs, unsigned char TF) + : SDNode(ISD::TargetIndex, DebugLoc(), getSDVTList(VT)), + TargetFlags(TF), Index(Idx), Offset(Ofs) {} +public: + + unsigned char getTargetFlags() const { return TargetFlags; } + int getIndex() const { return Index; } + int64_t getOffset() const { return Offset; } + + static bool classof(const TargetIndexSDNode*) { return true; } + static bool classof(const SDNode *N) { + return N->getOpcode() == ISD::TargetIndex; + } +}; + class BasicBlockSDNode : public SDNode { MachineBasicBlock *MBB; friend class SelectionDAG; diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index bda43dc..eb38cd3 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -68,36 +68,38 @@ namespace llvm { v2i32 = 22, // 2 x i32 v4i32 = 23, // 4 x i32 v8i32 = 24, // 8 x i32 - v1i64 = 25, // 1 x i64 - v2i64 = 26, // 2 x i64 - v4i64 = 27, // 4 x i64 - v8i64 = 28, // 8 x i64 - - v2f16 = 29, // 2 x f16 - v2f32 = 30, // 2 x f32 - v4f32 = 31, // 4 x f32 - v8f32 = 32, // 8 x f32 - v2f64 = 33, // 2 x f64 - v4f64 = 34, // 4 x f64 + v16i32 = 25, // 16 x i32 + v1i64 = 26, // 1 x i64 + v2i64 = 27, // 2 x i64 + v4i64 = 28, // 4 x i64 + v8i64 = 29, // 8 x i64 + v16i64 = 30, // 16 x i64 + + v2f16 = 31, // 2 x f16 + v2f32 = 32, // 2 x f32 + v4f32 = 33, // 4 x f32 + v8f32 = 34, // 8 x f32 + v2f64 = 35, // 2 x f64 + v4f64 = 36, // 4 x f64 FIRST_VECTOR_VALUETYPE = v2i8, LAST_VECTOR_VALUETYPE = v4f64, FIRST_INTEGER_VECTOR_VALUETYPE = v2i8, - LAST_INTEGER_VECTOR_VALUETYPE = v8i64, + LAST_INTEGER_VECTOR_VALUETYPE = v16i64, FIRST_FP_VECTOR_VALUETYPE = v2f16, LAST_FP_VECTOR_VALUETYPE = v4f64, - x86mmx = 35, // This is an X86 MMX value + x86mmx = 37, // This is an X86 MMX value - Glue = 36, // This glues nodes together during pre-RA sched + Glue = 38, // This glues nodes together during pre-RA sched - isVoid = 37, // This has no value + isVoid = 39, // This has no value - Untyped = 38, // This value takes a register, but has + Untyped = 40, // This value takes a register, but has // unspecified type. The register class // will be determined by the opcode. - LAST_VALUETYPE = 39, // This always remains at the end of the list. + LAST_VALUETYPE = 41, // This always remains at the end of the list. // This is the current maximum for LAST_VALUETYPE. // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors @@ -156,7 +158,7 @@ namespace llvm { return ((SimpleTy >= MVT::FIRST_FP_VALUETYPE && SimpleTy <= MVT::LAST_FP_VALUETYPE) || (SimpleTy >= MVT::FIRST_FP_VECTOR_VALUETYPE && - SimpleTy <= MVT::LAST_FP_VECTOR_VALUETYPE)); + SimpleTy <= MVT::LAST_FP_VECTOR_VALUETYPE)); } /// isInteger - Return true if this is an integer, or a vector integer type. @@ -173,6 +175,37 @@ namespace llvm { SimpleTy <= MVT::LAST_VECTOR_VALUETYPE); } + /// is64BitVector - Return true if this is a 64-bit vector type. + bool is64BitVector() const { + return (SimpleTy == MVT::v8i8 || SimpleTy == MVT::v4i16 || + SimpleTy == MVT::v2i32 || SimpleTy == MVT::v1i64 || + SimpleTy == MVT::v2f32); + } + + /// is128BitVector - Return true if this is a 128-bit vector type. + bool is128BitVector() const { + return (SimpleTy == MVT::v16i8 || SimpleTy == MVT::v8i16 || + SimpleTy == MVT::v4i32 || SimpleTy == MVT::v2i64 || + SimpleTy == MVT::v4f32 || SimpleTy == MVT::v2f64); + } + + /// is256BitVector - Return true if this is a 256-bit vector type. + bool is256BitVector() const { + return (SimpleTy == MVT::v8f32 || SimpleTy == MVT::v4f64 || + SimpleTy == MVT::v32i8 || SimpleTy == MVT::v16i16 || + SimpleTy == MVT::v8i32 || SimpleTy == MVT::v4i64); + } + + /// is512BitVector - Return true if this is a 512-bit vector type. + bool is512BitVector() const { + return (SimpleTy == MVT::v8i64 || SimpleTy == MVT::v16i32); + } + + /// is1024BitVector - Return true if this is a 1024-bit vector type. + bool is1024BitVector() const { + return (SimpleTy == MVT::v16i64); + } + /// isPow2VectorType - Returns true if the given vector is a power of 2. bool isPow2VectorType() const { unsigned NElts = getVectorNumElements(); @@ -211,11 +244,13 @@ namespace llvm { case v16i16: return i16; case v2i32: case v4i32: - case v8i32: return i32; + case v8i32: + case v16i32: return i32; case v1i64: case v2i64: case v4i64: - case v8i64: return i64; + case v8i64: + case v16i64: return i64; case v2f16: return f16; case v2f32: case v4f32: @@ -231,7 +266,9 @@ namespace llvm { llvm_unreachable("Not a vector MVT!"); case v32i8: return 32; case v16i8: - case v16i16: return 16; + case v16i16: + case v16i32: + case v16i64:return 16; case v8i8 : case v8i16: case v8i32: @@ -298,7 +335,9 @@ namespace llvm { case v4i64: case v8f32: case v4f64: return 256; + case v16i32: case v8i64: return 512; + case v16i64:return 1024; } } @@ -371,12 +410,14 @@ namespace llvm { if (NumElements == 2) return MVT::v2i32; if (NumElements == 4) return MVT::v4i32; if (NumElements == 8) return MVT::v8i32; + if (NumElements == 16) return MVT::v16i32; break; case MVT::i64: if (NumElements == 1) return MVT::v1i64; if (NumElements == 2) return MVT::v2i64; if (NumElements == 4) return MVT::v4i64; if (NumElements == 8) return MVT::v8i64; + if (NumElements == 16) return MVT::v16i64; break; case MVT::f16: if (NumElements == 2) return MVT::v2f16; @@ -490,32 +531,27 @@ namespace llvm { /// is64BitVector - Return true if this is a 64-bit vector type. bool is64BitVector() const { - if (!isSimple()) - return isExtended64BitVector(); - - return (V == MVT::v8i8 || V==MVT::v4i16 || V==MVT::v2i32 || - V == MVT::v1i64 || V==MVT::v2f32); + return isSimple() ? V.is64BitVector() : isExtended64BitVector(); } /// is128BitVector - Return true if this is a 128-bit vector type. bool is128BitVector() const { - if (!isSimple()) - return isExtended128BitVector(); - return (V==MVT::v16i8 || V==MVT::v8i16 || V==MVT::v4i32 || - V==MVT::v2i64 || V==MVT::v4f32 || V==MVT::v2f64); + return isSimple() ? V.is128BitVector() : isExtended128BitVector(); } /// is256BitVector - Return true if this is a 256-bit vector type. bool is256BitVector() const { - if (!isSimple()) - return isExtended256BitVector(); - return (V == MVT::v8f32 || V == MVT::v4f64 || V == MVT::v32i8 || - V == MVT::v16i16 || V == MVT::v8i32 || V == MVT::v4i64); + return isSimple() ? V.is256BitVector() : isExtended256BitVector(); } /// is512BitVector - Return true if this is a 512-bit vector type. bool is512BitVector() const { - return isSimple() ? (V == MVT::v8i64) : isExtended512BitVector(); + return isSimple() ? V.is512BitVector() : isExtended512BitVector(); + } + + /// is1024BitVector - Return true if this is a 1024-bit vector type. + bool is1024BitVector() const { + return isSimple() ? V.is1024BitVector() : isExtended1024BitVector(); } /// isOverloaded - Return true if this is an overloaded type for TableGen. @@ -708,6 +744,7 @@ namespace llvm { bool isExtended128BitVector() const; bool isExtended256BitVector() const; bool isExtended512BitVector() const; + bool isExtended1024BitVector() const; EVT getExtendedVectorElementType() const; unsigned getExtendedVectorNumElements() const; unsigned getExtendedSizeInBits() const; diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td index 6c22690..f4b75bd 100644 --- a/include/llvm/CodeGen/ValueTypes.td +++ b/include/llvm/CodeGen/ValueTypes.td @@ -45,22 +45,24 @@ def v16i16 : ValueType<256, 21>; // 16 x i16 vector value def v2i32 : ValueType<64 , 22>; // 2 x i32 vector value def v4i32 : ValueType<128, 23>; // 4 x i32 vector value def v8i32 : ValueType<256, 24>; // 8 x i32 vector value -def v1i64 : ValueType<64 , 25>; // 1 x i64 vector value -def v2i64 : ValueType<128, 26>; // 2 x i64 vector value -def v4i64 : ValueType<256, 27>; // 4 x i64 vector value -def v8i64 : ValueType<512, 28>; // 8 x i64 vector value +def v16i32 : ValueType<512, 25>; // 16 x i32 vector value +def v1i64 : ValueType<64 , 26>; // 1 x i64 vector value +def v2i64 : ValueType<128, 27>; // 2 x i64 vector value +def v4i64 : ValueType<256, 28>; // 4 x i64 vector value +def v8i64 : ValueType<512, 29>; // 8 x i64 vector value +def v16i64 : ValueType<1024,30>; // 16 x i64 vector value -def v2f16 : ValueType<32 , 29>; // 2 x f16 vector value -def v2f32 : ValueType<64 , 30>; // 2 x f32 vector value -def v4f32 : ValueType<128, 31>; // 4 x f32 vector value -def v8f32 : ValueType<256, 32>; // 8 x f32 vector value -def v2f64 : ValueType<128, 33>; // 2 x f64 vector value -def v4f64 : ValueType<256, 34>; // 4 x f64 vector value +def v2f16 : ValueType<32 , 31>; // 2 x f16 vector value +def v2f32 : ValueType<64 , 32>; // 2 x f32 vector value +def v4f32 : ValueType<128, 33>; // 4 x f32 vector value +def v8f32 : ValueType<256, 34>; // 8 x f32 vector value +def v2f64 : ValueType<128, 35>; // 2 x f64 vector value +def v4f64 : ValueType<256, 36>; // 4 x f64 vector value -def x86mmx : ValueType<64 , 35>; // X86 MMX value -def FlagVT : ValueType<0 , 36>; // Pre-RA sched glue -def isVoid : ValueType<0 , 37>; // Produces no value -def untyped: ValueType<8 , 38>; // Produces an untyped value +def x86mmx : ValueType<64 , 37>; // X86 MMX value +def FlagVT : ValueType<0 , 38>; // Pre-RA sched glue +def isVoid : ValueType<0 , 39>; // Produces no value +def untyped: ValueType<8 , 40>; // Produces an untyped value def MetadataVT: ValueType<0, 250>; // Metadata |
