[llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h

Chris Lattner lattner at cs.uiuc.edu
Mon Aug 11 09:57:01 PDT 2003


Changes in directory llvm/include/llvm/CodeGen:

SelectionDAG.h added (r1.1)

---
Log message:

Initial checkin of SelectionDAG header file


---
Diffs of the changes:

Index: llvm/include/llvm/CodeGen/SelectionDAG.h
diff -c /dev/null llvm/include/llvm/CodeGen/SelectionDAG.h:1.1
*** /dev/null	Mon Aug 11 09:56:36 2003
--- llvm/include/llvm/CodeGen/SelectionDAG.h	Mon Aug 11 09:56:26 2003
***************
*** 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





More information about the llvm-commits mailing list