mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			288 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* $Id$ -*-c++-*-
 | |
|  ****************************************************************************
 | |
|  * File:
 | |
|  *	InstrForest.h
 | |
|  * 
 | |
|  * Purpose:
 | |
|  *	Convert SSA graph to instruction trees for instruction selection.
 | |
|  * 
 | |
|  * Strategy:
 | |
|  *  The basic idea is that we would like to group instructions into a single
 | |
|  *  tree if one or more of them might be potentially combined into a single
 | |
|  *  complex instruction in the target machine.
 | |
|  *  Since this grouping is completely machine-independent, it is as
 | |
|  *  aggressive as possible.  In particular, we group two instructions
 | |
|  *  O and I if:
 | |
|  *  (1) Instruction O computes an operand of instruction I, and
 | |
|  *  (2) O and I are part of the same basic block, and
 | |
|  *  (3) O has only a single use, viz., I.
 | |
|  * 
 | |
|  * History:
 | |
|  *	6/28/01	 -  Vikram Adve  -  Created
 | |
|  ***************************************************************************/
 | |
| 
 | |
| #ifndef LLVM_CODEGEN_INSTRFOREST_H
 | |
| #define LLVM_CODEGEN_INSTRFOREST_H
 | |
| 
 | |
| #include "llvm/Support/NonCopyable.h"
 | |
| #include "llvm/Instruction.h"
 | |
| #include <hash_map>
 | |
| #include <hash_set>
 | |
| 
 | |
| class ConstPoolVal;
 | |
| class BasicBlock;
 | |
| class Method;
 | |
| class InstrTreeNode;
 | |
| class InstrForest;
 | |
| 
 | |
| //--------------------------------------------------------------------------
 | |
| // OpLabel values for special-case nodes created for instruction selection.
 | |
| // All op-labels not defined here are identical to the instruction
 | |
| // opcode returned by Instruction::getInstType()
 | |
| //--------------------------------------------------------------------------
 | |
| 
 | |
| const int  InvalidOp	=  -1;
 | |
| const int  VRegListOp   =  97;
 | |
| const int  VRegNodeOp	=  98;
 | |
| const int  ConstantNodeOp= 99;
 | |
| const int  LabelNodeOp	= 100;
 | |
| 
 | |
| const int  RetValueOp	= 100 + Instruction::Ret;
 | |
| const int  BrCondOp	= 100 + Instruction::Br;
 | |
| 
 | |
| const int  SetCCOp	= 100 + Instruction::SetEQ;
 | |
| 
 | |
| const int  AllocaN	= 100 + Instruction::Alloca;		// 121
 | |
| const int  LoadIdx	= 100 + Instruction::Load;		// 122
 | |
| const int  GetElemPtrIdx= 100 + Instruction::GetElementPtr;	// 124
 | |
| 
 | |
| const int  ToBoolTy	= 100 + Instruction::Cast;		// 126
 | |
| const int  ToUByteTy	= ToBoolTy +  1;
 | |
| const int  ToSByteTy	= ToBoolTy +  2;
 | |
| const int  ToUShortTy	= ToBoolTy +  3;
 | |
| const int  ToShortTy	= ToBoolTy +  4;
 | |
| const int  ToUIntTy	= ToBoolTy +  5;
 | |
| const int  ToIntTy	= ToBoolTy +  6;
 | |
| const int  ToULongTy	= ToBoolTy +  7;
 | |
| const int  ToLongTy	= ToBoolTy +  8;
 | |
| const int  ToFloatTy	= ToBoolTy +  9;
 | |
| const int  ToDoubleTy	= ToBoolTy + 10;
 | |
| const int  ToArrayTy	= ToBoolTy + 11;
 | |
| const int  ToPointerTy	= ToBoolTy + 12;
 | |
| 
 | |
| //-------------------------------------------------------------------------
 | |
| // Data types needed by BURG and implemented by us
 | |
| //-------------------------------------------------------------------------
 | |
| 
 | |
| typedef int OpLabel;
 | |
| typedef int StateLabel;
 | |
| 
 | |
| struct BasicTreeNode {
 | |
|   BasicTreeNode* leftChild;
 | |
|   BasicTreeNode* rightChild;
 | |
|   BasicTreeNode* parent;
 | |
|   OpLabel        opLabel;
 | |
|   StateLabel     state;
 | |
|   InstrTreeNode *treeNodePtr;	// points to the C++ tree node object
 | |
|                                 // that "contains" this node
 | |
| };
 | |
| 
 | |
| //-------------------------------------------------------------------------
 | |
| // Declarations of data and functions created by BURG
 | |
| //-------------------------------------------------------------------------
 | |
| 
 | |
| extern short*		burm_nts[];
 | |
|   
 | |
| extern StateLabel	burm_label	(BasicTreeNode* p);
 | |
|   
 | |
| extern StateLabel	burm_state	(OpLabel op, StateLabel leftState,
 | |
| 					 StateLabel rightState);
 | |
| 
 | |
| extern StateLabel	burm_rule	(StateLabel state, int goalNT);
 | |
|   
 | |
| extern BasicTreeNode** burm_kids	(BasicTreeNode* p, int eruleno,
 | |
| 					 BasicTreeNode* kids[]);
 | |
|   
 | |
| extern void		printcover	(BasicTreeNode*, int, int);
 | |
| extern void		printtree	(BasicTreeNode*);
 | |
| extern int		treecost	(BasicTreeNode*, int, int);
 | |
| extern void		printMatches	(BasicTreeNode*);
 | |
| 
 | |
| //************************ Exported Data Types *****************************/
 | |
| 
 | |
| // Provide a hash function for arbitrary pointers...
 | |
| template <class T> struct hash<T *> {
 | |
|   inline size_t operator()(T *Val) const { return (size_t)Val; }
 | |
| };
 | |
| 
 | |
| //------------------------------------------------------------------------ 
 | |
| // class InstrTreeNode
 | |
| // 
 | |
| // A single tree node in the instruction tree used for
 | |
| // instruction selection via BURG.
 | |
| //------------------------------------------------------------------------ 
 | |
| 
 | |
| inline InstrTreeNode*
 | |
| MainTreeNode(BasicTreeNode* node) {
 | |
|   return node->treeNodePtr;
 | |
| }
 | |
| 
 | |
| 
 | |
| class InstrTreeNode : public NonCopyableV {
 | |
| public:
 | |
|   enum InstrTreeNodeType { NTInstructionNode,
 | |
| 			   NTVRegListNode,
 | |
| 			   NTVRegNode,
 | |
| 			   NTConstNode,
 | |
| 			   NTLabelNode };
 | |
|   
 | |
| protected:
 | |
|   BasicTreeNode    basicNode;
 | |
|   InstrTreeNodeType treeNodeType;
 | |
|   Value*	   val;
 | |
|   
 | |
| public:
 | |
|   /*ctor*/		InstrTreeNode	(InstrTreeNodeType nodeType,
 | |
| 					 Value* _val);
 | |
|   /*dtor*/ virtual	~InstrTreeNode	() {}
 | |
|   
 | |
|   BasicTreeNode*	getBasicNode	()	 { return &basicNode; }
 | |
|   
 | |
|   InstrTreeNodeType	getNodeType	() const { return treeNodeType; }
 | |
|   
 | |
|   Value*		getValue	() const { return val; }
 | |
|   
 | |
|   inline OpLabel	getOpLabel	() const { return basicNode.opLabel; }
 | |
|   
 | |
|   inline InstrTreeNode*	leftChild	() const {
 | |
|     return (basicNode.leftChild? basicNode.leftChild->treeNodePtr : NULL);
 | |
|   }
 | |
|   
 | |
|   // If right child is a list node, recursively get its *left* child
 | |
|   inline InstrTreeNode* rightChild	() const {
 | |
|     return (InstrTreeNode*)
 | |
|       (basicNode.rightChild
 | |
|        ? (MainTreeNode(basicNode.rightChild)->getOpLabel() == VRegListOp
 | |
| 	  ? MainTreeNode(basicNode.rightChild)->leftChild()
 | |
| 	  : MainTreeNode(basicNode.rightChild))
 | |
|        : NULL);
 | |
|   }
 | |
|   
 | |
|   inline InstrTreeNode*	parent		() const {
 | |
|     return (basicNode.parent? basicNode.parent->treeNodePtr : NULL);
 | |
|   }
 | |
|   
 | |
|   void			dump		(int dumpChildren,
 | |
| 					 int indent) const;
 | |
|   
 | |
| protected:
 | |
|   virtual void		dumpNode	(int indent) const = 0;
 | |
| 
 | |
|   friend class InstrForest;
 | |
| };
 | |
| 
 | |
| 
 | |
| class InstructionNode: public InstrTreeNode {
 | |
| public:
 | |
|   /*ctor*/	InstructionNode		(Instruction* _instr);
 | |
|   Instruction*	getInstruction		() const { return (Instruction*) val; }
 | |
|   void		reverseBinaryArgumentOrder();
 | |
| protected:
 | |
|   virtual void		dumpNode	(int indent) const;
 | |
| };
 | |
| 
 | |
| 
 | |
| class VRegListNode: public InstrTreeNode {
 | |
| public:
 | |
|   /*ctor*/		VRegListNode	();
 | |
| protected:
 | |
|   virtual void		dumpNode	(int indent) const;
 | |
| };
 | |
| 
 | |
| 
 | |
| class VRegNode: public InstrTreeNode {
 | |
| public:
 | |
|   /*ctor*/		VRegNode	(Value* _val);
 | |
| protected:
 | |
|   virtual void		dumpNode	(int indent) const;
 | |
| };
 | |
| 
 | |
| 
 | |
| class ConstantNode: public InstrTreeNode {
 | |
| public:
 | |
|   /*ctor*/		ConstantNode	(ConstPoolVal* constVal);
 | |
|   ConstPoolVal*		getConstVal	() const { return (ConstPoolVal*) val;}
 | |
| protected:
 | |
|   virtual void		dumpNode	( int indent) const;
 | |
| };
 | |
| 
 | |
| 
 | |
| class LabelNode: public InstrTreeNode {
 | |
| public:
 | |
|   /*ctor*/		LabelNode	(BasicBlock* _bblock);
 | |
|   BasicBlock*		getBasicBlock	() const { return (BasicBlock*) val;}
 | |
| protected:
 | |
|   virtual void		dumpNode	(int indent) const;
 | |
| };
 | |
| 
 | |
| 
 | |
| //------------------------------------------------------------------------
 | |
| // class InstrForest
 | |
| // 
 | |
| // A forest of instruction trees, usually for a single method.
 | |
| //
 | |
| // Methods:
 | |
| //     buildTreesForMethod()	Builds the forest of trees for a method
 | |
| //     getTreeNodeForInstr()	Returns the tree node for an Instruction
 | |
| //     getRootSet()		Returns a set of root nodes for all the trees
 | |
| // 
 | |
| //------------------------------------------------------------------------ 
 | |
| 
 | |
| class InstrForest :
 | |
|   public NonCopyable,
 | |
|   private hash_map<const Instruction*, InstructionNode*> {
 | |
|   
 | |
| private:
 | |
|   hash_set<InstructionNode*> treeRoots;
 | |
|   
 | |
| public:
 | |
|   /*ctor*/	InstrForest		()	    {}
 | |
|   /*dtor*/	~InstrForest		()	    {}
 | |
|   
 | |
|   void		buildTreesForMethod	(Method *method);
 | |
| 				    
 | |
|   inline InstructionNode*
 | |
|   getTreeNodeForInstr(Instruction* instr)
 | |
|   {
 | |
|     return (*this)[instr];
 | |
|   }
 | |
|   
 | |
|   inline const hash_set<InstructionNode*> &getRootSet() const {
 | |
|     return treeRoots;
 | |
|   }
 | |
|   
 | |
|   void		dump			() const;
 | |
|   
 | |
| private:
 | |
|   //
 | |
|   // Private methods for buidling the instruction forest
 | |
|   //
 | |
|   void		setLeftChild		(InstrTreeNode* parent,
 | |
| 					 InstrTreeNode* child);
 | |
|   
 | |
|   void		setRightChild		(InstrTreeNode* parent,
 | |
| 					 InstrTreeNode* child);
 | |
|   
 | |
|   void		setParent		(InstrTreeNode* child,
 | |
| 					 InstrTreeNode* parent);
 | |
|   
 | |
|   void		noteTreeNodeForInstr	(Instruction* instr,
 | |
| 					 InstructionNode* treeNode);
 | |
|   
 | |
|   InstructionNode* buildTreeForInstruction(Instruction* instr);
 | |
| };
 | |
| 
 | |
| //---------------------------------------------------------------------------
 | |
| 
 | |
| #endif  /* #ifndef INSTRFOREST_H */
 |