X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=include%2Fllvm%2FCodeGen%2FSelectionDAG.h;h=d18e3c3c35938e78306912bb4aa00c073546489b;hb=47d9dcc584cdb7fd645ca1d5c2a0ce363570aeb7;hp=56cb17dee69c4cc369be767f78ec9fef6e290ac5;hpb=ea859be53ca13a1547c4675549946b74dc3c6f41;p=oota-llvm.git diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 56cb17dee69..d18e3c3c359 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -15,23 +15,50 @@ #ifndef LLVM_CODEGEN_SELECTIONDAG_H #define LLVM_CODEGEN_SELECTIONDAG_H +#include "llvm/ADT/ilist.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/ilist" +#include "llvm/ADT/StringMap.h" #include "llvm/CodeGen/SelectionDAGNodes.h" -#include +#include #include #include -#include #include namespace llvm { - class AliasAnalysis; - class TargetLowering; - class TargetMachine; - class MachineModuleInfo; - class MachineFunction; - class MachineConstantPoolValue; + +class AliasAnalysis; +class TargetLowering; +class TargetMachine; +class MachineModuleInfo; +class MachineFunction; +class MachineConstantPoolValue; +class FunctionLoweringInfo; + +template<> struct ilist_traits : public ilist_default_traits { +private: + mutable SDNode Sentinel; +public: + ilist_traits() : Sentinel(ISD::DELETED_NODE, SDVTList()) {} + + SDNode *createSentinel() const { + return &Sentinel; + } + static void destroySentinel(SDNode *) {} + + static void deleteNode(SDNode *) { + assert(0 && "ilist_traits shouldn't see a deleteNode call!"); + } +private: + static void createNode(const SDNode &); +}; + +enum CombineLevel { + Unrestricted, // Combine may create illegal operations and illegal types. + NoIllegalTypes, // Combine may create illegal operations but no illegal types. + NoIllegalOperations // Combine may only create legal operations and types. +}; /// SelectionDAG class - This is used to represent a portion of an LLVM function /// in a low-level Data Dependence DAG representation suitable for instruction @@ -46,33 +73,71 @@ namespace llvm { /// class SelectionDAG { TargetLowering &TLI; - MachineFunction &MF; + MachineFunction *MF; + FunctionLoweringInfo &FLI; MachineModuleInfo *MMI; - /// Root - The root of the entire DAG. EntryNode - The starting token. - SDOperand Root, EntryNode; + /// EntryNode - The starting token. + SDNode EntryNode; + + /// Root - The root of the entire DAG. + SDValue Root; /// AllNodes - A linked list of nodes in the current DAG. ilist AllNodes; + /// NodeAllocatorType - The AllocatorType for allocating SDNodes. We use + /// pool allocation with recycling. + typedef RecyclingAllocator::Alignment> + NodeAllocatorType; + + /// NodeAllocator - Pool allocation for nodes. + NodeAllocatorType NodeAllocator; + /// CSEMap - This structure is used to memoize nodes, automatically performing /// CSE with existing nodes with a duplicate is requested. FoldingSet CSEMap; + /// OperandAllocator - Pool allocation for machine-opcode SDNode operands. + BumpPtrAllocator OperandAllocator; + + /// Allocator - Pool allocation for misc. objects that are created once per + /// SelectionDAG. + BumpPtrAllocator Allocator; + + /// VerifyNode - Sanity check the given node. Aborts if it is invalid. + void VerifyNode(SDNode *N); + + /// setGraphColorHelper - Implementation of setSubgraphColor. + /// Return whether we had to truncate the search. + /// + bool setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet &visited, + int level, bool &printed); + public: - SelectionDAG(TargetLowering &tli, MachineFunction &mf, MachineModuleInfo *mmi) - : TLI(tli), MF(mf), MMI(mmi) { - EntryNode = Root = getNode(ISD::EntryToken, MVT::Other); - } + SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli); ~SelectionDAG(); - MachineFunction &getMachineFunction() const { return MF; } + /// init - Prepare this SelectionDAG to process code in the given + /// MachineFunction. + /// + void init(MachineFunction &mf, MachineModuleInfo *mmi); + + /// clear - Clear state and free memory necessary to make this + /// SelectionDAG ready to process a new block. + /// + void clear(); + + MachineFunction &getMachineFunction() const { return *MF; } const TargetMachine &getTarget() const; TargetLowering &getTargetLoweringInfo() const { return TLI; } + FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; } MachineModuleInfo *getMachineModuleInfo() const { return MMI; } /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'. /// + void viewGraph(const std::string &Title); void viewGraph(); #ifndef NDEBUG @@ -95,31 +160,52 @@ public: /// void setGraphColor(const SDNode *N, const char *Color); + /// setGraphColor - Convenience for setting subgraph color attribute. + /// + void setSubgraphColor(SDNode *N, const char *Color); + typedef ilist::const_iterator allnodes_const_iterator; allnodes_const_iterator allnodes_begin() const { return AllNodes.begin(); } allnodes_const_iterator allnodes_end() const { return AllNodes.end(); } typedef ilist::iterator allnodes_iterator; allnodes_iterator allnodes_begin() { return AllNodes.begin(); } allnodes_iterator allnodes_end() { return AllNodes.end(); } + ilist::size_type allnodes_size() const { + return AllNodes.size(); + } /// getRoot - Return the root tag of the SelectionDAG. /// - const SDOperand &getRoot() const { return Root; } + const SDValue &getRoot() const { return Root; } /// getEntryNode - Return the token chain corresponding to the entry of the /// function. - const SDOperand &getEntryNode() const { return EntryNode; } + SDValue getEntryNode() const { + return SDValue(const_cast(&EntryNode), 0); + } /// setRoot - Set the current root tag of the SelectionDAG. /// - const SDOperand &setRoot(SDOperand N) { return Root = N; } + const SDValue &setRoot(SDValue N) { + assert((!N.getNode() || N.getValueType() == MVT::Other) && + "DAG root value is not a chain!"); + return Root = N; + } /// Combine - This iterates over the nodes in the SelectionDAG, folding - /// certain types of nodes together, or eliminating superfluous nodes. When - /// the AfterLegalize argument is set to 'true', Combine takes care not to - /// generate any nodes that will be illegal on the target. - void Combine(bool AfterLegalize, AliasAnalysis &AA); - + /// certain types of nodes together, or eliminating superfluous nodes. The + /// Level argument controls whether Combine is allowed to produce nodes and + /// types that are illegal on the target. + void Combine(CombineLevel Level, AliasAnalysis &AA, bool Fast); + + /// LegalizeTypes - This transforms the SelectionDAG into a SelectionDAG that + /// only uses types natively supported by the target. Returns "true" if it + /// made any changes. + /// + /// Note that this is an involved process that may invalidate pointers into + /// the graph. + bool LegalizeTypes(); + /// Legalize - This transforms the SelectionDAG into a SelectionDAG that is /// compatible with the target instruction selector, as indicated by the /// TargetLowering object. @@ -132,85 +218,102 @@ public: /// SelectionDAG. void RemoveDeadNodes(); - /// RemoveDeadNode - Remove the specified node from the system. If any of its - /// operands then becomes dead, remove them as well. The vector Deleted is - /// populated with nodes that are deleted. - void RemoveDeadNode(SDNode *N, std::vector &Deleted); - /// DeleteNode - Remove the specified node from the system. This node must /// have no referrers. void DeleteNode(SDNode *N); /// getVTList - Return an SDVTList that represents the list of values /// specified. - SDVTList getVTList(MVT::ValueType VT); - SDVTList getVTList(MVT::ValueType VT1, MVT::ValueType VT2); - SDVTList getVTList(MVT::ValueType VT1, MVT::ValueType VT2,MVT::ValueType VT3); - SDVTList getVTList(const MVT::ValueType *VTs, unsigned NumVTs); + SDVTList getVTList(MVT VT); + SDVTList getVTList(MVT VT1, MVT VT2); + SDVTList getVTList(MVT VT1, MVT VT2, MVT VT3); + SDVTList getVTList(MVT VT1, MVT VT2, MVT VT3, MVT VT4); + SDVTList getVTList(const MVT *VTs, unsigned NumVTs); /// getNodeValueTypes - These are obsolete, use getVTList instead. - const MVT::ValueType *getNodeValueTypes(MVT::ValueType VT) { + const MVT *getNodeValueTypes(MVT VT) { return getVTList(VT).VTs; } - const MVT::ValueType *getNodeValueTypes(MVT::ValueType VT1, - MVT::ValueType VT2) { + const MVT *getNodeValueTypes(MVT VT1, MVT VT2) { return getVTList(VT1, VT2).VTs; } - const MVT::ValueType *getNodeValueTypes(MVT::ValueType VT1,MVT::ValueType VT2, - MVT::ValueType VT3) { + const MVT *getNodeValueTypes(MVT VT1, MVT VT2, MVT VT3) { return getVTList(VT1, VT2, VT3).VTs; } - const MVT::ValueType *getNodeValueTypes(std::vector &VTList) { - return getVTList(&VTList[0], VTList.size()).VTs; + const MVT *getNodeValueTypes(MVT VT1, MVT VT2, MVT VT3, MVT VT4) { + return getVTList(VT1, VT2, VT3, VT4).VTs; + } + const MVT *getNodeValueTypes(const std::vector &vtList) { + return getVTList(&vtList[0], (unsigned)vtList.size()).VTs; } //===--------------------------------------------------------------------===// // Node creation methods. // - SDOperand getString(const std::string &Val); - SDOperand getConstant(uint64_t Val, MVT::ValueType VT, bool isTarget = false); - SDOperand getTargetConstant(uint64_t Val, MVT::ValueType VT) { + SDValue getConstant(uint64_t Val, MVT VT, bool isTarget = false); + SDValue getConstant(const APInt &Val, MVT VT, bool isTarget = false); + SDValue getConstant(const ConstantInt &Val, MVT VT, bool isTarget = false); + SDValue getIntPtrConstant(uint64_t Val, bool isTarget = false); + SDValue getTargetConstant(uint64_t Val, MVT VT) { return getConstant(Val, VT, true); } - SDOperand getConstantFP(double Val, MVT::ValueType VT, bool isTarget = false); - SDOperand getTargetConstantFP(double Val, MVT::ValueType VT) { + SDValue getTargetConstant(const APInt &Val, MVT VT) { + return getConstant(Val, VT, true); + } + SDValue getTargetConstant(const ConstantInt &Val, MVT VT) { + return getConstant(Val, VT, true); + } + SDValue getConstantFP(double Val, MVT VT, bool isTarget = false); + SDValue getConstantFP(const APFloat& Val, MVT VT, bool isTarget = false); + SDValue getConstantFP(const ConstantFP &CF, MVT VT, bool isTarget = false); + SDValue getTargetConstantFP(double Val, MVT VT) { + return getConstantFP(Val, VT, true); + } + SDValue getTargetConstantFP(const APFloat& Val, MVT VT) { + return getConstantFP(Val, VT, true); + } + SDValue getTargetConstantFP(const ConstantFP &Val, MVT VT) { return getConstantFP(Val, VT, true); } - SDOperand getGlobalAddress(const GlobalValue *GV, MVT::ValueType VT, - int offset = 0, bool isTargetGA = false); - SDOperand getTargetGlobalAddress(const GlobalValue *GV, MVT::ValueType VT, - int offset = 0) { + SDValue getGlobalAddress(const GlobalValue *GV, MVT VT, + int64_t offset = 0, bool isTargetGA = false); + SDValue getTargetGlobalAddress(const GlobalValue *GV, MVT VT, + int64_t offset = 0) { return getGlobalAddress(GV, VT, offset, true); } - SDOperand getFrameIndex(int FI, MVT::ValueType VT, bool isTarget = false); - SDOperand getTargetFrameIndex(int FI, MVT::ValueType VT) { + SDValue getFrameIndex(int FI, MVT VT, bool isTarget = false); + SDValue getTargetFrameIndex(int FI, MVT VT) { return getFrameIndex(FI, VT, true); } - SDOperand getJumpTable(int JTI, MVT::ValueType VT, bool isTarget = false); - SDOperand getTargetJumpTable(int JTI, MVT::ValueType VT) { + SDValue getJumpTable(int JTI, MVT VT, bool isTarget = false); + SDValue getTargetJumpTable(int JTI, MVT VT) { return getJumpTable(JTI, VT, true); } - SDOperand getConstantPool(Constant *C, MVT::ValueType VT, + SDValue getConstantPool(Constant *C, MVT VT, unsigned Align = 0, int Offs = 0, bool isT=false); - SDOperand getTargetConstantPool(Constant *C, MVT::ValueType VT, + SDValue getTargetConstantPool(Constant *C, MVT VT, unsigned Align = 0, int Offset = 0) { return getConstantPool(C, VT, Align, Offset, true); } - SDOperand getConstantPool(MachineConstantPoolValue *C, MVT::ValueType VT, + SDValue getConstantPool(MachineConstantPoolValue *C, MVT VT, unsigned Align = 0, int Offs = 0, bool isT=false); - SDOperand getTargetConstantPool(MachineConstantPoolValue *C, - MVT::ValueType VT, unsigned Align = 0, + SDValue getTargetConstantPool(MachineConstantPoolValue *C, + MVT VT, unsigned Align = 0, int Offset = 0) { return getConstantPool(C, VT, Align, Offset, true); } - SDOperand getBasicBlock(MachineBasicBlock *MBB); - SDOperand getExternalSymbol(const char *Sym, MVT::ValueType VT); - SDOperand getTargetExternalSymbol(const char *Sym, MVT::ValueType VT); - SDOperand getValueType(MVT::ValueType); - SDOperand getRegister(unsigned Reg, MVT::ValueType VT); - - SDOperand getCopyToReg(SDOperand Chain, unsigned Reg, SDOperand N) { + SDValue getBasicBlock(MachineBasicBlock *MBB); + SDValue getExternalSymbol(const char *Sym, MVT VT); + SDValue getTargetExternalSymbol(const char *Sym, MVT VT); + SDValue getArgFlags(ISD::ArgFlagsTy Flags); + SDValue getValueType(MVT); + SDValue getRegister(unsigned Reg, MVT VT); + SDValue getDbgStopPoint(SDValue Root, unsigned Line, unsigned Col, + const CompileUnitDesc *CU); + SDValue getLabel(unsigned Opcode, SDValue Root, unsigned LabelID); + + SDValue getCopyToReg(SDValue Chain, unsigned Reg, SDValue N) { return getNode(ISD::CopyToReg, MVT::Other, Chain, getRegister(Reg, N.getValueType()), N); } @@ -218,123 +321,218 @@ public: // This version of the getCopyToReg method takes an extra operand, which // indicates that there is potentially an incoming flag value (if Flag is not // null) and that there should be a flag result. - SDOperand getCopyToReg(SDOperand Chain, unsigned Reg, SDOperand N, - SDOperand Flag) { - const MVT::ValueType *VTs = getNodeValueTypes(MVT::Other, MVT::Flag); - SDOperand Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Flag }; - return getNode(ISD::CopyToReg, VTs, 2, Ops, Flag.Val ? 4 : 3); + SDValue getCopyToReg(SDValue Chain, unsigned Reg, SDValue N, + SDValue Flag) { + const MVT *VTs = getNodeValueTypes(MVT::Other, MVT::Flag); + SDValue Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Flag }; + return getNode(ISD::CopyToReg, VTs, 2, Ops, Flag.getNode() ? 4 : 3); } - // Similar to last getCopyToReg() except parameter Reg is a SDOperand - SDOperand getCopyToReg(SDOperand Chain, SDOperand Reg, SDOperand N, - SDOperand Flag) { - const MVT::ValueType *VTs = getNodeValueTypes(MVT::Other, MVT::Flag); - SDOperand Ops[] = { Chain, Reg, N, Flag }; - return getNode(ISD::CopyToReg, VTs, 2, Ops, Flag.Val ? 4 : 3); + // Similar to last getCopyToReg() except parameter Reg is a SDValue + SDValue getCopyToReg(SDValue Chain, SDValue Reg, SDValue N, + SDValue Flag) { + const MVT *VTs = getNodeValueTypes(MVT::Other, MVT::Flag); + SDValue Ops[] = { Chain, Reg, N, Flag }; + return getNode(ISD::CopyToReg, VTs, 2, Ops, Flag.getNode() ? 4 : 3); } - SDOperand getCopyFromReg(SDOperand Chain, unsigned Reg, MVT::ValueType VT) { - const MVT::ValueType *VTs = getNodeValueTypes(VT, MVT::Other); - SDOperand Ops[] = { Chain, getRegister(Reg, VT) }; + SDValue getCopyFromReg(SDValue Chain, unsigned Reg, MVT VT) { + const MVT *VTs = getNodeValueTypes(VT, MVT::Other); + SDValue Ops[] = { Chain, getRegister(Reg, VT) }; return getNode(ISD::CopyFromReg, VTs, 2, Ops, 2); } // This version of the getCopyFromReg method takes an extra operand, which // indicates that there is potentially an incoming flag value (if Flag is not // null) and that there should be a flag result. - SDOperand getCopyFromReg(SDOperand Chain, unsigned Reg, MVT::ValueType VT, - SDOperand Flag) { - const MVT::ValueType *VTs = getNodeValueTypes(VT, MVT::Other, MVT::Flag); - SDOperand Ops[] = { Chain, getRegister(Reg, VT), Flag }; - return getNode(ISD::CopyFromReg, VTs, 3, Ops, Flag.Val ? 3 : 2); + SDValue getCopyFromReg(SDValue Chain, unsigned Reg, MVT VT, + SDValue Flag) { + const MVT *VTs = getNodeValueTypes(VT, MVT::Other, MVT::Flag); + SDValue Ops[] = { Chain, getRegister(Reg, VT), Flag }; + return getNode(ISD::CopyFromReg, VTs, 3, Ops, Flag.getNode() ? 3 : 2); } - SDOperand getCondCode(ISD::CondCode Cond); + SDValue getCondCode(ISD::CondCode Cond); + + /// Returns the ConvertRndSat Note: Avoid using this node because it may + /// disappear in the future and most targets don't support it. + SDValue getConvertRndSat(MVT VT, SDValue Val, SDValue DTy, SDValue STy, + SDValue Rnd, SDValue Sat, ISD::CvtCode Code); /// getZeroExtendInReg - Return the expression required to zero extend the Op /// value assuming it was the smaller SrcTy value. - SDOperand getZeroExtendInReg(SDOperand Op, MVT::ValueType SrcTy); + SDValue getZeroExtendInReg(SDValue Op, MVT SrcTy); /// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have /// a flag result (to ensure it's not CSE'd). - SDOperand getCALLSEQ_START(SDOperand Chain, SDOperand Op) { - const MVT::ValueType *VTs = getNodeValueTypes(MVT::Other, MVT::Flag); - SDOperand Ops[] = { Chain, Op }; + SDValue getCALLSEQ_START(SDValue Chain, SDValue Op) { + const MVT *VTs = getNodeValueTypes(MVT::Other, MVT::Flag); + SDValue Ops[] = { Chain, Op }; return getNode(ISD::CALLSEQ_START, VTs, 2, Ops, 2); } + /// getCALLSEQ_END - Return a new CALLSEQ_END node, which always must have a + /// flag result (to ensure it's not CSE'd). + SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, + SDValue InFlag) { + SDVTList NodeTys = getVTList(MVT::Other, MVT::Flag); + SmallVector Ops; + Ops.push_back(Chain); + Ops.push_back(Op1); + Ops.push_back(Op2); + Ops.push_back(InFlag); + return getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], + (unsigned)Ops.size() - (InFlag.getNode() == 0 ? 1 : 0)); + } + /// getNode - Gets or creates the specified node. /// - SDOperand getNode(unsigned Opcode, MVT::ValueType VT); - SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N); - SDOperand getNode(unsigned Opcode, MVT::ValueType VT, - SDOperand N1, SDOperand N2); - SDOperand getNode(unsigned Opcode, MVT::ValueType VT, - SDOperand N1, SDOperand N2, SDOperand N3); - SDOperand getNode(unsigned Opcode, MVT::ValueType VT, - SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4); - SDOperand getNode(unsigned Opcode, MVT::ValueType VT, - SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4, - SDOperand N5); - SDOperand getNode(unsigned Opcode, MVT::ValueType VT, - const SDOperand *Ops, unsigned NumOps); - SDOperand getNode(unsigned Opcode, std::vector &ResultTys, - const SDOperand *Ops, unsigned NumOps); - SDOperand getNode(unsigned Opcode, const MVT::ValueType *VTs, unsigned NumVTs, - const SDOperand *Ops, unsigned NumOps); - SDOperand getNode(unsigned Opcode, SDVTList VTs, - const SDOperand *Ops, unsigned NumOps); - + SDValue getNode(unsigned Opcode, MVT VT); + SDValue getNode(unsigned Opcode, MVT VT, SDValue N); + SDValue getNode(unsigned Opcode, MVT VT, SDValue N1, SDValue N2); + SDValue getNode(unsigned Opcode, MVT VT, + SDValue N1, SDValue N2, SDValue N3); + SDValue getNode(unsigned Opcode, MVT VT, + SDValue N1, SDValue N2, SDValue N3, SDValue N4); + SDValue getNode(unsigned Opcode, MVT VT, + SDValue N1, SDValue N2, SDValue N3, SDValue N4, + SDValue N5); + SDValue getNode(unsigned Opcode, MVT VT, + const SDValue *Ops, unsigned NumOps); + SDValue getNode(unsigned Opcode, MVT VT, + const SDUse *Ops, unsigned NumOps); + SDValue getNode(unsigned Opcode, const std::vector &ResultTys, + const SDValue *Ops, unsigned NumOps); + SDValue getNode(unsigned Opcode, const MVT *VTs, unsigned NumVTs, + const SDValue *Ops, unsigned NumOps); + SDValue getNode(unsigned Opcode, SDVTList VTs); + SDValue getNode(unsigned Opcode, SDVTList VTs, SDValue N); + SDValue getNode(unsigned Opcode, SDVTList VTs, SDValue N1, SDValue N2); + SDValue getNode(unsigned Opcode, SDVTList VTs, + SDValue N1, SDValue N2, SDValue N3); + SDValue getNode(unsigned Opcode, SDVTList VTs, + SDValue N1, SDValue N2, SDValue N3, SDValue N4); + SDValue getNode(unsigned Opcode, SDVTList VTs, + SDValue N1, SDValue N2, SDValue N3, SDValue N4, + SDValue N5); + SDValue getNode(unsigned Opcode, SDVTList VTs, + const SDValue *Ops, unsigned NumOps); + + SDValue getMemcpy(SDValue Chain, SDValue Dst, SDValue Src, + SDValue Size, unsigned Align, bool AlwaysInline, + const Value *DstSV, uint64_t DstSVOff, + const Value *SrcSV, uint64_t SrcSVOff); + + SDValue getMemmove(SDValue Chain, SDValue Dst, SDValue Src, + SDValue Size, unsigned Align, + const Value *DstSV, uint64_t DstOSVff, + const Value *SrcSV, uint64_t SrcSVOff); + + SDValue getMemset(SDValue Chain, SDValue Dst, SDValue Src, + SDValue Size, unsigned Align, + const Value *DstSV, uint64_t DstSVOff); + /// getSetCC - Helper function to make it easier to build SetCC's if you just - /// have an ISD::CondCode instead of an SDOperand. + /// have an ISD::CondCode instead of an SDValue. /// - SDOperand getSetCC(MVT::ValueType VT, SDOperand LHS, SDOperand RHS, - ISD::CondCode Cond) { + SDValue getSetCC(MVT VT, SDValue LHS, SDValue RHS, + ISD::CondCode Cond) { return getNode(ISD::SETCC, VT, LHS, RHS, getCondCode(Cond)); } + /// getVSetCC - Helper function to make it easier to build VSetCC's nodes + /// if you just have an ISD::CondCode instead of an SDValue. + /// + SDValue getVSetCC(MVT VT, SDValue LHS, SDValue RHS, + ISD::CondCode Cond) { + return getNode(ISD::VSETCC, VT, LHS, RHS, getCondCode(Cond)); + } + /// getSelectCC - Helper function to make it easier to build SelectCC's if you - /// just have an ISD::CondCode instead of an SDOperand. + /// just have an ISD::CondCode instead of an SDValue. /// - SDOperand getSelectCC(SDOperand LHS, SDOperand RHS, - SDOperand True, SDOperand False, ISD::CondCode Cond) { + SDValue getSelectCC(SDValue LHS, SDValue RHS, + SDValue True, SDValue False, ISD::CondCode Cond) { return getNode(ISD::SELECT_CC, True.getValueType(), LHS, RHS, True, False, getCondCode(Cond)); } /// getVAArg - VAArg produces a result and token chain, and takes a pointer /// and a source value as input. - SDOperand getVAArg(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, - SDOperand SV); + SDValue getVAArg(MVT VT, SDValue Chain, SDValue Ptr, + SDValue SV); + + /// getAtomic - Gets a node for an atomic op, produces result and chain and + /// takes 3 operands + SDValue getAtomic(unsigned Opcode, SDValue Chain, SDValue Ptr, + SDValue Cmp, SDValue Swp, const Value* PtrVal, + unsigned Alignment=0); + + /// getAtomic - Gets a node for an atomic op, produces result and chain and + /// takes 2 operands. + SDValue getAtomic(unsigned Opcode, SDValue Chain, SDValue Ptr, + SDValue Val, const Value* PtrVal, + unsigned Alignment = 0); + + /// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a + /// result and takes a list of operands. + SDValue getMemIntrinsicNode(unsigned Opcode, + const MVT *VTs, unsigned NumVTs, + const SDValue *Ops, unsigned NumOps, + MVT MemVT, const Value *srcValue, int SVOff, + unsigned Align = 0, bool Vol = false, + bool ReadMem = true, bool WriteMem = true); + + SDValue getMemIntrinsicNode(unsigned Opcode, SDVTList VTList, + const SDValue *Ops, unsigned NumOps, + MVT MemVT, const Value *srcValue, int SVOff, + unsigned Align = 0, bool Vol = false, + bool ReadMem = true, bool WriteMem = true); + + /// getMergeValues - Create a MERGE_VALUES node from the given operands. + SDValue getMergeValues(const SDValue *Ops, unsigned NumOps); + + /// getCall - Create a CALL node from the given information. + /// + SDValue getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall, + bool isInreg, SDVTList VTs, const SDValue *Operands, + unsigned NumOperands); /// getLoad - Loads are not normal binary operators: their result type is not /// determined by their operands, and they produce a value AND a token chain. /// - SDOperand getLoad(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr, + SDValue getLoad(MVT VT, SDValue Chain, SDValue Ptr, const Value *SV, int SVOffset, bool isVolatile=false, unsigned Alignment=0); - SDOperand getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT, - SDOperand Chain, SDOperand Ptr, const Value *SV, - int SVOffset, MVT::ValueType EVT, bool isVolatile=false, + SDValue getExtLoad(ISD::LoadExtType ExtType, MVT VT, + SDValue Chain, SDValue Ptr, const Value *SV, + int SVOffset, MVT EVT, bool isVolatile=false, unsigned Alignment=0); - SDOperand getIndexedLoad(SDOperand OrigLoad, SDOperand Base, - SDOperand Offset, ISD::MemIndexedMode AM); - SDOperand getVecLoad(unsigned Count, MVT::ValueType VT, SDOperand Chain, - SDOperand Ptr, SDOperand SV); + SDValue getIndexedLoad(SDValue OrigLoad, SDValue Base, + SDValue Offset, ISD::MemIndexedMode AM); + SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, + MVT VT, SDValue Chain, + SDValue Ptr, SDValue Offset, + const Value *SV, int SVOffset, MVT EVT, + bool isVolatile=false, unsigned Alignment=0); /// getStore - Helper function to build ISD::STORE nodes. /// - SDOperand getStore(SDOperand Chain, SDOperand Val, SDOperand Ptr, + SDValue getStore(SDValue Chain, SDValue Val, SDValue Ptr, const Value *SV, int SVOffset, bool isVolatile=false, unsigned Alignment=0); - SDOperand getTruncStore(SDOperand Chain, SDOperand Val, SDOperand Ptr, - const Value *SV, int SVOffset, MVT::ValueType TVT, + SDValue getTruncStore(SDValue Chain, SDValue Val, SDValue Ptr, + const Value *SV, int SVOffset, MVT TVT, bool isVolatile=false, unsigned Alignment=0); - SDOperand getIndexedStore(SDOperand OrigStoe, SDOperand Base, - SDOperand Offset, ISD::MemIndexedMode AM); + SDValue getIndexedStore(SDValue OrigStoe, SDValue Base, + SDValue Offset, ISD::MemIndexedMode AM); + + // getSrcValue - Construct a node to track a Value* through the backend. + SDValue getSrcValue(const Value *v); - // getSrcValue - construct a node to track a Value* through the backend - SDOperand getSrcValue(const Value* I, int offset = 0); + // getMemOperand - Construct a node to track a memory reference + // through the backend. + SDValue getMemOperand(const MachineMemOperand &MO); /// UpdateNodeOperands - *Mutate* the specified node in-place to have the /// specified operands. If the resultant node already exists in the DAG, @@ -342,36 +540,71 @@ public: /// already exists. If the resultant node does not exist in the DAG, the /// input node is returned. As a degenerate case, if you specify the same /// input operands as the node already has, the input node is returned. - SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op); - SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2); - SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2, - SDOperand Op3); - SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2, - SDOperand Op3, SDOperand Op4); - SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2, - SDOperand Op3, SDOperand Op4, SDOperand Op5); - SDOperand UpdateNodeOperands(SDOperand N, SDOperand *Ops, unsigned NumOps); + SDValue UpdateNodeOperands(SDValue N, SDValue Op); + SDValue UpdateNodeOperands(SDValue N, SDValue Op1, SDValue Op2); + SDValue UpdateNodeOperands(SDValue N, SDValue Op1, SDValue Op2, + SDValue Op3); + SDValue UpdateNodeOperands(SDValue N, SDValue Op1, SDValue Op2, + SDValue Op3, SDValue Op4); + SDValue UpdateNodeOperands(SDValue N, SDValue Op1, SDValue Op2, + SDValue Op3, SDValue Op4, SDValue Op5); + SDValue UpdateNodeOperands(SDValue N, + const SDValue *Ops, unsigned NumOps); /// SelectNodeTo - These are used for target selectors to *mutate* the /// specified node to have the specified return type, Target opcode, and /// operands. Note that target opcodes are stored as - /// ISD::BUILTIN_OP_END+TargetOpcode in the node opcode field. The 0th value - /// of the resultant node is returned. - SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT); - SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT, - SDOperand Op1); - SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT, - SDOperand Op1, SDOperand Op2); - SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT, - SDOperand Op1, SDOperand Op2, SDOperand Op3); - SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT, - const SDOperand *Ops, unsigned NumOps); - SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT1, - MVT::ValueType VT2, SDOperand Op1, SDOperand Op2); - SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT1, - MVT::ValueType VT2, SDOperand Op1, SDOperand Op2, - SDOperand Op3); - + /// ~TargetOpcode in the node opcode field. The resultant node is returned. + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT, SDValue Op1); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT, + SDValue Op1, SDValue Op2); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT, + SDValue Op1, SDValue Op2, SDValue Op3); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT, + const SDValue *Ops, unsigned NumOps); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT1, MVT VT2); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT1, + MVT VT2, const SDValue *Ops, unsigned NumOps); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT1, + MVT VT2, MVT VT3, const SDValue *Ops, unsigned NumOps); + SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, MVT VT1, + MVT VT2, MVT VT3, MVT VT4, const SDValue *Ops, + unsigned NumOps); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT1, + MVT VT2, SDValue Op1); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT1, + MVT VT2, SDValue Op1, SDValue Op2); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT1, + MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT1, + MVT VT2, MVT VT3, SDValue Op1, SDValue Op2, SDValue Op3); + SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, SDVTList VTs, + const SDValue *Ops, unsigned NumOps); + + /// MorphNodeTo - These *mutate* the specified node to have the specified + /// return type, opcode, and operands. + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT, SDValue Op1); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT, + SDValue Op1, SDValue Op2); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT, + SDValue Op1, SDValue Op2, SDValue Op3); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT, + const SDValue *Ops, unsigned NumOps); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT1, MVT VT2); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT1, + MVT VT2, const SDValue *Ops, unsigned NumOps); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT1, + MVT VT2, MVT VT3, const SDValue *Ops, unsigned NumOps); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT1, + MVT VT2, SDValue Op1); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT1, + MVT VT2, SDValue Op1, SDValue Op2); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT1, + MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, SDVTList VTs, + const SDValue *Ops, unsigned NumOps); /// getTargetNode - These are used for target selectors to create a new node /// with specified return type(s), target opcode, and operands. @@ -379,75 +612,114 @@ public: /// Note that getTargetNode returns the resultant node. If there is already a /// node of the specified opcode and operands, it returns that node instead of /// the current one. - SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT); - SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT, - SDOperand Op1); - SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT, - SDOperand Op1, SDOperand Op2); - SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT, - SDOperand Op1, SDOperand Op2, SDOperand Op3); - SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT, - const SDOperand *Ops, unsigned NumOps); - SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, - MVT::ValueType VT2, SDOperand Op1); - SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, - MVT::ValueType VT2, SDOperand Op1, SDOperand Op2); - SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, - MVT::ValueType VT2, SDOperand Op1, SDOperand Op2, - SDOperand Op3); - SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, - MVT::ValueType VT2, - const SDOperand *Ops, unsigned NumOps); - SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, - MVT::ValueType VT2, MVT::ValueType VT3, - SDOperand Op1, SDOperand Op2); - SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, - MVT::ValueType VT2, MVT::ValueType VT3, - SDOperand Op1, SDOperand Op2, SDOperand Op3); - SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1, - MVT::ValueType VT2, MVT::ValueType VT3, - const SDOperand *Ops, unsigned NumOps); + SDNode *getTargetNode(unsigned Opcode, MVT VT); + SDNode *getTargetNode(unsigned Opcode, MVT VT, SDValue Op1); + SDNode *getTargetNode(unsigned Opcode, MVT VT, SDValue Op1, SDValue Op2); + SDNode *getTargetNode(unsigned Opcode, MVT VT, + SDValue Op1, SDValue Op2, SDValue Op3); + SDNode *getTargetNode(unsigned Opcode, MVT VT, + const SDValue *Ops, unsigned NumOps); + SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2); + SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, SDValue Op1); + SDNode *getTargetNode(unsigned Opcode, MVT VT1, + MVT VT2, SDValue Op1, SDValue Op2); + SDNode *getTargetNode(unsigned Opcode, MVT VT1, + MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3); + SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, + const SDValue *Ops, unsigned NumOps); + SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3, + SDValue Op1, SDValue Op2); + SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3, + SDValue Op1, SDValue Op2, SDValue Op3); + SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3, + const SDValue *Ops, unsigned NumOps); + SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3, MVT VT4, + const SDValue *Ops, unsigned NumOps); + SDNode *getTargetNode(unsigned Opcode, const std::vector &ResultTys, + const SDValue *Ops, unsigned NumOps); + + /// getNodeIfExists - Get the specified node if it's already available, or + /// else return NULL. + SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs, + const SDValue *Ops, unsigned NumOps); + + /// DAGUpdateListener - Clients of various APIs that cause global effects on + /// the DAG can optionally implement this interface. This allows the clients + /// to handle the various sorts of updates that happen. + class DAGUpdateListener { + public: + virtual ~DAGUpdateListener(); + + /// NodeDeleted - The node N that was deleted and, if E is not null, an + /// equivalent node E that replaced it. + virtual void NodeDeleted(SDNode *N, SDNode *E) = 0; + + /// NodeUpdated - The node N that was updated. + virtual void NodeUpdated(SDNode *N) = 0; + }; + + /// RemoveDeadNode - Remove the specified node from the system. If any of its + /// operands then becomes dead, remove them as well. Inform UpdateListener + /// for each node deleted. + void RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener = 0); + /// RemoveDeadNodes - This method deletes the unreachable nodes in the + /// given list, and any nodes that become unreachable as a result. + void RemoveDeadNodes(SmallVectorImpl &DeadNodes, + DAGUpdateListener *UpdateListener = 0); + /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead. /// This can cause recursive merging of nodes in the DAG. Use the first /// version if 'From' is known to have a single result, use the second /// if you have two nodes with identical results, use the third otherwise. /// - /// These methods all take an optional vector, which (if not null) is - /// populated with any nodes that are deleted from the SelectionDAG, due to - /// new equivalences that are discovered. + /// These methods all take an optional UpdateListener, which (if not null) is + /// informed about nodes that are deleted and modified due to recursive + /// changes in the dag. /// - void ReplaceAllUsesWith(SDOperand From, SDOperand Op, - std::vector *Deleted = 0); + void ReplaceAllUsesWith(SDValue From, SDValue Op, + DAGUpdateListener *UpdateListener = 0); void ReplaceAllUsesWith(SDNode *From, SDNode *To, - std::vector *Deleted = 0); - void ReplaceAllUsesWith(SDNode *From, const SDOperand *To, - std::vector *Deleted = 0); + DAGUpdateListener *UpdateListener = 0); + void ReplaceAllUsesWith(SDNode *From, const SDValue *To, + DAGUpdateListener *UpdateListener = 0); /// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving - /// uses of other values produced by From.Val alone. The Deleted vector is - /// handled the same was as for ReplaceAllUsesWith, but it is required for - /// this method. - void ReplaceAllUsesOfValueWith(SDOperand From, SDOperand To, - std::vector &Deleted); - - /// AssignNodeIds - Assign a unique node id for each node in the DAG based on - /// their allnodes order. It returns the maximum id. - unsigned AssignNodeIds(); - - /// AssignTopologicalOrder - Assign a unique node id for each node in the DAG - /// based on their topological order. It returns the maximum id and a vector - /// of the SDNodes* in assigned order by reference. - unsigned AssignTopologicalOrder(std::vector &TopOrder); + /// uses of other values produced by From.Val alone. + void ReplaceAllUsesOfValueWith(SDValue From, SDValue To, + DAGUpdateListener *UpdateListener = 0); + + /// ReplaceAllUsesOfValuesWith - Like ReplaceAllUsesOfValueWith, but + /// for multiple values at once. This correctly handles the case where + /// there is an overlap between the From values and the To values. + void ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To, + unsigned Num, + DAGUpdateListener *UpdateListener = 0); + + /// AssignTopologicalOrder - Topological-sort the AllNodes list and a + /// assign a unique node id for each node in the DAG based on their + /// topological order. Returns the number of nodes. + unsigned AssignTopologicalOrder(); + + /// RepositionNode - Move node N in the AllNodes list to be immediately + /// before the given iterator Position. This may be used to update the + /// topological ordering when the list of nodes is modified. + void RepositionNode(allnodes_iterator Position, SDNode *N) { + AllNodes.insert(Position, AllNodes.remove(N)); + } /// isCommutativeBinOp - Returns true if the opcode is a commutative binary /// operation. static bool isCommutativeBinOp(unsigned Opcode) { + // FIXME: This should get its info from the td file, so that we can include + // target info. switch (Opcode) { case ISD::ADD: case ISD::MUL: case ISD::MULHU: case ISD::MULHS: + case ISD::SMUL_LOHI: + case ISD::UMUL_LOHI: case ISD::FADD: case ISD::FMUL: case ISD::AND: @@ -461,14 +733,33 @@ public: void dump() const; + /// CreateStackTemporary - Create a stack temporary, suitable for holding the + /// specified value type. If minAlign is specified, the slot size will have + /// at least that alignment. + SDValue CreateStackTemporary(MVT VT, unsigned minAlign = 1); + + /// CreateStackTemporary - Create a stack temporary suitable for holding + /// either of the specified value types. + SDValue CreateStackTemporary(MVT VT1, MVT VT2); + + /// FoldConstantArithmetic - + SDValue FoldConstantArithmetic(unsigned Opcode, + MVT VT, + ConstantSDNode *Cst1, + ConstantSDNode *Cst2); + /// FoldSetCC - Constant fold a setcc to true or false. - SDOperand FoldSetCC(MVT::ValueType VT, SDOperand N1, - SDOperand N2, ISD::CondCode Cond); + SDValue FoldSetCC(MVT VT, SDValue N1, + SDValue N2, ISD::CondCode Cond); + /// SignBitIsZero - Return true if the sign bit of Op is known to be zero. We + /// use this predicate to simplify operations downstream. + bool SignBitIsZero(SDValue Op, unsigned Depth = 0) const; + /// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero. We /// use this predicate to simplify operations downstream. Op and Mask are /// known to be the same type. - bool MaskedValueIsZero(SDOperand Op, uint64_t Mask, unsigned Depth = 0) + bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth = 0) const; /// ComputeMaskedBits - Determine which of the bits specified in Mask are @@ -476,9 +767,9 @@ public: /// bitsets. This code only analyzes bits in Mask, in order to short-circuit /// processing. Targets can implement the computeMaskedBitsForTargetNode /// method in the TargetLowering class to allow target nodes to be understood. - void ComputeMaskedBits(SDOperand Op, uint64_t Mask, uint64_t &KnownZero, - uint64_t &KnownOne, unsigned Depth = 0) const; - + void ComputeMaskedBits(SDValue Op, const APInt &Mask, APInt &KnownZero, + APInt &KnownOne, unsigned Depth = 0) const; + /// ComputeNumSignBits - Return the number of times the sign bit of the /// register is replicated into the other bits. We know that at least 1 bit /// is always equal to the sign bit (itself), but other cases can give us @@ -486,29 +777,41 @@ public: /// the top 3 bits are all equal to each other, so we return 3. Targets can /// implement the ComputeNumSignBitsForTarget method in the TargetLowering /// class to allow target nodes to be understood. - unsigned ComputeNumSignBits(SDOperand Op, unsigned Depth = 0) const; + unsigned ComputeNumSignBits(SDValue Op, unsigned Depth = 0) const; + + /// isVerifiedDebugInfoDesc - Returns true if the specified SDValue has + /// been verified as a debug information descriptor. + bool isVerifiedDebugInfoDesc(SDValue Op) const; + + /// getShuffleScalarElt - Returns the scalar element that will make up the ith + /// element of the result of the vector shuffle. + SDValue getShuffleScalarElt(const SDNode *N, unsigned Idx); private: - void RemoveNodeFromCSEMaps(SDNode *N); + bool RemoveNodeFromCSEMaps(SDNode *N); SDNode *AddNonLeafNodeToCSEMaps(SDNode *N); - SDNode *FindModifiedNodeSlot(SDNode *N, SDOperand Op, void *&InsertPos); - SDNode *FindModifiedNodeSlot(SDNode *N, SDOperand Op1, SDOperand Op2, + SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op, void *&InsertPos); + SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op1, SDValue Op2, void *&InsertPos); - SDNode *FindModifiedNodeSlot(SDNode *N, const SDOperand *Ops, unsigned NumOps, + SDNode *FindModifiedNodeSlot(SDNode *N, const SDValue *Ops, unsigned NumOps, void *&InsertPos); void DeleteNodeNotInCSEMaps(SDNode *N); + + unsigned getMVTAlignment(MVT MemoryVT) const; + + void allnodes_clear(); // List of non-single value types. - std::list > VTList; + std::vector VTList; // Maps to auto-CSE operations. std::vector CondCodeNodes; std::vector ValueTypeNodes; - std::map ExternalSymbols; - std::map TargetExternalSymbols; - std::map StringNodes; + std::map ExtendedValueTypeNodes; + StringMap ExternalSymbols; + StringMap TargetExternalSymbols; }; template <> struct GraphTraits : public GraphTraits {