namespace ISD {
//===--------------------------------------------------------------------===//
- /// ISD::NodeType enum - This enum defines all of the operators valid in a
- /// SelectionDAG.
+ /// ISD::NodeType enum - This enum defines the target-independent operators
+ /// for a SelectionDAG.
+ ///
+ /// Targets may also define target-dependent operator codes for SDNodes. For
+ /// example, on x86, these are the enum values in the X86ISD namespace.
+ /// Targets should aim to use target-independent operators to model their
+ /// instruction sets as much as possible, and only use target-dependent
+ /// operators when they have special requirements.
+ ///
+ /// Finally, during and after selection proper, SNodes may use special
+ /// operator codes that correspond directly with MachineInstr opcodes. These
+ /// are used to represent selected instructions. See the isMachineOpcode()
+ /// and getMachineOpcode() member functions of SDNode.
///
enum NodeType {
// DELETED_NODE - This is an illegal flag value that is used to catch
/// NodeId - Unique id per SDNode in the DAG.
int NodeId;
- /// debugLoc - source line information.
- DebugLoc debugLoc;
-
/// OperandList - The values that are used by this operation.
///
SDUse *OperandList;
/// define multiple values simultaneously.
const MVT *ValueList;
- /// NumOperands/NumValues - The number of entries in the Operand/Value list.
- unsigned short NumOperands, NumValues;
-
/// UseList - List of uses for this SDNode.
SDUse *UseList;
+ /// NumOperands/NumValues - The number of entries in the Operand/Value list.
+ unsigned short NumOperands, NumValues;
+
+ /// debugLoc - source line information.
+ DebugLoc debugLoc;
+
/// getValueTypeList - Return a pointer to the specified value type.
static const MVT *getValueTypeList(MVT VT);
///
std::string getOperationName(const SelectionDAG *G = 0) const;
static const char* getIndexedModeName(ISD::MemIndexedMode AM);
+ void print_types(raw_ostream &OS, const SelectionDAG *G) const;
+ void print_details(raw_ostream &OS, const SelectionDAG *G) const;
void print(raw_ostream &OS, const SelectionDAG *G = 0) const;
+ void printr(raw_ostream &OS, const SelectionDAG *G = 0) const;
void dump() const;
+ void dumpr() const;
void dump(const SelectionDAG *G) const;
static bool classof(const SDNode *) { return true; }
return Ret;
}
- /// The constructors that supply DebugLoc explicitly should be preferred
- /// for new code.
- SDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps)
- : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0),
- NodeId(-1), debugLoc(DebugLoc::getUnknownLoc()),
- OperandList(NumOps ? new SDUse[NumOps] : 0),
- ValueList(VTs.VTs),
- NumOperands(NumOps), NumValues(VTs.NumVTs),
- UseList(NULL) {
- for (unsigned i = 0; i != NumOps; ++i) {
- OperandList[i].setUser(this);
- OperandList[i].setInitial(Ops[i]);
- }
- }
-
- /// This constructor adds no operands itself; operands can be
- /// set later with InitOperands.
- SDNode(unsigned Opc, SDVTList VTs)
- : NodeType(Opc), OperandsNeedDelete(false), SubclassData(0),
- NodeId(-1), debugLoc(DebugLoc::getUnknownLoc()), OperandList(0),
- ValueList(VTs.VTs), NumOperands(0), NumValues(VTs.NumVTs),
- UseList(NULL) {}
-
- /// The next two constructors specify DebugLoc explicitly; the intent
- /// is that they will replace the above two over time, and eventually
- /// the ones above can be removed.
SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs, const SDValue *Ops,
unsigned NumOps)
: NodeType(Opc), OperandsNeedDelete(true), SubclassData(0),
- NodeId(-1), debugLoc(dl),
+ NodeId(-1),
OperandList(NumOps ? new SDUse[NumOps] : 0),
- ValueList(VTs.VTs),
+ ValueList(VTs.VTs), UseList(NULL),
NumOperands(NumOps), NumValues(VTs.NumVTs),
- UseList(NULL) {
+ debugLoc(dl) {
for (unsigned i = 0; i != NumOps; ++i) {
OperandList[i].setUser(this);
OperandList[i].setInitial(Ops[i]);
/// set later with InitOperands.
SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs)
: NodeType(Opc), OperandsNeedDelete(false), SubclassData(0),
- NodeId(-1), debugLoc(dl), OperandList(0),
- ValueList(VTs.VTs), NumOperands(0), NumValues(VTs.NumVTs),
- UseList(NULL) {}
+ NodeId(-1), OperandList(0), ValueList(VTs.VTs), UseList(NULL),
+ NumOperands(0), NumValues(VTs.NumVTs),
+ debugLoc(dl) {}
/// InitOperands - Initialize the operands list of this with 1 operand.
void InitOperands(SDUse *Ops, const SDValue &Op0) {
class UnarySDNode : public SDNode {
SDUse Op;
public:
- UnarySDNode(unsigned Opc, SDVTList VTs, SDValue X)
- : SDNode(Opc, VTs) {
+ UnarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X)
+ : SDNode(Opc, dl, VTs) {
InitOperands(&Op, X);
}
};
class BinarySDNode : public SDNode {
SDUse Ops[2];
public:
- BinarySDNode(unsigned Opc, SDVTList VTs, SDValue X, SDValue Y)
- : SDNode(Opc, VTs) {
+ BinarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y)
+ : SDNode(Opc, dl, VTs) {
InitOperands(Ops, X, Y);
}
};
class TernarySDNode : public SDNode {
SDUse Ops[3];
public:
- TernarySDNode(unsigned Opc, SDVTList VTs, SDValue X, SDValue Y,
+ TernarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y,
SDValue Z)
- : SDNode(Opc, VTs) {
+ : SDNode(Opc, dl, VTs) {
InitOperands(Ops, X, Y, Z);
}
};
#else
explicit HandleSDNode(SDValue X)
#endif
- : SDNode(ISD::HANDLENODE, getSDVTList(MVT::Other)) {
+ : SDNode(ISD::HANDLENODE, DebugLoc::getUnknownLoc(),
+ getSDVTList(MVT::Other)) {
InitOperands(&Op, X);
}
~HandleSDNode();
//! SVOffset - Memory location offset. Note that base is defined in MemSDNode
int SVOffset;
- /// Flags - the low bit indicates whether this is a volatile reference;
- /// the remainder is a log2 encoding of the alignment in bytes.
- unsigned Flags;
-
public:
- MemSDNode(unsigned Opc, SDVTList VTs, MVT MemoryVT,
+ MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, MVT MemoryVT,
const Value *srcValue, int SVOff,
unsigned alignment, bool isvolatile);
- MemSDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps,
- MVT MemoryVT, const Value *srcValue, int SVOff,
+ MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, const SDValue *Ops,
+ unsigned NumOps, MVT MemoryVT, const Value *srcValue, int SVOff,
unsigned alignment, bool isvolatile);
/// Returns alignment and volatility of the memory access
- unsigned getAlignment() const { return (1u << (Flags >> 1)) >> 1; }
- bool isVolatile() const { return Flags & 1; }
-
+ unsigned getAlignment() const { return (1u << (SubclassData >> 6)) >> 1; }
+ bool isVolatile() const { return (SubclassData >> 5) & 1; }
+
+ /// getRawSubclassData - Return the SubclassData value, which contains an
+ /// encoding of the alignment and volatile information, as well as bits
+ /// used by subclasses. This function should only be used to compute a
+ /// FoldingSetNodeID value.
+ unsigned getRawSubclassData() const {
+ return SubclassData;
+ }
+
/// Returns the SrcValue and offset that describes the location of the access
const Value *getSrcValue() const { return SrcValue; }
int getSrcValueOffset() const { return SVOffset; }
-
+
/// getMemoryVT - Return the type of the in-memory value.
MVT getMemoryVT() const { return MemoryVT; }
-
+
/// getMemOperand - Return a MachineMemOperand object describing the memory
/// reference performed by operation.
MachineMemOperand getMemOperand() const;
return getOperand(getOpcode() == ISD::STORE ? 2 : 1);
}
- /// getRawFlags - Represent the flags as a bunch of bits.
- ///
- unsigned getRawFlags() const { return Flags; }
-
// Methods to support isa and dyn_cast
static bool classof(const MemSDNode *) { return true; }
static bool classof(const SDNode *N) {
N->getOpcode() == ISD::INTRINSIC_W_CHAIN ||
N->getOpcode() == ISD::INTRINSIC_VOID ||
N->isTargetOpcode();
- }
+ }
};
/// AtomicSDNode - A SDNode reprenting atomic operations.
///
class AtomicSDNode : public MemSDNode {
SDUse Ops[4];
-
+
public:
// Opc: opcode for atomic
// VTL: value type list
// Swp: swap value
// SrcVal: address to update as a Value (used for MemOperand)
// Align: alignment of memory
- AtomicSDNode(unsigned Opc, SDVTList VTL, MVT MemVT,
+ AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, MVT MemVT,
SDValue Chain, SDValue Ptr,
SDValue Cmp, SDValue Swp, const Value* SrcVal,
unsigned Align=0)
- : MemSDNode(Opc, VTL, MemVT, SrcVal, /*SVOffset=*/0,
+ : MemSDNode(Opc, dl, VTL, MemVT, SrcVal, /*SVOffset=*/0,
Align, /*isVolatile=*/true) {
InitOperands(Ops, Chain, Ptr, Cmp, Swp);
}
- AtomicSDNode(unsigned Opc, SDVTList VTL, MVT MemVT,
- SDValue Chain, SDValue Ptr,
+ AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, MVT MemVT,
+ SDValue Chain, SDValue Ptr,
SDValue Val, const Value* SrcVal, unsigned Align=0)
- : MemSDNode(Opc, VTL, MemVT, SrcVal, /*SVOffset=*/0,
+ : MemSDNode(Opc, dl, VTL, MemVT, SrcVal, /*SVOffset=*/0,
Align, /*isVolatile=*/true) {
InitOperands(Ops, Chain, Ptr, Val);
}
-
+
const SDValue &getBasePtr() const { return getOperand(1); }
const SDValue &getVal() const { return getOperand(2); }
- bool isCompareAndSwap() const {
- unsigned Op = getOpcode();
+ bool isCompareAndSwap() const {
+ unsigned Op = getOpcode();
return Op == ISD::ATOMIC_CMP_SWAP;
}
bool ReadMem; // Intrinsic reads memory
bool WriteMem; // Intrinsic writes memory
public:
- MemIntrinsicSDNode(unsigned Opc, SDVTList VTs,
+ MemIntrinsicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs,
const SDValue *Ops, unsigned NumOps,
MVT MemoryVT, const Value *srcValue, int SVO,
unsigned Align, bool Vol, bool ReadMem, bool WriteMem)
- : MemSDNode(Opc, VTs, Ops, NumOps, MemoryVT, srcValue, SVO, Align, Vol),
+ : MemSDNode(Opc, dl, VTs, Ops, NumOps, MemoryVT, srcValue, SVO, Align, Vol),
ReadMem(ReadMem), WriteMem(WriteMem) {
}
protected:
friend class SelectionDAG;
ConstantSDNode(bool isTarget, const ConstantInt *val, MVT VT)
- : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, getSDVTList(VT)),
- Value(val) {
+ : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant,
+ DebugLoc::getUnknownLoc(), getSDVTList(VT)), Value(val) {
}
public:
friend class SelectionDAG;
ConstantFPSDNode(bool isTarget, const ConstantFP *val, MVT VT)
: SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP,
- getSDVTList(VT)), Value(val) {
+ DebugLoc::getUnknownLoc(), getSDVTList(VT)), Value(val) {
}
public:
protected:
friend class SelectionDAG;
FrameIndexSDNode(int fi, MVT VT, bool isTarg)
- : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, getSDVTList(VT)),
- FI(fi) {
+ : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex,
+ DebugLoc::getUnknownLoc(), getSDVTList(VT)), FI(fi) {
}
public:
protected:
friend class SelectionDAG;
JumpTableSDNode(int jti, MVT VT, bool isTarg)
- : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, getSDVTList(VT)),
- JTI(jti) {
+ : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable,
+ DebugLoc::getUnknownLoc(), getSDVTList(VT)), JTI(jti) {
}
public:
friend class SelectionDAG;
ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o=0)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ DebugLoc::getUnknownLoc(),
getSDVTList(VT)), Offset(o), Alignment(0) {
assert((int)Offset >= 0 && "Offset is too large");
Val.ConstVal = c;
}
ConstantPoolSDNode(bool isTarget, Constant *c, MVT VT, int o, unsigned Align)
- : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ DebugLoc::getUnknownLoc(),
getSDVTList(VT)), Offset(o), Alignment(Align) {
assert((int)Offset >= 0 && "Offset is too large");
Val.ConstVal = c;
ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
MVT VT, int o=0)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ DebugLoc::getUnknownLoc(),
getSDVTList(VT)), Offset(o), Alignment(0) {
assert((int)Offset >= 0 && "Offset is too large");
Val.MachineCPVal = v;
ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
MVT VT, int o, unsigned Align)
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ DebugLoc::getUnknownLoc(),
getSDVTList(VT)), Offset(o), Alignment(Align) {
assert((int)Offset >= 0 && "Offset is too large");
Val.MachineCPVal = v;
MachineBasicBlock *MBB;
protected:
friend class SelectionDAG;
+ /// Debug info is meaningful and potentially useful here, but we create
+ /// blocks out of order when they're jumped to, which makes it a bit
+ /// harder. Let's see if we need it first.
explicit BasicBlockSDNode(MachineBasicBlock *mbb)
- : SDNode(ISD::BasicBlock, getSDVTList(MVT::Other)), MBB(mbb) {
+ : SDNode(ISD::BasicBlock, DebugLoc::getUnknownLoc(),
+ getSDVTList(MVT::Other)), MBB(mbb) {
}
public:
friend class SelectionDAG;
/// Create a SrcValue for a general value.
explicit SrcValueSDNode(const Value *v)
- : SDNode(ISD::SRCVALUE, getSDVTList(MVT::Other)), V(v) {}
+ : SDNode(ISD::SRCVALUE, DebugLoc::getUnknownLoc(),
+ getSDVTList(MVT::Other)), V(v) {}
public:
/// getValue - return the contained Value.
friend class SelectionDAG;
/// Create a MachineMemOperand node
explicit MemOperandSDNode(const MachineMemOperand &mo)
- : SDNode(ISD::MEMOPERAND, getSDVTList(MVT::Other)), MO(mo) {}
+ : SDNode(ISD::MEMOPERAND, DebugLoc::getUnknownLoc(),
+ getSDVTList(MVT::Other)), MO(mo) {}
public:
/// MO - The contained MachineMemOperand.
protected:
friend class SelectionDAG;
RegisterSDNode(unsigned reg, MVT VT)
- : SDNode(ISD::Register, getSDVTList(VT)), Reg(reg) {
+ : SDNode(ISD::Register, DebugLoc::getUnknownLoc(),
+ getSDVTList(VT)), Reg(reg) {
}
public:
friend class SelectionDAG;
DbgStopPointSDNode(SDValue ch, unsigned l, unsigned c,
Value *cu)
- : SDNode(ISD::DBG_STOPPOINT, getSDVTList(MVT::Other)),
- Line(l), Column(c), CU(cu) {
+ : SDNode(ISD::DBG_STOPPOINT, DebugLoc::getUnknownLoc(),
+ getSDVTList(MVT::Other)), Line(l), Column(c), CU(cu) {
InitOperands(&Chain, ch);
}
public:
unsigned LabelID;
protected:
friend class SelectionDAG;
- LabelSDNode(unsigned NodeTy, SDValue ch, unsigned id)
- : SDNode(NodeTy, getSDVTList(MVT::Other)), LabelID(id) {
+LabelSDNode(unsigned NodeTy, DebugLoc dl, SDValue ch, unsigned id)
+ : SDNode(NodeTy, dl, getSDVTList(MVT::Other)), LabelID(id) {
InitOperands(&Chain, ch);
}
public:
friend class SelectionDAG;
ExternalSymbolSDNode(bool isTarget, const char *Sym, MVT VT)
: SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
+ DebugLoc::getUnknownLoc(),
getSDVTList(VT)), Symbol(Sym) {
}
public:
protected:
friend class SelectionDAG;
explicit CondCodeSDNode(ISD::CondCode Cond)
- : SDNode(ISD::CONDCODE, getSDVTList(MVT::Other)), Condition(Cond) {
+ : SDNode(ISD::CONDCODE, DebugLoc::getUnknownLoc(),
+ getSDVTList(MVT::Other)), Condition(Cond) {
}
public:
ISD::CvtCode CvtCode;
protected:
friend class SelectionDAG;
- explicit CvtRndSatSDNode(MVT VT, const SDValue *Ops, unsigned NumOps,
- ISD::CvtCode Code)
- : SDNode(ISD::CONVERT_RNDSAT, getSDVTList(VT), Ops, NumOps), CvtCode(Code) {
+ explicit CvtRndSatSDNode(MVT VT, DebugLoc dl, const SDValue *Ops,
+ unsigned NumOps, ISD::CvtCode Code)
+ : SDNode(ISD::CONVERT_RNDSAT, dl, getSDVTList(VT), Ops, NumOps),
+ CvtCode(Code) {
assert(NumOps == 5 && "wrong number of operations");
}
public:
protected:
friend class SelectionDAG;
explicit ARG_FLAGSSDNode(ISD::ArgFlagsTy Flags)
- : SDNode(ISD::ARG_FLAGS, getSDVTList(MVT::Other)), TheFlags(Flags) {
+ : SDNode(ISD::ARG_FLAGS, DebugLoc::getUnknownLoc(),
+ getSDVTList(MVT::Other)), TheFlags(Flags) {
}
public:
ISD::ArgFlagsTy getArgFlags() const { return TheFlags; }
bool Inreg;
protected:
friend class SelectionDAG;
- CallSDNode(unsigned cc, bool isvararg, bool istailcall, bool isinreg,
- SDVTList VTs, const SDValue *Operands, unsigned numOperands)
- : SDNode(ISD::CALL, VTs, Operands, numOperands),
+ CallSDNode(unsigned cc, DebugLoc dl, bool isvararg, bool istailcall,
+ bool isinreg, SDVTList VTs, const SDValue *Operands,
+ unsigned numOperands)
+ : SDNode(ISD::CALL, dl, VTs, Operands, numOperands),
CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall),
Inreg(isinreg) {}
public:
protected:
friend class SelectionDAG;
explicit VTSDNode(MVT VT)
- : SDNode(ISD::VALUETYPE, getSDVTList(MVT::Other)), ValueType(VT) {
+ : SDNode(ISD::VALUETYPE, DebugLoc::getUnknownLoc(),
+ getSDVTList(MVT::Other)), ValueType(VT) {
}
public:
*/
SDUse Ops[4];
public:
- LSBaseSDNode(ISD::NodeType NodeTy, SDValue *Operands, unsigned numOperands,
- SDVTList VTs, ISD::MemIndexedMode AM, MVT VT,
- const Value *SV, int SVO, unsigned Align, bool Vol)
- : MemSDNode(NodeTy, VTs, VT, SV, SVO, Align, Vol) {
- SubclassData = AM;
- InitOperands(Ops, Operands, numOperands);
+ LSBaseSDNode(ISD::NodeType NodeTy, DebugLoc dl, SDValue *Operands,
+ unsigned numOperands, SDVTList VTs, ISD::MemIndexedMode AM,
+ MVT VT, const Value *SV, int SVO, unsigned Align, bool Vol)
+ : MemSDNode(NodeTy, dl, VTs, VT, SV, SVO, Align, Vol) {
assert(Align != 0 && "Loads and stores should have non-zero aligment");
+ SubclassData |= AM << 2;
+ assert(getAddressingMode() == AM && "MemIndexedMode encoding error!");
+ InitOperands(Ops, Operands, numOperands);
assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) &&
"Only indexed loads and stores have a non-undef offset operand");
}
/// getAddressingMode - Return the addressing mode for this load or store:
/// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
ISD::MemIndexedMode getAddressingMode() const {
- return ISD::MemIndexedMode(SubclassData & 7);
+ return ISD::MemIndexedMode((SubclassData >> 2) & 7);
}
/// isIndexed - Return true if this is a pre/post inc/dec load/store.
class LoadSDNode : public LSBaseSDNode {
protected:
friend class SelectionDAG;
- LoadSDNode(SDValue *ChainPtrOff, SDVTList VTs,
+ LoadSDNode(SDValue *ChainPtrOff, DebugLoc dl, SDVTList VTs,
ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT LVT,
const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
- : LSBaseSDNode(ISD::LOAD, ChainPtrOff, 3,
+ : LSBaseSDNode(ISD::LOAD, dl, ChainPtrOff, 3,
VTs, AM, LVT, SV, O, Align, Vol) {
- SubclassData |= (unsigned short)ETy << 3;
+ SubclassData |= (unsigned short)ETy;
+ assert(getExtensionType() == ETy && "LoadExtType encoding error!");
}
public:
/// getExtensionType - Return whether this is a plain node,
/// or one of the varieties of value-extending loads.
ISD::LoadExtType getExtensionType() const {
- return ISD::LoadExtType((SubclassData >> 3) & 3);
+ return ISD::LoadExtType(SubclassData & 3);
}
const SDValue &getBasePtr() const { return getOperand(1); }
const SDValue &getOffset() const { return getOperand(2); }
-
+
static bool classof(const LoadSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::LOAD;
class StoreSDNode : public LSBaseSDNode {
protected:
friend class SelectionDAG;
- StoreSDNode(SDValue *ChainValuePtrOff, SDVTList VTs,
+ StoreSDNode(SDValue *ChainValuePtrOff, DebugLoc dl, SDVTList VTs,
ISD::MemIndexedMode AM, bool isTrunc, MVT SVT,
const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
- : LSBaseSDNode(ISD::STORE, ChainValuePtrOff, 4,
+ : LSBaseSDNode(ISD::STORE, dl, ChainValuePtrOff, 4,
VTs, AM, SVT, SV, O, Align, Vol) {
- SubclassData |= (unsigned short)isTrunc << 3;
+ SubclassData |= (unsigned short)isTrunc;
+ assert(isTruncatingStore() == isTrunc && "isTrunc encoding error!");
}
public:
/// isTruncatingStore - Return true if the op does a truncation before store.
/// For integers this is the same as doing a TRUNCATE and storing the result.
/// For floats, it is the same as doing an FP_ROUND and storing the result.
- bool isTruncatingStore() const { return (SubclassData >> 3) & 1; }
+ bool isTruncatingStore() const { return SubclassData & 1; }
const SDValue &getValue() const { return getOperand(1); }
const SDValue &getBasePtr() const { return getOperand(2); }
const SDValue &getOffset() const { return getOperand(3); }
-
+
static bool classof(const StoreSDNode *) { return true; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::STORE;