mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9903 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			371 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			371 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===-- llvm/CodeGen/SelectionDAG.h - InstSelection DAG Rep. ----*- C++ -*-===//
 | |
| // 
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file was developed by the LLVM research group and is distributed under
 | |
| // the University of Illinois Open Source License. See LICENSE.TXT for details.
 | |
| // 
 | |
| //===----------------------------------------------------------------------===//
 | |
| // 
 | |
| // 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>
 | |
| #include <cassert>
 | |
| 
 | |
| namespace llvm {
 | |
| 
 | |
| class Value;
 | |
| class Type;
 | |
| class Instruction;
 | |
| class CallInst;
 | |
| 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, BasicBlock,
 | |
| 
 | |
|     // Simple binary arithmetic operators
 | |
|     Plus, Minus, Times, SDiv, UDiv, SRem, URem,
 | |
| 
 | |
|     // Bitwise operators
 | |
|     And, Or, Xor,
 | |
| 
 | |
|     // Comparisons
 | |
|     SetEQ, SetNE, SetLT, SetLE, SetGT, SetGE,
 | |
| 
 | |
|     // Control flow instructions
 | |
|     Br, BrCond, Switch, Ret, RetVoid,
 | |
| 
 | |
|     // Other operators
 | |
|     Load, Store, PHI, Call,
 | |
| 
 | |
|     // Unknown operators, of a specified arity
 | |
|     Unspec1, Unspec2
 | |
|   };
 | |
| }
 | |
| 
 | |
| 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(ISD::NodeType NT, MVT::ValueType VT, MachineBasicBlock *bb,
 | |
|                    SelectionDAGNode *N1, SelectionDAGNode *N2,
 | |
|                    SelectionDAGNode *N3)
 | |
|     : NodeType(NT), ValueType(VT), BB(bb), ValList(0), Costs(0) {
 | |
|     assert(NT != ISD::ProtoNode && "Cannot specify uses for a protonode!");
 | |
|     Uses.reserve(3); Uses.push_back(N1); Uses.push_back(N2); Uses.push_back(N3);
 | |
|   }
 | |
| 
 | |
|   ~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) = 0;
 | |
| 
 | |
|   /// expandCall - This method is called once per function call by the
 | |
|   /// SelectionDAG construction algorithm.  It must add DAG nodes to the
 | |
|   /// SelectionDAG specified to perform that call.
 | |
|   virtual void expandCall(SelectionDAG &SD, CallInst &CI) = 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,
 | |
|     BasicBlock_i32_Slot,
 | |
|     BasicBlock_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<MachineBasicBlock*, ISD::BasicBlock_i32_Slot > ReducedValue_BasicBlock_i32;
 | |
| typedef ReducedValue<MachineBasicBlock*, ISD::BasicBlock_i64_Slot > ReducedValue_BasicBlock_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;
 | |
| 
 | |
| } // End llvm namespace
 | |
| 
 | |
| #endif
 |