diff options
Diffstat (limited to 'include/llvm/CodeGen/SelectionDAG.h')
-rw-r--r-- | include/llvm/CodeGen/SelectionDAG.h | 544 |
1 files changed, 327 insertions, 217 deletions
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index a21e9ae881a7..29cce873c2f3 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -23,6 +23,7 @@ #include "llvm/CodeGen/DAGCombine.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SelectionDAGNodes.h" +#include "llvm/Support/ArrayRecycler.h" #include "llvm/Support/RecyclingAllocator.h" #include "llvm/Target/TargetMachine.h" #include <cassert> @@ -37,7 +38,7 @@ class MachineFunction; class MDNode; class SDDbgValue; class TargetLowering; -class TargetSelectionDAGInfo; +class SelectionDAGTargetInfo; class SDVTListNode : public FoldingSetNode { friend struct FoldingSetTrait<SDVTListNode>; @@ -178,7 +179,7 @@ void checkForCycles(const SelectionDAG *DAG, bool force = false); /// class SelectionDAG { const TargetMachine &TM; - const TargetSelectionDAGInfo *TSI; + const SelectionDAGTargetInfo *TSI; const TargetLowering *TLI; MachineFunction *MF; LLVMContext *Context; @@ -208,6 +209,7 @@ class SelectionDAG { /// Pool allocation for machine-opcode SDNode operands. BumpPtrAllocator OperandAllocator; + ArrayRecycler<SDUse> OperandRecycler; /// Pool allocation for misc. objects that are created once per SelectionDAG. BumpPtrAllocator Allocator; @@ -247,6 +249,14 @@ public: virtual void NodeUpdated(SDNode *N); }; + struct DAGNodeDeletedListener : public DAGUpdateListener { + std::function<void(SDNode *, SDNode *)> Callback; + DAGNodeDeletedListener(SelectionDAG &DAG, + std::function<void(SDNode *, SDNode *)> Callback) + : DAGUpdateListener(DAG), Callback(Callback) {} + void NodeDeleted(SDNode *N, SDNode *E) override { Callback(N, E); } + }; + /// When true, additional steps are taken to /// ensure that getConstant() and similar functions return DAG nodes that /// have legal types. This is important after type legalization since @@ -268,6 +278,36 @@ private: DenseSet<SDNode *> &visited, int level, bool &printed); + template <typename SDNodeT, typename... ArgTypes> + SDNodeT *newSDNode(ArgTypes &&... Args) { + return new (NodeAllocator.template Allocate<SDNodeT>()) + SDNodeT(std::forward<ArgTypes>(Args)...); + } + + void createOperands(SDNode *Node, ArrayRef<SDValue> Vals) { + assert(!Node->OperandList && "Node already has operands"); + SDUse *Ops = OperandRecycler.allocate( + ArrayRecycler<SDUse>::Capacity::get(Vals.size()), OperandAllocator); + + for (unsigned I = 0; I != Vals.size(); ++I) { + Ops[I].setUser(Node); + Ops[I].setInitial(Vals[I]); + } + Node->NumOperands = Vals.size(); + Node->OperandList = Ops; + checkForCycles(Node); + } + + void removeOperands(SDNode *Node) { + if (!Node->OperandList) + return; + OperandRecycler.deallocate( + ArrayRecycler<SDUse>::Capacity::get(Node->NumOperands), + Node->OperandList); + Node->NumOperands = 0; + Node->OperandList = nullptr; + } + void operator=(const SelectionDAG&) = delete; SelectionDAG(const SelectionDAG&) = delete; @@ -287,7 +327,7 @@ public: const TargetMachine &getTarget() const { return TM; } const TargetSubtargetInfo &getSubtarget() const { return MF->getSubtarget(); } const TargetLowering &getTargetLoweringInfo() const { return *TLI; } - const TargetSelectionDAGInfo &getSelectionDAGInfo() const { return *TSI; } + const SelectionDAGTargetInfo &getSelectionDAGInfo() const { return *TSI; } LLVMContext *getContext() const {return Context; } /// Pop up a GraphViz/gv window with the DAG rendered using 'dot'. @@ -427,45 +467,64 @@ public: //===--------------------------------------------------------------------===// // Node creation methods. // - SDValue getConstant(uint64_t Val, SDLoc DL, EVT VT, bool isTarget = false, - bool isOpaque = false); - SDValue getConstant(const APInt &Val, SDLoc DL, EVT VT, bool isTarget = false, - bool isOpaque = false); - SDValue getConstant(const ConstantInt &Val, SDLoc DL, EVT VT, + + /// \brief Create a ConstantSDNode wrapping a constant value. + /// If VT is a vector type, the constant is splatted into a BUILD_VECTOR. + /// + /// If only legal types can be produced, this does the necessary + /// transformations (e.g., if the vector element type is illegal). + /// @{ + SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, + bool isTarget = false, bool isOpaque = false); + SDValue getConstant(const APInt &Val, const SDLoc &DL, EVT VT, bool isTarget = false, bool isOpaque = false); - SDValue getIntPtrConstant(uint64_t Val, SDLoc DL, bool isTarget = false); - SDValue getTargetConstant(uint64_t Val, SDLoc DL, EVT VT, + SDValue getConstant(const ConstantInt &Val, const SDLoc &DL, EVT VT, + bool isTarget = false, bool isOpaque = false); + SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, + bool isTarget = false); + SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque = false) { return getConstant(Val, DL, VT, true, isOpaque); } - SDValue getTargetConstant(const APInt &Val, SDLoc DL, EVT VT, + SDValue getTargetConstant(const APInt &Val, const SDLoc &DL, EVT VT, bool isOpaque = false) { return getConstant(Val, DL, VT, true, isOpaque); } - SDValue getTargetConstant(const ConstantInt &Val, SDLoc DL, EVT VT, + SDValue getTargetConstant(const ConstantInt &Val, const SDLoc &DL, EVT VT, bool isOpaque = false) { return getConstant(Val, DL, VT, true, isOpaque); } - // The forms below that take a double should only be used for simple - // constants that can be exactly represented in VT. No checks are made. - SDValue getConstantFP(double Val, SDLoc DL, EVT VT, bool isTarget = false); - SDValue getConstantFP(const APFloat& Val, SDLoc DL, EVT VT, + /// @} + + /// \brief Create a ConstantFPSDNode wrapping a constant value. + /// If VT is a vector type, the constant is splatted into a BUILD_VECTOR. + /// + /// If only legal types can be produced, this does the necessary + /// transformations (e.g., if the vector element type is illegal). + /// The forms that take a double should only be used for simple constants + /// that can be exactly represented in VT. No checks are made. + /// @{ + SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget = false); - SDValue getConstantFP(const ConstantFP &CF, SDLoc DL, EVT VT, + SDValue getConstantFP(const APFloat &Val, const SDLoc &DL, EVT VT, bool isTarget = false); - SDValue getTargetConstantFP(double Val, SDLoc DL, EVT VT) { + SDValue getConstantFP(const ConstantFP &CF, const SDLoc &DL, EVT VT, + bool isTarget = false); + SDValue getTargetConstantFP(double Val, const SDLoc &DL, EVT VT) { return getConstantFP(Val, DL, VT, true); } - SDValue getTargetConstantFP(const APFloat& Val, SDLoc DL, EVT VT) { + SDValue getTargetConstantFP(const APFloat &Val, const SDLoc &DL, EVT VT) { return getConstantFP(Val, DL, VT, true); } - SDValue getTargetConstantFP(const ConstantFP &Val, SDLoc DL, EVT VT) { + SDValue getTargetConstantFP(const ConstantFP &Val, const SDLoc &DL, EVT VT) { return getConstantFP(Val, DL, VT, true); } - SDValue getGlobalAddress(const GlobalValue *GV, SDLoc DL, EVT VT, + /// @} + + SDValue getGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset = 0, bool isTargetGA = false, unsigned char TargetFlags = 0); - SDValue getTargetGlobalAddress(const GlobalValue *GV, SDLoc DL, EVT VT, + SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset = 0, unsigned char TargetFlags = 0) { return getGlobalAddress(GV, DL, VT, offset, true, TargetFlags); @@ -502,7 +561,7 @@ public: SDValue getBasicBlock(MachineBasicBlock *MBB); SDValue getBasicBlock(MachineBasicBlock *MBB, SDLoc dl); SDValue getExternalSymbol(const char *Sym, EVT VT); - SDValue getExternalSymbol(const char *Sym, SDLoc dl, EVT VT); + SDValue getExternalSymbol(const char *Sym, const SDLoc &dl, EVT VT); SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned char TargetFlags = 0); SDValue getMCSymbol(MCSymbol *Sym, EVT VT); @@ -510,7 +569,7 @@ public: SDValue getValueType(EVT); SDValue getRegister(unsigned Reg, EVT VT); SDValue getRegisterMask(const uint32_t *RegMask); - SDValue getEHLabel(SDLoc dl, SDValue Root, MCSymbol *Label); + SDValue getEHLabel(const SDLoc &dl, SDValue Root, MCSymbol *Label); SDValue getBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset = 0, bool isTarget = false, unsigned char TargetFlags = 0); @@ -520,7 +579,8 @@ public: return getBlockAddress(BA, VT, Offset, true, TargetFlags); } - SDValue getCopyToReg(SDValue Chain, SDLoc dl, unsigned Reg, SDValue N) { + SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, + SDValue N) { return getNode(ISD::CopyToReg, dl, MVT::Other, Chain, getRegister(Reg, N.getValueType()), N); } @@ -528,7 +588,7 @@ public: // This version of the getCopyToReg method takes an extra operand, which // indicates that there is potentially an incoming glue value (if Glue is not // null) and that there should be a glue result. - SDValue getCopyToReg(SDValue Chain, SDLoc dl, unsigned Reg, SDValue N, + SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N, SDValue Glue) { SDVTList VTs = getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Glue }; @@ -537,15 +597,15 @@ public: } // Similar to last getCopyToReg() except parameter Reg is a SDValue - SDValue getCopyToReg(SDValue Chain, SDLoc dl, SDValue Reg, SDValue N, - SDValue Glue) { + SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, SDValue Reg, SDValue N, + SDValue Glue) { SDVTList VTs = getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, Reg, N, Glue }; return getNode(ISD::CopyToReg, dl, VTs, makeArrayRef(Ops, Glue.getNode() ? 4 : 3)); } - SDValue getCopyFromReg(SDValue Chain, SDLoc dl, unsigned Reg, EVT VT) { + SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT) { SDVTList VTs = getVTList(VT, MVT::Other); SDValue Ops[] = { Chain, getRegister(Reg, VT) }; return getNode(ISD::CopyFromReg, dl, VTs, Ops); @@ -554,8 +614,8 @@ public: // This version of the getCopyFromReg method takes an extra operand, which // indicates that there is potentially an incoming glue value (if Glue is not // null) and that there should be a glue result. - SDValue getCopyFromReg(SDValue Chain, SDLoc dl, unsigned Reg, EVT VT, - SDValue Glue) { + SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT, + SDValue Glue) { SDVTList VTs = getVTList(VT, MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, getRegister(Reg, VT), Glue }; return getNode(ISD::CopyFromReg, dl, VTs, @@ -566,20 +626,46 @@ public: /// Returns the ConvertRndSat Note: Avoid using this node because it may /// disappear in the future and most targets don't support it. - SDValue getConvertRndSat(EVT VT, SDLoc dl, SDValue Val, SDValue DTy, - SDValue STy, - SDValue Rnd, SDValue Sat, ISD::CvtCode Code); + SDValue getConvertRndSat(EVT VT, const SDLoc &dl, SDValue Val, SDValue DTy, + SDValue STy, SDValue Rnd, SDValue Sat, + ISD::CvtCode Code); /// Return an ISD::VECTOR_SHUFFLE node. The number of elements in VT, /// which must be a vector type, must match the number of mask elements /// NumElts. An integer mask element equal to -1 is treated as undefined. - SDValue getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, SDValue N2, - const int *MaskElts); - SDValue getVectorShuffle(EVT VT, SDLoc dl, SDValue N1, SDValue N2, - ArrayRef<int> MaskElts) { - assert(VT.getVectorNumElements() == MaskElts.size() && - "Must have the same number of vector elements as mask elements!"); - return getVectorShuffle(VT, dl, N1, N2, MaskElts.data()); + SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, + ArrayRef<int> Mask); + + /// Return an ISD::BUILD_VECTOR node. The number of elements in VT, + /// which must be a vector type, must match the number of operands in Ops. + /// The operands must have the same type as (or, for integers, a type wider + /// than) VT's element type. + SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef<SDValue> Ops) { + // VerifySDNode (via InsertNode) checks BUILD_VECTOR later. + return getNode(ISD::BUILD_VECTOR, DL, VT, Ops); + } + + /// Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all + /// elements. VT must be a vector type. Op's type must be the same as (or, + /// for integers, a type wider than) VT's element type. + SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op) { + // VerifySDNode (via InsertNode) checks BUILD_VECTOR later. + if (Op.getOpcode() == ISD::UNDEF) { + assert((VT.getVectorElementType() == Op.getValueType() || + (VT.isInteger() && + VT.getVectorElementType().bitsLE(Op.getValueType()))) && + "A splatted value must have a width equal or (for integers) " + "greater than the vector element type!"); + return getNode(ISD::UNDEF, SDLoc(), VT); + } + + SmallVector<SDValue, 16> Ops(VT.getVectorNumElements(), Op); + return getNode(ISD::BUILD_VECTOR, DL, VT, Ops); + } + + /// Return a splat ISD::BUILD_VECTOR node, but with Op's SDLoc. + SDValue getSplatBuildVector(EVT VT, SDValue Op) { + return getSplatBuildVector(VT, SDLoc(Op), Op); } /// \brief Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to @@ -590,52 +676,52 @@ public: /// Convert Op, which must be of integer type, to the /// integer type VT, by either any-extending or truncating it. - SDValue getAnyExtOrTrunc(SDValue Op, SDLoc DL, EVT VT); + SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT); /// Convert Op, which must be of integer type, to the /// integer type VT, by either sign-extending or truncating it. - SDValue getSExtOrTrunc(SDValue Op, SDLoc DL, EVT VT); + SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT); /// Convert Op, which must be of integer type, to the /// integer type VT, by either zero-extending or truncating it. - SDValue getZExtOrTrunc(SDValue Op, SDLoc DL, EVT VT); + SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT); /// Return the expression required to zero extend the Op /// value assuming it was the smaller SrcTy value. - SDValue getZeroExtendInReg(SDValue Op, SDLoc DL, EVT SrcTy); + SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT SrcTy); /// Return an operation which will any-extend the low lanes of the operand /// into the specified vector type. For example, /// this can convert a v16i8 into a v4i32 by any-extending the low four /// lanes of the operand from i8 to i32. - SDValue getAnyExtendVectorInReg(SDValue Op, SDLoc DL, EVT VT); + SDValue getAnyExtendVectorInReg(SDValue Op, const SDLoc &DL, EVT VT); /// Return an operation which will sign extend the low lanes of the operand /// into the specified vector type. For example, /// this can convert a v16i8 into a v4i32 by sign extending the low four /// lanes of the operand from i8 to i32. - SDValue getSignExtendVectorInReg(SDValue Op, SDLoc DL, EVT VT); + SDValue getSignExtendVectorInReg(SDValue Op, const SDLoc &DL, EVT VT); /// Return an operation which will zero extend the low lanes of the operand /// into the specified vector type. For example, /// this can convert a v16i8 into a v4i32 by zero extending the low four /// lanes of the operand from i8 to i32. - SDValue getZeroExtendVectorInReg(SDValue Op, SDLoc DL, EVT VT); + SDValue getZeroExtendVectorInReg(SDValue Op, const SDLoc &DL, EVT VT); /// Convert Op, which must be of integer type, to the integer type VT, /// by using an extension appropriate for the target's /// BooleanContent for type OpVT or truncating it. - SDValue getBoolExtOrTrunc(SDValue Op, SDLoc SL, EVT VT, EVT OpVT); + SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT); /// Create a bitwise NOT operation as (XOR Val, -1). - SDValue getNOT(SDLoc DL, SDValue Val, EVT VT); + SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT); /// \brief Create a logical NOT operation as (XOR Val, BooleanOne). - SDValue getLogicalNOT(SDLoc DL, SDValue Val, EVT VT); + SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT); /// Return a new CALLSEQ_START node, which always must have a glue result /// (to ensure it's not CSE'd). CALLSEQ_START does not have a useful SDLoc. - SDValue getCALLSEQ_START(SDValue Chain, SDValue Op, SDLoc DL) { + SDValue getCALLSEQ_START(SDValue Chain, SDValue Op, const SDLoc &DL) { SDVTList VTs = getVTList(MVT::Other, MVT::Glue); SDValue Ops[] = { Chain, Op }; return getNode(ISD::CALLSEQ_START, DL, VTs, Ops); @@ -645,7 +731,7 @@ public: /// glue result (to ensure it's not CSE'd). /// CALLSEQ_END does not have a useful SDLoc. SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, - SDValue InGlue, SDLoc DL) { + SDValue InGlue, const SDLoc &DL) { SDVTList NodeTys = getVTList(MVT::Other, MVT::Glue); SmallVector<SDValue, 4> Ops; Ops.push_back(Chain); @@ -668,38 +754,38 @@ public: /// Gets or creates the specified node. /// - SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, + SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef<SDUse> Ops); - SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, + SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef<SDValue> Ops, const SDNodeFlags *Flags = nullptr); - SDValue getNode(unsigned Opcode, SDLoc DL, ArrayRef<EVT> ResultTys, + SDValue getNode(unsigned Opcode, const SDLoc &DL, ArrayRef<EVT> ResultTys, ArrayRef<SDValue> Ops); - SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs, + SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs, ArrayRef<SDValue> Ops); // Specialize based on number of operands. - SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT); - SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N); - SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2, - const SDNodeFlags *Flags = nullptr); - SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2, - SDValue N3); - SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2, - SDValue N3, SDValue N4); - SDValue getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, SDValue N2, - SDValue N3, SDValue N4, SDValue N5); + SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT); + SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N); + SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1, + SDValue N2, const SDNodeFlags *Flags = nullptr); + SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1, + SDValue N2, SDValue N3); + SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1, + SDValue N2, SDValue N3, SDValue N4); + SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1, + SDValue N2, SDValue N3, SDValue N4, SDValue N5); // Specialize again based on number of operands for nodes with a VTList // rather than a single VT. - SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs); - SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs, SDValue N); - SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs, SDValue N1, + SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs); + SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs, SDValue N); + SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs, SDValue N1, SDValue N2); - SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs, SDValue N1, + SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs, SDValue N1, SDValue N2, SDValue N3); - SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs, SDValue N1, + SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs, SDValue N1, SDValue N2, SDValue N3, SDValue N4); - SDValue getNode(unsigned Opcode, SDLoc DL, SDVTList VTs, SDValue N1, + SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs, SDValue N1, SDValue N2, SDValue N3, SDValue N4, SDValue N5); /// Compute a TokenFactor to force all the incoming stack arguments to be @@ -707,24 +793,24 @@ public: /// stack arguments from being clobbered. SDValue getStackArgumentTokenFactor(SDValue Chain); - SDValue getMemcpy(SDValue Chain, SDLoc dl, SDValue Dst, SDValue Src, + SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo); - SDValue getMemmove(SDValue Chain, SDLoc dl, SDValue Dst, SDValue Src, + SDValue getMemmove(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo); - SDValue getMemset(SDValue Chain, SDLoc dl, SDValue Dst, SDValue Src, + SDValue getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, unsigned Align, bool isVol, bool isTailCall, MachinePointerInfo DstPtrInfo); /// Helper function to make it easier to build SetCC's if you just /// have an ISD::CondCode instead of an SDValue. /// - SDValue getSetCC(SDLoc DL, EVT VT, SDValue LHS, SDValue RHS, + SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond) { assert(LHS.getValueType().isVector() == RHS.getValueType().isVector() && "Cannot compare scalars to vectors"); @@ -737,8 +823,8 @@ public: /// Helper function to make it easier to build Select's if you just /// have operands and don't want to check for vector. - SDValue getSelect(SDLoc DL, EVT VT, SDValue Cond, - SDValue LHS, SDValue RHS) { + SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, + SDValue RHS) { assert(LHS.getValueType() == RHS.getValueType() && "Cannot use select on differing types"); assert(VT.isVector() == LHS.getValueType().isVector() && @@ -750,139 +836,145 @@ public: /// Helper function to make it easier to build SelectCC's if you /// just have an ISD::CondCode instead of an SDValue. /// - SDValue getSelectCC(SDLoc DL, SDValue LHS, SDValue RHS, - SDValue True, SDValue False, ISD::CondCode Cond) { + SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, + SDValue False, ISD::CondCode Cond) { return getNode(ISD::SELECT_CC, DL, True.getValueType(), LHS, RHS, True, False, getCondCode(Cond)); } /// VAArg produces a result and token chain, and takes a pointer /// and a source value as input. - SDValue getVAArg(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr, + SDValue getVAArg(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue SV, unsigned Align); /// Gets a node for an atomic cmpxchg op. There are two /// valid Opcodes. ISD::ATOMIC_CMO_SWAP produces the value loaded and a /// chain result. ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS produces the value loaded, /// a success flag (initially i1), and a chain. - SDValue getAtomicCmpSwap(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTs, - SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp, - MachinePointerInfo PtrInfo, unsigned Alignment, - AtomicOrdering SuccessOrdering, + SDValue getAtomicCmpSwap(unsigned Opcode, const SDLoc &dl, EVT MemVT, + SDVTList VTs, SDValue Chain, SDValue Ptr, + SDValue Cmp, SDValue Swp, MachinePointerInfo PtrInfo, + unsigned Alignment, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SynchronizationScope SynchScope); - SDValue getAtomicCmpSwap(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTs, - SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp, - MachineMemOperand *MMO, + SDValue getAtomicCmpSwap(unsigned Opcode, const SDLoc &dl, EVT MemVT, + SDVTList VTs, SDValue Chain, SDValue Ptr, + SDValue Cmp, SDValue Swp, MachineMemOperand *MMO, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SynchronizationScope SynchScope); /// Gets a node for an atomic op, produces result (if relevant) /// and chain and takes 2 operands. - SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDValue Chain, + SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, const Value *PtrVal, unsigned Alignment, AtomicOrdering Ordering, SynchronizationScope SynchScope); - SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDValue Chain, + SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO, - AtomicOrdering Ordering, - SynchronizationScope SynchScope); + AtomicOrdering Ordering, SynchronizationScope SynchScope); /// Gets a node for an atomic op, produces result and chain and /// takes 1 operand. - SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, EVT VT, + SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, EVT VT, SDValue Chain, SDValue Ptr, MachineMemOperand *MMO, - AtomicOrdering Ordering, - SynchronizationScope SynchScope); + AtomicOrdering Ordering, SynchronizationScope SynchScope); /// Gets a node for an atomic op, produces result and chain and takes N /// operands. - SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTList, - ArrayRef<SDValue> Ops, MachineMemOperand *MMO, - AtomicOrdering SuccessOrdering, + SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, + SDVTList VTList, ArrayRef<SDValue> Ops, + MachineMemOperand *MMO, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SynchronizationScope SynchScope); - SDValue getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTList, - ArrayRef<SDValue> Ops, MachineMemOperand *MMO, - AtomicOrdering Ordering, SynchronizationScope SynchScope); + SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, + SDVTList VTList, ArrayRef<SDValue> Ops, + MachineMemOperand *MMO, AtomicOrdering Ordering, + SynchronizationScope SynchScope); /// Creates a MemIntrinsicNode that may produce a /// result and takes a list of operands. Opcode may be INTRINSIC_VOID, /// INTRINSIC_W_CHAIN, or a target-specific opcode with a value not /// less than FIRST_TARGET_MEMORY_OPCODE. - SDValue getMemIntrinsicNode(unsigned Opcode, SDLoc dl, SDVTList VTList, - ArrayRef<SDValue> Ops, - EVT MemVT, MachinePointerInfo PtrInfo, - unsigned Align = 0, bool Vol = false, - bool ReadMem = true, bool WriteMem = true, - unsigned Size = 0); + SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, + ArrayRef<SDValue> Ops, EVT MemVT, + MachinePointerInfo PtrInfo, unsigned Align = 0, + bool Vol = false, bool ReadMem = true, + bool WriteMem = true, unsigned Size = 0); - SDValue getMemIntrinsicNode(unsigned Opcode, SDLoc dl, SDVTList VTList, - ArrayRef<SDValue> Ops, - EVT MemVT, MachineMemOperand *MMO); + SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, + ArrayRef<SDValue> Ops, EVT MemVT, + MachineMemOperand *MMO); /// Create a MERGE_VALUES node from the given operands. - SDValue getMergeValues(ArrayRef<SDValue> Ops, SDLoc dl); + SDValue getMergeValues(ArrayRef<SDValue> Ops, const SDLoc &dl); /// Loads are not normal binary operators: their result type is not /// determined by their operands, and they produce a value AND a token chain. /// - SDValue getLoad(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr, - MachinePointerInfo PtrInfo, bool isVolatile, - bool isNonTemporal, bool isInvariant, unsigned Alignment, + /// This function will set the MOLoad flag on MMOFlags, but you can set it if + /// you want. The MOStore flag must not be set. + SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, + MachinePointerInfo PtrInfo, unsigned Alignment = 0, + MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone, const AAMDNodes &AAInfo = AAMDNodes(), const MDNode *Ranges = nullptr); - SDValue getLoad(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr, + SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachineMemOperand *MMO); - SDValue getExtLoad(ISD::LoadExtType ExtType, SDLoc dl, EVT VT, - SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, - EVT MemVT, bool isVolatile, - bool isNonTemporal, bool isInvariant, unsigned Alignment, - const AAMDNodes &AAInfo = AAMDNodes()); - SDValue getExtLoad(ISD::LoadExtType ExtType, SDLoc dl, EVT VT, + SDValue + getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, + SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, + unsigned Alignment = 0, + MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone, + const AAMDNodes &AAInfo = AAMDNodes()); + SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, EVT MemVT, MachineMemOperand *MMO); - SDValue getIndexedLoad(SDValue OrigLoad, SDLoc dl, SDValue Base, + SDValue getIndexedLoad(SDValue OrigLoad, const SDLoc &dl, SDValue Base, SDValue Offset, ISD::MemIndexedMode AM); - SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, - EVT VT, SDLoc dl, - SDValue Chain, SDValue Ptr, SDValue Offset, - MachinePointerInfo PtrInfo, EVT MemVT, - bool isVolatile, bool isNonTemporal, bool isInvariant, - unsigned Alignment, const AAMDNodes &AAInfo = AAMDNodes(), + SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT, + const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Offset, + MachinePointerInfo PtrInfo, EVT MemVT, unsigned Alignment = 0, + MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone, + const AAMDNodes &AAInfo = AAMDNodes(), const MDNode *Ranges = nullptr); - SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, - EVT VT, SDLoc dl, - SDValue Chain, SDValue Ptr, SDValue Offset, + SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT, + const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Offset, EVT MemVT, MachineMemOperand *MMO); /// Helper function to build ISD::STORE nodes. - SDValue getStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr, - MachinePointerInfo PtrInfo, bool isVolatile, - bool isNonTemporal, unsigned Alignment, - const AAMDNodes &AAInfo = AAMDNodes()); - SDValue getStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr, + /// + /// This function will set the MOStore flag on MMOFlags, but you can set it if + /// you want. The MOLoad and MOInvariant flags must not be set. + SDValue + getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, + MachinePointerInfo PtrInfo, unsigned Alignment = 0, + MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone, + const AAMDNodes &AAInfo = AAMDNodes()); + SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachineMemOperand *MMO); - SDValue getTruncStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr, - MachinePointerInfo PtrInfo, EVT TVT, - bool isNonTemporal, bool isVolatile, - unsigned Alignment, - const AAMDNodes &AAInfo = AAMDNodes()); - SDValue getTruncStore(SDValue Chain, SDLoc dl, SDValue Val, SDValue Ptr, - EVT TVT, MachineMemOperand *MMO); - SDValue getIndexedStore(SDValue OrigStoe, SDLoc dl, SDValue Base, - SDValue Offset, ISD::MemIndexedMode AM); - - SDValue getMaskedLoad(EVT VT, SDLoc dl, SDValue Chain, SDValue Ptr, + SDValue + getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, + MachinePointerInfo PtrInfo, EVT TVT, unsigned Alignment = 0, + MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone, + const AAMDNodes &AAInfo = AAMDNodes()); + SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, + SDValue Ptr, EVT TVT, MachineMemOperand *MMO); + SDValue getIndexedStore(SDValue OrigStoe, const SDLoc &dl, SDValue Base, + SDValue Offset, ISD::MemIndexedMode AM); + + /// Returns sum of the base pointer and offset. + SDValue getMemBasePlusOffset(SDValue Base, unsigned Offset, const SDLoc &DL); + + SDValue getMaskedLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Mask, SDValue Src0, EVT MemVT, MachineMemOperand *MMO, ISD::LoadExtType); - SDValue getMaskedStore(SDValue Chain, SDLoc dl, SDValue Val, + SDValue getMaskedStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Mask, EVT MemVT, MachineMemOperand *MMO, bool IsTrunc); - SDValue getMaskedGather(SDVTList VTs, EVT VT, SDLoc dl, + SDValue getMaskedGather(SDVTList VTs, EVT VT, const SDLoc &dl, ArrayRef<SDValue> Ops, MachineMemOperand *MMO); - SDValue getMaskedScatter(SDVTList VTs, EVT VT, SDLoc dl, + SDValue getMaskedScatter(SDVTList VTs, EVT VT, const SDLoc &dl, ArrayRef<SDValue> Ops, MachineMemOperand *MMO); /// Construct a node to track a Value* through the backend. SDValue getSrcValue(const Value *v); @@ -895,8 +987,8 @@ public: SDValue getBitcast(EVT VT, SDValue V); /// Return an AddrSpaceCastSDNode. - SDValue getAddrSpaceCast(SDLoc dl, EVT VT, SDValue Ptr, - unsigned SrcAS, unsigned DestAS); + SDValue getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr, unsigned SrcAS, + unsigned DestAS); /// Return the specified value casted to /// the target's desired shift amount type. @@ -965,45 +1057,46 @@ public: /// Note that getMachineNode 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. - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT, - SDValue Op1); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT, - SDValue Op1, SDValue Op2); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT, - SDValue Op1, SDValue Op2, SDValue Op3); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT, - ArrayRef<SDValue> Ops); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2, + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT); + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT, SDValue Op1); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2, + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT, SDValue Op1, SDValue Op2); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2, + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT, SDValue Op1, SDValue Op2, SDValue Op3); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2, + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT, ArrayRef<SDValue> Ops); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2, - EVT VT3, SDValue Op1, SDValue Op2); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2, - EVT VT3, SDValue Op1, SDValue Op2, + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1, + EVT VT2); + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1, + EVT VT2, SDValue Op1); + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1, + EVT VT2, SDValue Op1, SDValue Op2); + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1, + EVT VT2, SDValue Op1, SDValue Op2, SDValue Op3); + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1, + EVT VT2, ArrayRef<SDValue> Ops); + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1, + EVT VT2, EVT VT3, SDValue Op1, SDValue Op2); + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1, + EVT VT2, EVT VT3, SDValue Op1, SDValue Op2, SDValue Op3); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2, - EVT VT3, ArrayRef<SDValue> Ops); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, EVT VT1, EVT VT2, - EVT VT3, EVT VT4, ArrayRef<SDValue> Ops); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, - ArrayRef<EVT> ResultTys, + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1, + EVT VT2, EVT VT3, ArrayRef<SDValue> Ops); + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1, + EVT VT2, EVT VT3, EVT VT4, ArrayRef<SDValue> Ops); - MachineSDNode *getMachineNode(unsigned Opcode, SDLoc dl, SDVTList VTs, + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, + ArrayRef<EVT> ResultTys, ArrayRef<SDValue> Ops); + MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, SDVTList VTs, ArrayRef<SDValue> Ops); /// A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes. - SDValue getTargetExtractSubreg(int SRIdx, SDLoc DL, EVT VT, + SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand); /// A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes. - SDValue getTargetInsertSubreg(int SRIdx, SDLoc DL, EVT VT, + SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg); /// Get the specified node if it's already available, or else return NULL. @@ -1012,16 +1105,17 @@ public: /// Creates a SDDbgValue node. SDDbgValue *getDbgValue(MDNode *Var, MDNode *Expr, SDNode *N, unsigned R, - bool IsIndirect, uint64_t Off, DebugLoc DL, + bool IsIndirect, uint64_t Off, const DebugLoc &DL, unsigned O); /// Constant SDDbgValue *getConstantDbgValue(MDNode *Var, MDNode *Expr, const Value *C, - uint64_t Off, DebugLoc DL, unsigned O); + uint64_t Off, const DebugLoc &DL, unsigned O); /// FrameIndex SDDbgValue *getFrameIndexDbgValue(MDNode *Var, MDNode *Expr, unsigned FI, - uint64_t Off, DebugLoc DL, unsigned O); + uint64_t Off, const DebugLoc &DL, + unsigned O); /// Remove the specified node from the system. If any of its /// operands then becomes dead, remove them as well. Inform UpdateListener @@ -1129,9 +1223,11 @@ public: return DbgInfo->getSDDbgValues(SD); } - /// Transfer SDDbgValues. +private: + /// Transfer SDDbgValues. Called via ReplaceAllUses{OfValue}?With void TransferDbgValues(SDValue From, SDValue To); +public: /// Return true if there are any SDDbgValue nodes associated /// with this SelectionDAG. bool hasDebugValues() const { return !DbgInfo->empty(); } @@ -1147,29 +1243,32 @@ public: void dump() const; - /// Create a stack temporary, suitable for holding the - /// specified value type. If minAlign is specified, the slot size will have - /// at least that alignment. + /// 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(EVT VT, unsigned minAlign = 1); - /// Create a stack temporary suitable for holding - /// either of the specified value types. + /// Create a stack temporary suitable for holding either of the specified + /// value types. SDValue CreateStackTemporary(EVT VT1, EVT VT2); - SDValue FoldConstantArithmetic(unsigned Opcode, SDLoc DL, EVT VT, + SDValue FoldSymbolOffset(unsigned Opcode, EVT VT, + const GlobalAddressSDNode *GA, + const SDNode *N2); + + SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, SDNode *Cst1, SDNode *Cst2); - SDValue FoldConstantArithmetic(unsigned Opcode, SDLoc DL, EVT VT, + SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, const ConstantSDNode *Cst1, const ConstantSDNode *Cst2); - SDValue FoldConstantVectorArithmetic(unsigned Opcode, SDLoc DL, - EVT VT, ArrayRef<SDValue> Ops, + SDValue FoldConstantVectorArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, + ArrayRef<SDValue> Ops, const SDNodeFlags *Flags = nullptr); /// Constant fold a setcc to true or false. - SDValue FoldSetCC(EVT VT, SDValue N1, - SDValue N2, ISD::CondCode Cond, SDLoc dl); + SDValue FoldSetCC(EVT VT, SDValue N1, SDValue N2, ISD::CondCode Cond, + const SDLoc &dl); /// Return true if the sign bit of Op is known to be zero. /// We use this predicate to simplify operations downstream. @@ -1188,27 +1287,32 @@ public: void computeKnownBits(SDValue Op, APInt &KnownZero, APInt &KnownOne, unsigned Depth = 0) const; - /// 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 - /// information. For example, immediately after an "SRA X, 2", we know that - /// 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. + /// Test if the given value is known to have exactly one bit set. This differs + /// from computeKnownBits in that it doesn't necessarily determine which bit + /// is set. + bool isKnownToBeAPowerOfTwo(SDValue Val) const; + + /// 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 information. For example, + /// immediately after an "SRA X, 2", we know that 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(SDValue Op, unsigned Depth = 0) const; - /// Return true if the specified operand is an - /// ISD::ADD with a ConstantSDNode on the right-hand side, or if it is an - /// ISD::OR with a ConstantSDNode that is guaranteed to have the same - /// semantics as an ADD. This handles the equivalence: + /// Return true if the specified operand is an ISD::ADD with a ConstantSDNode + /// on the right-hand side, or if it is an ISD::OR with a ConstantSDNode that + /// is guaranteed to have the same semantics as an ADD. This handles the + /// equivalence: /// X|Cst == X+Cst iff X&Cst = 0. bool isBaseWithConstantOffset(SDValue Op) const; /// Test whether the given SDValue is known to never be NaN. bool isKnownNeverNaN(SDValue Op) const; - /// Test whether the given SDValue is known to never be - /// positive or negative Zero. + /// Test whether the given SDValue is known to never be positive or negative + /// zero. bool isKnownNeverZero(SDValue Op) const; /// Test whether two SDValues are known to compare equal. This @@ -1228,10 +1332,12 @@ public: /// vector op and fill the end of the resulting vector with UNDEFS. SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0); - /// Return true if LD is loading 'Bytes' bytes from a location that is 'Dist' - /// units away from the location that the 'Base' load is loading from. - bool isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base, - unsigned Bytes, int Dist) const; + /// Return true if loads are next to each other and can be + /// merged. Check that both are nonvolatile and if LD is loading + /// 'Bytes' bytes from a location that is 'Dist' units away from the + /// location that the 'Base' load is loading from. + bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, + unsigned Bytes, int Dist) const; /// Infer alignment of a load / store address. Return 0 if /// it cannot be inferred. @@ -1265,8 +1371,12 @@ public: void ExtractVectorElements(SDValue Op, SmallVectorImpl<SDValue> &Args, unsigned Start = 0, unsigned Count = 0); + /// Compute the default alignment value for the given type. unsigned getEVTAlignment(EVT MemoryVT) const; + /// Test whether the given value is a constant int or similar node. + SDNode *isConstantIntBuildVectorOrConstantInt(SDValue N); + private: void InsertNode(SDNode *N); bool RemoveNodeFromCSEMaps(SDNode *N); @@ -1276,16 +1386,16 @@ private: void *&InsertPos); SDNode *FindModifiedNodeSlot(SDNode *N, ArrayRef<SDValue> Ops, void *&InsertPos); - SDNode *UpdadeSDLocOnMergedSDNode(SDNode *N, SDLoc loc); + SDNode *UpdadeSDLocOnMergedSDNode(SDNode *N, const SDLoc &loc); void DeleteNodeNotInCSEMaps(SDNode *N); void DeallocateNode(SDNode *N); void allnodes_clear(); - BinarySDNode *GetBinarySDNode(unsigned Opcode, SDLoc DL, SDVTList VTs, - SDValue N1, SDValue N2, - const SDNodeFlags *Flags = nullptr); + SDNode *GetBinarySDNode(unsigned Opcode, const SDLoc &DL, SDVTList VTs, + SDValue N1, SDValue N2, + const SDNodeFlags *Flags = nullptr); /// Look up the node specified by ID in CSEMap. If it exists, return it. If /// not, return the insertion token that will make insertion faster. This @@ -1296,7 +1406,7 @@ private: /// Look up the node specified by ID in CSEMap. If it exists, return it. If /// not, return the insertion token that will make insertion faster. Performs /// additional processing for constant nodes. - SDNode *FindNodeOrInsertPos(const FoldingSetNodeID &ID, DebugLoc DL, + SDNode *FindNodeOrInsertPos(const FoldingSetNodeID &ID, const SDLoc &DL, void *&InsertPos); /// List of non-single value types. |