blob: fafe0234e34d62b9b2f922db69a37ca325c04247 [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"
Vikram S. Adve6d353262001-10-17 23:57:50 +000018#include "llvm/CodeGen/InstrSelectionSupport.h"
Chris Lattnerd268ad62001-09-11 23:52:11 +000019#include "llvm/CodeGen/MachineInstr.h"
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000020#include "llvm/Support/CommandLine.h"
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000021#include "llvm/Instruction.h"
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000022#include "llvm/BasicBlock.h"
23#include "llvm/Method.h"
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000024
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000025
Vikram S. Adve7ad10462001-10-22 13:51:09 +000026//******************** Internal Data Declarations ************************/
27
28// Use a static vector to avoid allocating a new one per VM instruction
29static MachineInstr* minstrVec[MAX_INSTR_PER_VMINSTR];
30
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000031
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000032enum SelectDebugLevel_t {
33 Select_NoDebugInfo,
34 Select_PrintMachineCode,
35 Select_DebugInstTrees,
36 Select_DebugBurgTrees,
37};
38
39// Enable Debug Options to be specified on the command line
Chris Lattner5f6baf72001-09-12 16:34:03 +000040cl::Enum<enum SelectDebugLevel_t> SelectDebugLevel("dselect", cl::NoFlags,
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000041 "enable instruction selection debugging information",
42 clEnumValN(Select_NoDebugInfo, "n", "disable debug output"),
43 clEnumValN(Select_PrintMachineCode, "y", "print generated machine code"),
Vikram S. Adve6e447182001-09-18 12:56:28 +000044 clEnumValN(Select_DebugInstTrees, "i", "print debugging info for instruction selection "),
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000045 clEnumValN(Select_DebugBurgTrees, "b", "print burg trees"), 0);
46
47
Vikram S. Adve7ad10462001-10-22 13:51:09 +000048//******************** Forward Function Declarations ***********************/
49
50
51static bool SelectInstructionsForTree (InstrTreeNode* treeRoot,
52 int goalnt,
53 TargetMachine &target);
54
55static void PostprocessMachineCodeForTree(InstructionNode* instrNode,
56 int ruleForNode,
57 short* nts,
58 TargetMachine &target);
59
60
61//******************* Externally Visible Functions *************************/
62
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000063
64//---------------------------------------------------------------------------
65// Entry point for instruction selection using BURG.
66// Returns true if instruction selection failed, false otherwise.
67//---------------------------------------------------------------------------
68
Vikram S. Adve6e447182001-09-18 12:56:28 +000069bool
Vikram S. Adve6d353262001-10-17 23:57:50 +000070SelectInstructionsForMethod(Method* method, TargetMachine &target)
Vikram S. Adve6e447182001-09-18 12:56:28 +000071{
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000072 bool failed = false;
73
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000074 //
75 // Build the instruction trees to be given as inputs to BURG.
76 //
Chris Lattner5f6baf72001-09-12 16:34:03 +000077 InstrForest instrForest(method);
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000078
79 if (SelectDebugLevel >= Select_DebugInstTrees)
80 {
81 cout << "\n\n*** Instruction trees for method "
82 << (method->hasName()? method->getName() : "")
83 << endl << endl;
84 instrForest.dump();
85 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000086
87 //
88 // Invoke BURG instruction selection for each tree
89 //
Vikram S. Adve89df1ae2001-08-28 23:04:38 +000090 const hash_set<InstructionNode*> &treeRoots = instrForest.getRootSet();
Chris Lattner75279cc2001-07-23 03:50:57 +000091 for (hash_set<InstructionNode*>::const_iterator
Chris Lattner0e6530e2001-09-14 03:37:52 +000092 treeRootIter = treeRoots.begin(); treeRootIter != treeRoots.end();
Vikram S. Adve6e447182001-09-18 12:56:28 +000093 ++treeRootIter)
94 {
95 InstrTreeNode* basicNode = *treeRootIter;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000096
Vikram S. Adve6e447182001-09-18 12:56:28 +000097 // Invoke BURM to label each tree node with a state
98 burm_label(basicNode);
Vikram S. Adve70bc4b52001-07-21 12:41:50 +000099
Vikram S. Adve6e447182001-09-18 12:56:28 +0000100 if (SelectDebugLevel >= Select_DebugBurgTrees)
101 {
102 printcover(basicNode, 1, 0);
103 cerr << "\nCover cost == " << treecost(basicNode, 1, 0) << "\n\n";
104 printMatches(basicNode);
105 }
106
107 // Then recursively walk the tree to select instructions
Vikram S. Adve6d353262001-10-17 23:57:50 +0000108 if (SelectInstructionsForTree(basicNode, /*goalnt*/1, target))
Vikram S. Adve6e447182001-09-18 12:56:28 +0000109 {
110 failed = true;
111 break;
112 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000113 }
114
Vikram S. Adve76d35202001-07-30 18:48:43 +0000115 //
116 // Record instructions in the vector for each basic block
117 //
Vikram S. Adve6e447182001-09-18 12:56:28 +0000118 for (Method::iterator BI = method->begin(); BI != method->end(); ++BI)
119 {
120 MachineCodeForBasicBlock& bbMvec = (*BI)->getMachineInstrVec();
121 for (BasicBlock::iterator II = (*BI)->begin(); II != (*BI)->end(); ++II)
122 {
123 MachineCodeForVMInstr& mvec = (*II)->getMachineInstrVec();
124 for (unsigned i=0; i < mvec.size(); i++)
125 bbMvec.push_back(mvec[i]);
126 }
Vikram S. Adve76d35202001-07-30 18:48:43 +0000127 }
128
Vikram S. Adve6e447182001-09-18 12:56:28 +0000129 if (SelectDebugLevel >= Select_PrintMachineCode)
130 {
Vikram S. Adve7ad10462001-10-22 13:51:09 +0000131 cout << endl
132 << "*** Machine instructions after INSTRUCTION SELECTION" << endl;
Vikram S. Advebe495262001-11-08 04:47:06 +0000133 MachineCodeForMethod::get(method).dump();
Vikram S. Adve6e447182001-09-18 12:56:28 +0000134 }
Vikram S. Adve89df1ae2001-08-28 23:04:38 +0000135
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000136 return false;
137}
138
139
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000140//*********************** Private Functions *****************************/
141
142
143//---------------------------------------------------------------------------
Vikram S. Adve7ad10462001-10-22 13:51:09 +0000144// Function AppendMachineCodeForVMInstr
145//
146// Append machine instr sequence to the machine code vec for a VM instr
147//---------------------------------------------------------------------------
148
149inline void
150AppendMachineCodeForVMInstr(MachineInstr** minstrVec,
151 unsigned int N,
152 Instruction* vmInstr)
153{
154 if (N == 0)
155 return;
156 MachineCodeForVMInstr& mvec = vmInstr->getMachineInstrVec();
157 mvec.insert(mvec.end(), minstrVec, minstrVec+N);
158}
159
160
161
162//---------------------------------------------------------------------------
Vikram S. Adve6d353262001-10-17 23:57:50 +0000163// Function PostprocessMachineCodeForTree
164//
165// Apply any final cleanups to machine code for the root of a subtree
166// after selection for all its children has been completed.
167//---------------------------------------------------------------------------
168
Vikram S. Adve7ad10462001-10-22 13:51:09 +0000169static void
Vikram S. Adve6d353262001-10-17 23:57:50 +0000170PostprocessMachineCodeForTree(InstructionNode* instrNode,
171 int ruleForNode,
172 short* nts,
173 TargetMachine &target)
174{
175 // Fix up any constant operands in the machine instructions to either
176 // use an immediate field or to load the constant into a register
177 // Walk backwards and use direct indexes to allow insertion before current
178 //
179 Instruction* vmInstr = instrNode->getInstruction();
180 MachineCodeForVMInstr& mvec = vmInstr->getMachineInstrVec();
181 for (int i = (int) mvec.size()-1; i >= 0; i--)
182 {
183 vector<MachineInstr*> loadConstVec =
184 FixConstantOperandsForInstr(vmInstr, mvec[i], target);
185
186 if (loadConstVec.size() > 0)
187 mvec.insert(mvec.begin()+i, loadConstVec.begin(), loadConstVec.end());
188 }
189}
190
191//---------------------------------------------------------------------------
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000192// Function SelectInstructionsForTree
193//
194// Recursively walk the tree to select instructions.
195// Do this top-down so that child instructions can exploit decisions
196// made at the child instructions.
197//
198// E.g., if br(setle(reg,const)) decides the constant is 0 and uses
199// a branch-on-integer-register instruction, then the setle node
200// can use that information to avoid generating the SUBcc instruction.
201//
202// Note that this cannot be done bottom-up because setle must do this
203// only if it is a child of the branch (otherwise, the result of setle
204// may be used by multiple instructions).
205//---------------------------------------------------------------------------
206
Vikram S. Adve6e447182001-09-18 12:56:28 +0000207bool
208SelectInstructionsForTree(InstrTreeNode* treeRoot, int goalnt,
Vikram S. Adve6d353262001-10-17 23:57:50 +0000209 TargetMachine &target)
Vikram S. Adve6e447182001-09-18 12:56:28 +0000210{
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000211 // Get the rule that matches this node.
212 //
213 int ruleForNode = burm_rule(treeRoot->state, goalnt);
214
Vikram S. Adve6e447182001-09-18 12:56:28 +0000215 if (ruleForNode == 0)
216 {
217 cerr << "Could not match instruction tree for instr selection" << endl;
218 assert(0);
219 return true;
220 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000221
222 // Get this rule's non-terminals and the corresponding child nodes (if any)
223 //
224 short *nts = burm_nts[ruleForNode];
225
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000226 // First, select instructions for the current node and rule.
227 // (If this is a list node, not an instruction, then skip this step).
228 // This function is specific to the target architecture.
229 //
Vikram S. Adve6e447182001-09-18 12:56:28 +0000230 if (treeRoot->opLabel != VRegListOp)
231 {
232 InstructionNode* instrNode = (InstructionNode*)treeRoot;
233 assert(instrNode->getNodeType() == InstrTreeNode::NTInstructionNode);
Vikram S. Adve7ad10462001-10-22 13:51:09 +0000234
Vikram S. Adve6d353262001-10-17 23:57:50 +0000235 unsigned N = GetInstructionsByRule(instrNode, ruleForNode, nts, target,
Vikram S. Adve6e447182001-09-18 12:56:28 +0000236 minstrVec);
Vikram S. Adve7ad10462001-10-22 13:51:09 +0000237 if (N > 0)
238 {
239 assert(N <= MAX_INSTR_PER_VMINSTR);
240 AppendMachineCodeForVMInstr(minstrVec,N,instrNode->getInstruction());
241 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000242 }
243
244 // Then, recursively compile the child nodes, if any.
245 //
Vikram S. Adve6e447182001-09-18 12:56:28 +0000246 if (nts[0])
247 { // i.e., there is at least one kid
248 InstrTreeNode* kids[2];
249 int currentRule = ruleForNode;
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000250 burm_kids(treeRoot, currentRule, kids);
Vikram S. Adve6e447182001-09-18 12:56:28 +0000251
252 // First skip over any chain rules so that we don't visit
253 // the current node again.
254 //
255 while (ThisIsAChainRule(currentRule))
256 {
257 currentRule = burm_rule(treeRoot->state, nts[0]);
258 nts = burm_nts[currentRule];
259 burm_kids(treeRoot, currentRule, kids);
260 }
Chris Lattner0e6530e2001-09-14 03:37:52 +0000261
Vikram S. Adve6e447182001-09-18 12:56:28 +0000262 // Now we have the first non-chain rule so we have found
263 // the actual child nodes. Recursively compile them.
264 //
265 for (int i = 0; nts[i]; i++)
266 {
267 assert(i < 2);
268 InstrTreeNode::InstrTreeNodeType nodeType = kids[i]->getNodeType();
269 if (nodeType == InstrTreeNode::NTVRegListNode ||
270 nodeType == InstrTreeNode::NTInstructionNode)
271 {
Vikram S. Adve6d353262001-10-17 23:57:50 +0000272 if (SelectInstructionsForTree(kids[i], nts[i], target))
Vikram S. Adve6e447182001-09-18 12:56:28 +0000273 return true; // failure
274 }
275 }
Chris Lattner0e6530e2001-09-14 03:37:52 +0000276 }
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000277
Vikram S. Adve6d353262001-10-17 23:57:50 +0000278 // Finally, do any postprocessing on this node after its children
279 // have been translated
280 //
281 if (treeRoot->opLabel != VRegListOp)
282 {
283 InstructionNode* instrNode = (InstructionNode*)treeRoot;
284 PostprocessMachineCodeForTree(instrNode, ruleForNode, nts, target);
285 }
286
Vikram S. Adve70bc4b52001-07-21 12:41:50 +0000287 return false; // success
288}
289