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"
37 //--------------------------------------------------------------------------
38 // OpLabel values for special-case nodes created for instruction selection.
39 // All op-labels not defined here are identical to the instruction
40 // opcode returned by Instruction::getOpcode()
41 //--------------------------------------------------------------------------
43 const int InvalidOp = -1;
44 const int VRegListOp = 97;
45 const int VRegNodeOp = 98;
46 const int ConstantNodeOp= 99;
47 const int LabelNodeOp = 100;
49 const int RetValueOp = 100 + Instruction::Ret; // 101
50 const int BrCondOp = 100 + Instruction::Br; // 102
52 const int BAndOp = 100 + Instruction::And; // 111
53 const int BOrOp = 100 + Instruction::Or; // 112
54 const int BXorOp = 100 + Instruction::Xor; // 113
55 const int BNotOp = 200 + Instruction::Xor; // 213
56 const int NotOp = 300 + Instruction::Xor; // 313
58 const int SetCCOp = 100 + Instruction::SetEQ; // 114
60 const int AllocaN = 100 + Instruction::Alloca; // 122
61 const int LoadIdx = 100 + Instruction::Load; // 123
62 const int GetElemPtrIdx= 100 + Instruction::GetElementPtr; // 125
64 const int ToBoolTy = 100 + Instruction::Cast; // 127
65 const int ToUByteTy = ToBoolTy + 1;
66 const int ToSByteTy = ToBoolTy + 2;
67 const int ToUShortTy = ToBoolTy + 3;
68 const int ToShortTy = ToBoolTy + 4;
69 const int ToUIntTy = ToBoolTy + 5;
70 const int ToIntTy = ToBoolTy + 6;
71 const int ToULongTy = ToBoolTy + 7;
72 const int ToLongTy = ToBoolTy + 8;
73 const int ToFloatTy = ToBoolTy + 9;
74 const int ToDoubleTy = ToBoolTy + 10;
75 const int ToArrayTy = ToBoolTy + 11;
76 const int ToPointerTy = ToBoolTy + 12;
78 //-------------------------------------------------------------------------
79 // Data types needed by BURG and implemented by us
80 //-------------------------------------------------------------------------
83 typedef int StateLabel;
85 //-------------------------------------------------------------------------
86 // Declarations of data and functions created by BURG
87 //-------------------------------------------------------------------------
89 extern short* burm_nts[];
91 extern StateLabel burm_label (InstrTreeNode* p);
93 extern StateLabel burm_state (OpLabel op, StateLabel leftState,
94 StateLabel rightState);
96 extern StateLabel burm_rule (StateLabel state, int goalNT);
98 extern InstrTreeNode** burm_kids (InstrTreeNode* p, int eruleno,
99 InstrTreeNode* kids[]);
101 extern void printcover (InstrTreeNode*, int, int);
102 extern void printtree (InstrTreeNode*);
103 extern int treecost (InstrTreeNode*, int, int);
104 extern void printMatches (InstrTreeNode*);
107 //------------------------------------------------------------------------
108 // class InstrTreeNode
110 // A single tree node in the instruction tree used for
111 // instruction selection via BURG.
112 //------------------------------------------------------------------------
114 class InstrTreeNode {
115 InstrTreeNode(const InstrTreeNode &); // DO NOT IMPLEMENT
116 void operator=(const InstrTreeNode &); // DO NOT IMPLEMENT
118 enum InstrTreeNodeType { NTInstructionNode,
124 // BASIC TREE NODE START
125 InstrTreeNode* LeftChild;
126 InstrTreeNode* RightChild;
127 InstrTreeNode* Parent;
130 // BASIC TREE NODE END
133 InstrTreeNodeType treeNodeType;
137 InstrTreeNode(InstrTreeNodeType nodeType, Value* _val)
138 : treeNodeType(nodeType), val(_val) {
139 LeftChild = RightChild = Parent = 0;
142 virtual ~InstrTreeNode() {
147 InstrTreeNodeType getNodeType () const { return treeNodeType; }
149 Value* getValue () const { return val; }
151 inline OpLabel getOpLabel () const { return opLabel; }
153 inline InstrTreeNode* leftChild() const {
157 // If right child is a list node, recursively get its *left* child
158 inline InstrTreeNode* rightChild() const {
159 return (!RightChild ? 0 :
160 (RightChild->getOpLabel() == VRegListOp
161 ? RightChild->LeftChild : RightChild));
164 inline InstrTreeNode *parent() const {
168 void dump(int dumpChildren, int indent) const;
171 virtual void dumpNode(int indent) const = 0;
173 friend class InstrForest;
177 class InstructionNode : public InstrTreeNode {
179 bool codeIsFoldedIntoParent;
182 InstructionNode(Instruction *_instr);
184 Instruction *getInstruction() const {
185 assert(treeNodeType == NTInstructionNode);
186 return cast<Instruction>(val);
189 void markFoldedIntoParent() { codeIsFoldedIntoParent = true; }
190 bool isFoldedIntoParent() { return codeIsFoldedIntoParent; }
192 // Methods to support type inquiry through isa, cast, and dyn_cast:
193 static inline bool classof(const InstructionNode *N) { return true; }
194 static inline bool classof(const InstrTreeNode *N) {
195 return N->getNodeType() == InstrTreeNode::NTInstructionNode;
199 virtual void dumpNode(int indent) const;
203 class VRegListNode : public InstrTreeNode {
205 VRegListNode() : InstrTreeNode(NTVRegListNode, 0) {
206 opLabel = VRegListOp;
209 // Methods to support type inquiry through isa, cast, and dyn_cast:
210 static inline bool classof(const VRegListNode *N) { return true; }
211 static inline bool classof(const InstrTreeNode *N) {
212 return N->getNodeType() == InstrTreeNode::NTVRegListNode;
216 virtual void dumpNode(int indent) const;
220 class VRegNode : public InstrTreeNode {
222 VRegNode(Value* _val) : InstrTreeNode(NTVRegNode, _val) {
223 opLabel = VRegNodeOp;
226 // Methods to support type inquiry through isa, cast, and dyn_cast:
227 static inline bool classof(const VRegNode *N) { return true; }
228 static inline bool classof(const InstrTreeNode *N) {
229 return N->getNodeType() == InstrTreeNode::NTVRegNode;
233 virtual void dumpNode(int indent) const;
237 class ConstantNode : public InstrTreeNode {
239 ConstantNode(Constant *constVal)
240 : InstrTreeNode(NTConstNode, (Value*)constVal) {
241 opLabel = ConstantNodeOp;
243 Constant *getConstVal() const { return (Constant*) val;}
245 // Methods to support type inquiry through isa, cast, and dyn_cast:
246 static inline bool classof(const ConstantNode *N) { return true; }
247 static inline bool classof(const InstrTreeNode *N) {
248 return N->getNodeType() == InstrTreeNode::NTConstNode;
252 virtual void dumpNode(int indent) const;
256 class LabelNode : public InstrTreeNode {
258 LabelNode(BasicBlock* BB) : InstrTreeNode(NTLabelNode, (Value*)BB) {
259 opLabel = LabelNodeOp;
262 BasicBlock *getBasicBlock() const { return (BasicBlock*)val;}
264 // Methods to support type inquiry through isa, cast, and dyn_cast:
265 static inline bool classof(const LabelNode *N) { return true; }
266 static inline bool classof(const InstrTreeNode *N) {
267 return N->getNodeType() == InstrTreeNode::NTLabelNode;
271 virtual void dumpNode(int indent) const;
275 //------------------------------------------------------------------------
278 // A forest of instruction trees, usually for a single method.
281 // buildTreesForMethod() Builds the forest of trees for a method
282 // getTreeNodeForInstr() Returns the tree node for an Instruction
283 // getRootSet() Returns a set of root nodes for all the trees
285 //------------------------------------------------------------------------
287 class InstrForest : private hash_map<const Instruction *, InstructionNode*> {
289 // Use a vector for the root set to get a deterministic iterator
290 // for stable code generation. Even though we need to erase nodes
291 // during forest construction, a vector should still be efficient
292 // because the elements to erase are nearly always near the end.
293 typedef std::vector<InstructionNode*> RootSet;
294 typedef RootSet:: iterator root_iterator;
295 typedef RootSet::const_iterator const_root_iterator;
301 /*ctor*/ InstrForest (Function *F);
302 /*dtor*/ ~InstrForest ();
304 inline InstructionNode *getTreeNodeForInstr(Instruction* instr) {
305 return (*this)[instr];
308 const_root_iterator roots_begin() const { return treeRoots.begin(); }
309 root_iterator roots_begin() { return treeRoots.begin(); }
310 const_root_iterator roots_end () const { return treeRoots.end(); }
311 root_iterator roots_end () { return treeRoots.end(); }
317 // Private methods for buidling the instruction forest
319 void eraseRoot (InstructionNode* node);
320 void setLeftChild (InstrTreeNode* parent, InstrTreeNode* child);
321 void setRightChild(InstrTreeNode* parent, InstrTreeNode* child);
322 void setParent (InstrTreeNode* child, InstrTreeNode* parent);
323 void noteTreeNodeForInstr(Instruction* instr, InstructionNode* treeNode);
325 InstructionNode* buildTreeForInstruction(Instruction* instr);