aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/CodeGen/SelectionDAG.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/CodeGen/SelectionDAG.h')
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h544
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.