Initial support for carrying MachineInstrs in SUnits.
[oota-llvm.git] / include / llvm / CodeGen / SelectionDAG.h
index 3c1c031bd76ec0c809ca88cfe48aaf2912fd2116..62dc77af5245e69cfc67d7e4ad7a08cdf263e5a9 100644 (file)
 #define LLVM_CODEGEN_SELECTIONDAG_H
 
 #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 <cassert>
-#include <list>
 #include <vector>
 #include <map>
 #include <string>
@@ -36,14 +36,8 @@ class MachineFunction;
 class MachineConstantPoolValue;
 class FunctionLoweringInfo;
 
-/// NodeAllocatorType - The AllocatorType for allocating SDNodes. We use
-/// pool allocation with recycling.
-///
-typedef RecyclingAllocator<BumpPtrAllocator, SDNode, sizeof(LargestSDNode),
-                           AlignOf<MostAlignedSDNode>::Alignment>
-  NodeAllocatorType;
-
-template<> class ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
+template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
+private:
   mutable SDNode Sentinel;
 public:
   ilist_traits() : Sentinel(ISD::DELETED_NODE, SDVTList()) {}
@@ -73,25 +67,35 @@ private:
 ///
 class SelectionDAG {
   TargetLowering &TLI;
-  MachineFunction &MF;
+  MachineFunction *MF;
   FunctionLoweringInfo &FLI;
   MachineModuleInfo *MMI;
 
-  /// Root - The root of the entire DAG.  EntryNode - The starting token.
-  SDValue Root, EntryNode;
+  /// EntryNode - The starting token.
+  SDNode EntryNode;
+
+  /// Root - The root of the entire DAG.
+  SDValue Root;
 
   /// AllNodes - A linked list of nodes in the current DAG.
   ilist<SDNode> AllNodes;
 
-  /// NodeAllocator - Pool allocation for nodes. The allocator isn't
-  /// allocated inside this class because we want to reuse a single
-  /// recycler across multiple SelectionDAG runs.
-  NodeAllocatorType &NodeAllocator;
+  /// NodeAllocatorType - The AllocatorType for allocating SDNodes. We use
+  /// pool allocation with recycling.
+  typedef RecyclingAllocator<BumpPtrAllocator, SDNode, sizeof(LargestSDNode),
+                             AlignOf<MostAlignedSDNode>::Alignment>
+    NodeAllocatorType;
+
+  /// NodeAllocator - Pool allocation for nodes.
+  NodeAllocatorType NodeAllocator;
 
   /// CSEMap - This structure is used to memoize nodes, automatically performing
   /// CSE with existing nodes with a duplicate is requested.
   FoldingSet<SDNode> CSEMap;
 
+  /// OperandAllocator - Pool allocation for machine-opcode SDNode operands.
+  BumpPtrAllocator OperandAllocator;
+
   /// Allocator - Pool allocation for misc. objects that are created once per
   /// SelectionDAG.
   BumpPtrAllocator Allocator;
@@ -99,16 +103,27 @@ class SelectionDAG {
   /// VerifyNode - Sanity check the given node.  Aborts if it is invalid.
   void VerifyNode(SDNode *N);
 
+  /// setGraphColorHelper - Implementation of setSubgraphColor.
+  /// Return whether we had to truncate the search.
+  ///
+  bool setSubgraphColorHelper(SDNode *N, const char *Color, DenseSet<SDNode *> &visited,
+                              int level, bool &printed);
+
 public:
-  SelectionDAG(TargetLowering &tli, MachineFunction &mf, 
-               FunctionLoweringInfo &fli, MachineModuleInfo *mmi,
-               NodeAllocatorType &nodeallocator)
-  : TLI(tli), MF(mf), FLI(fli), MMI(mmi), NodeAllocator(nodeallocator) {
-    EntryNode = Root = getNode(ISD::EntryToken, MVT::Other);
-  }
+  SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli);
   ~SelectionDAG();
 
-  MachineFunction &getMachineFunction() const { return MF; }
+  /// init - Prepare this SelectionDAG to process code in the given
+  /// MachineFunction.
+  ///
+  void init(MachineFunction &mf, MachineModuleInfo *mmi);
+
+  /// clear - Clear state and free memory necessary to make this
+  /// SelectionDAG ready to process a new block.
+  ///
+  void clear();
+
+  MachineFunction &getMachineFunction() const { return *MF; }
   const TargetMachine &getTarget() const;
   TargetLowering &getTargetLoweringInfo() const { return TLI; }
   FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; }
@@ -139,6 +154,10 @@ public:
   ///
   void setGraphColor(const SDNode *N, const char *Color);
 
+  /// setGraphColor - Convenience for setting subgraph color attribute.
+  ///
+  void setSubgraphColor(SDNode *N, const char *Color);
+
   typedef ilist<SDNode>::const_iterator allnodes_const_iterator;
   allnodes_const_iterator allnodes_begin() const { return AllNodes.begin(); }
   allnodes_const_iterator allnodes_end() const { return AllNodes.end(); }
@@ -155,12 +174,14 @@ public:
 
   /// getEntryNode - Return the token chain corresponding to the entry of the
   /// function.
-  const SDValue &getEntryNode() const { return EntryNode; }
+  SDValue getEntryNode() const {
+    return SDValue(const_cast<SDNode *>(&EntryNode), 0);
+  }
 
   /// setRoot - Set the current root tag of the SelectionDAG.
   ///
   const SDValue &setRoot(SDValue N) {
-    assert((!N.Val || N.getValueType() == MVT::Other) &&
+    assert((!N.getNode() || N.getValueType() == MVT::Other) &&
            "DAG root value is not a chain!");
     return Root = N;
   }
@@ -169,7 +190,7 @@ public:
   /// certain types of nodes together, or eliminating superfluous nodes.  When
   /// the AfterLegalize argument is set to 'true', Combine takes care not to
   /// generate any nodes that will be illegal on the target.
-  void Combine(bool AfterLegalize, AliasAnalysis &AA);
+  void Combine(bool AfterLegalize, AliasAnalysis &AA, bool Fast);
   
   /// LegalizeTypes - This transforms the SelectionDAG into a SelectionDAG that
   /// only uses types natively supported by the target.
@@ -221,6 +242,7 @@ public:
   //
   SDValue getConstant(uint64_t Val, MVT VT, bool isTarget = false);
   SDValue getConstant(const APInt &Val, MVT VT, bool isTarget = false);
+  SDValue getConstant(const ConstantInt &Val, MVT VT, bool isTarget = false);
   SDValue getIntPtrConstant(uint64_t Val, bool isTarget = false);
   SDValue getTargetConstant(uint64_t Val, MVT VT) {
     return getConstant(Val, VT, true);
@@ -228,18 +250,25 @@ public:
   SDValue getTargetConstant(const APInt &Val, MVT VT) {
     return getConstant(Val, VT, true);
   }
+  SDValue getTargetConstant(const ConstantInt &Val, MVT VT) {
+    return getConstant(Val, VT, true);
+  }
   SDValue getConstantFP(double Val, MVT VT, bool isTarget = false);
   SDValue getConstantFP(const APFloat& Val, MVT VT, bool isTarget = false);
+  SDValue getConstantFP(const ConstantFP &CF, MVT VT, bool isTarget = false);
   SDValue getTargetConstantFP(double Val, MVT VT) {
     return getConstantFP(Val, VT, true);
   }
   SDValue getTargetConstantFP(const APFloat& Val, MVT VT) {
     return getConstantFP(Val, VT, true);
   }
+  SDValue getTargetConstantFP(const ConstantFP &Val, MVT VT) {
+    return getConstantFP(Val, VT, true);
+  }
   SDValue getGlobalAddress(const GlobalValue *GV, MVT VT,
-                             int offset = 0, bool isTargetGA = false);
+                           int64_t offset = 0, bool isTargetGA = false);
   SDValue getTargetGlobalAddress(const GlobalValue *GV, MVT VT,
-                                   int offset = 0) {
+                                 int64_t offset = 0) {
     return getGlobalAddress(GV, VT, offset, true);
   }
   SDValue getFrameIndex(int FI, MVT VT, bool isTarget = false);
@@ -285,7 +314,7 @@ public:
                          SDValue Flag) {
     const MVT *VTs = getNodeValueTypes(MVT::Other, MVT::Flag);
     SDValue Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Flag };
-    return getNode(ISD::CopyToReg, VTs, 2, Ops, Flag.Val ? 4 : 3);
+    return getNode(ISD::CopyToReg, VTs, 2, Ops, Flag.getNode() ? 4 : 3);
   }
 
   // Similar to last getCopyToReg() except parameter Reg is a SDValue
@@ -293,7 +322,7 @@ public:
                          SDValue Flag) {
     const MVT *VTs = getNodeValueTypes(MVT::Other, MVT::Flag);
     SDValue Ops[] = { Chain, Reg, N, Flag };
-    return getNode(ISD::CopyToReg, VTs, 2, Ops, Flag.Val ? 4 : 3);
+    return getNode(ISD::CopyToReg, VTs, 2, Ops, Flag.getNode() ? 4 : 3);
   }
   
   SDValue getCopyFromReg(SDValue Chain, unsigned Reg, MVT VT) {
@@ -309,11 +338,16 @@ public:
                            SDValue Flag) {
     const MVT *VTs = getNodeValueTypes(VT, MVT::Other, MVT::Flag);
     SDValue Ops[] = { Chain, getRegister(Reg, VT), Flag };
-    return getNode(ISD::CopyFromReg, VTs, 3, Ops, Flag.Val ? 3 : 2);
+    return getNode(ISD::CopyFromReg, VTs, 3, Ops, Flag.getNode() ? 3 : 2);
   }
 
   SDValue getCondCode(ISD::CondCode Cond);
 
+  /// Returns the ConvertRndSat Note: Avoid using this node because it may
+  /// disappear in the future and most targets don't support it.
+  SDValue getConvertRndSat(MVT VT, SDValue Val, SDValue DTy, SDValue STy,
+                           SDValue Rnd, SDValue Sat, ISD::CvtCode Code);
+
   /// getZeroExtendInReg - Return the expression required to zero extend the Op
   /// value assuming it was the smaller SrcTy value.
   SDValue getZeroExtendInReg(SDValue Op, MVT SrcTy);
@@ -337,7 +371,7 @@ public:
     Ops.push_back(Op2);
     Ops.push_back(InFlag);
     return getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0],
-                   (unsigned)Ops.size() - (InFlag.Val == 0 ? 1 : 0));
+                   (unsigned)Ops.size() - (InFlag.getNode() == 0 ? 1 : 0));
   }
 
   /// getNode - Gets or creates the specified node.
@@ -418,18 +452,33 @@ public:
   SDValue getVAArg(MVT VT, SDValue Chain, SDValue Ptr,
                      SDValue SV);
 
-  /// getAtomic - Gets a node for an atomic op, produces result and chain, takes
-  /// 3 operands
+  /// getAtomic - Gets a node for an atomic op, produces result and chain and 
+  /// takes 3 operands
   SDValue getAtomic(unsigned Opcode, SDValue Chain, SDValue Ptr, 
                       SDValue Cmp, SDValue Swp, const Value* PtrVal,
                       unsigned Alignment=0);
 
-  /// getAtomic - Gets a node for an atomic op, produces result and chain, takes
-  /// 2 operands
+  /// getAtomic - Gets a node for an atomic op, produces result and chain and
+  /// takes 2 operands.
   SDValue getAtomic(unsigned Opcode, SDValue Chain, SDValue Ptr, 
                       SDValue Val, const Value* PtrVal,
                       unsigned Alignment = 0);
 
+  /// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a
+  /// result and takes a list of operands.
+  SDValue getMemIntrinsicNode(unsigned Opcode,
+                              const MVT *VTs, unsigned NumVTs,
+                              const SDValue *Ops, unsigned NumOps,
+                              MVT MemVT, const Value *srcValue, int SVOff,
+                              unsigned Align = 0, bool Vol = false,
+                              bool ReadMem = true, bool WriteMem = true);
+
+  SDValue getMemIntrinsicNode(unsigned Opcode, SDVTList VTList,
+                              const SDValue *Ops, unsigned NumOps,
+                              MVT MemVT, const Value *srcValue, int SVOff,
+                              unsigned Align = 0, bool Vol = false,
+                              bool ReadMem = true, bool WriteMem = true);
+
   /// getMergeValues - Create a MERGE_VALUES node from the given operands.
   /// Allowed to return something different (and simpler) if Simplify is true.
   SDValue getMergeValues(const SDValue *Ops, unsigned NumOps,
@@ -445,6 +494,12 @@ public:
     return getNode(ISD::MERGE_VALUES, VTs, Ops, NumOps);
   }
 
+  /// getCall - Create a CALL node from the given information.
+  ///
+  SDValue getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall,
+                  bool isInreg, SDVTList VTs, const SDValue *Operands, 
+                  unsigned NumOperands);
+
   /// 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.
   ///
@@ -638,10 +693,17 @@ public:
                                   unsigned Num,
                                   DAGUpdateListener *UpdateListener = 0);
 
-  /// AssignTopologicalOrder - Assign a unique node id for each node in the DAG
-  /// based on their topological order. It returns the maximum id and a vector
-  /// of the SDNodes* in assigned order by reference.
-  unsigned AssignTopologicalOrder(std::vector<SDNode*> &TopOrder);
+  /// AssignTopologicalOrder - Topological-sort the AllNodes list and a
+  /// assign a unique node id for each node in the DAG based on their
+  /// topological order. Returns the number of nodes.
+  unsigned AssignTopologicalOrder();
+
+  /// RepositionNode - Move node N in the AllNodes list to be immediately
+  /// before the given iterator Position. This may be used to update the
+  /// topological ordering when the list of nodes is modified.
+  void RepositionNode(allnodes_iterator Position, SDNode *N) {
+    AllNodes.insert(Position, AllNodes.remove(N));
+  }
 
   /// isCommutativeBinOp - Returns true if the opcode is a commutative binary
   /// operation.
@@ -673,9 +735,15 @@ public:
   /// at least that alignment.
   SDValue CreateStackTemporary(MVT VT, unsigned minAlign = 1);
   
+  /// FoldConstantArithmetic - 
+  SDValue FoldConstantArithmetic(unsigned Opcode,
+                                 MVT VT,
+                                 ConstantSDNode *Cst1,
+                                 ConstantSDNode *Cst2);
+
   /// FoldSetCC - Constant fold a setcc to true or false.
   SDValue FoldSetCC(MVT VT, SDValue N1,
-                      SDValue N2, ISD::CondCode Cond);
+                    SDValue N2, ISD::CondCode Cond);
   
   /// SignBitIsZero - Return true if the sign bit of Op is known to be zero.  We
   /// use this predicate to simplify operations downstream.
@@ -713,7 +781,7 @@ public:
   SDValue getShuffleScalarElt(const SDNode *N, unsigned Idx);
   
 private:
-  void RemoveNodeFromCSEMaps(SDNode *N);
+  bool RemoveNodeFromCSEMaps(SDNode *N);
   SDNode *AddNonLeafNodeToCSEMaps(SDNode *N);
   SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op, void *&InsertPos);
   SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op1, SDValue Op2,
@@ -724,6 +792,8 @@ private:
   void DeleteNodeNotInCSEMaps(SDNode *N);
 
   unsigned getMVTAlignment(MVT MemoryVT) const;
+
+  void allnodes_clear();
   
   // List of non-single value types.
   std::vector<SDVTList> VTList;