static void noteHead(SDNode*, SDNode*) {}
static void deleteNode(SDNode *) {
- assert(0 && "ilist_traits<SDNode> shouldn't see a deleteNode call!");
+ llvm_unreachable("ilist_traits<SDNode> shouldn't see a deleteNode call!");
}
private:
static void createNode(const SDNode &);
return DbgValues.empty() && ByvalParmDbgValues.empty();
}
- SmallVector<SDDbgValue*,2> &getSDDbgValues(const SDNode *Node) {
- return DbgValMap[Node];
- }
-
- void removeSDDbgValues(const SDNode *Node) {
- DbgValMap.erase(Node);
+ ArrayRef<SDDbgValue*> getSDDbgValues(const SDNode *Node) {
+ DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> >::iterator I =
+ DbgValMap.find(Node);
+ if (I != DbgValMap.end())
+ return I->second;
+ return ArrayRef<SDDbgValue*>();
}
typedef SmallVector<SDDbgValue*,32>::iterator DbgIterator;
};
enum CombineLevel {
- Unrestricted, // Combine may create illegal operations and illegal types.
- NoIllegalTypes, // Combine may create illegal operations but no illegal types.
- NoIllegalOperations // Combine may only create legal operations and types.
+ BeforeLegalizeTypes,
+ AfterLegalizeTypes,
+ AfterLegalizeVectorOps,
+ AfterLegalizeDAG
};
class SelectionDAG;
const TargetSelectionDAGInfo &TSI;
MachineFunction *MF;
LLVMContext *Context;
+ CodeGenOpt::Level OptLevel;
/// EntryNode - The starting token.
SDNode EntryNode;
/// DbgInfo - Tracks dbg_value information through SDISel.
SDDbgInfo *DbgInfo;
+public:
+ /// 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.
+ ///
+ /// A DAGUpdateListener automatically registers itself with DAG when it is
+ /// constructed, and removes itself when destroyed in RAII fashion.
+ struct DAGUpdateListener {
+ DAGUpdateListener *const Next;
+ SelectionDAG &DAG;
+
+ explicit DAGUpdateListener(SelectionDAG &D)
+ : Next(D.UpdateListeners), DAG(D) {
+ DAG.UpdateListeners = this;
+ }
+
+ virtual ~DAGUpdateListener() {
+ assert(DAG.UpdateListeners == this &&
+ "DAGUpdateListeners must be destroyed in LIFO order");
+ DAG.UpdateListeners = Next;
+ }
+
+ /// NodeDeleted - The node N that was deleted and, if E is not null, an
+ /// equivalent node E that replaced it.
+ virtual void NodeDeleted(SDNode *N, SDNode *E);
+
+ /// NodeUpdated - The node N that was updated.
+ virtual void NodeUpdated(SDNode *N);
+ };
+
+private:
+ /// DAGUpdateListener is a friend so it can manipulate the listener stack.
+ friend struct DAGUpdateListener;
+
+ /// UpdateListeners - Linked list of registered DAGUpdateListener instances.
+ /// This stack is maintained by DAGUpdateListener RAII.
+ DAGUpdateListener *UpdateListeners;
+
/// setGraphColorHelper - Implementation of setSubgraphColor.
/// Return whether we had to truncate the search.
///
SelectionDAG(const SelectionDAG&); // Do not implement.
public:
- explicit SelectionDAG(const TargetMachine &TM);
+ explicit SelectionDAG(const TargetMachine &TM, llvm::CodeGenOpt::Level);
~SelectionDAG();
/// init - Prepare this SelectionDAG to process code in the given
///
/// Note that this is an involved process that may invalidate pointers into
/// the graph.
- void Legalize(CodeGenOpt::Level OptLevel);
+ void Legalize();
/// LegalizeVectors - This transforms the SelectionDAG into a SelectionDAG
/// that only uses vector math operations supported by the target. This is
unsigned char TargetFlags = 0);
SDValue getValueType(EVT);
SDValue getRegister(unsigned Reg, EVT VT);
+ SDValue getRegisterMask(const uint32_t *RegMask);
SDValue getEHLabel(DebugLoc dl, SDValue Root, MCSymbol *Label);
SDValue getBlockAddress(const BlockAddress *BA, EVT VT,
bool isTarget = false, unsigned char TargetFlags = 0);
SDValue getConvertRndSat(EVT 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(EVT VT, DebugLoc dl, SDValue N1, SDValue N2,
+ SDValue getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1, SDValue N2,
const int *MaskElts);
+ /// getAnyExtOrTrunc - Convert Op, which must be of integer type, to the
+ /// integer type VT, by either any-extending or truncating it.
+ SDValue getAnyExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT);
+
/// getSExtOrTrunc - Convert Op, which must be of integer type, to the
/// integer type VT, by either sign-extending or truncating it.
SDValue getSExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT);
///
SDValue getSetCC(DebugLoc DL, EVT VT, SDValue LHS, SDValue RHS,
ISD::CondCode Cond) {
+ assert(LHS.getValueType().isVector() == RHS.getValueType().isVector() &&
+ "Cannot compare scalars to vectors");
+ assert(LHS.getValueType().isVector() == VT.isVector() &&
+ "Cannot compare scalars to vectors");
return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond));
}
- /// getVSetCC - Helper function to make it easier to build VSetCC's nodes
- /// if you just have an ISD::CondCode instead of an SDValue.
- ///
- SDValue getVSetCC(DebugLoc DL, EVT VT, SDValue LHS, SDValue RHS,
- ISD::CondCode Cond) {
- return getNode(ISD::VSETCC, DL, VT, LHS, RHS, getCondCode(Cond));
- }
-
/// getSelectCC - Helper function to make it easier to build SelectCC's if you
/// just have an ISD::CondCode instead of an SDValue.
///
/// takes 3 operands
SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Cmp, SDValue Swp,
- MachinePointerInfo PtrInfo, unsigned Alignment=0);
+ MachinePointerInfo PtrInfo, unsigned Alignment,
+ AtomicOrdering Ordering,
+ SynchronizationScope SynchScope);
SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Cmp, SDValue Swp,
- MachineMemOperand *MMO);
+ MachineMemOperand *MMO,
+ AtomicOrdering Ordering,
+ SynchronizationScope SynchScope);
- /// getAtomic - Gets a node for an atomic op, produces result and chain and
- /// takes 2 operands.
+ /// getAtomic - Gets a node for an atomic op, produces result (if relevant)
+ /// and chain and takes 2 operands.
SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain,
SDValue Ptr, SDValue Val, const Value* PtrVal,
- unsigned Alignment = 0);
+ unsigned Alignment, AtomicOrdering Ordering,
+ SynchronizationScope SynchScope);
SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain,
- SDValue Ptr, SDValue Val,
- MachineMemOperand *MMO);
+ SDValue Ptr, SDValue Val, MachineMemOperand *MMO,
+ AtomicOrdering Ordering,
+ SynchronizationScope SynchScope);
+
+ /// getAtomic - Gets a node for an atomic op, produces result and chain and
+ /// takes 1 operand.
+ SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, EVT VT,
+ SDValue Chain, SDValue Ptr, const Value* PtrVal,
+ unsigned Alignment,
+ AtomicOrdering Ordering,
+ SynchronizationScope SynchScope);
+ SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, EVT VT,
+ SDValue Chain, SDValue Ptr, MachineMemOperand *MMO,
+ AtomicOrdering Ordering,
+ SynchronizationScope SynchScope);
/// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a
/// result and takes a list of operands. Opcode may be INTRINSIC_VOID,
///
SDValue getLoad(EVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr,
MachinePointerInfo PtrInfo, bool isVolatile,
- bool isNonTemporal, unsigned Alignment,
- const MDNode *TBAAInfo = 0);
+ bool isNonTemporal, bool isInvariant, unsigned Alignment,
+ const MDNode *TBAAInfo = 0, const MDNode *Ranges = 0);
SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, EVT VT,
SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo,
EVT MemVT, bool isVolatile,
EVT VT, DebugLoc dl,
SDValue Chain, SDValue Ptr, SDValue Offset,
MachinePointerInfo PtrInfo, EVT MemVT,
- bool isVolatile, bool isNonTemporal, unsigned Alignment,
- const MDNode *TBAAInfo = 0);
+ bool isVolatile, bool isNonTemporal, bool isInvariant,
+ unsigned Alignment, const MDNode *TBAAInfo = 0,
+ const MDNode *Ranges = 0);
SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
EVT VT, DebugLoc dl,
SDValue Chain, SDValue Ptr, SDValue Offset,
/// getMDNode - Return an MDNodeSDNode which holds an MDNode.
SDValue getMDNode(const MDNode *MD);
-
+
/// getShiftAmountOperand - Return the specified value casted to
/// the target's desired shift amount type.
- SDValue getShiftAmountOperand(SDValue Op);
+ SDValue getShiftAmountOperand(EVT LHSTy, SDValue Op);
/// UpdateNodeOperands - *Mutate* the specified node in-place to have the
/// specified operands. If the resultant node already exists in the DAG,
SDDbgValue *getDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off,
DebugLoc DL, unsigned O);
- /// 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.
- class DAGUpdateListener {
- public:
- virtual ~DAGUpdateListener();
-
- /// NodeDeleted - The node N that was deleted and, if E is not null, an
- /// equivalent node E that replaced it.
- virtual void NodeDeleted(SDNode *N, SDNode *E) = 0;
-
- /// 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);
+ void RemoveDeadNode(SDNode *N);
/// 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,
- DAGUpdateListener *UpdateListener = 0);
+ 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
/// These functions only replace all existing uses. It's possible that as
/// these replacements are being performed, CSE may cause the From node
/// to be given new uses. These new uses of From are left in place, and
- /// not automatically transfered to To.
+ /// not automatically transferred to To.
///
- void ReplaceAllUsesWith(SDValue From, SDValue Op,
- DAGUpdateListener *UpdateListener = 0);
- void ReplaceAllUsesWith(SDNode *From, SDNode *To,
- DAGUpdateListener *UpdateListener = 0);
- void ReplaceAllUsesWith(SDNode *From, const SDValue *To,
- DAGUpdateListener *UpdateListener = 0);
+ void ReplaceAllUsesWith(SDValue From, SDValue Op);
+ void ReplaceAllUsesWith(SDNode *From, SDNode *To);
+ void ReplaceAllUsesWith(SDNode *From, const SDValue *To);
/// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving
/// uses of other values produced by From.Val alone.
- void ReplaceAllUsesOfValueWith(SDValue From, SDValue To,
- DAGUpdateListener *UpdateListener = 0);
+ void ReplaceAllUsesOfValueWith(SDValue From, SDValue To);
/// ReplaceAllUsesOfValuesWith - Like ReplaceAllUsesOfValueWith, but
/// for multiple values at once. This correctly handles the case where
/// there is an overlap between the From values and the To values.
void ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To,
- unsigned Num,
- DAGUpdateListener *UpdateListener = 0);
+ unsigned Num);
/// AssignTopologicalOrder - Topological-sort the AllNodes list and a
/// assign a unique node id for each node in the DAG based on their
void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter);
/// GetDbgValues - Get the debug values which reference the given SDNode.
- SmallVector<SDDbgValue*,2> &GetDbgValues(const SDNode* SD) {
+ ArrayRef<SDDbgValue*> GetDbgValues(const SDNode* SD) {
return DbgInfo->getSDDbgValues(SD);
}
-
+
/// TransferDbgValues - Transfer SDDbgValues.
void TransferDbgValues(SDValue From, SDValue To);
SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); }
SDDbgInfo::DbgIterator DbgEnd() { return DbgInfo->DbgEnd(); }
- SDDbgInfo::DbgIterator ByvalParmDbgBegin() {
- return DbgInfo->ByvalParmDbgBegin();
+ SDDbgInfo::DbgIterator ByvalParmDbgBegin() {
+ return DbgInfo->ByvalParmDbgBegin();
}
- SDDbgInfo::DbgIterator ByvalParmDbgEnd() {
- return DbgInfo->ByvalParmDbgEnd();
+ SDDbgInfo::DbgIterator ByvalParmDbgEnd() {
+ return DbgInfo->ByvalParmDbgEnd();
}
void dump() const;
/// bitsets. This code only analyzes bits in Mask, in order to short-circuit
/// 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;
+ void ComputeMaskedBits(SDValue Op, APInt &KnownZero, APInt &KnownOne,
+ unsigned Depth = 0) const;
/// ComputeNumSignBits - Return the number of times the sign bit of the
/// register is replicated into the other bits. We know that at least 1 bit
/// semantics as an ADD. This handles the equivalence:
/// X|Cst == X+Cst iff X&Cst = 0.
bool isBaseWithConstantOffset(SDValue Op) const;
-
+
/// isKnownNeverNan - Test whether the given SDValue is known to never be NaN.
bool isKnownNeverNaN(SDValue Op) const;
/// other positive zero.
bool isEqualTo(SDValue A, SDValue B) const;
- /// isVerifiedDebugInfoDesc - Returns true if the specified SDValue has
- /// been verified as a debug information descriptor.
- bool isVerifiedDebugInfoDesc(SDValue Op) const;
-
/// UnrollVectorOp - Utility function used by legalize and lowering to
/// "unroll" a vector operation by splitting out the scalars and operating
/// on each element individually. If the ResNE is 0, fully unroll the vector
/// vector op and fill the end of the resulting vector with UNDEFS.
SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0);
- /// isConsecutiveLoad - Return true if LD is loading 'Bytes' bytes from a
- /// location that is 'Dist' units away from the location that the 'Base' load
+ /// isConsecutiveLoad - 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;
private:
bool RemoveNodeFromCSEMaps(SDNode *N);
- void AddModifiedNodeToCSEMaps(SDNode *N, DAGUpdateListener *UpdateListener);
+ void AddModifiedNodeToCSEMaps(SDNode *N);
SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op, void *&InsertPos);
SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op1, SDValue Op2,
void *&InsertPos);
SDNode *FindModifiedNodeSlot(SDNode *N, const SDValue *Ops, unsigned NumOps,
void *&InsertPos);
+ SDNode *UpdadeDebugLocOnMergedSDNode(SDNode *N, DebugLoc loc);
void DeleteNodeNotInCSEMaps(SDNode *N);
void DeallocateNode(SDNode *N);
std::vector<SDNode*> ValueTypeNodes;
std::map<EVT, SDNode*, EVT::compareRawBits> ExtendedValueTypeNodes;
StringMap<SDNode*> ExternalSymbols;
-
+
std::map<std::pair<std::string, unsigned char>,SDNode*> TargetExternalSymbols;
};