Initial checkin of SelectionDAG header file
authorChris Lattner <sabre@nondot.org>
Mon, 11 Aug 2003 14:56:26 +0000 (14:56 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 11 Aug 2003 14:56:26 +0000 (14:56 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7716 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAG.h [new file with mode: 0644]

diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
new file mode 100644 (file)
index 0000000..eab8b7d
--- /dev/null
@@ -0,0 +1,334 @@
+//===-- llvm/CodeGen/SelectionDAG.h - InstSelection DAG Rep. ----*- C++ -*-===//
+// 
+// This file declares the SelectionDAG class, which is used to represent an LLVM
+// function in a low-level representation suitable for instruction selection.
+// This DAG is constructed as the first step of instruction selection in order
+// to allow implementation of machine specific optimizations and code
+// simplifications.
+//
+// The representation used by the SelectionDAG is a target-independent
+// representation, which is loosly modeled after the GCC RTL representation, but
+// is significantly simpler.
+//   
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SELECTIONDAG_H
+#define LLVM_CODEGEN_SELECTIONDAG_H
+
+#include "llvm/CodeGen/ValueTypes.h"
+#include "Support/DataTypes.h"
+#include <map>
+#include <vector>
+class Value;
+class Type;
+class Instruction;
+class BasicBlock;
+class MachineBasicBlock;
+class MachineFunction;
+class TargetMachine;
+class SelectionDAGNode;
+class SelectionDAGBlock;
+class SelectionDAGBuilder;
+class SelectionDAGTargetBuilder;
+
+/// ISD namespace - This namespace contains an enum which represents all of the
+/// SelectionDAG node types and value types.
+///
+namespace ISD {
+  enum NodeType {
+    // ChainNode nodes are used to sequence operations within a basic block
+    // which cannot be reordered (such as loads, stores, calls, etc).
+    // BlockChainNodes are used to connect the DAG's for different basic blocks
+    // into one big DAG.
+    ChainNode, BlockChainNode,
+
+    // ProtoNodes are nodes that are only half way constructed.
+    ProtoNode,
+
+    // Leaf nodes.
+    Constant, FrameIndex,
+
+    // Simple binary arithmetic operators
+    Plus, Minus, Times, SDiv, UDiv, SRem, URem,
+
+    // Bitwise operators
+    And, Or, Xor,
+
+    // Control flow instructions
+    Br, Switch, Ret, RetVoid,
+
+    // Other operators
+    Load, Store, PHI, Call,
+  };
+}
+
+class SelectionDAG {
+  friend class SelectionDAGBuilder;
+  MachineFunction &F;
+  const TargetMachine &TM;
+  MVT::ValueType PointerType;    // The ValueType the target uses for pointers
+
+  // ValueMap - The SelectionDAGNode for each LLVM value in the function.
+  std::map<const Value*, SelectionDAGNode*> ValueMap;
+
+  // BlockMap - The MachineBasicBlock created for each LLVM BasicBlock
+  std::map<const BasicBlock*, MachineBasicBlock*> BlockMap;
+
+  // Root - The root of the entire DAG
+  SelectionDAGNode *Root;
+
+  // AllNodes - All of the nodes in the DAG
+  std::vector<SelectionDAGNode*> AllNodes;
+public:
+  /// SelectionDAG constructor - Build a SelectionDAG for the specified
+  /// function.  Implemented in DAGBuilder.cpp
+  ///
+  SelectionDAG(MachineFunction &F, const TargetMachine &TM,
+               SelectionDAGTargetBuilder &SDTB);
+  ~SelectionDAG();
+
+  /// getValueType - Return the ValueType for the specified LLVM type.  This
+  /// method works on all scalar LLVM types.
+  ///
+  MVT::ValueType getValueType(const Type *Ty) const;
+
+  /// getRoot - Return the root of the current SelectionDAG.
+  ///
+  SelectionDAGNode *getRoot() const { return Root; }
+
+  /// getMachineFunction - Return the MachineFunction object that this
+  /// SelectionDAG corresponds to.
+  ///
+  MachineFunction &getMachineFunction() const { return F; }
+
+  //===--------------------------------------------------------------------===//
+  // Addition and updating methods
+  //
+
+  /// addNode - Add the specified node to the SelectionDAG so that it will be
+  /// deleted when the DAG is...
+  ///
+  SelectionDAGNode *addNode(SelectionDAGNode *N) {
+    AllNodes.push_back(N);
+    return N;
+  }
+
+  /// addNodeForValue - Add the specified node to the SelectionDAG so that it
+  /// will be deleted when the DAG is... and update the value map to indicate
+  /// that the specified DAG node computes the value.  Note that it is an error
+  /// to specify multiple DAG nodes that compute the same value.
+  ///
+  SelectionDAGNode *addNodeForValue(SelectionDAGNode *N, const Value *V) {
+    assert(ValueMap.count(V) == 0 && "Value already has a DAG node!");
+    return addNode(ValueMap[V] = N);
+  }
+
+  void dump() const;
+private:
+  void addInstructionToDAG(const Instruction &I, const BasicBlock &BB);
+};
+
+
+/// SelectionDAGReducedValue - During the reducer pass we need the ability to
+/// add an arbitrary (but usually 1 or 0) number of arbitrarily sized values to
+/// the selection DAG.  Because of this, we represent these values as a singly
+/// linked list of values attached to the DAGNode.  We end up putting the
+/// arbitrary state for the value in subclasses of this node.
+///
+/// Note that this class does not have a virtual dtor, this is because we know
+/// that the subclasses will not hold state that needs to be destroyed.
+///
+class SelectionDAGReducedValue {
+  unsigned Code;
+  SelectionDAGReducedValue *Next;
+public:
+  SelectionDAGReducedValue(unsigned C) : Code(C), Next(0) {}
+
+  /// getValueCode - Return the code for this reducer value...
+  ///
+  unsigned getValueCode() const { return Code; }
+  
+  /// getNext - Return the next value in the list
+  ///
+  const SelectionDAGReducedValue *getNext() const { return Next; }
+  void setNext(SelectionDAGReducedValue *N) { Next = N; }
+
+  SelectionDAGReducedValue *getNext() { return Next; }
+};
+
+
+
+/// SelectionDAGNode - Represents one node in the selection DAG.
+///
+class SelectionDAGNode {
+  std::vector<SelectionDAGNode*> Uses;
+  ISD::NodeType  NodeType;
+  MVT::ValueType ValueType;
+  MachineBasicBlock *BB;
+  SelectionDAGReducedValue *ValList;
+
+  /// Costs - Each pair of elements of 'Costs' contains the cost of producing
+  /// the value with the target specific slot number and the production number
+  /// to use to produce it.  A zero value for the production number indicates
+  /// that the cost has not yet been computed.
+  unsigned *Costs;
+public:
+  SelectionDAGNode(ISD::NodeType NT, MVT::ValueType VT,
+                   MachineBasicBlock *bb = 0) 
+    : NodeType(NT), ValueType(VT), BB(bb), ValList(0), Costs(0) {}
+
+  SelectionDAGNode(ISD::NodeType NT, MVT::ValueType VT, MachineBasicBlock *bb,
+                   SelectionDAGNode *N)
+    : NodeType(NT), ValueType(VT), BB(bb), ValList(0), Costs(0) {
+    assert(NT != ISD::ProtoNode && "Cannot specify uses for a protonode!");
+    Uses.reserve(1); Uses.push_back(N);
+  }
+  SelectionDAGNode(ISD::NodeType NT, MVT::ValueType VT, MachineBasicBlock *bb,
+                   SelectionDAGNode *N1, SelectionDAGNode *N2)
+    : NodeType(NT), ValueType(VT), BB(bb), ValList(0), Costs(0) {
+    assert(NT != ISD::ProtoNode && "Cannot specify uses for a protonode!");
+    Uses.reserve(2); Uses.push_back(N1); Uses.push_back(N2);
+  }
+
+  ~SelectionDAGNode() { delete [] Costs; delete ValList; }
+
+  void setNode(ISD::NodeType NT, MachineBasicBlock *bb) {
+    assert(NodeType == ISD::ProtoNode && NT != ISD::ProtoNode);
+    NodeType = NT; BB = bb;
+  }
+  void setNode(ISD::NodeType NT, MachineBasicBlock *bb, SelectionDAGNode *N) {
+    assert(NodeType == ISD::ProtoNode && NT != ISD::ProtoNode);
+    NodeType = NT; BB = bb; Uses.reserve(1); Uses.push_back(N);
+  }
+  void setNode(ISD::NodeType NT, MachineBasicBlock *bb, 
+               SelectionDAGNode *N1, SelectionDAGNode *N2) {
+    assert(NodeType == ISD::ProtoNode && NT != ISD::ProtoNode);
+    NodeType = NT; BB = bb;
+    Uses.reserve(1); Uses.push_back(N1); Uses.push_back(N2);
+  }
+
+  //===--------------------------------------------------------------------===//
+  //  Accessors
+  //
+  ISD::NodeType  getNodeType()  const { return NodeType; }
+  MVT::ValueType getValueType() const { return ValueType; }
+  MachineBasicBlock *getBB() const { return BB; }
+
+  SelectionDAGNode *getUse(unsigned Num) {
+    assert(Num < Uses.size() && "Invalid child # of SelectionDAGNode!");
+    return Uses[Num];
+  }
+
+  template<class Type>
+  Type *getValue(unsigned Code) const {
+    SelectionDAGReducedValue *Vals = ValList;
+    while (1) {
+      assert(Vals && "Code does not exist in this list!");
+      if (Vals->getValueCode() == Code)
+        return (Type*)Vals;
+      Vals = Vals->getNext();
+    }
+  }
+
+  template<class Type>
+  Type *hasValue(unsigned Code) const {
+    SelectionDAGReducedValue *Vals = ValList;
+    while (Vals) {
+      if (Vals->getValueCode() == Code)
+        return (Type*)Vals;
+      Vals = Vals->getNext();
+    }
+    return false;
+  }
+
+  void addValue(SelectionDAGReducedValue *New) {
+    assert(New->getNext() == 0);
+    New->setNext(ValList);
+    ValList = New;
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Utility methods used by the pattern matching instruction selector
+  //
+
+  /// getPatternFor - Return the pattern selected to compute the specified slot,
+  /// or zero if there is no pattern yet.
+  ///
+  unsigned getPatternFor(unsigned Slot) const {
+    return Costs ? Costs[Slot*2] : 0;
+  }
+
+  /// getCostFor - Return the cost to compute the value corresponding to Slot.
+  ///
+  unsigned getCostFor(unsigned Slot) const {
+    return Costs ? Costs[Slot*2+1] : 0;
+  }
+
+  /// setPatternCostFor - Sets the pattern and the cost for the specified slot
+  /// to the specified values.  This allocates the Costs vector if necessary, so
+  /// you must specify the maximum number of slots that may be used.
+  ///
+  void setPatternCostFor(unsigned Slot, unsigned Pattern, unsigned Cost,
+                         unsigned NumSlots) {
+    if (Costs == 0) {
+      Costs = new unsigned[NumSlots*2];
+      for (unsigned i = 0; i != NumSlots*2; ++i) Costs[i] = 0;
+    }
+    Costs[Slot*2] = Pattern;
+    Costs[Slot*2+1] = Cost;
+  }
+
+  void dump() const;
+private:
+  void printit(unsigned Offset, unsigned &LastID,
+               std::map<const SelectionDAGNode*, unsigned> &NodeIDs) const;
+};
+
+
+/// SelectionDAGTargetBuilder - This class must be implemented by the target, to
+/// indicate how to perform the extremely target-specific tasks of building DAG
+/// nodes to represent the calling convention used by the target.
+///
+struct SelectionDAGTargetBuilder {
+  /// expandArguments - This method is called once by the SelectionDAG
+  /// construction mechanisms to add DAG nodes for each formal argument to the
+  /// current function.  If any of the incoming arguments lives on the stack,
+  /// this method should also create the stack slots for the arguments as
+  /// necessary.
+  virtual void expandArguments(SelectionDAG &SD, MachineFunction &MF) = 0;
+};
+
+namespace ISD {
+  enum {   // Builtin Slot numbers
+    Constant_i1_Slot,
+    Constant_i8_Slot,
+    Constant_i16_Slot,
+    Constant_i32_Slot,
+    Constant_i64_Slot,
+    Constant_f32_Slot,
+    Constant_f64_Slot,
+
+    FrameIndex_i32_Slot,
+    FrameIndex_i64_Slot,
+    NumBuiltinSlots
+  };
+}
+
+template<typename ValType, unsigned NodeCode>
+struct ReducedValue : public SelectionDAGReducedValue {
+  ReducedValue(const ValType &V) : SelectionDAGReducedValue(NodeCode), Val(V) {}
+  ValType Val;
+};
+
+typedef ReducedValue<int, ISD::FrameIndex_i32_Slot > ReducedValue_FrameIndex_i32;
+typedef ReducedValue<int, ISD::FrameIndex_i64_Slot > ReducedValue_FrameIndex_i64;
+
+typedef ReducedValue<bool          , ISD::Constant_i1_Slot > ReducedValue_Constant_i1;
+typedef ReducedValue<unsigned char , ISD::Constant_i8_Slot > ReducedValue_Constant_i8;
+typedef ReducedValue<unsigned short, ISD::Constant_i16_Slot> ReducedValue_Constant_i16;
+typedef ReducedValue<unsigned      , ISD::Constant_i32_Slot> ReducedValue_Constant_i32;
+typedef ReducedValue<uint64_t      , ISD::Constant_i64_Slot> ReducedValue_Constant_i64;
+typedef ReducedValue<float         , ISD::Constant_f32_Slot> ReducedValue_Constant_f32;
+typedef ReducedValue<double        , ISD::Constant_f64_Slot> ReducedValue_Constant_f64;
+
+#endif