#include "llvm/ADT/ilist.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
-
+#include "llvm/Target/TargetMachine.h"
#include <cassert>
#include <vector>
#include <map>
class AliasAnalysis;
class TargetLowering;
-class TargetMachine;
class MachineModuleInfo;
class DwarfWriter;
class MachineFunction;
template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
private:
- mutable SDNode Sentinel;
+ mutable ilist_node<SDNode> Sentinel;
public:
- ilist_traits() : Sentinel(ISD::DELETED_NODE, SDVTList()) {}
-
SDNode *createSentinel() const {
- return &Sentinel;
+ return static_cast<SDNode*>(&Sentinel);
}
static void destroySentinel(SDNode *) {}
+ SDNode *provideInitialHead() const { return createSentinel(); }
+ SDNode *ensureHead(SDNode*) const { return createSentinel(); }
+ static void noteHead(SDNode*, SDNode*) {}
+
static void deleteNode(SDNode *) {
assert(0 && "ilist_traits<SDNode> shouldn't see a deleteNode call!");
}
/// setGraphColorHelper - Implementation of setSubgraphColor.
/// Return whether we had to truncate the search.
///
- bool setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet<SDNode *> &visited,
+ bool setSubgraphColorHelper(SDNode *N, const char *Color,
+ DenseSet<SDNode *> &visited,
int level, bool &printed);
public:
///
void viewGraph(const std::string &Title);
void viewGraph();
-
+
#ifndef NDEBUG
std::map<const SDNode *, std::string> NodeGraphAttrs;
#endif
/// clearGraphAttrs - Clear all previously defined node graph attributes.
/// Intended to be used from a debugging tool (eg. gdb).
void clearGraphAttrs();
-
+
/// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
///
void setGraphAttrs(const SDNode *N, const char *Attrs);
-
+
/// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
/// Used from getNodeAttributes.
const std::string getGraphAttrs(const SDNode *N) const;
-
+
/// setGraphColor - Convenience for setting node color attribute.
///
void setGraphColor(const SDNode *N, const char *Color);
ilist<SDNode>::size_type allnodes_size() const {
return AllNodes.size();
}
-
+
/// getRoot - Return the root tag of the SelectionDAG.
///
const SDValue &getRoot() const { return Root; }
/// certain types of nodes together, or eliminating superfluous nodes. The
/// Level argument controls whether Combine is allowed to produce nodes and
/// types that are illegal on the target.
- void Combine(CombineLevel Level, AliasAnalysis &AA, bool Fast);
+ void Combine(CombineLevel Level, AliasAnalysis &AA,
+ CodeGenOpt::Level OptLevel);
/// LegalizeTypes - This transforms the SelectionDAG into a SelectionDAG that
/// only uses types natively supported by the target. Returns "true" if it
///
/// Note that this is an involved process that may invalidate pointers into
/// the graph.
- void Legalize(bool TypesNeedLegalizing);
+ void Legalize(bool TypesNeedLegalizing, CodeGenOpt::Level OptLevel);
+
+ /// LegalizeVectors - This transforms the SelectionDAG into a SelectionDAG
+ /// that only uses vector math operations supported by the target. This is
+ /// necessary as a separate step from Legalize because unrolling a vector
+ /// operation can introduce illegal types, which requires running
+ /// LegalizeTypes again.
+ ///
+ /// This returns true if it made any changes; in that case, LegalizeTypes
+ /// is called again before Legalize.
+ ///
+ /// Note that this is an involved process that may invalidate pointers into
+ /// the graph.
+ bool LegalizeVectors();
/// RemoveDeadNodes - This method deletes all unreachable nodes in the
/// SelectionDAG.
SDVTList getVTList(MVT VT1, MVT VT2, MVT VT3);
SDVTList getVTList(MVT VT1, MVT VT2, MVT VT3, MVT VT4);
SDVTList getVTList(const MVT *VTs, unsigned NumVTs);
-
- /// getNodeValueTypes - These are obsolete, use getVTList instead.
- const MVT *getNodeValueTypes(MVT VT) {
- return getVTList(VT).VTs;
- }
- const MVT *getNodeValueTypes(MVT VT1, MVT VT2) {
- return getVTList(VT1, VT2).VTs;
- }
- const MVT *getNodeValueTypes(MVT VT1, MVT VT2, MVT VT3) {
- return getVTList(VT1, VT2, VT3).VTs;
- }
- const MVT *getNodeValueTypes(MVT VT1, MVT VT2, MVT VT3, MVT VT4) {
- return getVTList(VT1, VT2, VT3, VT4).VTs;
- }
- const MVT *getNodeValueTypes(const std::vector<MVT> &vtList) {
- return getVTList(&vtList[0], (unsigned)vtList.size()).VTs;
- }
-
-
+
//===--------------------------------------------------------------------===//
// Node creation methods.
//
return getConstantFP(Val, VT, true);
}
SDValue getGlobalAddress(const GlobalValue *GV, MVT VT,
- int64_t offset = 0, bool isTargetGA = false);
+ int64_t offset = 0, bool isTargetGA = false,
+ unsigned char TargetFlags = 0);
SDValue getTargetGlobalAddress(const GlobalValue *GV, MVT VT,
- int64_t offset = 0) {
- return getGlobalAddress(GV, VT, offset, true);
+ int64_t offset = 0,
+ unsigned char TargetFlags = 0) {
+ return getGlobalAddress(GV, VT, offset, true, TargetFlags);
}
SDValue getFrameIndex(int FI, MVT VT, bool isTarget = false);
SDValue getTargetFrameIndex(int FI, MVT VT) {
return getFrameIndex(FI, VT, true);
}
- SDValue getJumpTable(int JTI, MVT VT, bool isTarget = false);
- SDValue getTargetJumpTable(int JTI, MVT VT) {
- return getJumpTable(JTI, VT, true);
+ SDValue getJumpTable(int JTI, MVT VT, bool isTarget = false,
+ unsigned char TargetFlags = 0);
+ SDValue getTargetJumpTable(int JTI, MVT VT, unsigned char TargetFlags = 0) {
+ return getJumpTable(JTI, VT, true, TargetFlags);
}
SDValue getConstantPool(Constant *C, MVT VT,
- unsigned Align = 0, int Offs = 0, bool isT=false);
+ unsigned Align = 0, int Offs = 0, bool isT=false,
+ unsigned char TargetFlags = 0);
SDValue getTargetConstantPool(Constant *C, MVT VT,
- unsigned Align = 0, int Offset = 0) {
- return getConstantPool(C, VT, Align, Offset, true);
+ unsigned Align = 0, int Offset = 0,
+ unsigned char TargetFlags = 0) {
+ return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
}
SDValue getConstantPool(MachineConstantPoolValue *C, MVT VT,
- unsigned Align = 0, int Offs = 0, bool isT=false);
+ unsigned Align = 0, int Offs = 0, bool isT=false,
+ unsigned char TargetFlags = 0);
SDValue getTargetConstantPool(MachineConstantPoolValue *C,
MVT VT, unsigned Align = 0,
- int Offset = 0) {
- return getConstantPool(C, VT, Align, Offset, true);
+ int Offset = 0, unsigned char TargetFlags=0) {
+ return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
}
// When generating a branch to a BB, we don't in general know enough
// to provide debug info for the BB at that time, so keep this one around.
SDValue getBasicBlock(MachineBasicBlock *MBB, DebugLoc dl);
SDValue getExternalSymbol(const char *Sym, MVT VT);
SDValue getExternalSymbol(const char *Sym, DebugLoc dl, MVT VT);
- SDValue getTargetExternalSymbol(const char *Sym, MVT VT);
- SDValue getTargetExternalSymbol(const char *Sym, DebugLoc dl, MVT VT);
+ SDValue getTargetExternalSymbol(const char *Sym, MVT VT,
+ unsigned char TargetFlags = 0);
SDValue getArgFlags(ISD::ArgFlagsTy Flags);
SDValue getValueType(MVT);
SDValue getRegister(unsigned Reg, MVT VT);
- SDValue getDbgStopPoint(SDValue Root, unsigned Line, unsigned Col,
- Value *CU);
- SDValue getLabel(unsigned Opcode, DebugLoc dl, SDValue Root,
+ SDValue getDbgStopPoint(DebugLoc DL, SDValue Root,
+ unsigned Line, unsigned Col, Value *CU);
+ SDValue getLabel(unsigned Opcode, DebugLoc dl, SDValue Root,
unsigned LabelID);
SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) {
// indicates that there is potentially an incoming flag value (if Flag is not
// null) and that there should be a flag result.
SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N,
- SDValue Flag) {
- const MVT *VTs = getNodeValueTypes(MVT::Other, MVT::Flag);
+ SDValue Flag) {
+ SDVTList VTs = getVTList(MVT::Other, MVT::Flag);
SDValue Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Flag };
- return getNode(ISD::CopyToReg, dl, VTs, 2, Ops, Flag.getNode() ? 4 : 3);
+ return getNode(ISD::CopyToReg, dl, VTs, Ops, Flag.getNode() ? 4 : 3);
}
// Similar to last getCopyToReg() except parameter Reg is a SDValue
SDValue getCopyToReg(SDValue Chain, DebugLoc dl, SDValue Reg, SDValue N,
SDValue Flag) {
- const MVT *VTs = getNodeValueTypes(MVT::Other, MVT::Flag);
+ SDVTList VTs = getVTList(MVT::Other, MVT::Flag);
SDValue Ops[] = { Chain, Reg, N, Flag };
- return getNode(ISD::CopyToReg, dl, VTs, 2, Ops, Flag.getNode() ? 4 : 3);
+ return getNode(ISD::CopyToReg, dl, VTs, Ops, Flag.getNode() ? 4 : 3);
}
-
+
SDValue getCopyFromReg(SDValue Chain, DebugLoc dl, unsigned Reg, MVT VT) {
- const MVT *VTs = getNodeValueTypes(VT, MVT::Other);
+ SDVTList VTs = getVTList(VT, MVT::Other);
SDValue Ops[] = { Chain, getRegister(Reg, VT) };
- return getNode(ISD::CopyFromReg, dl, VTs, 2, Ops, 2);
+ return getNode(ISD::CopyFromReg, dl, VTs, Ops, 2);
}
-
+
// This version of the getCopyFromReg method takes an extra operand, which
// indicates that there is potentially an incoming flag value (if Flag is not
// null) and that there should be a flag result.
SDValue getCopyFromReg(SDValue Chain, DebugLoc dl, unsigned Reg, MVT VT,
SDValue Flag) {
- const MVT *VTs = getNodeValueTypes(VT, MVT::Other, MVT::Flag);
+ SDVTList VTs = getVTList(VT, MVT::Other, MVT::Flag);
SDValue Ops[] = { Chain, getRegister(Reg, VT), Flag };
- return getNode(ISD::CopyFromReg, dl, VTs, 3, Ops, Flag.getNode() ? 3 : 2);
+ return getNode(ISD::CopyFromReg, dl, VTs, Ops, Flag.getNode() ? 3 : 2);
}
SDValue getCondCode(ISD::CondCode Cond);
SDValue getConvertRndSat(MVT VT, DebugLoc dl, SDValue Val, SDValue DTy,
SDValue STy,
SDValue Rnd, SDValue Sat, ISD::CvtCode Code);
+
+ /// getVectorShuffle - 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. A integer mask element equal to -1 is treated as
+ /// undefined.
+ SDValue getVectorShuffle(MVT VT, DebugLoc dl, SDValue N1, SDValue N2,
+ const int *MaskElts);
/// getZeroExtendInReg - Return the expression required to zero extend the Op
/// value assuming it was the smaller SrcTy value.
SDValue getZeroExtendInReg(SDValue Op, DebugLoc DL, MVT SrcTy);
-
+
/// getNOT - Create a bitwise NOT operation as (XOR Val, -1).
SDValue getNOT(DebugLoc DL, SDValue Val, MVT VT);
/// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have
- /// a flag result (to ensure it's not CSE'd).
+ /// a flag result (to ensure it's not CSE'd). CALLSEQ_START does not have a
+ /// useful DebugLoc.
SDValue getCALLSEQ_START(SDValue Chain, SDValue Op) {
- const MVT *VTs = getNodeValueTypes(MVT::Other, MVT::Flag);
+ SDVTList VTs = getVTList(MVT::Other, MVT::Flag);
SDValue Ops[] = { Chain, Op };
- return getNode(ISD::CALLSEQ_START, VTs, 2, Ops, 2);
+ return getNode(ISD::CALLSEQ_START, DebugLoc::getUnknownLoc(),
+ VTs, Ops, 2);
}
/// getCALLSEQ_END - Return a new CALLSEQ_END node, which always must have a
- /// flag result (to ensure it's not CSE'd).
+ /// flag result (to ensure it's not CSE'd). CALLSEQ_END does not have
+ /// a useful DebugLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2,
SDValue InFlag) {
SDVTList NodeTys = getVTList(MVT::Other, MVT::Flag);
Ops.push_back(Op1);
Ops.push_back(Op2);
Ops.push_back(InFlag);
- return getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0],
+ return getNode(ISD::CALLSEQ_END, DebugLoc::getUnknownLoc(), NodeTys,
+ &Ops[0],
(unsigned)Ops.size() - (InFlag.getNode() == 0 ? 1 : 0));
}
+ /// getUNDEF - Return an UNDEF node. UNDEF does not have a useful DebugLoc.
+ SDValue getUNDEF(MVT VT) {
+ return getNode(ISD::UNDEF, DebugLoc::getUnknownLoc(), VT);
+ }
+
+ /// getGLOBAL_OFFSET_TABLE - Return a GLOBAL_OFFSET_TABLE node. This does
+ /// not have a useful DebugLoc.
+ SDValue getGLOBAL_OFFSET_TABLE(MVT VT) {
+ return getNode(ISD::GLOBAL_OFFSET_TABLE, DebugLoc::getUnknownLoc(), VT);
+ }
+
/// getNode - Gets or creates the specified node.
///
- SDValue getNode(unsigned Opcode, MVT VT);
SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT);
- SDValue getNode(unsigned Opcode, MVT VT, SDValue N);
SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT, SDValue N);
- SDValue getNode(unsigned Opcode, MVT VT, SDValue N1, SDValue N2);
SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT, SDValue N1, SDValue N2);
- SDValue getNode(unsigned Opcode, MVT VT,
- SDValue N1, SDValue N2, SDValue N3);
SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
SDValue N1, SDValue N2, SDValue N3);
- SDValue getNode(unsigned Opcode, MVT VT,
- SDValue N1, SDValue N2, SDValue N3, SDValue N4);
SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
SDValue N1, SDValue N2, SDValue N3, SDValue N4);
- SDValue getNode(unsigned Opcode, MVT VT,
- SDValue N1, SDValue N2, SDValue N3, SDValue N4,
- SDValue N5);
SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
SDValue N1, SDValue N2, SDValue N3, SDValue N4,
SDValue N5);
- SDValue getNode(unsigned Opcode, MVT VT,
- const SDUse *Ops, unsigned NumOps);
SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
const SDUse *Ops, unsigned NumOps);
SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
SDValue getNode(unsigned Opcode, DebugLoc DL,
const std::vector<MVT> &ResultTys,
const SDValue *Ops, unsigned NumOps);
- SDValue getNode(unsigned Opcode, const MVT *VTs, unsigned NumVTs,
- const SDValue *Ops, unsigned NumOps);
SDValue getNode(unsigned Opcode, DebugLoc DL, const MVT *VTs, unsigned NumVTs,
const SDValue *Ops, unsigned NumOps);
- SDValue getNode(unsigned Opcode, SDVTList VTs,
- const SDValue *Ops, unsigned NumOps);
SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
const SDValue *Ops, unsigned NumOps);
-
SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs);
SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, SDValue N);
SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
return getNode(ISD::SELECT_CC, DL, True.getValueType(),
LHS, RHS, True, False, getCondCode(Cond));
}
-
+
/// getVAArg - VAArg produces a result and token chain, and takes a pointer
/// and a source value as input.
SDValue getVAArg(MVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr,
SDValue SV);
- /// getAtomic - Gets a node for an atomic op, produces result and chain and
+ /// getAtomic - Gets a node for an atomic op, produces result and chain and
/// takes 3 operands
- SDValue getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT, SDValue Chain,
+ SDValue getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Cmp, SDValue Swp, const Value* PtrVal,
unsigned Alignment=0);
///
SDValue getCall(unsigned CallingConv, DebugLoc dl, bool IsVarArgs,
bool IsTailCall, bool isInreg, SDVTList VTs,
- const SDValue *Operands, unsigned NumOperands);
+ const SDValue *Operands, unsigned NumOperands,
+ unsigned NumFixedArgs);
/// getLoad - Loads are not normal binary operators: their result type is not
/// determined by their operands, and they produce a value AND a token chain.
SDValue Op3, SDValue Op4, SDValue Op5);
SDValue UpdateNodeOperands(SDValue N,
const SDValue *Ops, unsigned NumOps);
-
+
/// SelectNodeTo - These are used for target selectors to *mutate* the
/// specified node to have the specified return type, Target opcode, and
/// operands. Note that target opcodes are stored as
/// Note that getTargetNode returns the resultant node. If there is already a
/// node of the specified opcode and operands, it returns that node instead of
/// the current one.
- SDNode *getTargetNode(unsigned Opcode, MVT VT);
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT);
-
- SDNode *getTargetNode(unsigned Opcode, MVT VT, SDValue Op1);
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT, SDValue Op1);
-
- SDNode *getTargetNode(unsigned Opcode, MVT VT, SDValue Op1, SDValue Op2);
- SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT, SDValue Op1,
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT, SDValue Op1,
SDValue Op2);
-
- SDNode *getTargetNode(unsigned Opcode, MVT VT,
- SDValue Op1, SDValue Op2, SDValue Op3);
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
SDValue Op1, SDValue Op2, SDValue Op3);
-
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
const SDValue *Ops, unsigned NumOps);
-
- SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2);
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2);
-
- SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, SDValue Op1);
- SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2,
+ SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2,
SDValue Op1);
-
- SDNode *getTargetNode(unsigned Opcode, MVT VT1,
- MVT VT2, SDValue Op1, SDValue Op2);
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
MVT VT2, SDValue Op1, SDValue Op2);
-
- SDNode *getTargetNode(unsigned Opcode, MVT VT1,
- MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
-
- SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2,
- const SDValue *Ops, unsigned NumOps);
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2,
const SDValue *Ops, unsigned NumOps);
-
- SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
- SDValue Op1, SDValue Op2);
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
SDValue Op1, SDValue Op2);
-
- SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
- SDValue Op1, SDValue Op2, SDValue Op3);
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
SDValue Op1, SDValue Op2, SDValue Op3);
-
- SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
- const SDValue *Ops, unsigned NumOps);
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
const SDValue *Ops, unsigned NumOps);
-
- SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3, MVT VT4,
- const SDValue *Ops, unsigned NumOps);
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
MVT VT4, const SDValue *Ops, unsigned NumOps);
-
- SDNode *getTargetNode(unsigned Opcode, const std::vector<MVT> &ResultTys,
- const SDValue *Ops, unsigned NumOps);
SDNode *getTargetNode(unsigned Opcode, DebugLoc dl,
const std::vector<MVT> &ResultTys, const SDValue *Ops,
unsigned NumOps);
/// else return NULL.
SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTs,
const SDValue *Ops, unsigned NumOps);
-
+
/// DAGUpdateListener - Clients of various APIs that cause global effects on
/// the DAG can optionally implement this interface. This allows the clients
/// to handle the various sorts of updates that happen.
/// NodeUpdated - The node N that was updated.
virtual void NodeUpdated(SDNode *N) = 0;
};
-
+
/// RemoveDeadNode - Remove the specified node from the system. If any of its
/// operands then becomes dead, remove them as well. Inform UpdateListener
/// for each node deleted.
void RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener = 0);
-
+
/// RemoveDeadNodes - This method deletes the unreachable nodes in the
/// given list, and any nodes that become unreachable as a result.
void RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes,
/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
/// This can cause recursive merging of nodes in the DAG. Use the first
/// version if 'From' is known to have a single result, use the second
- /// if you have two nodes with identical results, use the third otherwise.
+ /// if you have two nodes with identical results (or if 'To' has a superset
+ /// of the results of 'From'), use the third otherwise.
///
- /// These methods all take an optional UpdateListener, which (if not null) is
+ /// These methods all take an optional UpdateListener, which (if not null) is
/// informed about nodes that are deleted and modified due to recursive
/// changes in the dag.
///
case ISD::AND:
case ISD::OR:
case ISD::XOR:
- case ISD::ADDC:
+ case ISD::SADDO:
+ case ISD::UADDO:
+ case ISD::ADDC:
case ISD::ADDE: return true;
default: return false;
}
/// either of the specified value types.
SDValue CreateStackTemporary(MVT VT1, MVT VT2);
- /// FoldConstantArithmetic -
+ /// FoldConstantArithmetic -
SDValue FoldConstantArithmetic(unsigned Opcode,
MVT VT,
ConstantSDNode *Cst1,
/// FoldSetCC - Constant fold a setcc to true or false.
SDValue FoldSetCC(MVT VT, SDValue N1,
SDValue N2, ISD::CondCode Cond, DebugLoc dl);
-
+
/// SignBitIsZero - Return true if the sign bit of Op is known to be zero. We
/// use this predicate to simplify operations downstream.
bool SignBitIsZero(SDValue Op, unsigned Depth = 0) const;
/// known to be the same type.
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth = 0)
const;
-
+
/// ComputeMaskedBits - Determine which of the bits specified in Mask are
/// known to be either zero or one and return them in the KnownZero/KnownOne
/// bitsets. This code only analyzes bits in Mask, in order to short-circuit
- /// processing. Targets can implement the computeMaskedBitsForTargetNode
+ /// processing. Targets can implement the computeMaskedBitsForTargetNode
/// method in the TargetLowering class to allow target nodes to be understood.
void ComputeMaskedBits(SDValue Op, const APInt &Mask, APInt &KnownZero,
APInt &KnownOne, unsigned Depth = 0) const;
/// getShuffleScalarElt - Returns the scalar element that will make up the ith
/// element of the result of the vector shuffle.
- SDValue getShuffleScalarElt(const SDNode *N, unsigned Idx);
-
+ SDValue getShuffleScalarElt(const ShuffleVectorSDNode *N, unsigned Idx);
+
private:
bool RemoveNodeFromCSEMaps(SDNode *N);
void AddModifiedNodeToCSEMaps(SDNode *N, DAGUpdateListener *UpdateListener);
unsigned getMVTAlignment(MVT MemoryVT) const;
void allnodes_clear();
-
+
/// VTList - List of non-single value types.
std::vector<SDVTList> VTList;
-
+
/// CondCodeNodes - Maps to auto-CSE operations.
std::vector<CondCodeSDNode*> CondCodeNodes;
std::vector<SDNode*> ValueTypeNodes;
std::map<MVT, SDNode*, MVT::compareRawBits> ExtendedValueTypeNodes;
StringMap<SDNode*> ExternalSymbols;
- StringMap<SDNode*> TargetExternalSymbols;
+
+ std::map<std::pair<std::string, unsigned char>,SDNode*> TargetExternalSymbols;
};
template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> {