1 //===-- llvm/CodeGen/InstForest.h -------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 // Convert SSA graph to instruction trees for instruction selection.
14 // The basic idea is that we would like to group instructions into a single
15 // tree if one or more of them might be potentially combined into a single
16 // complex instruction in the target machine.
17 // Since this grouping is completely machine-independent, it is as
18 // aggressive as possible. In particular, we group two instructions
20 // (1) Instruction O computes an operand of instruction I, and
21 // (2) O and I are part of the same basic block, and
22 // (3) O has only a single use, viz., I.
24 //===----------------------------------------------------------------------===//
26 #ifndef LLVM_CODEGEN_INSTRFOREST_H
27 #define LLVM_CODEGEN_INSTRFOREST_H
29 #include "llvm/Instruction.h"
30 #include "Support/hash_map"
39 } // End llvm namespace
43 //--------------------------------------------------------------------------
44 // OpLabel values for special-case nodes created for instruction selection.
45 // All op-labels not defined here are identical to the instruction
46 // opcode returned by Instruction::getOpcode()
47 //--------------------------------------------------------------------------
51 const int InvalidOp = -1;
52 const int VRegListOp = 97;
53 const int VRegNodeOp = 98;
54 const int ConstantNodeOp= 99;
55 const int LabelNodeOp = 100;
57 const int RetValueOp = 100 + Instruction::Ret; // 101
58 const int BrCondOp = 100 + Instruction::Br; // 102
60 const int BAndOp = 100 + Instruction::And; // 111
61 const int BOrOp = 100 + Instruction::Or; // 112
62 const int BXorOp = 100 + Instruction::Xor; // 113
63 const int BNotOp = 200 + Instruction::Xor; // 213
64 const int NotOp = 300 + Instruction::Xor; // 313
66 const int SetCCOp = 100 + Instruction::SetEQ; // 114
68 const int AllocaN = 100 + Instruction::Alloca; // 122
69 const int LoadIdx = 100 + Instruction::Load; // 123
70 const int GetElemPtrIdx= 100 + Instruction::GetElementPtr; // 125
72 const int ToBoolTy = 100 + Instruction::Cast; // 127
73 const int ToUByteTy = ToBoolTy + 1;
74 const int ToSByteTy = ToBoolTy + 2;
75 const int ToUShortTy = ToBoolTy + 3;
76 const int ToShortTy = ToBoolTy + 4;
77 const int ToUIntTy = ToBoolTy + 5;
78 const int ToIntTy = ToBoolTy + 6;
79 const int ToULongTy = ToBoolTy + 7;
80 const int ToLongTy = ToBoolTy + 8;
81 const int ToFloatTy = ToBoolTy + 9;
82 const int ToDoubleTy = ToBoolTy + 10;
83 const int ToArrayTy = ToBoolTy + 11;
84 const int ToPointerTy = ToBoolTy + 12;
86 //-------------------------------------------------------------------------
87 // Data types needed by BURG and implemented by us
88 //-------------------------------------------------------------------------
91 typedef int StateLabel;
93 //-------------------------------------------------------------------------
94 // Declarations of data and functions created by BURG
95 //-------------------------------------------------------------------------
97 extern short* burm_nts[];
99 extern StateLabel burm_label (InstrTreeNode* p);
101 extern StateLabel burm_state (OpLabel op, StateLabel leftState,
102 StateLabel rightState);
104 extern StateLabel burm_rule (StateLabel state, int goalNT);
106 extern InstrTreeNode** burm_kids (InstrTreeNode* p, int eruleno,
107 InstrTreeNode* kids[]);
109 extern void printcover (InstrTreeNode*, int, int);
110 extern void printtree (InstrTreeNode*);
111 extern int treecost (InstrTreeNode*, int, int);
112 extern void printMatches (InstrTreeNode*);
116 //------------------------------------------------------------------------
117 // class InstrTreeNode
119 // A single tree node in the instruction tree used for
120 // instruction selection via BURG.
121 //------------------------------------------------------------------------
123 class InstrTreeNode {
124 InstrTreeNode(const InstrTreeNode &); // DO NOT IMPLEMENT
125 void operator=(const InstrTreeNode &); // DO NOT IMPLEMENT
127 enum InstrTreeNodeType { NTInstructionNode,
133 // BASIC TREE NODE START
134 InstrTreeNode* LeftChild;
135 InstrTreeNode* RightChild;
136 InstrTreeNode* Parent;
139 // BASIC TREE NODE END
142 InstrTreeNodeType treeNodeType;
146 InstrTreeNode(InstrTreeNodeType nodeType, Value* _val)
147 : treeNodeType(nodeType), val(_val) {
148 LeftChild = RightChild = Parent = 0;
151 virtual ~InstrTreeNode() {
156 InstrTreeNodeType getNodeType () const { return treeNodeType; }
158 Value* getValue () const { return val; }
160 inline OpLabel getOpLabel () const { return opLabel; }
162 inline InstrTreeNode* leftChild() const {
166 // If right child is a list node, recursively get its *left* child
167 inline InstrTreeNode* rightChild() const {
168 return (!RightChild ? 0 :
169 (RightChild->getOpLabel() == VRegListOp
170 ? RightChild->LeftChild : RightChild));
173 inline InstrTreeNode *parent() const {
177 void dump(int dumpChildren, int indent) const;
180 virtual void dumpNode(int indent) const = 0;
182 friend class InstrForest;
186 class InstructionNode : public InstrTreeNode {
188 bool codeIsFoldedIntoParent;
191 InstructionNode(Instruction *_instr);
193 Instruction *getInstruction() const {
194 assert(treeNodeType == NTInstructionNode);
195 return cast<Instruction>(val);
198 void markFoldedIntoParent() { codeIsFoldedIntoParent = true; }
199 bool isFoldedIntoParent() { return codeIsFoldedIntoParent; }
201 // Methods to support type inquiry through isa, cast, and dyn_cast:
202 static inline bool classof(const InstructionNode *N) { return true; }
203 static inline bool classof(const InstrTreeNode *N) {
204 return N->getNodeType() == InstrTreeNode::NTInstructionNode;
208 virtual void dumpNode(int indent) const;
212 class VRegListNode : public InstrTreeNode {
214 VRegListNode() : InstrTreeNode(NTVRegListNode, 0) {
215 opLabel = VRegListOp;
218 // Methods to support type inquiry through isa, cast, and dyn_cast:
219 static inline bool classof(const VRegListNode *N) { return true; }
220 static inline bool classof(const InstrTreeNode *N) {
221 return N->getNodeType() == InstrTreeNode::NTVRegListNode;
225 virtual void dumpNode(int indent) const;
229 class VRegNode : public InstrTreeNode {
231 VRegNode(Value* _val) : InstrTreeNode(NTVRegNode, _val) {
232 opLabel = VRegNodeOp;
235 // Methods to support type inquiry through isa, cast, and dyn_cast:
236 static inline bool classof(const VRegNode *N) { return true; }
237 static inline bool classof(const InstrTreeNode *N) {
238 return N->getNodeType() == InstrTreeNode::NTVRegNode;
242 virtual void dumpNode(int indent) const;
246 class ConstantNode : public InstrTreeNode {
248 ConstantNode(Constant *constVal)
249 : InstrTreeNode(NTConstNode, (Value*)constVal) {
250 opLabel = ConstantNodeOp;
252 Constant *getConstVal() const { return (Constant*) val;}
254 // Methods to support type inquiry through isa, cast, and dyn_cast:
255 static inline bool classof(const ConstantNode *N) { return true; }
256 static inline bool classof(const InstrTreeNode *N) {
257 return N->getNodeType() == InstrTreeNode::NTConstNode;
261 virtual void dumpNode(int indent) const;
265 class LabelNode : public InstrTreeNode {
267 LabelNode(BasicBlock* BB) : InstrTreeNode(NTLabelNode, (Value*)BB) {
268 opLabel = LabelNodeOp;
271 BasicBlock *getBasicBlock() const { return (BasicBlock*)val;}
273 // Methods to support type inquiry through isa, cast, and dyn_cast:
274 static inline bool classof(const LabelNode *N) { return true; }
275 static inline bool classof(const InstrTreeNode *N) {
276 return N->getNodeType() == InstrTreeNode::NTLabelNode;
280 virtual void dumpNode(int indent) const;
284 //------------------------------------------------------------------------
287 // A forest of instruction trees, usually for a single method.
290 // buildTreesForMethod() Builds the forest of trees for a method
291 // getTreeNodeForInstr() Returns the tree node for an Instruction
292 // getRootSet() Returns a set of root nodes for all the trees
294 //------------------------------------------------------------------------
296 class InstrForest : private hash_map<const Instruction *, InstructionNode*> {
298 // Use a vector for the root set to get a deterministic iterator
299 // for stable code generation. Even though we need to erase nodes
300 // during forest construction, a vector should still be efficient
301 // because the elements to erase are nearly always near the end.
302 typedef std::vector<InstructionNode*> RootSet;
303 typedef RootSet:: iterator root_iterator;
304 typedef RootSet::const_iterator const_root_iterator;
310 /*ctor*/ InstrForest (Function *F);
311 /*dtor*/ ~InstrForest ();
313 inline InstructionNode *getTreeNodeForInstr(Instruction* instr) {
314 return (*this)[instr];
317 const_root_iterator roots_begin() const { return treeRoots.begin(); }
318 root_iterator roots_begin() { return treeRoots.begin(); }
319 const_root_iterator roots_end () const { return treeRoots.end(); }
320 root_iterator roots_end () { return treeRoots.end(); }
326 // Private methods for buidling the instruction forest
328 void eraseRoot (InstructionNode* node);
329 void setLeftChild (InstrTreeNode* parent, InstrTreeNode* child);
330 void setRightChild(InstrTreeNode* parent, InstrTreeNode* child);
331 void setParent (InstrTreeNode* child, InstrTreeNode* parent);
332 void noteTreeNodeForInstr(Instruction* instr, InstructionNode* treeNode);
334 InstructionNode* buildTreeForInstruction(Instruction* instr);
337 } // End llvm namespace