[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