Index: include/llvm/ADT/SmallVector.h =================================================================== --- include/llvm/ADT/SmallVector.h +++ include/llvm/ADT/SmallVector.h @@ -28,6 +28,96 @@ namespace llvm { +/// FlagVector is a class to contain simple type element, such as bool, int, etc. +/// [] operation is safe for any > 0 index since it will expand according to the index +/// it is mainly used to indicate the existence of one element in a set. +template +class FlagVector { +public: + // Default ctor - Initialize to empty. + explicit FlagVector() { + BeginX = SmallStorage; + Size = 0; + Capacity = SmallSize; + memset(BeginX, 0, sizeof(T) * Capacity); + } +private: + T SmallStorage[SmallSize]; + T *BeginX; + size_t Size, Capacity; + +public: + ~FlagVector() { + if (BeginX != SmallStorage) { + free(BeginX); + } + } + + size_t size() const { return Size; } + + void push_back(T val) { + assert(Size < Capacity); + this->operator[](Size++) = val; + } + + void reserve(unsigned N) { + if (Capacity < N) { + this->grow(N); + } + } + + T& operator[](unsigned idx) { + if (idx >= Capacity) { + grow(idx + 1); + } + if (idx >= Size) { + Size = idx + 1; + } + return BeginX[idx]; + } + + const T& operator[](unsigned idx) const { + if (idx >= Capacity) { + grow(idx + 1); + } + if (idx >= Size) { + Size = idx + 1; + } + return BeginX[idx]; + } + +private: + void grow(size_t NewSize) { + if (NewSize <= Capacity) { + return; + } + while (Capacity <= NewSize) { + Capacity = Capacity << 1; + } + + T *NewElts = static_cast(malloc(Capacity * sizeof(T))); + memcpy(NewElts, BeginX, Size * sizeof(T)); + memset(NewElts + Size, 0, (Capacity - Size) * sizeof(T)); + if (BeginX != SmallStorage) { + free(BeginX); + } + BeginX = NewElts; + } + + void reset() { + memset(BeginX, 0, sizeof(T) * Size); + } + + void resize(unsigned N) { + if (N < Size) { + Size = N; + memset(BeginX + Size, 0, sizeof(T) * (Capacity - Size)); + } else if (Capacity < N) { + this->grow(N); + } + } +}; + /// SmallVectorBase - This is all the non-templated stuff common to all /// SmallVectors. class SmallVectorBase { Index: include/llvm/CodeGen/SelectionDAG.h =================================================================== --- include/llvm/CodeGen/SelectionDAG.h +++ include/llvm/CodeGen/SelectionDAG.h @@ -127,7 +127,7 @@ /// but is significantly more simple, powerful, and is a graph form instead of a /// linear form. /// -class SelectionDAG { +class SelectionDAG : public SDContext { const TargetMachine &TM; const TargetSelectionDAGInfo &TSI; const TargetTransformInfo *TTI; Index: include/llvm/CodeGen/SelectionDAGNodes.h =================================================================== --- include/llvm/CodeGen/SelectionDAGNodes.h +++ include/llvm/CodeGen/SelectionDAGNodes.h @@ -50,6 +50,16 @@ void checkForCycles(const SDNode *N); +/// SDContext provide the interface to number the SDNode in a selection DAG +class SDContext { +protected: + /// SDNode counter in a DAG, to facilitating the numbering of SDNode. + int SDNodeCount; + SDContext() : SDNodeCount(0) {} +public: + int SDNodeNumber() { return SDNodeCount++; } +}; + /// SDVTList - This represents a list of ValueType's that has been intern'd by /// a SelectionDAG. Instances of this simple value class are returned by /// SelectionDAG::getVTList(...). @@ -358,6 +368,9 @@ friend struct ilist_traits; public: + // The unique number for a SDNode in a selection DAG + // SDNode is numbered from 0 incrementally in one DAG + int SeqPos; //===--------------------------------------------------------------------===// // Accessors // @@ -696,7 +709,7 @@ return Ret; } - SDNode(unsigned Opc, unsigned Order, const DebugLoc dl, SDVTList VTs, + SDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, const DebugLoc dl, SDVTList VTs, const SDValue *Ops, unsigned NumOps) : NodeType(Opc), OperandsNeedDelete(true), HasDebugValue(false), SubclassData(0), NodeId(-1), @@ -704,6 +717,8 @@ ValueList(VTs.VTs), UseList(NULL), NumOperands(NumOps), NumValues(VTs.NumVTs), debugLoc(dl), IROrder(Order) { + assert(ownerDAG && "SDNode is created with a null ownerDAG!"); + SeqPos = ownerDAG->SDNodeNumber(); for (unsigned i = 0; i != NumOps; ++i) { OperandList[i].setUser(this); OperandList[i].setInitial(Ops[i]); @@ -713,11 +728,14 @@ /// This constructor adds no operands itself; operands can be /// set later with InitOperands. - SDNode(unsigned Opc, unsigned Order, const DebugLoc dl, SDVTList VTs) + SDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, const DebugLoc dl, SDVTList VTs) : NodeType(Opc), OperandsNeedDelete(false), HasDebugValue(false), SubclassData(0), NodeId(-1), OperandList(0), ValueList(VTs.VTs), UseList(NULL), NumOperands(0), NumValues(VTs.NumVTs), - debugLoc(dl), IROrder(Order) {} + debugLoc(dl), IROrder(Order) { + assert(ownerDAG && "SDNode is created with a null ownerDAG!"); + SeqPos = ownerDAG->SDNodeNumber(); + } /// InitOperands - Initialize the operands list of this with 1 operand. void InitOperands(SDUse *Ops, const SDValue &Op0) { @@ -901,8 +919,8 @@ class UnarySDNode : public SDNode { SDUse Op; public: - UnarySDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, SDValue X) - : SDNode(Opc, Order, dl, VTs) { + UnarySDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, SDValue X) + : SDNode(ownerDAG, Opc, Order, dl, VTs) { InitOperands(&Op, X); } }; @@ -912,8 +930,8 @@ class BinarySDNode : public SDNode { SDUse Ops[2]; public: - BinarySDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y) - : SDNode(Opc, Order, dl, VTs) { + BinarySDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y) + : SDNode(ownerDAG, Opc, Order, dl, VTs) { InitOperands(Ops, X, Y); } }; @@ -923,9 +941,9 @@ class TernarySDNode : public SDNode { SDUse Ops[3]; public: - TernarySDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, + TernarySDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y, SDValue Z) - : SDNode(Opc, Order, dl, VTs) { + : SDNode(ownerDAG, Opc, Order, dl, VTs) { InitOperands(Ops, X, Y, Z); } }; @@ -943,9 +961,9 @@ #if __GNUC__==4 && __GNUC_MINOR__==2 && defined(__APPLE__) && !defined(__llvm__) explicit __attribute__((__noinline__)) HandleSDNode(SDValue X) #else - explicit HandleSDNode(SDValue X) + explicit HandleSDNode(SDContext *ownerDAG, SDValue X) #endif - : SDNode(ISD::HANDLENODE, 0, DebugLoc(), getSDVTList(MVT::Other)) { + : SDNode(ownerDAG, ISD::HANDLENODE, 0, DebugLoc(), getSDVTList(MVT::Other)) { InitOperands(&Op, X); } ~HandleSDNode(); @@ -963,10 +981,10 @@ MachineMemOperand *MMO; public: - MemSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, + MemSDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, EVT MemoryVT, MachineMemOperand *MMO); - MemSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, const SDValue *Ops, + MemSDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, const SDValue *Ops, unsigned NumOps, EVT MemoryVT, MachineMemOperand *MMO); bool readMem() const { return MMO->isLoad(); } @@ -1090,27 +1108,27 @@ // Swp: swap value // SrcVal: address to update as a Value (used for MemOperand) // Align: alignment of memory - AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL, EVT MemVT, + AtomicSDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp, MachineMemOperand *MMO, AtomicOrdering Ordering, SynchronizationScope SynchScope) - : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) { + : MemSDNode(ownerDAG, Opc, Order, dl, VTL, MemVT, MMO) { InitAtomic(Ordering, SynchScope); InitOperands(Ops, Chain, Ptr, Cmp, Swp); } - AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL, EVT MemVT, + AtomicSDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO, AtomicOrdering Ordering, SynchronizationScope SynchScope) - : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) { + : MemSDNode(ownerDAG, Opc, Order, dl, VTL, MemVT, MMO) { InitAtomic(Ordering, SynchScope); InitOperands(Ops, Chain, Ptr, Val); } - AtomicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL, EVT MemVT, + AtomicSDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTL, EVT MemVT, SDValue Chain, SDValue Ptr, MachineMemOperand *MMO, AtomicOrdering Ordering, SynchronizationScope SynchScope) - : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) { + : MemSDNode(ownerDAG, Opc, Order, dl, VTL, MemVT, MMO) { InitAtomic(Ordering, SynchScope); InitOperands(Ops, Chain, Ptr); } @@ -1148,10 +1166,10 @@ /// with a value not less than FIRST_TARGET_MEMORY_OPCODE. class MemIntrinsicSDNode : public MemSDNode { public: - MemIntrinsicSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, + MemIntrinsicSDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, const SDValue *Ops, unsigned NumOps, EVT MemoryVT, MachineMemOperand *MMO) - : MemSDNode(Opc, Order, dl, VTs, Ops, NumOps, MemoryVT, MMO) { + : MemSDNode(ownerDAG, Opc, Order, dl, VTs, Ops, NumOps, MemoryVT, MMO) { } // Methods to support isa and dyn_cast @@ -1181,8 +1199,8 @@ const int *Mask; protected: friend class SelectionDAG; - ShuffleVectorSDNode(EVT VT, unsigned Order, DebugLoc dl, SDValue N1, SDValue N2, const int *M) - : SDNode(ISD::VECTOR_SHUFFLE, Order, dl, getSDVTList(VT)), Mask(M) { + ShuffleVectorSDNode(SDContext *ownerDAG, EVT VT, unsigned Order, DebugLoc dl, SDValue N1, SDValue N2, const int *M) + : SDNode(ownerDAG, ISD::VECTOR_SHUFFLE, Order, dl, getSDVTList(VT)), Mask(M) { InitOperands(Ops, N1, N2); } public: @@ -1216,8 +1234,8 @@ class ConstantSDNode : public SDNode { const ConstantInt *Value; friend class SelectionDAG; - ConstantSDNode(bool isTarget, const ConstantInt *val, EVT VT) - : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, + ConstantSDNode(SDContext *ownerDAG, bool isTarget, const ConstantInt *val, EVT VT) + : SDNode(ownerDAG, isTarget ? ISD::TargetConstant : ISD::Constant, 0, DebugLoc(), getSDVTList(VT)), Value(val) { } public: @@ -1240,8 +1258,8 @@ class ConstantFPSDNode : public SDNode { const ConstantFP *Value; friend class SelectionDAG; - ConstantFPSDNode(bool isTarget, const ConstantFP *val, EVT VT) - : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, + ConstantFPSDNode(SDContext *ownerDAG, bool isTarget, const ConstantFP *val, EVT VT) + : SDNode(ownerDAG, isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, 0, DebugLoc(), getSDVTList(VT)), Value(val) { } public: @@ -1285,7 +1303,7 @@ int64_t Offset; unsigned char TargetFlags; friend class SelectionDAG; - GlobalAddressSDNode(unsigned Opc, unsigned Order, DebugLoc DL, const GlobalValue *GA, EVT VT, + GlobalAddressSDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc DL, const GlobalValue *GA, EVT VT, int64_t o, unsigned char TargetFlags); public: @@ -1306,8 +1324,8 @@ class FrameIndexSDNode : public SDNode { int FI; friend class SelectionDAG; - FrameIndexSDNode(int fi, EVT VT, bool isTarg) - : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, + FrameIndexSDNode(SDContext *ownerDAG, int fi, EVT VT, bool isTarg) + : SDNode(ownerDAG, isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, 0, DebugLoc(), getSDVTList(VT)), FI(fi) { } public: @@ -1324,8 +1342,8 @@ int JTI; unsigned char TargetFlags; friend class SelectionDAG; - JumpTableSDNode(int jti, EVT VT, bool isTarg, unsigned char TF) - : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, + JumpTableSDNode(SDContext *ownerDAG, int jti, EVT VT, bool isTarg, unsigned char TF) + : SDNode(ownerDAG, isTarg ? ISD::TargetJumpTable : ISD::JumpTable, 0, DebugLoc(), getSDVTList(VT)), JTI(jti), TargetFlags(TF) { } public: @@ -1348,16 +1366,16 @@ unsigned Alignment; // Minimum alignment requirement of CP (not log2 value). unsigned char TargetFlags; friend class SelectionDAG; - ConstantPoolSDNode(bool isTarget, const Constant *c, EVT VT, int o, + ConstantPoolSDNode(SDContext *ownerDAG, bool isTarget, const Constant *c, EVT VT, int o, unsigned Align, unsigned char TF) - : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0, DebugLoc(), + : SDNode(ownerDAG, isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0, DebugLoc(), getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) { assert(Offset >= 0 && "Offset is too large"); Val.ConstVal = c; } - ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, + ConstantPoolSDNode(SDContext *ownerDAG, bool isTarget, MachineConstantPoolValue *v, EVT VT, int o, unsigned Align, unsigned char TF) - : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0, DebugLoc(), + : SDNode(ownerDAG, isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0, DebugLoc(), getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) { assert(Offset >= 0 && "Offset is too large"); Val.MachineCPVal = v; @@ -1405,8 +1423,8 @@ friend class SelectionDAG; public: - TargetIndexSDNode(int Idx, EVT VT, int64_t Ofs, unsigned char TF) - : SDNode(ISD::TargetIndex, 0, DebugLoc(), getSDVTList(VT)), + TargetIndexSDNode(SDContext *ownerDAG, int Idx, EVT VT, int64_t Ofs, unsigned char TF) + : SDNode(ownerDAG, ISD::TargetIndex, 0, DebugLoc(), getSDVTList(VT)), TargetFlags(TF), Index(Idx), Offset(Ofs) {} public: @@ -1425,8 +1443,8 @@ /// Debug info is meaningful and potentially useful here, but we create /// blocks out of order when they're jumped to, which makes it a bit /// harder. Let's see if we need it first. - explicit BasicBlockSDNode(MachineBasicBlock *mbb) - : SDNode(ISD::BasicBlock, 0, DebugLoc(), getSDVTList(MVT::Other)), MBB(mbb) { + explicit BasicBlockSDNode(SDContext *ownerDAG, MachineBasicBlock *mbb) + : SDNode(ownerDAG, ISD::BasicBlock, 0, DebugLoc(), getSDVTList(MVT::Other)), MBB(mbb) { } public: @@ -1469,8 +1487,8 @@ const Value *V; friend class SelectionDAG; /// Create a SrcValue for a general value. - explicit SrcValueSDNode(const Value *v) - : SDNode(ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {} + explicit SrcValueSDNode(SDContext *ownerDAG, const Value *v) + : SDNode(ownerDAG, ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {} public: /// getValue - return the contained Value. @@ -1484,8 +1502,8 @@ class MDNodeSDNode : public SDNode { const MDNode *MD; friend class SelectionDAG; - explicit MDNodeSDNode(const MDNode *md) - : SDNode(ISD::MDNODE_SDNODE, 0, DebugLoc(), getSDVTList(MVT::Other)), MD(md) {} + explicit MDNodeSDNode(SDContext *ownerDAG, const MDNode *md) + : SDNode(ownerDAG, ISD::MDNODE_SDNODE, 0, DebugLoc(), getSDVTList(MVT::Other)), MD(md) {} public: const MDNode *getMD() const { return MD; } @@ -1499,8 +1517,8 @@ class RegisterSDNode : public SDNode { unsigned Reg; friend class SelectionDAG; - RegisterSDNode(unsigned reg, EVT VT) - : SDNode(ISD::Register, 0, DebugLoc(), getSDVTList(VT)), Reg(reg) { + RegisterSDNode(SDContext *ownerDAG, unsigned reg, EVT VT) + : SDNode(ownerDAG, ISD::Register, 0, DebugLoc(), getSDVTList(VT)), Reg(reg) { } public: @@ -1515,8 +1533,8 @@ // The memory for RegMask is not owned by the node. const uint32_t *RegMask; friend class SelectionDAG; - RegisterMaskSDNode(const uint32_t *mask) - : SDNode(ISD::RegisterMask, 0, DebugLoc(), getSDVTList(MVT::Untyped)), + RegisterMaskSDNode(SDContext *ownerDAG, const uint32_t *mask) + : SDNode(ownerDAG, ISD::RegisterMask, 0, DebugLoc(), getSDVTList(MVT::Untyped)), RegMask(mask) {} public: @@ -1532,9 +1550,9 @@ int64_t Offset; unsigned char TargetFlags; friend class SelectionDAG; - BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba, + BlockAddressSDNode(SDContext *ownerDAG, unsigned NodeTy, EVT VT, const BlockAddress *ba, int64_t o, unsigned char Flags) - : SDNode(NodeTy, 0, DebugLoc(), getSDVTList(VT)), + : SDNode(ownerDAG, NodeTy, 0, DebugLoc(), getSDVTList(VT)), BA(ba), Offset(o), TargetFlags(Flags) { } public: @@ -1552,8 +1570,8 @@ SDUse Chain; MCSymbol *Label; friend class SelectionDAG; - EHLabelSDNode(unsigned Order, DebugLoc dl, SDValue ch, MCSymbol *L) - : SDNode(ISD::EH_LABEL, Order, dl, getSDVTList(MVT::Other)), Label(L) { + EHLabelSDNode(SDContext *ownerDAG, unsigned Order, DebugLoc dl, SDValue ch, MCSymbol *L) + : SDNode(ownerDAG, ISD::EH_LABEL, Order, dl, getSDVTList(MVT::Other)), Label(L) { InitOperands(&Chain, ch); } public: @@ -1569,8 +1587,8 @@ unsigned char TargetFlags; friend class SelectionDAG; - ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned char TF, EVT VT) - : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, + ExternalSymbolSDNode(SDContext *ownerDAG, bool isTarget, const char *Sym, unsigned char TF, EVT VT) + : SDNode(ownerDAG, isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, 0, DebugLoc(), getSDVTList(VT)), Symbol(Sym), TargetFlags(TF) { } public: @@ -1587,8 +1605,8 @@ class CondCodeSDNode : public SDNode { ISD::CondCode Condition; friend class SelectionDAG; - explicit CondCodeSDNode(ISD::CondCode Cond) - : SDNode(ISD::CONDCODE, 0, DebugLoc(), getSDVTList(MVT::Other)), + explicit CondCodeSDNode(SDContext *ownerDAG, ISD::CondCode Cond) + : SDNode(ownerDAG, ISD::CONDCODE, 0, DebugLoc(), getSDVTList(MVT::Other)), Condition(Cond) { } public: @@ -1605,9 +1623,9 @@ class CvtRndSatSDNode : public SDNode { ISD::CvtCode CvtCode; friend class SelectionDAG; - explicit CvtRndSatSDNode(EVT VT, unsigned Order, DebugLoc dl, const SDValue *Ops, + explicit CvtRndSatSDNode(SDContext *ownerDAG, EVT VT, unsigned Order, DebugLoc dl, const SDValue *Ops, unsigned NumOps, ISD::CvtCode Code) - : SDNode(ISD::CONVERT_RNDSAT, Order, dl, getSDVTList(VT), Ops, NumOps), + : SDNode(ownerDAG, ISD::CONVERT_RNDSAT, Order, dl, getSDVTList(VT), Ops, NumOps), CvtCode(Code) { assert(NumOps == 5 && "wrong number of operations"); } @@ -1624,8 +1642,8 @@ class VTSDNode : public SDNode { EVT ValueType; friend class SelectionDAG; - explicit VTSDNode(EVT VT) - : SDNode(ISD::VALUETYPE, 0, DebugLoc(), getSDVTList(MVT::Other)), + explicit VTSDNode(SDContext *ownerDAG, EVT VT) + : SDNode(ownerDAG, ISD::VALUETYPE, 0, DebugLoc(), getSDVTList(MVT::Other)), ValueType(VT) { } public: @@ -1648,10 +1666,10 @@ */ SDUse Ops[4]; public: - LSBaseSDNode(ISD::NodeType NodeTy, unsigned Order, DebugLoc dl, SDValue *Operands, + LSBaseSDNode(SDContext *ownerDAG, ISD::NodeType NodeTy, unsigned Order, DebugLoc dl, SDValue *Operands, unsigned numOperands, SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT, MachineMemOperand *MMO) - : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) { + : MemSDNode(ownerDAG, NodeTy, Order, dl, VTs, MemVT, MMO) { SubclassData |= AM << 2; assert(getAddressingMode() == AM && "MemIndexedMode encoding error!"); InitOperands(Ops, Operands, numOperands); @@ -1685,10 +1703,10 @@ /// class LoadSDNode : public LSBaseSDNode { friend class SelectionDAG; - LoadSDNode(SDValue *ChainPtrOff, unsigned Order, DebugLoc dl, SDVTList VTs, + LoadSDNode(SDContext *ownerDAG, SDValue *ChainPtrOff, unsigned Order, DebugLoc dl, SDVTList VTs, ISD::MemIndexedMode AM, ISD::LoadExtType ETy, EVT MemVT, MachineMemOperand *MMO) - : LSBaseSDNode(ISD::LOAD, Order, dl, ChainPtrOff, 3, VTs, AM, MemVT, MMO) { + : LSBaseSDNode(ownerDAG, ISD::LOAD, Order, dl, ChainPtrOff, 3, VTs, AM, MemVT, MMO) { SubclassData |= (unsigned short)ETy; assert(getExtensionType() == ETy && "LoadExtType encoding error!"); assert(readMem() && "Load MachineMemOperand is not a load!"); @@ -1714,10 +1732,10 @@ /// class StoreSDNode : public LSBaseSDNode { friend class SelectionDAG; - StoreSDNode(SDValue *ChainValuePtrOff, unsigned Order, DebugLoc dl, + StoreSDNode(SDContext *ownerDAG, SDValue *ChainValuePtrOff, unsigned Order, DebugLoc dl, SDVTList VTs, ISD::MemIndexedMode AM, bool isTrunc, EVT MemVT, MachineMemOperand *MMO) - : LSBaseSDNode(ISD::STORE, Order, dl, ChainValuePtrOff, 4, + : LSBaseSDNode(ownerDAG, ISD::STORE, Order, dl, ChainValuePtrOff, 4, VTs, AM, MemVT, MMO) { SubclassData |= (unsigned short)isTrunc; assert(isTruncatingStore() == isTrunc && "isTrunc encoding error!"); @@ -1750,8 +1768,8 @@ private: friend class SelectionDAG; - MachineSDNode(unsigned Opc, unsigned Order, const DebugLoc DL, SDVTList VTs) - : SDNode(Opc, Order, DL, VTs), MemRefs(0), MemRefsEnd(0) {} + MachineSDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, const DebugLoc DL, SDVTList VTs) + : SDNode(ownerDAG, Opc, Order, DL, VTs), MemRefs(0), MemRefsEnd(0) {} /// LocalOperands - Operands for this instruction, if they fit here. If /// they don't, this field is unused. Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -80,8 +80,9 @@ // contain duplicate or removed nodes. When choosing a node to // visit, we pop off the order stack until we find an item that is // also in the contents set. All operations are O(log N). - SmallPtrSet WorkListContents; - SmallVector WorkListOrder; + // Each DAG node has a UID, use a flag vector to indicate whether it is visited + FlagVector WorkListFlag; + SmallVector WorkListOrder; // AA - Used for DAG load/store alias analysis. AliasAnalysis &AA; @@ -104,7 +105,7 @@ /// AddToWorkList - Add to the work list making sure its instance is at the /// back (next to be processed.) void AddToWorkList(SDNode *N) { - WorkListContents.insert(N); + WorkListFlag[N->SeqPos] = true; WorkListOrder.push_back(N); } @@ -111,7 +112,7 @@ /// removeFromWorkList - remove all instances of N from the worklist. /// void removeFromWorkList(SDNode *N) { - WorkListContents.erase(N); + WorkListFlag[N->SeqPos] = false; } SDValue CombineTo(SDNode *N, const SDValue *To, unsigned NumTo, @@ -999,6 +1000,9 @@ LegalOperations = Level >= AfterLegalizeVectorOps; LegalTypes = Level >= AfterLegalizeTypes; + WorkListOrder.reserve(DAG.allnodes_size()); + WorkListFlag.reserve(DAG.allnodes_size()); + // Add all the dag nodes to the worklist. for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), E = DAG.allnodes_end(); I != E; ++I) @@ -1007,7 +1011,7 @@ // Create a dummy node (which is not added to allnodes), that adds a reference // to the root node, preventing it from being deleted, and tracking any // changes of the root. - HandleSDNode Dummy(DAG.getRoot()); + HandleSDNode Dummy(&DAG, DAG.getRoot()); // The root of the dag may dangle to deleted nodes until the dag combiner is // done. Set it to null to avoid confusion. @@ -1015,15 +1019,17 @@ // while the worklist isn't empty, find a node and // try and combine it. - while (!WorkListContents.empty()) { + while (!WorkListOrder.empty()) { SDNode *N; // The WorkListOrder holds the SDNodes in order, but it may contain duplicates. // In order to avoid a linear scan, we use a set (O(log N)) to hold what the // worklist *should* contain, and check the node we want to visit is should // actually be visited. - do { - N = WorkListOrder.pop_back_val(); - } while (!WorkListContents.erase(N)); + N = WorkListOrder.pop_back_val(); + if (!WorkListFlag[N->SeqPos]) { + continue; + } + WorkListFlag[N->SeqPos] = false; // If N has no uses, it is dead. Make sure to revisit all N's operands once // N is deleted from the DAG, since they too may now be dead or may have a @@ -1275,7 +1281,7 @@ SmallVector TFs; // List of token factors to visit. SmallVector Ops; // Ops for replacing token factor. - SmallPtrSet SeenOps; + FlagVector SeenOps; bool Changed = false; // If we should replace this token factor. // Start out with this token factor. @@ -1311,10 +1317,12 @@ default: // Only add if it isn't already in the list. - if (SeenOps.insert(Op.getNode())) + if (!SeenOps[Op.getNode()->SeqPos]) { + SeenOps[Op.getNode()->SeqPos] = true; Ops.push_back(Op); - else + } else { Changed = true; + } break; } } Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -56,7 +56,8 @@ SelectionDAG::allnodes_iterator LegalizePosition; /// LegalizedNodes - The set of nodes which have already been legalized. - SmallPtrSet LegalizedNodes; + FlagVector LegalizedNodes; + // Each DAG node has a UID, use a flag vector to indicate whether it is legalized EVT getSetCCResultType(EVT VT) const { return TLI.getSetCCResultType(*DAG.getContext(), VT); @@ -145,7 +146,7 @@ void PromoteNode(SDNode *Node); void ForgetNode(SDNode *N) { - LegalizedNodes.erase(N); + LegalizedNodes[N->SeqPos] = false; if (LegalizePosition == SelectionDAG::allnodes_iterator(N)) ++LegalizePosition; } @@ -232,7 +233,8 @@ --LegalizePosition; SDNode *N = LegalizePosition; - if (LegalizedNodes.insert(N)) { + if (!LegalizedNodes[N->SeqPos]) { + LegalizedNodes[N->SeqPos] = true; AnyLegalized = true; LegalizeOp(N); } @@ -1285,7 +1287,7 @@ SDValue SAO = DAG.getShiftAmountOperand(Node->getOperand(0).getValueType(), Node->getOperand(1)); - HandleSDNode Handle(SAO); + HandleSDNode Handle(&DAG, SAO); LegalizeOp(SAO.getNode()); NewNode = DAG.UpdateNodeOperands(Node, Node->getOperand(0), Handle.getValue()); @@ -1300,7 +1302,7 @@ SDValue SAO = DAG.getShiftAmountOperand(Node->getOperand(0).getValueType(), Node->getOperand(2)); - HandleSDNode Handle(SAO); + HandleSDNode Handle(&DAG, SAO); LegalizeOp(SAO.getNode()); NewNode = DAG.UpdateNodeOperands(Node, Node->getOperand(0), Node->getOperand(1), @@ -2407,7 +2409,7 @@ DAG.getEntryNode(), CPIdx, MachinePointerInfo::getConstantPool(), MVT::f32, false, false, Alignment); - HandleSDNode Handle(Load); + HandleSDNode Handle(&DAG, Load); LegalizeOp(Load.getNode()); FudgeInReg = Handle.getValue(); } Index: lib/CodeGen/SelectionDAG/LegalizeTypes.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -182,7 +182,7 @@ // Create a dummy node (which is not added to allnodes), that adds a reference // to the root node, preventing it from being deleted, and tracking any // changes of the root. - HandleSDNode Dummy(DAG.getRoot()); + HandleSDNode Dummy(&DAG, DAG.getRoot()); Dummy.setNodeId(Unanalyzed); // The root of the dag may dangle to deleted nodes until the type legalizer is Index: lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp =================================================================== --- lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp +++ lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp @@ -214,7 +214,8 @@ // Look for other loads of the same chain. Find loads that are loading from // the same base pointer and different offsets. - SmallPtrSet Visited; + FlagVector Visited; + // Each DAG node has a UID, use a flag vector to indicate whether it is visited SmallVector Offsets; DenseMap O2SMap; // Map from offset to SDNode. bool Cluster = false; @@ -222,8 +223,12 @@ for (SDNode::use_iterator I = Chain->use_begin(), E = Chain->use_end(); I != E; ++I) { SDNode *User = *I; - if (User == Node || !Visited.insert(User)) + if (User == Node) continue; + if (Visited[User->SeqPos]) { + continue; + } + Visited[User->SeqPos] = true; int64_t Offset1, Offset2; if (!TII->areLoadsFromSameBasePtr(Base, User, Offset1, Offset2) || Offset1 == Offset2) @@ -323,9 +328,10 @@ // Add all nodes in depth first order. SmallVector Worklist; - SmallPtrSet Visited; + // Each DAG node has a UID, use a flag vector to indicate whether it is visited + FlagVector WorkListFlag; Worklist.push_back(DAG->getRoot().getNode()); - Visited.insert(DAG->getRoot().getNode()); + WorkListFlag[DAG->getRoot().getNode()->SeqPos] = true; SmallVector CallSUnits; while (!Worklist.empty()) { @@ -332,9 +338,12 @@ SDNode *NI = Worklist.pop_back_val(); // Add all operands to the worklist unless they've already been added. - for (unsigned i = 0, e = NI->getNumOperands(); i != e; ++i) - if (Visited.insert(NI->getOperand(i).getNode())) + for (unsigned i = 0, e = NI->getNumOperands(); i != e; ++i) { + if (!WorkListFlag[NI->getOperand(i).getNode()->SeqPos]) { Worklist.push_back(NI->getOperand(i).getNode()); + WorkListFlag[NI->getOperand(i).getNode()->SeqPos] = true; + } + } if (isPassiveNode(NI)) // Leaf node, e.g. a TargetImmediate. continue; Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -549,7 +549,7 @@ void SelectionDAG::RemoveDeadNodes() { // Create a dummy node (which is not added to allnodes), that adds a reference // to the root node, preventing it from being deleted. - HandleSDNode Dummy(getRoot()); + HandleSDNode Dummy(this, getRoot()); SmallVector DeadNodes; @@ -601,7 +601,7 @@ // Create a dummy node that adds a reference to the root node, preventing // it from being deleted. (This matters if the root is an operand of the // dead node.) - HandleSDNode Dummy(getRoot()); + HandleSDNode Dummy(this, getRoot()); RemoveDeadNodes(DeadNodes); } @@ -870,7 +870,7 @@ // EntryNode could meaningfully have debug info if we can find it... SelectionDAG::SelectionDAG(const TargetMachine &tm, CodeGenOpt::Level OL) : TM(tm), TSI(*tm.getSelectionDAGInfo()), TTI(0), OptLevel(OL), - EntryNode(ISD::EntryToken, 0, DebugLoc(), getVTList(MVT::Other)), + EntryNode(this, ISD::EntryToken, 0, DebugLoc(), getVTList(MVT::Other)), Root(getEntryNode()), UpdateListeners(0) { AllNodes.push_back(&EntryNode); DbgInfo = new SDDbgInfo(); @@ -883,6 +883,7 @@ } SelectionDAG::~SelectionDAG() { + SDNodeCount = 0; assert(!UpdateListeners && "Dangling registered DAGUpdateListeners"); allnodes_clear(); delete DbgInfo; @@ -896,6 +897,7 @@ } void SelectionDAG::clear() { + SDNodeCount = 1; allnodes_clear(); OperandAllocator.Reset(); CSEMap.clear(); @@ -997,7 +999,7 @@ return SDValue(N, 0); if (!N) { - N = new (NodeAllocator) ConstantSDNode(isT, Elt, EltVT); + N = new (NodeAllocator) ConstantSDNode(this, isT, Elt, EltVT); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); } @@ -1039,7 +1041,7 @@ return SDValue(N, 0); if (!N) { - N = new (NodeAllocator) ConstantFPSDNode(isTarget, &V, EltVT); + N = new (NodeAllocator) ConstantFPSDNode(this, isTarget, &V, EltVT); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); } @@ -1106,7 +1108,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) GlobalAddressSDNode(Opc, DL.getIROrder(), + SDNode *N = new (NodeAllocator) GlobalAddressSDNode(this, Opc, DL.getIROrder(), DL.getDebugLoc(), GV, VT, Offset, TargetFlags); CSEMap.InsertNode(N, IP); @@ -1123,7 +1125,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) FrameIndexSDNode(FI, VT, isTarget); + SDNode *N = new (NodeAllocator) FrameIndexSDNode(this, FI, VT, isTarget); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); return SDValue(N, 0); @@ -1142,7 +1144,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) JumpTableSDNode(JTI, VT, isTarget, + SDNode *N = new (NodeAllocator) JumpTableSDNode(this, JTI, VT, isTarget, TargetFlags); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); @@ -1169,7 +1171,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) ConstantPoolSDNode(isTarget, C, VT, Offset, + SDNode *N = new (NodeAllocator) ConstantPoolSDNode(this, isTarget, C, VT, Offset, Alignment, TargetFlags); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); @@ -1197,7 +1199,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) ConstantPoolSDNode(isTarget, C, VT, Offset, + SDNode *N = new (NodeAllocator) ConstantPoolSDNode(this, isTarget, C, VT, Offset, Alignment, TargetFlags); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); @@ -1215,7 +1217,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) TargetIndexSDNode(Index, VT, Offset, + SDNode *N = new (NodeAllocator) TargetIndexSDNode(this, Index, VT, Offset, TargetFlags); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); @@ -1230,7 +1232,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) BasicBlockSDNode(MBB); + SDNode *N = new (NodeAllocator) BasicBlockSDNode(this, MBB); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); return SDValue(N, 0); @@ -1245,7 +1247,7 @@ ExtendedValueTypeNodes[VT] : ValueTypeNodes[VT.getSimpleVT().SimpleTy]; if (N) return SDValue(N, 0); - N = new (NodeAllocator) VTSDNode(VT); + N = new (NodeAllocator) VTSDNode(this, VT); AllNodes.push_back(N); return SDValue(N, 0); } @@ -1253,7 +1255,7 @@ SDValue SelectionDAG::getExternalSymbol(const char *Sym, EVT VT) { SDNode *&N = ExternalSymbols[Sym]; if (N) return SDValue(N, 0); - N = new (NodeAllocator) ExternalSymbolSDNode(false, Sym, 0, VT); + N = new (NodeAllocator) ExternalSymbolSDNode(this, false, Sym, 0, VT); AllNodes.push_back(N); return SDValue(N, 0); } @@ -1264,7 +1266,7 @@ TargetExternalSymbols[std::pair(Sym, TargetFlags)]; if (N) return SDValue(N, 0); - N = new (NodeAllocator) ExternalSymbolSDNode(true, Sym, TargetFlags, VT); + N = new (NodeAllocator) ExternalSymbolSDNode(this, true, Sym, TargetFlags, VT); AllNodes.push_back(N); return SDValue(N, 0); } @@ -1274,7 +1276,7 @@ CondCodeNodes.resize(Cond+1); if (CondCodeNodes[Cond] == 0) { - CondCodeSDNode *N = new (NodeAllocator) CondCodeSDNode(Cond); + CondCodeSDNode *N = new (NodeAllocator) CondCodeSDNode(this, Cond); CondCodeNodes[Cond] = N; AllNodes.push_back(N); } @@ -1380,7 +1382,7 @@ memcpy(MaskAlloc, &MaskVec[0], NElts * sizeof(int)); ShuffleVectorSDNode *N = - new (NodeAllocator) ShuffleVectorSDNode(VT, dl.getIROrder(), dl.getDebugLoc(), N1, N2, MaskAlloc); + new (NodeAllocator) ShuffleVectorSDNode(this, VT, dl.getIROrder(), dl.getDebugLoc(), N1, N2, MaskAlloc); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); return SDValue(N, 0); @@ -1403,7 +1405,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - CvtRndSatSDNode *N = new (NodeAllocator) CvtRndSatSDNode(VT, dl.getIROrder(), dl.getDebugLoc(), Ops, 5, + CvtRndSatSDNode *N = new (NodeAllocator) CvtRndSatSDNode(this, VT, dl.getIROrder(), dl.getDebugLoc(), Ops, 5, Code); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); @@ -1418,7 +1420,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) RegisterSDNode(RegNo, VT); + SDNode *N = new (NodeAllocator) RegisterSDNode(this, RegNo, VT); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); return SDValue(N, 0); @@ -1432,7 +1434,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) RegisterMaskSDNode(RegMask); + SDNode *N = new (NodeAllocator) RegisterMaskSDNode(this, RegMask); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); return SDValue(N, 0); @@ -1447,7 +1449,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) EHLabelSDNode(dl.getIROrder(), dl.getDebugLoc(), Root, Label); + SDNode *N = new (NodeAllocator) EHLabelSDNode(this, dl.getIROrder(), dl.getDebugLoc(), Root, Label); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); return SDValue(N, 0); @@ -1469,7 +1471,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) BlockAddressSDNode(Opc, VT, BA, Offset, + SDNode *N = new (NodeAllocator) BlockAddressSDNode(this, Opc, VT, BA, Offset, TargetFlags); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); @@ -1488,7 +1490,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) SrcValueSDNode(V); + SDNode *N = new (NodeAllocator) SrcValueSDNode(this, V); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); return SDValue(N, 0); @@ -1504,7 +1506,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) MDNodeSDNode(MD); + SDNode *N = new (NodeAllocator) MDNodeSDNode(this, MD); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); return SDValue(N, 0); @@ -2411,7 +2413,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), getVTList(VT)); + SDNode *N = new (NodeAllocator) SDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), getVTList(VT)); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); @@ -2672,10 +2674,10 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - N = new (NodeAllocator) UnarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, Operand); + N = new (NodeAllocator) UnarySDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, Operand); CSEMap.InsertNode(N, IP); } else { - N = new (NodeAllocator) UnarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, Operand); + N = new (NodeAllocator) UnarySDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, Operand); } AllNodes.push_back(N); @@ -3244,10 +3246,10 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - N = new (NodeAllocator) BinarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, N1, N2); + N = new (NodeAllocator) BinarySDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, N1, N2); CSEMap.InsertNode(N, IP); } else { - N = new (NodeAllocator) BinarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, N1, N2); + N = new (NodeAllocator) BinarySDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, N1, N2); } AllNodes.push_back(N); @@ -3349,10 +3351,10 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - N = new (NodeAllocator) TernarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, N1, N2, N3); + N = new (NodeAllocator) TernarySDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, N1, N2, N3); CSEMap.InsertNode(N, IP); } else { - N = new (NodeAllocator) TernarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, N1, N2, N3); + N = new (NodeAllocator) TernarySDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, N1, N2, N3); } AllNodes.push_back(N); @@ -4127,7 +4129,7 @@ cast(E)->refineAlignment(MMO); return SDValue(E, 0); } - SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl.getIROrder(), dl.getDebugLoc(), VTs, MemVT, Chain, + SDNode *N = new (NodeAllocator) AtomicSDNode(this, Opcode, dl.getIROrder(), dl.getDebugLoc(), VTs, MemVT, Chain, Ptr, Cmp, Swp, MMO, Ordering, SynchScope); CSEMap.InsertNode(N, IP); @@ -4200,7 +4202,7 @@ cast(E)->refineAlignment(MMO); return SDValue(E, 0); } - SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl.getIROrder(), dl.getDebugLoc(), VTs, MemVT, Chain, + SDNode *N = new (NodeAllocator) AtomicSDNode(this, Opcode, dl.getIROrder(), dl.getDebugLoc(), VTs, MemVT, Chain, Ptr, Val, MMO, Ordering, SynchScope); CSEMap.InsertNode(N, IP); @@ -4258,7 +4260,7 @@ cast(E)->refineAlignment(MMO); return SDValue(E, 0); } - SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl.getIROrder(), dl.getDebugLoc(), VTs, MemVT, Chain, + SDNode *N = new (NodeAllocator) AtomicSDNode(this, Opcode, dl.getIROrder(), dl.getDebugLoc(), VTs, MemVT, Chain, Ptr, MMO, Ordering, SynchScope); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); @@ -4339,11 +4341,11 @@ return SDValue(E, 0); } - N = new (NodeAllocator) MemIntrinsicSDNode(Opcode, dl.getIROrder(), dl.getDebugLoc(), VTList, Ops, NumOps, + N = new (NodeAllocator) MemIntrinsicSDNode(this, Opcode, dl.getIROrder(), dl.getDebugLoc(), VTList, Ops, NumOps, MemVT, MMO); CSEMap.InsertNode(N, IP); } else { - N = new (NodeAllocator) MemIntrinsicSDNode(Opcode, dl.getIROrder(), dl.getDebugLoc(), VTList, Ops, NumOps, + N = new (NodeAllocator) MemIntrinsicSDNode(this, Opcode, dl.getIROrder(), dl.getDebugLoc(), VTList, Ops, NumOps, MemVT, MMO); } AllNodes.push_back(N); @@ -4458,7 +4460,7 @@ cast(E)->refineAlignment(MMO); return SDValue(E, 0); } - SDNode *N = new (NodeAllocator) LoadSDNode(Ops, dl.getIROrder(), dl.getDebugLoc(), VTs, AM, ExtType, + SDNode *N = new (NodeAllocator) LoadSDNode(this, Ops, dl.getIROrder(), dl.getDebugLoc(), VTs, AM, ExtType, MemVT, MMO); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); @@ -4548,7 +4550,7 @@ cast(E)->refineAlignment(MMO); return SDValue(E, 0); } - SDNode *N = new (NodeAllocator) StoreSDNode(Ops, dl.getIROrder(), dl.getDebugLoc(), VTs, ISD::UNINDEXED, + SDNode *N = new (NodeAllocator) StoreSDNode(this, Ops, dl.getIROrder(), dl.getDebugLoc(), VTs, ISD::UNINDEXED, false, VT, MMO); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); @@ -4616,7 +4618,7 @@ cast(E)->refineAlignment(MMO); return SDValue(E, 0); } - SDNode *N = new (NodeAllocator) StoreSDNode(Ops, dl.getIROrder(), dl.getDebugLoc(), VTs, ISD::UNINDEXED, + SDNode *N = new (NodeAllocator) StoreSDNode(this, Ops, dl.getIROrder(), dl.getDebugLoc(), VTs, ISD::UNINDEXED, true, SVT, MMO); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); @@ -4640,7 +4642,7 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - SDNode *N = new (NodeAllocator) StoreSDNode(Ops, dl.getIROrder(), dl.getDebugLoc(), VTs, AM, + SDNode *N = new (NodeAllocator) StoreSDNode(this, Ops, dl.getIROrder(), dl.getDebugLoc(), VTs, AM, ST->isTruncatingStore(), ST->getMemoryVT(), ST->getMemOperand()); @@ -4715,10 +4717,10 @@ if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); - N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, Ops, NumOps); + N = new (NodeAllocator) SDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, Ops, NumOps); CSEMap.InsertNode(N, IP); } else { - N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, Ops, NumOps); + N = new (NodeAllocator) SDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, Ops, NumOps); } AllNodes.push_back(N); @@ -4781,26 +4783,26 @@ return SDValue(E, 0); if (NumOps == 1) { - N = new (NodeAllocator) UnarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops[0]); + N = new (NodeAllocator) UnarySDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops[0]); } else if (NumOps == 2) { - N = new (NodeAllocator) BinarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops[0], Ops[1]); + N = new (NodeAllocator) BinarySDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops[0], Ops[1]); } else if (NumOps == 3) { - N = new (NodeAllocator) TernarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops[0], Ops[1], + N = new (NodeAllocator) TernarySDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops[0], Ops[1], Ops[2]); } else { - N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops, NumOps); + N = new (NodeAllocator) SDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops, NumOps); } CSEMap.InsertNode(N, IP); } else { if (NumOps == 1) { - N = new (NodeAllocator) UnarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops[0]); + N = new (NodeAllocator) UnarySDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops[0]); } else if (NumOps == 2) { - N = new (NodeAllocator) BinarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops[0], Ops[1]); + N = new (NodeAllocator) BinarySDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops[0], Ops[1]); } else if (NumOps == 3) { - N = new (NodeAllocator) TernarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops[0], Ops[1], + N = new (NodeAllocator) TernarySDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops[0], Ops[1], Ops[2]); } else { - N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops, NumOps); + N = new (NodeAllocator) SDNode(this, Opcode, DL.getIROrder(), DL.getDebugLoc(), VTList, Ops, NumOps); } } AllNodes.push_back(N); @@ -5410,7 +5412,7 @@ } // Allocate a new MachineSDNode. - N = new (NodeAllocator) MachineSDNode(~Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs); + N = new (NodeAllocator) MachineSDNode(this, ~Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs); // Initialize the operands list. if (NumOps > array_lengthof(N->LocalOperands)) @@ -5909,16 +5911,16 @@ DropOperands(); } -GlobalAddressSDNode::GlobalAddressSDNode(unsigned Opc, unsigned Order, +GlobalAddressSDNode::GlobalAddressSDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc DL, const GlobalValue *GA, EVT VT, int64_t o, unsigned char TF) - : SDNode(Opc, Order, DL, getSDVTList(VT)), Offset(o), TargetFlags(TF) { + : SDNode(ownerDAG, Opc, Order, DL, getSDVTList(VT)), Offset(o), TargetFlags(TF) { TheGlobal = GA; } -MemSDNode::MemSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, +MemSDNode::MemSDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, EVT memvt, MachineMemOperand *mmo) - : SDNode(Opc, Order, dl, VTs), MemoryVT(memvt), MMO(mmo) { + : SDNode(ownerDAG, Opc, Order, dl, VTs), MemoryVT(memvt), MMO(mmo) { SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, MMO->isVolatile(), MMO->isNonTemporal(), MMO->isInvariant()); assert(isVolatile() == MMO->isVolatile() && "Volatile encoding error!"); @@ -5927,10 +5929,10 @@ assert(memvt.getStoreSize() == MMO->getSize() && "Size mismatch!"); } -MemSDNode::MemSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, +MemSDNode::MemSDNode(SDContext *ownerDAG, unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, const SDValue *Ops, unsigned NumOps, EVT memvt, MachineMemOperand *mmo) - : SDNode(Opc, Order, dl, VTs, Ops, NumOps), + : SDNode(ownerDAG, Opc, Order, dl, VTs, Ops, NumOps), MemoryVT(memvt), MMO(mmo) { SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, MMO->isVolatile(), MMO->isNonTemporal(), MMO->isInvariant()); Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -531,7 +531,8 @@ } void SelectionDAGISel::ComputeLiveOutVRegInfo() { - SmallPtrSet VisitedNodes; + /// Each DAG node has a UID, use a flag vector to indicate whether it is visited + FlagVector VisitedNodes; SmallVector Worklist; Worklist.push_back(CurDAG->getRoot().getNode()); @@ -543,9 +544,11 @@ SDNode *N = Worklist.pop_back_val(); // If we've already seen this node, ignore it. - if (!VisitedNodes.insert(N)) + if (VisitedNodes[N->SeqPos]) { continue; - + } else { + VisitedNodes[N->SeqPos] = true; + } // Otherwise, add all chain operands to the worklist. for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) if (N->getOperand(i).getValueType() == MVT::Other) @@ -766,7 +769,7 @@ // Create a dummy node (which is not added to allnodes), that adds // a reference to the root node, preventing it from being deleted, // and tracking any changes of the root. - HandleSDNode Dummy(CurDAG->getRoot()); + HandleSDNode Dummy(CurDAG, CurDAG->getRoot()); SelectionDAG::allnodes_iterator ISelPosition (CurDAG->getRoot().getNode()); ++ISelPosition; Index: lib/Target/X86/X86ISelDAGToDAG.cpp =================================================================== --- lib/Target/X86/X86ISelDAGToDAG.cpp +++ lib/Target/X86/X86ISelDAGToDAG.cpp @@ -1127,7 +1127,7 @@ // Add an artificial use to this node so that we can keep track of // it if it gets CSE'd with a different node. - HandleSDNode Handle(N); + HandleSDNode Handle(CurDAG, N); // Test if the LHS of the sub can be folded. X86ISelAddressMode Backup = AM; @@ -1187,7 +1187,7 @@ case ISD::ADD: { // Add an artificial use to this node so that we can keep track of // it if it gets CSE'd with a different node. - HandleSDNode Handle(N); + HandleSDNode Handle(CurDAG, N); X86ISelAddressMode Backup = AM; if (!MatchAddressRecursively(N.getOperand(0), AM, Depth+1) &&