blob: aac247adf71b3633d4e169f6b26eaa7356b69d8c [file] [log] [blame]
Vikram S. Adve0fb49802001-09-18 13:01:29 +00001// $Id$
Chris Lattner20b1ea02001-09-14 03:47:57 +00002//***************************************************************************
3// File:
4// Sparc.cpp
5//
6// Purpose:
7//
8// History:
9// 7/15/01 - Vikram Adve - Created
10//**************************************************************************/
11
Vikram S. Adve9db43182001-10-22 13:44:23 +000012
Chris Lattner20b1ea02001-09-14 03:47:57 +000013#include "SparcInternals.h"
Vikram S. Adve9db43182001-10-22 13:44:23 +000014#include "llvm/Target/Sparc.h"
Chris Lattner20b1ea02001-09-14 03:47:57 +000015#include "llvm/CodeGen/InstrScheduling.h"
16#include "llvm/CodeGen/InstrSelection.h"
Ruchira Sasankae38bd5332001-09-15 00:30:44 +000017#include "llvm/CodeGen/PhyRegAlloc.h"
Vikram S. Adve9db43182001-10-22 13:44:23 +000018#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
19#include "llvm/Method.h"
20
Ruchira Sasankae38bd5332001-09-15 00:30:44 +000021
Chris Lattner9a3d63b2001-09-19 15:56:23 +000022// Build the MachineInstruction Description Array...
23const MachineInstrDescriptor SparcMachineInstrDesc[] = {
24#define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
25 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS) \
26 { OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
27 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS },
28#include "SparcInstr.def"
29};
Vikram S. Adve0fb49802001-09-18 13:01:29 +000030
31//----------------------------------------------------------------------------
Chris Lattner46cbff62001-09-14 16:56:32 +000032// allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
33// that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
Vikram S. Adve0fb49802001-09-18 13:01:29 +000034//----------------------------------------------------------------------------
Chris Lattner46cbff62001-09-14 16:56:32 +000035//
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +000036
Chris Lattner46cbff62001-09-14 16:56:32 +000037TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
Chris Lattner20b1ea02001-09-14 03:47:57 +000038
39
Vikram S. Adve0fb49802001-09-18 13:01:29 +000040//----------------------------------------------------------------------------
41// Entry point for register allocation for a module
42//----------------------------------------------------------------------------
43
Vikram S. Adve9db43182001-10-22 13:44:23 +000044void AllocateRegisters(Method *M, TargetMachine &target)
Vikram S. Adve0fb49802001-09-18 13:01:29 +000045{
46
47 if ( (M)->isExternal() ) // don't process prototypes
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000048 return;
Vikram S. Adve0fb49802001-09-18 13:01:29 +000049
50 if( DEBUG_RA ) {
Chris Lattner1e23ed72001-10-15 18:15:27 +000051 cerr << endl << "******************** Method "<< (M)->getName();
52 cerr << " ********************" <<endl;
Vikram S. Adve0fb49802001-09-18 13:01:29 +000053 }
54
55 MethodLiveVarInfo LVI(M ); // Analyze live varaibles
56 LVI.analyze();
57
58
Vikram S. Adve9db43182001-10-22 13:44:23 +000059 PhyRegAlloc PRA(M, target, &LVI); // allocate registers
Vikram S. Adve0fb49802001-09-18 13:01:29 +000060 PRA.allocateRegisters();
61
62
Chris Lattner1e23ed72001-10-15 18:15:27 +000063 if( DEBUG_RA ) cerr << endl << "Register allocation complete!" << endl;
Vikram S. Adve0fb49802001-09-18 13:01:29 +000064
Vikram S. Adve0fb49802001-09-18 13:01:29 +000065}
66
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +000067
Vikram S. Adve9db43182001-10-22 13:44:23 +000068// Initialize the required area of the stack frame.
69static void
70InitializeFrameLayout(Method *method, TargetMachine &target)
71{
72 int minFrameSize = ((UltraSparc&) target).getFrameInfo().MinStackFrameSize;
73 method->getMachineCode().incrementStackSize(minFrameSize);
74}
75
76//---------------------------------------------------------------------------
77// Function InsertPrologCode
78// Function InsertEpilogCode
79// Function InsertPrologEpilog
80//
81// Insert prolog code at the unique method entry point.
82// Insert epilog code at each method exit point.
83// InsertPrologEpilog invokes these only if the method is not compiled
84// with the leaf method optimization.
85//---------------------------------------------------------------------------
86
87static MachineInstr* minstrVec[MAX_INSTR_PER_VMINSTR];
88
89static void
90InsertPrologCode(Method* method, TargetMachine& target)
91{
92 BasicBlock* entryBB = method->getEntryNode();
93 unsigned N = GetInstructionsForProlog(entryBB, target, minstrVec);
94 assert(N <= MAX_INSTR_PER_VMINSTR);
95 if (N > 0)
96 {
97 MachineCodeForBasicBlock& bbMvec = entryBB->getMachineInstrVec();
98 bbMvec.insert(bbMvec.begin(), minstrVec, minstrVec+N);
99 }
100}
101
102
103static void
104InsertEpilogCode(Method* method, TargetMachine& target)
105{
106 for (Method::iterator I=method->begin(), E=method->end(); I != E; ++I)
107 if ((*I)->getTerminator()->getOpcode() == Instruction::Ret)
108 {
109 BasicBlock* exitBB = *I;
110 unsigned N = GetInstructionsForEpilog(exitBB, target, minstrVec);
111
112 MachineCodeForBasicBlock& bbMvec = exitBB->getMachineInstrVec();
113 MachineCodeForVMInstr& termMvec =
114 exitBB->getTerminator()->getMachineInstrVec();
115
116 // Remove the NOPs in the delay slots of the return instruction
117 const MachineInstrInfo& mii = target.getInstrInfo();
118 unsigned numNOPs = 0;
119 while (termMvec.back()->getOpCode() == NOP)
120 {
121 assert( termMvec.back() == bbMvec.back());
122 termMvec.pop_back();
123 bbMvec.pop_back();
124 ++numNOPs;
125 }
126 assert(termMvec.back() == bbMvec.back());
127
128 // Check that we found the right number of NOPs and have the right
129 // number of instructions to replace them.
130 unsigned ndelays = mii.getNumDelaySlots(termMvec.back()->getOpCode());
131 assert(numNOPs == ndelays && "Missing NOPs in delay slots?");
132 assert(N == ndelays && "Cannot use epilog code for delay slots?");
133
134 // Append the epilog code to the end of the basic block.
135 bbMvec.push_back(minstrVec[0]);
136 }
137}
138
139
140// Insert SAVE/RESTORE instructions for the method
141static void
142InsertPrologEpilog(Method *method, TargetMachine &target)
143{
144 MachineCodeForMethod& mcodeInfo = method->getMachineCode();
145 if (mcodeInfo.isCompiledAsLeafMethod())
146 return; // nothing to do
147
148 InsertPrologCode(method, target);
149 InsertEpilogCode(method, target);
150}
151
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000152
Chris Lattner20b1ea02001-09-14 03:47:57 +0000153//---------------------------------------------------------------------------
Chris Lattner20b1ea02001-09-14 03:47:57 +0000154// class UltraSparcSchedInfo
155//
156// Purpose:
157// Scheduling information for the UltraSPARC.
158// Primarily just initializes machine-dependent parameters in
159// class MachineSchedInfo.
160//---------------------------------------------------------------------------
161
162/*ctor*/
163UltraSparcSchedInfo::UltraSparcSchedInfo(const MachineInstrInfo* mii)
164 : MachineSchedInfo((unsigned int) SPARC_NUM_SCHED_CLASSES,
165 mii,
166 SparcRUsageDesc,
167 SparcInstrUsageDeltas,
168 SparcInstrIssueDeltas,
169 sizeof(SparcInstrUsageDeltas)/sizeof(InstrRUsageDelta),
170 sizeof(SparcInstrIssueDeltas)/sizeof(InstrIssueDelta))
171{
172 maxNumIssueTotal = 4;
173 longestIssueConflict = 0; // computed from issuesGaps[]
174
175 branchMispredictPenalty = 4; // 4 for SPARC IIi
176 branchTargetUnknownPenalty = 2; // 2 for SPARC IIi
177 l1DCacheMissPenalty = 8; // 7 or 9 for SPARC IIi
178 l1ICacheMissPenalty = 8; // ? for SPARC IIi
179
180 inOrderLoads = true; // true for SPARC IIi
181 inOrderIssue = true; // true for SPARC IIi
182 inOrderExec = false; // false for most architectures
183 inOrderRetire= true; // true for most architectures
184
185 // must be called after above parameters are initialized.
186 this->initializeResources();
187}
188
189void
190UltraSparcSchedInfo::initializeResources()
191{
192 // Compute MachineSchedInfo::instrRUsages and MachineSchedInfo::issueGaps
193 MachineSchedInfo::initializeResources();
194
195 // Machine-dependent fixups go here. None for now.
196}
197
198
Vikram S. Adve9db43182001-10-22 13:44:23 +0000199//---------------------------------------------------------------------------
200// class UltraSparcFrameInfo
201//
202// Purpose:
203// Interface to stack frame layout info for the UltraSPARC.
204// Note that there is no machine-independent interface to this information
205//---------------------------------------------------------------------------
206
207int
208UltraSparcFrameInfo::getFirstAutomaticVarOffsetFromFP (const Method* method)
209{
210 return StaticStackAreaOffsetFromFP;
211}
212
213int
214UltraSparcFrameInfo::getRegSpillAreaOffsetFromFP(const Method* method)
215{
216 unsigned int autoVarsSize = method->getMachineCode().getAutomaticVarsSize();
217 return StaticStackAreaOffsetFromFP + autoVarsSize;
218}
219
220int
221UltraSparcFrameInfo::getFrameSizeBelowDynamicArea(const Method* method)
222{
223 unsigned int optArgsSize =
224 method->getMachineCode().getOptionalOutgoingArgsSize();
225 return optArgsSize + FirstOptionalOutgoingArgOffsetFromSP;
226}
227
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000228
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000229
Chris Lattner20b1ea02001-09-14 03:47:57 +0000230//---------------------------------------------------------------------------
231// class UltraSparcMachine
232//
233// Purpose:
234// Primary interface to machine description for the UltraSPARC.
235// Primarily just initializes machine-dependent parameters in
236// class TargetMachine, and creates machine-dependent subclasses
237// for classes such as MachineInstrInfo.
238//
239//---------------------------------------------------------------------------
240
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000241UltraSparc::UltraSparc()
242 : TargetMachine("UltraSparc-Native"),
243 instrInfo(),
244 schedInfo(&instrInfo),
Vikram S. Adve9db43182001-10-22 13:44:23 +0000245 regInfo( this ),
246 frameInfo()
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000247{
Chris Lattner20b1ea02001-09-14 03:47:57 +0000248 optSizeForSubWordData = 4;
249 minMemOpWordSize = 8;
250 maxAtomicMemOpWordSize = 8;
Chris Lattner20b1ea02001-09-14 03:47:57 +0000251}
252
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000253
Vikram S. Adve9db43182001-10-22 13:44:23 +0000254void
255ApplyPeepholeOptimizations(Method *method, TargetMachine &target)
256{
257 return;
258
259 // OptimizeLeafProcedures();
260 // DeleteFallThroughBranches();
261 // RemoveChainedBranches(); // should be folded with previous
262 // RemoveRedundantOps(); // operations with %g0, NOP, etc.
263}
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000264
265
266
Vikram S. Adve9db43182001-10-22 13:44:23 +0000267bool
268UltraSparc::compileMethod(Method *M)
269{
270 InitializeFrameLayout(M, *this); // initialize the required area of
271 // the stack frame
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000272 if (SelectInstructionsForMethod(M, *this))
273 {
274 cerr << "Instruction selection failed for method " << M->getName()
275 << "\n\n";
276 return true;
277 }
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000278
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000279 if (ScheduleInstructionsWithSSA(M, *this))
280 {
281 cerr << "Instruction scheduling before allocation failed for method "
282 << M->getName() << "\n\n";
283 return true;
284 }
Chris Lattner20b1ea02001-09-14 03:47:57 +0000285
Vikram S. Adve9db43182001-10-22 13:44:23 +0000286 AllocateRegisters(M, *this); // allocate registers
287
288 ApplyPeepholeOptimizations(M, *this); // machine-dependent peephole opts
289
290 InsertPrologEpilog(M, *this);
291
Chris Lattner20b1ea02001-09-14 03:47:57 +0000292 return false;
293}