2 //***************************************************************************
9 // 7/15/01 - Vikram Adve - Created
10 //**************************************************************************/
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"
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"
31 //----------------------------------------------------------------------------
32 // allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
33 // that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
34 //----------------------------------------------------------------------------
37 TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
40 //----------------------------------------------------------------------------
41 // Entry point for register allocation for a module
42 //----------------------------------------------------------------------------
44 void AllocateRegisters(Method *M, TargetMachine &target)
47 if ( (M)->isExternal() ) // don't process prototypes
51 cerr << endl << "******************** Method "<< (M)->getName();
52 cerr << " ********************" <<endl;
55 MethodLiveVarInfo LVI(M ); // Analyze live varaibles
59 PhyRegAlloc PRA(M, target, &LVI); // allocate registers
60 PRA.allocateRegisters();
63 if( DEBUG_RA ) cerr << endl << "Register allocation complete!" << endl;
68 // Initialize the required area of the stack frame.
70 InitializeFrameLayout(Method *method, TargetMachine &target)
72 int minFrameSize = ((UltraSparc&) target).getFrameInfo().MinStackFrameSize;
73 method->getMachineCode().incrementStackSize(minFrameSize);
76 //---------------------------------------------------------------------------
77 // Function InsertPrologCode
78 // Function InsertEpilogCode
79 // Function InsertPrologEpilog
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 //---------------------------------------------------------------------------
87 static MachineInstr* minstrVec[MAX_INSTR_PER_VMINSTR];
90 InsertPrologCode(Method* method, TargetMachine& target)
92 BasicBlock* entryBB = method->getEntryNode();
93 unsigned N = GetInstructionsForProlog(entryBB, target, minstrVec);
94 assert(N <= MAX_INSTR_PER_VMINSTR);
97 MachineCodeForBasicBlock& bbMvec = entryBB->getMachineInstrVec();
98 bbMvec.insert(bbMvec.begin(), minstrVec, minstrVec+N);
104 InsertEpilogCode(Method* method, TargetMachine& target)
106 for (Method::iterator I=method->begin(), E=method->end(); I != E; ++I)
107 if ((*I)->getTerminator()->getOpcode() == Instruction::Ret)
109 BasicBlock* exitBB = *I;
110 unsigned N = GetInstructionsForEpilog(exitBB, target, minstrVec);
112 MachineCodeForBasicBlock& bbMvec = exitBB->getMachineInstrVec();
113 MachineCodeForVMInstr& termMvec =
114 exitBB->getTerminator()->getMachineInstrVec();
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)
121 assert( termMvec.back() == bbMvec.back());
126 assert(termMvec.back() == bbMvec.back());
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?");
134 // Append the epilog code to the end of the basic block.
135 bbMvec.push_back(minstrVec[0]);
140 // Insert SAVE/RESTORE instructions for the method
142 InsertPrologEpilog(Method *method, TargetMachine &target)
144 MachineCodeForMethod& mcodeInfo = method->getMachineCode();
145 if (mcodeInfo.isCompiledAsLeafMethod())
146 return; // nothing to do
148 InsertPrologCode(method, target);
149 InsertEpilogCode(method, target);
153 //---------------------------------------------------------------------------
154 // class UltraSparcSchedInfo
157 // Scheduling information for the UltraSPARC.
158 // Primarily just initializes machine-dependent parameters in
159 // class MachineSchedInfo.
160 //---------------------------------------------------------------------------
163 UltraSparcSchedInfo::UltraSparcSchedInfo(const MachineInstrInfo* mii)
164 : MachineSchedInfo((unsigned int) SPARC_NUM_SCHED_CLASSES,
167 SparcInstrUsageDeltas,
168 SparcInstrIssueDeltas,
169 sizeof(SparcInstrUsageDeltas)/sizeof(InstrRUsageDelta),
170 sizeof(SparcInstrIssueDeltas)/sizeof(InstrIssueDelta))
172 maxNumIssueTotal = 4;
173 longestIssueConflict = 0; // computed from issuesGaps[]
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
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
185 // must be called after above parameters are initialized.
186 this->initializeResources();
190 UltraSparcSchedInfo::initializeResources()
192 // Compute MachineSchedInfo::instrRUsages and MachineSchedInfo::issueGaps
193 MachineSchedInfo::initializeResources();
195 // Machine-dependent fixups go here. None for now.
199 //---------------------------------------------------------------------------
200 // class UltraSparcFrameInfo
203 // Interface to stack frame layout info for the UltraSPARC.
204 // Note that there is no machine-independent interface to this information
205 //---------------------------------------------------------------------------
208 UltraSparcFrameInfo::getFirstAutomaticVarOffsetFromFP (const Method* method)
210 return StaticStackAreaOffsetFromFP;
214 UltraSparcFrameInfo::getRegSpillAreaOffsetFromFP(const Method* method)
216 unsigned int autoVarsSize = method->getMachineCode().getAutomaticVarsSize();
217 return StaticStackAreaOffsetFromFP + autoVarsSize;
221 UltraSparcFrameInfo::getFrameSizeBelowDynamicArea(const Method* method)
223 unsigned int optArgsSize =
224 method->getMachineCode().getOptionalOutgoingArgsSize();
225 return optArgsSize + FirstOptionalOutgoingArgOffsetFromSP;
230 //---------------------------------------------------------------------------
231 // class UltraSparcMachine
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.
239 //---------------------------------------------------------------------------
241 UltraSparc::UltraSparc()
242 : TargetMachine("UltraSparc-Native"),
244 schedInfo(&instrInfo),
248 optSizeForSubWordData = 4;
249 minMemOpWordSize = 8;
250 maxAtomicMemOpWordSize = 8;
255 ApplyPeepholeOptimizations(Method *method, TargetMachine &target)
259 // OptimizeLeafProcedures();
260 // DeleteFallThroughBranches();
261 // RemoveChainedBranches(); // should be folded with previous
262 // RemoveRedundantOps(); // operations with %g0, NOP, etc.
268 UltraSparc::compileMethod(Method *M)
270 InitializeFrameLayout(M, *this); // initialize the required area of
272 if (SelectInstructionsForMethod(M, *this))
274 cerr << "Instruction selection failed for method " << M->getName()
279 if (ScheduleInstructionsWithSSA(M, *this))
281 cerr << "Instruction scheduling before allocation failed for method "
282 << M->getName() << "\n\n";
286 AllocateRegisters(M, *this); // allocate registers
288 ApplyPeepholeOptimizations(M, *this); // machine-dependent peephole opts
290 InsertPrologEpilog(M, *this);