blob: d52088c0eb6474c715144e323e16c0fac2c0f83d [file] [log] [blame]
Vikram S. Adve70bc4b52001-07-21 12:41:50 +00001// $Id$ -*-c++-*-
2//***************************************************************************
3// File:
Vikram S. Adve89df1ae2001-08-28 23:04:38 +00004// InstrSelection.cpp
Vikram S. Adve70bc4b52001-07-21 12:41:50 +00005//
6// Purpose:
Vikram S. Adve6e447182001-09-18 12:56:28 +00007// Machine-independent driver file for instruction selection.
8// This file constructs a forest of BURG instruction trees and then
Vikram S. Adve9aba1d32001-10-10 20:49:07 +00009// uses the BURG-generated tree grammar (BURM) to find the optimal
Vikram S. Adve6e447182001-09-18 12:56:28 +000010// instruction sequences for a given machine.
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000011//
12// History:
13// 7/02/01 - Vikram Adve - Created
Vikram S. Adve960066a2001-07-31 21:53:25 +000014//**************************************************************************/
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000015
16
Chris Lattnerfeb60592001-09-07 17:15:18 +000017#include "llvm/CodeGen/InstrSelection.h"
Chris Lattnerd268ad62001-09-11 23:52:11 +000018#include "llvm/CodeGen/MachineInstr.h"
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000019#include "llvm/Support/CommandLine.h"
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000020#include "llvm/Instruction.h"
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000021#include "llvm/BasicBlock.h"
22#include "llvm/Method.h"
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000023
Chris Lattnerd268ad62001-09-11 23:52:11 +000024static bool SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt,
Chris Lattner6c5a32d2001-07-23 03:09:03 +000025 TargetMachine &Target);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000026
27
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000028enum SelectDebugLevel_t {
29 Select_NoDebugInfo,
30 Select_PrintMachineCode,
31 Select_DebugInstTrees,
32 Select_DebugBurgTrees,
33};
34
35// Enable Debug Options to be specified on the command line
Chris Lattner5f6baf72001-09-12 16:34:03 +000036cl::Enum<enum SelectDebugLevel_t> SelectDebugLevel("dselect", cl::NoFlags,
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000037 "enable instruction selection debugging information",
38 clEnumValN(Select_NoDebugInfo, "n", "disable debug output"),
39 clEnumValN(Select_PrintMachineCode, "y", "print generated machine code"),
Vikram S. Adve6e447182001-09-18 12:56:28 +000040 clEnumValN(Select_DebugInstTrees, "i", "print debugging info for instruction selection "),
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000041 clEnumValN(Select_DebugBurgTrees, "b", "print burg trees"), 0);
42
43
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000044
45//---------------------------------------------------------------------------
46// Entry point for instruction selection using BURG.
47// Returns true if instruction selection failed, false otherwise.
48//---------------------------------------------------------------------------
49
Vikram S. Adve6e447182001-09-18 12:56:28 +000050bool
51SelectInstructionsForMethod(Method* method, TargetMachine &Target)
52{
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000053 bool failed = false;
54
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000055 //
56 // Build the instruction trees to be given as inputs to BURG.
57 //
Chris Lattner5f6baf72001-09-12 16:34:03 +000058 InstrForest instrForest(method);
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000059
60 if (SelectDebugLevel >= Select_DebugInstTrees)
61 {
62 cout << "\n\n*** Instruction trees for method "
63 << (method->hasName()? method->getName() : "")
64 << endl << endl;
65 instrForest.dump();
66 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000067
68 //
69 // Invoke BURG instruction selection for each tree
70 //
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000071 const hash_set<InstructionNode*> &treeRoots = instrForest.getRootSet();
Chris Lattner75279cc2001-07-23 03:50:57 +000072 for (hash_set<InstructionNode*>::const_iterator
Chris Lattner0e6530e2001-09-14 03:37:52 +000073 treeRootIter = treeRoots.begin(); treeRootIter != treeRoots.end();
Vikram S. Adve6e447182001-09-18 12:56:28 +000074 ++treeRootIter)
75 {
76 InstrTreeNode* basicNode = *treeRootIter;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000077
Vikram S. Adve6e447182001-09-18 12:56:28 +000078 // Invoke BURM to label each tree node with a state
79 burm_label(basicNode);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000080
Vikram S. Adve6e447182001-09-18 12:56:28 +000081 if (SelectDebugLevel >= Select_DebugBurgTrees)
82 {
83 printcover(basicNode, 1, 0);
84 cerr << "\nCover cost == " << treecost(basicNode, 1, 0) << "\n\n";
85 printMatches(basicNode);
86 }
87
88 // Then recursively walk the tree to select instructions
89 if (SelectInstructionsForTree(basicNode, /*goalnt*/1, Target))
90 {
91 failed = true;
92 break;
93 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000094 }
95
Vikram S. Adve76d35202001-07-30 18:48:43 +000096 //
97 // Record instructions in the vector for each basic block
98 //
Vikram S. Adve6e447182001-09-18 12:56:28 +000099 for (Method::iterator BI = method->begin(); BI != method->end(); ++BI)
100 {
101 MachineCodeForBasicBlock& bbMvec = (*BI)->getMachineInstrVec();
102 for (BasicBlock::iterator II = (*BI)->begin(); II != (*BI)->end(); ++II)
103 {
104 MachineCodeForVMInstr& mvec = (*II)->getMachineInstrVec();
105 for (unsigned i=0; i < mvec.size(); i++)
106 bbMvec.push_back(mvec[i]);
107 }
Vikram S. Adve76d35202001-07-30 18:48:43 +0000108 }
109
Vikram S. Adve6e447182001-09-18 12:56:28 +0000110 if (SelectDebugLevel >= Select_PrintMachineCode)
111 {
112 cout << endl << "*** Machine instructions after INSTRUCTION SELECTION" << endl;
113 PrintMachineInstructions(method);
114 }
Vikram S. Adve89df1ae2001-08-28 23:04:38 +0000115
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000116 return false;
117}
118
119
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000120//*********************** Private Functions *****************************/
121
122
123//---------------------------------------------------------------------------
124// Function SelectInstructionsForTree
125//
126// Recursively walk the tree to select instructions.
127// Do this top-down so that child instructions can exploit decisions
128// made at the child instructions.
129//
130// E.g., if br(setle(reg,const)) decides the constant is 0 and uses
131// a branch-on-integer-register instruction, then the setle node
132// can use that information to avoid generating the SUBcc instruction.
133//
134// Note that this cannot be done bottom-up because setle must do this
135// only if it is a child of the branch (otherwise, the result of setle
136// may be used by multiple instructions).
137//---------------------------------------------------------------------------
138
Vikram S. Adve6e447182001-09-18 12:56:28 +0000139bool
140SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt,
141 TargetMachine &Target)
142{
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000143 // Use a static vector to avoid allocating a new one per VM instruction
144 static MachineInstr* minstrVec[MAX_INSTR_PER_VMINSTR];
145
146 // Get the rule that matches this node.
147 //
148 int ruleForNode = burm_rule(treeRoot->state, goalnt);
149
Vikram S. Adve6e447182001-09-18 12:56:28 +0000150 if (ruleForNode == 0)
151 {
152 cerr << "Could not match instruction tree for instr selection" << endl;
153 assert(0);
154 return true;
155 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000156
157 // Get this rule's non-terminals and the corresponding child nodes (if any)
158 //
159 short *nts = burm_nts[ruleForNode];
160
161
162 // First, select instructions for the current node and rule.
163 // (If this is a list node, not an instruction, then skip this step).
164 // This function is specific to the target architecture.
165 //
Vikram S. Adve6e447182001-09-18 12:56:28 +0000166 if (treeRoot->opLabel != VRegListOp)
167 {
168 InstructionNode* instrNode = (InstructionNode*)treeRoot;
169 assert(instrNode->getNodeType() == InstrTreeNode::NTInstructionNode);
Chris Lattner0e6530e2001-09-14 03:37:52 +0000170
Vikram S. Adve6e447182001-09-18 12:56:28 +0000171 unsigned N = GetInstructionsByRule(instrNode, ruleForNode, nts, Target,
172 minstrVec);
173 assert(N <= MAX_INSTR_PER_VMINSTR);
174 for (unsigned i=0; i < N; i++)
175 {
176 assert(minstrVec[i] != NULL);
177 instrNode->getInstruction()->addMachineInstruction(minstrVec[i]);
178 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000179 }
180
181 // Then, recursively compile the child nodes, if any.
182 //
Vikram S. Adve6e447182001-09-18 12:56:28 +0000183 if (nts[0])
184 { // i.e., there is at least one kid
185 InstrTreeNode* kids[2];
186 int currentRule = ruleForNode;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000187 burm_kids(treeRoot, currentRule, kids);
Vikram S. Adve6e447182001-09-18 12:56:28 +0000188
189 // First skip over any chain rules so that we don't visit
190 // the current node again.
191 //
192 while (ThisIsAChainRule(currentRule))
193 {
194 currentRule = burm_rule(treeRoot->state, nts[0]);
195 nts = burm_nts[currentRule];
196 burm_kids(treeRoot, currentRule, kids);
197 }
Chris Lattner0e6530e2001-09-14 03:37:52 +0000198
Vikram S. Adve6e447182001-09-18 12:56:28 +0000199 // Now we have the first non-chain rule so we have found
200 // the actual child nodes. Recursively compile them.
201 //
202 for (int i = 0; nts[i]; i++)
203 {
204 assert(i < 2);
205 InstrTreeNode::InstrTreeNodeType nodeType = kids[i]->getNodeType();
206 if (nodeType == InstrTreeNode::NTVRegListNode ||
207 nodeType == InstrTreeNode::NTInstructionNode)
208 {
209 if (SelectInstructionsForTree(kids[i], nts[i], Target))
210 return true; // failure
211 }
212 }
Chris Lattner0e6530e2001-09-14 03:37:52 +0000213 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000214
215 return false; // success
216}
217