2 //***************************************************************************
7 // Convert SSA graph to instruction trees for instruction selection.
10 // The basic idea is that we would like to group instructions into a single
11 // tree if one or more of them might be potentially combined into a single
12 // complex instruction in the target machine.
13 // Since this grouping is completely machine-independent, it is as
14 // aggressive as possible. In particular, we group two instructions
16 // (1) Instruction O computes an operand of instruction I, and
17 // (2) O and I are part of the same basic block, and
18 // (3) O has only a single use, viz., I.
21 // 6/28/01 - Vikram Adve - Created
22 //**************************************************************************/
24 #ifndef LLVM_CODEGEN_INSTRFOREST_H
25 #define LLVM_CODEGEN_INSTRFOREST_H
27 #include "llvm/Instruction.h"
28 #include "Support/NonCopyable.h"
29 #include "Support/HashExtras.h"
30 #include <ext/hash_set>
38 //--------------------------------------------------------------------------
39 // OpLabel values for special-case nodes created for instruction selection.
40 // All op-labels not defined here are identical to the instruction
41 // opcode returned by Instruction::getInstType()
42 //--------------------------------------------------------------------------
44 const int InvalidOp = -1;
45 const int VRegListOp = 97;
46 const int VRegNodeOp = 98;
47 const int ConstantNodeOp= 99;
48 const int LabelNodeOp = 100;
50 const int RetValueOp = 100 + Instruction::Ret;
51 const int BrCondOp = 100 + Instruction::Br;
53 const int BAndOp = 100 + Instruction::And;
54 const int BOrOp = 100 + Instruction::Or;
55 const int BXorOp = 100 + Instruction::Xor;
56 const int BNotOp = 100 + Instruction::Not;
58 const int SetCCOp = 100 + Instruction::SetEQ;
60 const int AllocaN = 100 + Instruction::Alloca; // 121
61 const int LoadIdx = 100 + Instruction::Load; // 122
62 const int GetElemPtrIdx= 100 + Instruction::GetElementPtr; // 124
64 const int ToBoolTy = 100 + Instruction::Cast; // 126
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 : public NonCopyableV {
116 enum InstrTreeNodeType { NTInstructionNode,
122 // BASIC TREE NODE START
123 InstrTreeNode* LeftChild;
124 InstrTreeNode* RightChild;
125 InstrTreeNode* Parent;
128 // BASIC TREE NODE END
131 InstrTreeNodeType treeNodeType;
135 InstrTreeNode(InstrTreeNodeType nodeType, Value* _val)
136 : treeNodeType(nodeType), val(_val) {
137 LeftChild = RightChild = Parent = 0;
140 virtual ~InstrTreeNode() {}
142 InstrTreeNodeType getNodeType () const { return treeNodeType; }
144 Value* getValue () const { return val; }
146 inline OpLabel getOpLabel () const { return opLabel; }
148 inline InstrTreeNode* leftChild() const {
152 // If right child is a list node, recursively get its *left* child
153 inline InstrTreeNode* rightChild() const {
154 return (!RightChild ? 0 :
155 (RightChild->getOpLabel() == VRegListOp
156 ? RightChild->LeftChild : RightChild));
159 inline InstrTreeNode *parent() const {
163 void dump(int dumpChildren, int indent) const;
166 virtual void dumpNode(int indent) const = 0;
168 friend class InstrForest;
172 class InstructionNode : public InstrTreeNode {
174 InstructionNode(Instruction *_instr);
176 Instruction *getInstruction() const {
177 assert(treeNodeType == NTInstructionNode);
178 return cast<Instruction>(val);
181 virtual void dumpNode(int indent) const;
185 class VRegListNode : public InstrTreeNode {
187 VRegListNode() : InstrTreeNode(NTVRegListNode, 0) {
188 opLabel = VRegListOp;
191 virtual void dumpNode(int indent) const;
195 class VRegNode : public InstrTreeNode {
197 VRegNode(Value* _val) : InstrTreeNode(NTVRegNode, _val) {
198 opLabel = VRegNodeOp;
201 virtual void dumpNode(int indent) const;
205 class ConstantNode : public InstrTreeNode {
207 ConstantNode(Constant *constVal)
208 : InstrTreeNode(NTConstNode, (Value*)constVal) {
209 opLabel = ConstantNodeOp;
211 Constant *getConstVal() const { return (Constant*) val;}
213 virtual void dumpNode(int indent) const;
217 class LabelNode : public InstrTreeNode {
219 LabelNode(BasicBlock* BB) : InstrTreeNode(NTLabelNode, (Value*)BB) {
220 opLabel = LabelNodeOp;
223 BasicBlock *getBasicBlock() const { return (BasicBlock*)val;}
225 virtual void dumpNode(int indent) const;
229 //------------------------------------------------------------------------
232 // A forest of instruction trees, usually for a single method.
235 // buildTreesForMethod() Builds the forest of trees for a method
236 // getTreeNodeForInstr() Returns the tree node for an Instruction
237 // getRootSet() Returns a set of root nodes for all the trees
239 //------------------------------------------------------------------------
241 class InstrForest : private std::hash_map<const Instruction *, InstructionNode*> {
243 std::hash_set<InstructionNode*> treeRoots;
246 /*ctor*/ InstrForest (Method *M);
247 /*dtor*/ ~InstrForest ();
249 inline InstructionNode *getTreeNodeForInstr(Instruction* instr) {
250 return (*this)[instr];
253 inline const std::hash_set<InstructionNode*> &getRootSet() const {
261 // Private methods for buidling the instruction forest
263 void setLeftChild (InstrTreeNode* parent, InstrTreeNode* child);
264 void setRightChild(InstrTreeNode* parent, InstrTreeNode* child);
265 void setParent (InstrTreeNode* child, InstrTreeNode* parent);
266 void noteTreeNodeForInstr(Instruction* instr, InstructionNode* treeNode);
268 InstructionNode* buildTreeForInstruction(Instruction* instr);