aac247adf71b3633d4e169f6b26eaa7356b69d8c
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9TargetMachine.cpp
1 // $Id$
2 //***************************************************************************
3 // File:
4 //      Sparc.cpp
5 // 
6 // Purpose:
7 //      
8 // History:
9 //      7/15/01  -  Vikram Adve  -  Created
10 //**************************************************************************/
11
12
13 #include "SparcInternals.h"
14 #include "llvm/Target/Sparc.h"
15 #include "llvm/CodeGen/InstrScheduling.h"
16 #include "llvm/CodeGen/InstrSelection.h"
17 #include "llvm/CodeGen/PhyRegAlloc.h"
18 #include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
19 #include "llvm/Method.h"
20
21
22 // Build the MachineInstruction Description Array...
23 const 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 };
30
31 //----------------------------------------------------------------------------
32 // allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
33 // that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
34 //----------------------------------------------------------------------------
35 //
36
37 TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
38
39
40 //----------------------------------------------------------------------------
41 // Entry point for register allocation for a module
42 //----------------------------------------------------------------------------
43
44 void AllocateRegisters(Method *M, TargetMachine &target)
45 {
46  
47   if ( (M)->isExternal() )     // don't process prototypes
48     return;
49     
50   if( DEBUG_RA ) {
51     cerr << endl << "******************** Method "<< (M)->getName();
52     cerr <<        " ********************" <<endl;
53   }
54     
55   MethodLiveVarInfo LVI(M );   // Analyze live varaibles
56   LVI.analyze();
57   
58     
59   PhyRegAlloc PRA(M, target, &LVI); // allocate registers
60   PRA.allocateRegisters();
61     
62
63   if( DEBUG_RA )  cerr << endl << "Register allocation complete!" << endl;
64
65 }
66
67
68 // Initialize the required area of the stack frame.
69 static void
70 InitializeFrameLayout(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
87 static MachineInstr* minstrVec[MAX_INSTR_PER_VMINSTR];
88
89 static void
90 InsertPrologCode(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
103 static void
104 InsertEpilogCode(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
141 static void
142 InsertPrologEpilog(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
152
153 //---------------------------------------------------------------------------
154 // 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*/
163 UltraSparcSchedInfo::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
189 void
190 UltraSparcSchedInfo::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
199 //---------------------------------------------------------------------------
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
207 int
208 UltraSparcFrameInfo::getFirstAutomaticVarOffsetFromFP (const Method* method)
209 {
210   return StaticStackAreaOffsetFromFP;
211 }
212
213 int
214 UltraSparcFrameInfo::getRegSpillAreaOffsetFromFP(const Method* method)
215 {
216   unsigned int autoVarsSize = method->getMachineCode().getAutomaticVarsSize();
217   return  StaticStackAreaOffsetFromFP + autoVarsSize;
218 }
219
220 int
221 UltraSparcFrameInfo::getFrameSizeBelowDynamicArea(const Method* method)
222 {
223   unsigned int optArgsSize =
224     method->getMachineCode().getOptionalOutgoingArgsSize();
225   return optArgsSize + FirstOptionalOutgoingArgOffsetFromSP;
226 }
227
228
229
230 //---------------------------------------------------------------------------
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
241 UltraSparc::UltraSparc()
242   : TargetMachine("UltraSparc-Native"),
243     instrInfo(),
244     schedInfo(&instrInfo),
245     regInfo( this ),
246     frameInfo()
247 {
248   optSizeForSubWordData = 4;
249   minMemOpWordSize = 8; 
250   maxAtomicMemOpWordSize = 8;
251 }
252
253
254 void
255 ApplyPeepholeOptimizations(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 }
264
265
266
267 bool
268 UltraSparc::compileMethod(Method *M)
269 {
270   InitializeFrameLayout(M, *this);        // initialize the required area of
271                                           // the stack frame
272   if (SelectInstructionsForMethod(M, *this))
273     {
274       cerr << "Instruction selection failed for method " << M->getName()
275            << "\n\n";
276       return true;
277     }
278   
279   if (ScheduleInstructionsWithSSA(M, *this))
280     {
281       cerr << "Instruction scheduling before allocation failed for method "
282            << M->getName() << "\n\n";
283       return true;
284     }
285   
286   AllocateRegisters(M, *this);          // allocate registers
287   
288   ApplyPeepholeOptimizations(M, *this); // machine-dependent peephole opts
289   
290   InsertPrologEpilog(M, *this);
291   
292   return false;
293 }