AssertSext, AssertZext,
// Various leaf nodes.
- Constant, ConstantFP, STRING,
- GlobalAddress, FrameIndex, ConstantPool,
- BasicBlock, ExternalSymbol, VALUETYPE, CONDCODE, Register,
-
- // ConstantVec works like Constant or ConstantFP, except that it is not a
- // leaf node. All operands are either Constant or ConstantFP nodes.
- ConstantVec,
-
- // TargetConstant - Like Constant, but the DAG does not do any folding or
- // simplification of the constant. This is used by the DAG->DAG selector.
+ STRING, BasicBlock, VALUETYPE, CONDCODE, Register,
+ Constant, ConstantFP,
+ GlobalAddress, FrameIndex, ConstantPool, ExternalSymbol,
+
+ // TargetConstant* - Like Constant*, but the DAG does not do any folding or
+ // simplification of the constant.
TargetConstant,
+ TargetConstantFP,
// TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or
// anything else with this node, and this is valid in the target-specific
TargetFrameIndex,
TargetConstantPool,
TargetExternalSymbol,
-
+
+ /// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...)
+ /// This node represents a target intrinsic function with no side effects.
+ /// The first operand is the ID number of the intrinsic from the
+ /// llvm::Intrinsic namespace. The operands to the intrinsic follow. The
+ /// node has returns the result of the intrinsic.
+ INTRINSIC_WO_CHAIN,
+
+ /// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...)
+ /// This node represents a target intrinsic function with side effects that
+ /// returns a result. The first operand is a chain pointer. The second is
+ /// the ID number of the intrinsic from the llvm::Intrinsic namespace. The
+ /// operands to the intrinsic follow. The node has two results, the result
+ /// of the intrinsic and an output chain.
+ INTRINSIC_W_CHAIN,
+
+ /// OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...)
+ /// This node represents a target intrinsic function with side effects that
+ /// does not return a result. The first operand is a chain pointer. The
+ /// second is the ID number of the intrinsic from the llvm::Intrinsic
+ /// namespace. The operands to the intrinsic follow.
+ INTRINSIC_VOID,
+
// CopyToReg - This node has three operands: a chain, a register number to
// set to this value, and a value.
CopyToReg,
// Simple integer binary arithmetic operators.
ADD, SUB, MUL, SDIV, UDIV, SREM, UREM,
+ // Carry-setting nodes for multiple precision addition and subtraction.
+ // These nodes take two operands of the same value type, and produce two
+ // results. The first result is the normal add or sub result, the second
+ // result is the carry flag result.
+ ADDC, SUBC,
+
+ // Carry-using nodes for multiple precision addition and subtraction. These
+ // nodes take three operands: The first two are the normal lhs and rhs to
+ // the add or sub, and the third is the input carry flag. These nodes
+ // produce two results; the normal result of the add or sub, and the output
+ // carry flag. These nodes both read and write a carry flag to allow them
+ // to them to be chained together for add and sub of arbitrarily large
+ // values.
+ ADDE, SUBE,
+
// Simple binary floating point operators.
FADD, FSUB, FMUL, FDIV, FREM,
-
- // Simple abstract vector operators. Unlike the integer and floating point
- // binary operators, these nodes also take two additional operands:
- // a constant element count, and a value type node indicating the type of
- // the elements. The order is op0, op1, count, type. All vector opcodes,
- // including VLOAD, must currently have count and type as their 3rd and 4th
- // arguments.
- VADD, VSUB, VMUL,
+ // FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This
+ // DAG node does not require that X and Y have the same type, just that they
+ // are both floating point. X and the result must have the same type.
+ // FCOPYSIGN(f32, f64) is allowed.
+ FCOPYSIGN,
+
+ /// VBUILD_VECTOR(ELT1, ELT2, ELT3, ELT4,..., COUNT,TYPE) - Return a vector
+ /// with the specified, possibly variable, elements. The number of elements
+ /// is required to be a power of two.
+ VBUILD_VECTOR,
+
+ /// BUILD_VECTOR(ELT1, ELT2, ELT3, ELT4,...) - Return a vector
+ /// with the specified, possibly variable, elements. The number of elements
+ /// is required to be a power of two.
+ BUILD_VECTOR,
+
+ /// VINSERT_VECTOR_ELT(VECTOR, VAL, IDX, COUNT,TYPE) - Given a vector
+ /// VECTOR, an element ELEMENT, and a (potentially variable) index IDX,
+ /// return an vector with the specified element of VECTOR replaced with VAL.
+ /// COUNT and TYPE specify the type of vector, as is standard for V* nodes.
+ VINSERT_VECTOR_ELT,
+
+ /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR (a legal packed
+ /// type) with the element at IDX replaced with VAL.
+ INSERT_VECTOR_ELT,
+
+ /// VEXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR
+ /// (an MVT::Vector value) identified by the (potentially variable) element
+ /// number IDX.
+ VEXTRACT_VECTOR_ELT,
+
+ /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR
+ /// (a legal packed type vector) identified by the (potentially variable)
+ /// element number IDX.
+ EXTRACT_VECTOR_ELT,
+
+ /// VVECTOR_SHUFFLE(VEC1, VEC2, SHUFFLEVEC, COUNT,TYPE) - Returns a vector,
+ /// of the same type as VEC1/VEC2. SHUFFLEVEC is a VBUILD_VECTOR of
+ /// constant int values that indicate which value each result element will
+ /// get. The elements of VEC1/VEC2 are enumerated in order. This is quite
+ /// similar to the Altivec 'vperm' instruction, except that the indices must
+ /// be constants and are in terms of the element size of VEC1/VEC2, not in
+ /// terms of bytes.
+ VVECTOR_SHUFFLE,
+
+ /// VECTOR_SHUFFLE(VEC1, VEC2, SHUFFLEVEC) - Returns a vector, of the same
+ /// type as VEC1/VEC2. SHUFFLEVEC is a BUILD_VECTOR of constant int values
+ /// (regardless of whether its datatype is legal or not) that indicate
+ /// which value each result element will get. The elements of VEC1/VEC2 are
+ /// enumerated in order. This is quite similar to the Altivec 'vperm'
+ /// instruction, except that the indices must be constants and are in terms
+ /// of the element size of VEC1/VEC2, not in terms of bytes.
+ VECTOR_SHUFFLE,
+
+ /// X = VBIT_CONVERT(Y) and X = VBIT_CONVERT(Y, COUNT,TYPE) - This node
+ /// represents a conversion from or to an ISD::Vector type.
+ ///
+ /// This is lowered to a BIT_CONVERT of the appropriate input/output types.
+ /// The input and output are required to have the same size and at least one
+ /// is required to be a vector (if neither is a vector, just use
+ /// BIT_CONVERT).
+ ///
+ /// If the result is a vector, this takes three operands (like any other
+ /// vector producer) which indicate the size and type of the vector result.
+ /// Otherwise it takes one input.
+ VBIT_CONVERT,
+
+ /// BINOP(LHS, RHS, COUNT,TYPE)
+ /// Simple abstract vector operators. Unlike the integer and floating point
+ /// binary operators, these nodes also take two additional operands:
+ /// a constant element count, and a value type node indicating the type of
+ /// the elements. The order is count, type, op0, op1. All vector opcodes,
+ /// including VLOAD and VConstant must currently have count and type as
+ /// their last two operands.
+ VADD, VSUB, VMUL, VSDIV, VUDIV,
+ VAND, VOR, VXOR,
+
+ /// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a
+ /// scalar value into the low element of the resultant vector type. The top
+ /// elements of the vector are undefined.
+ SCALAR_TO_VECTOR,
+
// MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing
// an unsigned/signed value of type i[2*n], then return the top part.
MULHU, MULHS,
- // Bitwise operators.
- AND, OR, XOR, SHL, SRA, SRL,
+ // Bitwise operators - logical and, logical or, logical xor, shift left,
+ // shift right algebraic (shift in sign bits), shift right logical (shift in
+ // zeroes), rotate left, rotate right, and byteswap.
+ AND, OR, XOR, SHL, SRA, SRL, ROTL, ROTR, BSWAP,
// Counting operators
CTTZ, CTLZ, CTPOP,
- // Select
+ // Select(COND, TRUEVAL, FALSEVAL)
SELECT,
// Select with condition operator - This selects between a true value and
// (op #2) as a CondCodeSDNode.
SETCC,
- // ADD_PARTS/SUB_PARTS - These operators take two logical operands which are
- // broken into a multiple pieces each, and return the resulting pieces of
- // doing an atomic add/sub operation. This is used to handle add/sub of
- // expanded types. The operation ordering is:
- // [Lo,Hi] = op [LoLHS,HiLHS], [LoRHS,HiRHS]
- ADD_PARTS, SUB_PARTS,
-
// SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
// integer shift operations, just like ADD/SUB_PARTS. The operation
// ordering is:
// FNEG, FABS, FSQRT, FSIN, FCOS - Perform unary floating point negation,
// absolute value, square root, sine and cosine operations.
FNEG, FABS, FSQRT, FSIN, FCOS,
-
+
// Other operators. LOAD and STORE have token chains as their first
// operand, then the same operands as an LLVM load/store instruction, then a
// SRCVALUE node that provides alias analysis information.
LOAD, STORE,
- // Abstract vector version of LOAD. VLOAD has a token chain as the first
- // operand, followed by a pointer operand, a constant element count, a value
- // type node indicating the type of the elements, and a SRCVALUE node.
+ // Abstract vector version of LOAD. VLOAD has a constant element count as
+ // the first operand, followed by a value type node indicating the type of
+ // the elements, a token chain, a pointer operand, and a SRCVALUE node.
VLOAD,
// EXTLOAD, SEXTLOAD, ZEXTLOAD - These three operators all load a value from
// integer result type.
// ZEXTLOAD loads the integer operand and zero extends it to a larger
// integer result type.
- // EXTLOAD is used for two things: floating point extending loads, and
- // integer extending loads where it doesn't matter what the high
- // bits are set to. The code generator is allowed to codegen this
- // into whichever operation is more efficient.
+ // EXTLOAD is used for three things: floating point extending loads,
+ // integer extending loads [the top bits are undefined], and vector
+ // extending loads [load into low elt].
EXTLOAD, SEXTLOAD, ZEXTLOAD,
// TRUNCSTORE - This operators truncates (for integer) or rounds (for FP) a
// to if the condition is true.
BRCOND,
- // BRCONDTWOWAY - Two-way conditional branch. The first operand is the
- // chain, the second is the condition, the third is the block to branch to
- // if true, and the forth is the block to branch to if false. Targets
- // usually do not implement this, preferring to have legalize demote the
- // operation to BRCOND/BR pairs when necessary.
- BRCONDTWOWAY,
-
// BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
// that the condition is represented as condition code, and two nodes to
// compare, rather than as a combined SetCC node. The operands in order are
// chain, cc, lhs, rhs, block to branch to if condition is true.
BR_CC,
- // BRTWOWAY_CC - Two-way conditional branch. The operands in order are
- // chain, cc, lhs, rhs, block to branch to if condition is true, block to
- // branch to if condition is false. Targets usually do not implement this,
- // preferring to have legalize demote the operation to BRCOND/BR pairs.
- BRTWOWAY_CC,
-
// RET - Return from function. The first operand is the chain,
// and any subsequent operands are the return values for the
// function. This operation can have variable number of operands.
RET,
- // CALL - Call to a function pointer. The first operand is the chain, the
- // second is the destination function pointer (a GlobalAddress for a direct
- // call). Arguments have already been lowered to explicit DAGs according to
- // the calling convention in effect here. TAILCALL is the same as CALL, but
- // the callee is known not to access the stack of the caller.
- CALL,
- TAILCALL,
-
+ // INLINEASM - Represents an inline asm block. This node always has two
+ // return values: a chain and a flag result. The inputs are as follows:
+ // Operand #0 : Input chain.
+ // Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string.
+ // Operand #2n+2: A RegisterNode.
+ // Operand #2n+3: A TargetConstant, indicating if the reg is a use/def
+ // Operand #last: Optional, an incoming flag.
+ INLINEASM,
+
+ // STACKSAVE - STACKSAVE has one operand, an input chain. It produces a
+ // value, the same type as the pointer type for the system, and an output
+ // chain.
+ STACKSAVE,
+
+ // STACKRESTORE has two operands, an input chain and a pointer to restore to
+ // it returns an output chain.
+ STACKRESTORE,
+
// MEMSET/MEMCPY/MEMMOVE - The first operand is the chain, and the rest
// correspond to the operands of the LLVM intrinsic functions. The only
// result is a token chain. The alignment argument is guaranteed to be a
// target and not touched by the DAG optimizers.
CALLSEQ_START, // Beginning of a call sequence
CALLSEQ_END, // End of a call sequence
+
+ // VAARG - VAARG has three operands: an input chain, a pointer, and a
+ // SRCVALUE. It returns a pair of values: the vaarg value and a new chain.
+ VAARG,
+
+ // VACOPY - VACOPY has five operands: an input chain, a destination pointer,
+ // a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the
+ // source.
+ VACOPY,
+
+ // VAEND, VASTART - VAEND and VASTART have three operands: an input chain, a
+ // pointer, and a SRCVALUE.
+ VAEND, VASTART,
// SRCVALUE - This corresponds to a Value*, and is used to associate memory
// locations with their value. This allows one use alias analysis
// register (or other high accuracy low latency clock source)
READCYCLECOUNTER,
- // READPORT, WRITEPORT, READIO, WRITEIO - These correspond to the LLVM
- // intrinsics of the same name. The first operand is a token chain, the
- // other operands match the intrinsic. These produce a token chain in
- // addition to a value (if any).
- READPORT, WRITEPORT, READIO, WRITEIO,
-
// HANDLENODE node - Used as a handle for various purposes.
HANDLENODE,
DEBUG_LABEL,
// BUILTIN_OP_END - This must be the last enum value in this list.
- BUILTIN_OP_END,
+ BUILTIN_OP_END
};
+ /// Node predicates
+
+ /// isBuildVectorAllOnes - Return true if the specified node is a
+ /// BUILD_VECTOR where all of the elements are ~0 or undef.
+ bool isBuildVectorAllOnes(const SDNode *N);
+
+ /// isBuildVectorAllZeros - Return true if the specified node is a
+ /// BUILD_VECTOR where all of the elements are 0 or undef.
+ bool isBuildVectorAllZeros(const SDNode *N);
+
//===--------------------------------------------------------------------===//
/// ISD::CondCode enum - These are ordered carefully to make the bitfields
/// below work out, when considering SETFALSE (something that never exists
SETNE, // 1 X 1 1 0 True if not equal
SETTRUE2, // 1 X 1 1 1 Always true (always folded)
- SETCC_INVALID, // Marker value.
+ SETCC_INVALID // Marker value.
};
/// isSignedIntSetCC - Return true if this is a setcc instruction that
return SDOperand(Val, R);
}
+ // isOperand - Return true if this node is an operand of N.
+ bool isOperand(SDNode *N) const;
+
/// getValueType - Return the ValueType of the referenced return value.
///
inline MVT::ValueType getValueType() const;
/// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
/// indicated value. This method ignores uses of other values defined by this
/// operation.
- bool hasNUsesOfValue(unsigned NUses, unsigned Value);
+ bool hasNUsesOfValue(unsigned NUses, unsigned Value) const;
+
+ // isOnlyUse - Return true if this node is the only use of N.
+ bool isOnlyUse(SDNode *N) const;
+
+ // isOperand - Return true if this node is an operand of N.
+ bool isOperand(SDNode *N) const;
/// getNumOperands - Return the number of values used by this operation.
///
static bool classof(const SDNode *) { return true; }
-
- /// setAdjCallChain - This method should only be used by the legalizer.
- void setAdjCallChain(SDOperand N);
-
protected:
friend class SelectionDAG;
Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this);
Op4.Val->Uses.push_back(this); Op5.Val->Uses.push_back(this);
}
+ void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2, SDOperand Op3,
+ SDOperand Op4, SDOperand Op5, SDOperand Op6) {
+ assert(NumOperands == 0 && "Should not have operands yet!");
+ OperandList = new SDOperand[7];
+ OperandList[0] = Op0;
+ OperandList[1] = Op1;
+ OperandList[2] = Op2;
+ OperandList[3] = Op3;
+ OperandList[4] = Op4;
+ OperandList[5] = Op5;
+ OperandList[6] = Op6;
+ NumOperands = 7;
+ Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this);
+ Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this);
+ Op4.Val->Uses.push_back(this); Op5.Val->Uses.push_back(this);
+ Op6.Val->Uses.push_back(this);
+ }
+ void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2, SDOperand Op3,
+ SDOperand Op4, SDOperand Op5, SDOperand Op6, SDOperand Op7) {
+ assert(NumOperands == 0 && "Should not have operands yet!");
+ OperandList = new SDOperand[8];
+ OperandList[0] = Op0;
+ OperandList[1] = Op1;
+ OperandList[2] = Op2;
+ OperandList[3] = Op3;
+ OperandList[4] = Op4;
+ OperandList[5] = Op5;
+ OperandList[6] = Op6;
+ OperandList[7] = Op7;
+ NumOperands = 8;
+ Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this);
+ Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this);
+ Op4.Val->Uses.push_back(this); Op5.Val->Uses.push_back(this);
+ Op6.Val->Uses.push_back(this); Op7.Val->Uses.push_back(this);
+ }
+
void addUser(SDNode *User) {
Uses.push_back(User);
}
bool isNullValue() const { return Value == 0; }
bool isAllOnesValue() const {
- int NumBits = MVT::getSizeInBits(getValueType(0));
- if (NumBits == 64) return Value+1 == 0;
- return Value == (1ULL << NumBits)-1;
+ return Value == MVT::getIntVTBitMask(getValueType(0));
}
static bool classof(const ConstantSDNode *) { return true; }
double Value;
protected:
friend class SelectionDAG;
- ConstantFPSDNode(double val, MVT::ValueType VT)
- : SDNode(ISD::ConstantFP, VT), Value(val) {
+ ConstantFPSDNode(bool isTarget, double val, MVT::ValueType VT)
+ : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, VT),
+ Value(val) {
}
public:
static bool classof(const ConstantFPSDNode *) { return true; }
static bool classof(const SDNode *N) {
- return N->getOpcode() == ISD::ConstantFP;
+ return N->getOpcode() == ISD::ConstantFP ||
+ N->getOpcode() == ISD::TargetConstantFP;
}
};
class GlobalAddressSDNode : public SDNode {
GlobalValue *TheGlobal;
- int offset;
+ int Offset;
protected:
friend class SelectionDAG;
GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT::ValueType VT,
int o=0)
- : SDNode(isTarget ? ISD::TargetGlobalAddress : ISD::GlobalAddress, VT) {
+ : SDNode(isTarget ? ISD::TargetGlobalAddress : ISD::GlobalAddress, VT),
+ Offset(o) {
TheGlobal = const_cast<GlobalValue*>(GA);
- offset = o;
}
public:
GlobalValue *getGlobal() const { return TheGlobal; }
- int getOffset() const { return offset; }
+ int getOffset() const { return Offset; }
static bool classof(const GlobalAddressSDNode *) { return true; }
static bool classof(const SDNode *N) {
class ConstantPoolSDNode : public SDNode {
Constant *C;
+ int Offset;
+ unsigned Alignment;
protected:
friend class SelectionDAG;
- ConstantPoolSDNode(Constant *c, MVT::ValueType VT, bool isTarget)
+ ConstantPoolSDNode(bool isTarget, Constant *c, MVT::ValueType VT,
+ int o=0)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, VT),
- C(c) {}
+ C(c), Offset(o), Alignment(0) {}
+ ConstantPoolSDNode(bool isTarget, Constant *c, MVT::ValueType VT, int o,
+ unsigned Align)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, VT),
+ C(c), Offset(o), Alignment(Align) {}
public:
Constant *get() const { return C; }
+ int getOffset() const { return Offset; }
+
+ // Return the alignment of this constant pool object, which is either 0 (for
+ // default alignment) or log2 of the desired value.
+ unsigned getAlignment() const { return Alignment; }
static bool classof(const ConstantPoolSDNode *) { return true; }
static bool classof(const SDNode *N) {