dac4d208da7e733e3dca637f842b307b01201df9
[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 #include "llvm/Target/Sparc.h"
13 #include "SparcInternals.h"
14 #include "llvm/Method.h"
15 #include "llvm/CodeGen/InstrScheduling.h"
16 #include "llvm/CodeGen/InstrSelection.h"
17
18 #include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
19 #include "llvm/CodeGen/PhyRegAlloc.h"
20
21 // Build the MachineInstruction Description Array...
22 const MachineInstrDescriptor SparcMachineInstrDesc[] = {
23 #define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
24           NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS)             \
25   { OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE,             \
26           NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS },
27 #include "SparcInstr.def"
28 };
29
30 //----------------------------------------------------------------------------
31 // allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
32 // that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
33 //----------------------------------------------------------------------------
34 //
35 TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
36
37
38
39 //----------------------------------------------------------------------------
40 // Entry point for register allocation for a module
41 //----------------------------------------------------------------------------
42
43 void AllocateRegisters(Method *M, TargetMachine &TM)
44 {
45  
46   if ( (M)->isExternal() )     // don't process prototypes
47     return;
48     
49   if( DEBUG_RA ) {
50     cout << endl << "******************** Method "<< (M)->getName();
51     cout <<        " ********************" <<endl;
52   }
53     
54   MethodLiveVarInfo LVI(M );   // Analyze live varaibles
55   LVI.analyze();
56   
57     
58   PhyRegAlloc PRA(M, TM , &LVI); // allocate registers
59   PRA.allocateRegisters();
60     
61
62   if( DEBUG_RA )  cout << endl << "Register allocation complete!" << endl;
63
64 }
65
66
67
68 //---------------------------------------------------------------------------
69 // class UltraSparcInstrInfo 
70 // 
71 // Purpose:
72 //   Information about individual instructions.
73 //   Most information is stored in the SparcMachineInstrDesc array above.
74 //   Other information is computed on demand, and most such functions
75 //   default to member functions in base class MachineInstrInfo. 
76 //---------------------------------------------------------------------------
77
78 /*ctor*/
79 UltraSparcInstrInfo::UltraSparcInstrInfo()
80   : MachineInstrInfo(SparcMachineInstrDesc,
81                      /*descSize = */ NUM_TOTAL_OPCODES,
82                      /*numRealOpCodes = */ NUM_REAL_OPCODES)
83 {
84 }
85
86
87 //---------------------------------------------------------------------------
88 // class UltraSparcSchedInfo 
89 // 
90 // Purpose:
91 //   Scheduling information for the UltraSPARC.
92 //   Primarily just initializes machine-dependent parameters in
93 //   class MachineSchedInfo.
94 //---------------------------------------------------------------------------
95
96 /*ctor*/
97 UltraSparcSchedInfo::UltraSparcSchedInfo(const MachineInstrInfo* mii)
98   : MachineSchedInfo((unsigned int) SPARC_NUM_SCHED_CLASSES,
99                      mii,
100                      SparcRUsageDesc,
101                      SparcInstrUsageDeltas,
102                      SparcInstrIssueDeltas,
103                      sizeof(SparcInstrUsageDeltas)/sizeof(InstrRUsageDelta),
104                      sizeof(SparcInstrIssueDeltas)/sizeof(InstrIssueDelta))
105 {
106   maxNumIssueTotal = 4;
107   longestIssueConflict = 0;             // computed from issuesGaps[]
108   
109   branchMispredictPenalty = 4;          // 4 for SPARC IIi
110   branchTargetUnknownPenalty = 2;       // 2 for SPARC IIi
111   l1DCacheMissPenalty = 8;              // 7 or 9 for SPARC IIi
112   l1ICacheMissPenalty = 8;              // ? for SPARC IIi
113   
114   inOrderLoads = true;                  // true for SPARC IIi
115   inOrderIssue = true;                  // true for SPARC IIi
116   inOrderExec  = false;                 // false for most architectures
117   inOrderRetire= true;                  // true for most architectures
118   
119   // must be called after above parameters are initialized.
120   this->initializeResources();
121 }
122
123 void
124 UltraSparcSchedInfo::initializeResources()
125 {
126   // Compute MachineSchedInfo::instrRUsages and MachineSchedInfo::issueGaps
127   MachineSchedInfo::initializeResources();
128   
129   // Machine-dependent fixups go here.  None for now.
130 }
131
132
133
134
135 //---------------------------------------------------------------------------
136 // class UltraSparcMachine 
137 // 
138 // Purpose:
139 //   Primary interface to machine description for the UltraSPARC.
140 //   Primarily just initializes machine-dependent parameters in
141 //   class TargetMachine, and creates machine-dependent subclasses
142 //   for classes such as MachineInstrInfo. 
143 // 
144 //---------------------------------------------------------------------------
145
146 UltraSparc::UltraSparc()
147   : TargetMachine("UltraSparc-Native"),
148     instrInfo(),
149     schedInfo(&instrInfo),
150     regInfo( this )
151 {
152   optSizeForSubWordData = 4;
153   minMemOpWordSize = 8; 
154   maxAtomicMemOpWordSize = 8;
155 }
156
157
158
159
160
161 bool UltraSparc::compileMethod(Method *M) {
162
163   if (SelectInstructionsForMethod(M, *this))
164     {
165       cerr << "Instruction selection failed for method " << M->getName()
166            << "\n\n";
167       return true;
168     }
169   
170   if (ScheduleInstructionsWithSSA(M, *this))
171     {
172       cerr << "Instruction scheduling before allocation failed for method "
173            << M->getName() << "\n\n";
174       return true;
175     }
176   
177   AllocateRegisters(M, *this);    // allocate registers
178
179
180   return false;
181 }
182
183
184