blob: 5b2c0b03e6cdd17cc1f8934cabcbe4f8e6d93ae7 [file] [log] [blame]
Brian Gaeke3ca4fcc2004-04-25 07:04:49 +00001//===-- SparcV9TargetMachine.cpp - SparcV9 Target Machine Implementation --===//
John Criswellb576c942003-10-20 19:43:21 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Misha Brukmand71295a2003-12-17 22:04:00 +00009//
10// Primary interface to machine description for the UltraSPARC. Primarily just
11// initializes machine-dependent parameters in class TargetMachine, and creates
12// machine-dependent subclasses for classes such as TargetInstrInfo.
13//
Chris Lattner1d21f3e2002-04-09 05:21:26 +000014//===----------------------------------------------------------------------===//
Vikram S. Adve9db43182001-10-22 13:44:23 +000015
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000016#include "llvm/Function.h"
Chris Lattner4f946372002-10-28 01:03:43 +000017#include "llvm/PassManager.h"
Chris Lattner48e60792003-08-13 02:38:16 +000018#include "llvm/Assembly/PrintModulePass.h"
Chris Lattner4f946372002-10-28 01:03:43 +000019#include "llvm/CodeGen/InstrScheduling.h"
Chris Lattner30483732004-06-20 07:49:54 +000020#include "llvm/CodeGen/IntrinsicLowering.h"
Misha Brukmand71295a2003-12-17 22:04:00 +000021#include "llvm/CodeGen/MachineFunction.h"
Chris Lattner56d22512003-09-30 22:24:00 +000022#include "llvm/CodeGen/Passes.h"
Chris Lattner0cf0c372004-07-11 04:17:10 +000023#include "llvm/Target/TargetOptions.h"
Chris Lattnerd36c9702004-07-11 02:48:49 +000024#include "llvm/Target/TargetMachineRegistry.h"
Misha Brukmand71295a2003-12-17 22:04:00 +000025#include "llvm/Transforms/Scalar.h"
26#include "MappingInfo.h"
Chris Lattner85015a02004-08-16 21:55:02 +000027#include "MachineFunctionInfo.h"
28#include "MachineCodeForInstruction.h"
Brian Gaekee3d68072004-02-25 18:44:15 +000029#include "SparcV9Internals.h"
30#include "SparcV9TargetMachine.h"
Brian Gaekeaceb7d82004-08-04 07:30:04 +000031#include "SparcV9BurgISel.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000032#include "llvm/Support/CommandLine.h"
Misha Brukmand71295a2003-12-17 22:04:00 +000033using namespace llvm;
34
Chris Lattner6af20402002-12-03 05:41:54 +000035static const unsigned ImplicitRegUseList[] = { 0 }; /* not used yet */
Chris Lattner9a3d63b2001-09-19 15:56:23 +000036// Build the MachineInstruction Description Array...
Brian Gaekee3d68072004-02-25 18:44:15 +000037const TargetInstrDescriptor llvm::SparcV9MachineInstrDesc[] = {
Chris Lattner9a3d63b2001-09-19 15:56:23 +000038#define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
39 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS) \
40 { OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
Chris Lattner6af20402002-12-03 05:41:54 +000041 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS, 0, \
42 ImplicitRegUseList, ImplicitRegUseList },
Brian Gaekee3d68072004-02-25 18:44:15 +000043#include "SparcV9Instr.def"
Chris Lattner9a3d63b2001-09-19 15:56:23 +000044};
Vikram S. Adve0fb49802001-09-18 13:01:29 +000045
Chris Lattner4f946372002-10-28 01:03:43 +000046//---------------------------------------------------------------------------
47// Command line options to control choice of code generation passes.
48//---------------------------------------------------------------------------
49
Brian Gaeke828c68a2004-09-30 20:20:01 +000050namespace llvm {
51 bool EmitMappingInfo = false;
52}
53
Misha Brukman1be1a232003-11-13 00:16:28 +000054namespace {
55 cl::opt<bool> DisableSched("disable-sched",
56 cl::desc("Disable local scheduling pass"));
Chris Lattner4f946372002-10-28 01:03:43 +000057
Misha Brukman1be1a232003-11-13 00:16:28 +000058 cl::opt<bool> DisablePeephole("disable-peephole",
Chris Lattner4f946372002-10-28 01:03:43 +000059 cl::desc("Disable peephole optimization pass"));
60
Brian Gaeke828c68a2004-09-30 20:20:01 +000061 cl::opt<bool, true> EmitMappingInfoOpt("enable-maps",
62 cl::location(EmitMappingInfo),
63 cl::init(false),
Misha Brukman1be1a232003-11-13 00:16:28 +000064 cl::desc("Emit LLVM-to-MachineCode mapping info to assembly"));
Brian Gaeke2e2f2dc2003-06-18 21:14:23 +000065
Misha Brukman1be1a232003-11-13 00:16:28 +000066 cl::opt<bool> DisableStrip("disable-strip",
67 cl::desc("Do not strip the LLVM bytecode in executable"));
Chris Lattnerd36c9702004-07-11 02:48:49 +000068
Tanya Lattner75e84192004-11-18 18:38:01 +000069
Tanya Lattnerdef57452004-11-19 23:34:33 +000070 cl::opt<bool> EnableModSched("enable-modsched",
71 cl::desc("Enable modulo scheduling pass instead of local scheduling"), cl::Hidden);
Tanya Lattner75e84192004-11-18 18:38:01 +000072
Chris Lattnerd36c9702004-07-11 02:48:49 +000073 // Register the target.
Chris Lattner71d24aa2004-07-11 03:27:42 +000074 RegisterTarget<SparcV9TargetMachine> X("sparcv9", " SPARC V9");
Chris Lattnerd36c9702004-07-11 02:48:49 +000075}
76
77unsigned SparcV9TargetMachine::getJITMatchQuality() {
Misha Brukman1155d312004-09-29 23:01:17 +000078#if defined(__sparcv9)
Chris Lattnerd36c9702004-07-11 02:48:49 +000079 return 10;
80#else
81 return 0;
82#endif
83}
84
85unsigned SparcV9TargetMachine::getModuleMatchQuality(const Module &M) {
86 if (M.getEndianness() == Module::BigEndian &&
87 M.getPointerSize() == Module::Pointer64)
88 return 10; // Direct match
89 else if (M.getEndianness() != Module::AnyEndianness ||
90 M.getPointerSize() != Module::AnyPointerSize)
91 return 0; // Match for some other target
92
93 return getJITMatchQuality()/2;
Misha Brukman1be1a232003-11-13 00:16:28 +000094}
Brian Gaeke2e2f2dc2003-06-18 21:14:23 +000095
Chris Lattner583b9d82003-12-20 09:17:40 +000096//===---------------------------------------------------------------------===//
97// Code generation/destruction passes
98//===---------------------------------------------------------------------===//
99
100namespace {
101 class ConstructMachineFunction : public FunctionPass {
102 TargetMachine &Target;
103 public:
104 ConstructMachineFunction(TargetMachine &T) : Target(T) {}
105
106 const char *getPassName() const {
107 return "ConstructMachineFunction";
108 }
109
110 bool runOnFunction(Function &F) {
Chris Lattnera1e51ff2004-08-18 18:13:37 +0000111 MachineFunction::construct(&F, Target).getInfo<SparcV9FunctionInfo>()->CalculateArgSize();
Chris Lattner583b9d82003-12-20 09:17:40 +0000112 return false;
113 }
114 };
115
116 struct DestroyMachineFunction : public FunctionPass {
Brian Gaeke3d1fdee2004-02-27 21:01:14 +0000117 const char *getPassName() const { return "DestroyMachineFunction"; }
Chris Lattner583b9d82003-12-20 09:17:40 +0000118
119 static void freeMachineCode(Instruction &I) {
120 MachineCodeForInstruction::destroy(&I);
121 }
122
123 bool runOnFunction(Function &F) {
124 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
125 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I)
126 MachineCodeForInstruction::get(I).dropAllReferences();
127
128 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
129 for_each(FI->begin(), FI->end(), freeMachineCode);
130
Misha Brukman36158452003-12-22 03:47:58 +0000131 MachineFunction::destruct(&F);
Chris Lattner583b9d82003-12-20 09:17:40 +0000132 return false;
133 }
134 };
135
136 FunctionPass *createMachineCodeConstructionPass(TargetMachine &Target) {
137 return new ConstructMachineFunction(Target);
138 }
139}
140
Brian Gaekee3d68072004-02-25 18:44:15 +0000141FunctionPass *llvm::createSparcV9MachineCodeDestructionPass() {
Chris Lattner583b9d82003-12-20 09:17:40 +0000142 return new DestroyMachineFunction();
143}
144
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +0000145
Chris Lattnerd36c9702004-07-11 02:48:49 +0000146SparcV9TargetMachine::SparcV9TargetMachine(const Module &M,
147 IntrinsicLowering *il)
Brian Gaekee3d68072004-02-25 18:44:15 +0000148 : TargetMachine("UltraSparcV9-Native", il, false),
Vikram S. Adve7f37fe52001-11-08 04:55:13 +0000149 schedInfo(*this),
150 regInfo(*this),
Vikram S. Adveb7048402001-11-09 02:16:04 +0000151 frameInfo(*this),
Chris Lattnerf70e0c22003-12-28 21:23:38 +0000152 jitInfo(*this) {
Chris Lattner20b1ea02001-09-14 03:47:57 +0000153}
154
Misha Brukman2647c392004-02-09 23:18:42 +0000155/// addPassesToEmitAssembly - This method controls the entire code generation
156/// process for the ultra sparc.
157///
Misha Brukmand71295a2003-12-17 22:04:00 +0000158bool
Brian Gaekee3d68072004-02-25 18:44:15 +0000159SparcV9TargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out)
Chris Lattner4f946372002-10-28 01:03:43 +0000160{
Chris Lattner99c59e82004-05-23 21:23:35 +0000161 // FIXME: Implement efficient support for garbage collection intrinsics.
162 PM.add(createLowerGCPass());
163
Brian Gaeke2e2f2dc2003-06-18 21:14:23 +0000164 // Replace malloc and free instructions with library calls.
165 PM.add(createLowerAllocationsPass());
166
Chris Lattner155e68f2003-04-23 16:24:55 +0000167 // FIXME: implement the switch instruction in the instruction selector.
168 PM.add(createLowerSwitchPass());
Chris Lattnerd324e252003-10-05 19:16:09 +0000169
170 // FIXME: implement the invoke/unwind instructions!
171 PM.add(createLowerInvokePass());
Brian Gaeke2e2f2dc2003-06-18 21:14:23 +0000172
Vikram S. Adve248932b2003-08-01 15:53:24 +0000173 // decompose multi-dimensional array references into single-dim refs
174 PM.add(createDecomposeMultiDimRefsPass());
Chris Lattner4f946372002-10-28 01:03:43 +0000175
Brian Gaeke79ee87b2004-04-02 17:52:40 +0000176 // Lower LLVM code to the form expected by the SPARCv9 instruction selector.
Misha Brukman35188172003-11-07 20:33:25 +0000177 PM.add(createPreSelectionPass(*this));
Brian Gaeke79ee87b2004-04-02 17:52:40 +0000178 PM.add(createLowerSelectPass());
179
180 // Run basic LLVM dataflow optimizations, to clean up after pre-selection.
Misha Brukman35188172003-11-07 20:33:25 +0000181 PM.add(createReassociatePass());
182 PM.add(createLICMPass());
183 PM.add(createGCSEPass());
184
Brian Gaekeb9851582004-05-28 19:33:59 +0000185 // If the user's trying to read the generated code, they'll need to see the
186 // transformed input.
187 if (PrintMachineCode)
188 PM.add(new PrintModulePass());
189
Brian Gaeke79ee87b2004-04-02 17:52:40 +0000190 // Construct and initialize the MachineFunction object for this fn.
191 PM.add(createMachineCodeConstructionPass(*this));
192
193 // Insert empty stackslots in the stack frame of each function
194 // so %fp+offset-8 and %fp+offset-16 are empty slots now!
195 PM.add(createStackSlotsPass(*this));
196
Brian Gaekeaceb7d82004-08-04 07:30:04 +0000197 PM.add(createSparcV9BurgInstSelector(*this));
Chris Lattner4f946372002-10-28 01:03:43 +0000198
Tanya Lattner75e84192004-11-18 18:38:01 +0000199 if(PrintMachineCode)
200 PM.add(createMachineFunctionPrinterPass(&std::cerr, "Before modulo scheduling:\n"));
Chris Lattner4f946372002-10-28 01:03:43 +0000201
Tanya Lattner75e84192004-11-18 18:38:01 +0000202 //Use ModuloScheduling if enabled, otherwise use local scheduling if not disabled.
203 if(EnableModSched)
204 PM.add(createModuloSchedulingPass(*this));
205 else {
206 if (!DisableSched)
207 PM.add(createInstructionSchedulingWithSSAPass(*this));
208 }
209
Brian Gaeke215fb762004-03-12 21:19:08 +0000210 if (PrintMachineCode)
211 PM.add(createMachineFunctionPrinterPass(&std::cerr, "Before reg alloc:\n"));
212
Chris Lattner4f946372002-10-28 01:03:43 +0000213 PM.add(getRegisterAllocator(*this));
Brian Gaeke323819e2004-03-04 19:16:23 +0000214
215 if (PrintMachineCode)
Brian Gaeke215fb762004-03-12 21:19:08 +0000216 PM.add(createMachineFunctionPrinterPass(&std::cerr, "After reg alloc:\n"));
Brian Gaeke323819e2004-03-04 19:16:23 +0000217
Misha Brukman1be1a232003-11-13 00:16:28 +0000218 PM.add(createPrologEpilogInsertionPass());
Chris Lattner4f946372002-10-28 01:03:43 +0000219
220 if (!DisablePeephole)
221 PM.add(createPeepholeOptsPass(*this));
222
Brian Gaekef3210d22004-06-14 05:05:45 +0000223 if (PrintMachineCode)
224 PM.add(createMachineFunctionPrinterPass(&std::cerr, "Final code:\n"));
225
Brian Gaeke58215952004-06-03 05:03:01 +0000226 if (EmitMappingInfo) {
227 PM.add(createInternalGlobalMapperPass());
228 PM.add(getMappingInfoAsmPrinterPass(Out));
229 }
Chris Lattner4f946372002-10-28 01:03:43 +0000230
231 // Output assembly language to the .s file. Assembly emission is split into
232 // two parts: Function output and Global value output. This is because
233 // function output is pipelined with all of the rest of code generation stuff,
234 // allowing machine code representations for functions to be free'd after the
235 // function has been emitted.
Misha Brukman1be1a232003-11-13 00:16:28 +0000236 PM.add(createAsmPrinterPass(Out, *this));
Brian Gaeke9f78bf22004-02-27 21:15:40 +0000237
Brian Gaeke9f78bf22004-02-27 21:15:40 +0000238 // Free machine-code IR which is no longer needed:
Chris Lattnerec726a12004-03-01 15:28:27 +0000239 PM.add(createSparcV9MachineCodeDestructionPass());
Chris Lattner4f946372002-10-28 01:03:43 +0000240
Chris Lattner4f946372002-10-28 01:03:43 +0000241 // Emit bytecode to the assembly file into its special section next
Brian Gaeke79ee87b2004-04-02 17:52:40 +0000242 if (EmitMappingInfo) {
243 // Strip all of the symbols from the bytecode so that it will be smaller...
244 if (!DisableStrip)
245 PM.add(createSymbolStrippingPass());
Misha Brukman1be1a232003-11-13 00:16:28 +0000246 PM.add(createBytecodeAsmPrinterPass(Out));
Brian Gaeke79ee87b2004-04-02 17:52:40 +0000247 }
248
Chris Lattner63342052002-10-29 21:12:46 +0000249 return false;
Chris Lattner4f946372002-10-28 01:03:43 +0000250}
Misha Brukman86172ab2003-05-27 22:24:48 +0000251
Misha Brukman2647c392004-02-09 23:18:42 +0000252/// addPassesToJITCompile - This method controls the JIT method of code
Brian Gaekee3d68072004-02-25 18:44:15 +0000253/// generation for the UltraSparcV9.
Misha Brukman2647c392004-02-09 23:18:42 +0000254///
Brian Gaekee3d68072004-02-25 18:44:15 +0000255void SparcV9JITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
Chris Lattner99c59e82004-05-23 21:23:35 +0000256 // FIXME: Implement efficient support for garbage collection intrinsics.
257 PM.add(createLowerGCPass());
258
Misha Brukmana5124502003-06-06 07:11:16 +0000259 // Replace malloc and free instructions with library calls.
Misha Brukmana5124502003-06-06 07:11:16 +0000260 PM.add(createLowerAllocationsPass());
Brian Gaeke79ee87b2004-04-02 17:52:40 +0000261
Misha Brukman86172ab2003-05-27 22:24:48 +0000262 // FIXME: implement the switch instruction in the instruction selector.
263 PM.add(createLowerSwitchPass());
264
Chris Lattnerd324e252003-10-05 19:16:09 +0000265 // FIXME: implement the invoke/unwind instructions!
266 PM.add(createLowerInvokePass());
Brian Gaeke79ee87b2004-04-02 17:52:40 +0000267
Misha Brukman58ba50f2003-08-06 23:06:21 +0000268 // decompose multi-dimensional array references into single-dim refs
269 PM.add(createDecomposeMultiDimRefsPass());
Misha Brukman86172ab2003-05-27 22:24:48 +0000270
Brian Gaeke79ee87b2004-04-02 17:52:40 +0000271 // Lower LLVM code to the form expected by the SPARCv9 instruction selector.
Chris Lattner1e60a912003-12-20 01:22:19 +0000272 PM.add(createPreSelectionPass(TM));
Brian Gaeke79ee87b2004-04-02 17:52:40 +0000273 PM.add(createLowerSelectPass());
274
275 // Run basic LLVM dataflow optimizations, to clean up after pre-selection.
Misha Brukman35188172003-11-07 20:33:25 +0000276 PM.add(createReassociatePass());
Misha Brukman6d2670d2003-11-08 00:01:39 +0000277 // FIXME: these passes crash the FunctionPassManager when being added...
278 //PM.add(createLICMPass());
279 //PM.add(createGCSEPass());
Misha Brukman35188172003-11-07 20:33:25 +0000280
Brian Gaekef3210d22004-06-14 05:05:45 +0000281 // If the user's trying to read the generated code, they'll need to see the
282 // transformed input.
283 if (PrintMachineCode)
284 PM.add(new PrintFunctionPass());
285
Brian Gaeke79ee87b2004-04-02 17:52:40 +0000286 // Construct and initialize the MachineFunction object for this fn.
287 PM.add(createMachineCodeConstructionPass(TM));
288
Brian Gaekeaceb7d82004-08-04 07:30:04 +0000289 PM.add(createSparcV9BurgInstSelector(TM));
Misha Brukman86172ab2003-05-27 22:24:48 +0000290
Brian Gaeke79ee87b2004-04-02 17:52:40 +0000291 if (PrintMachineCode)
292 PM.add(createMachineFunctionPrinterPass(&std::cerr, "Before reg alloc:\n"));
293
Chris Lattner1e60a912003-12-20 01:22:19 +0000294 PM.add(getRegisterAllocator(TM));
Brian Gaeke79ee87b2004-04-02 17:52:40 +0000295
296 if (PrintMachineCode)
297 PM.add(createMachineFunctionPrinterPass(&std::cerr, "After reg alloc:\n"));
298
Misha Brukman1be1a232003-11-13 00:16:28 +0000299 PM.add(createPrologEpilogInsertionPass());
Misha Brukman86172ab2003-05-27 22:24:48 +0000300
Misha Brukmand1ef7a82003-05-30 20:00:13 +0000301 if (!DisablePeephole)
Chris Lattner1e60a912003-12-20 01:22:19 +0000302 PM.add(createPeepholeOptsPass(TM));
Brian Gaekef3210d22004-06-14 05:05:45 +0000303
304 if (PrintMachineCode)
305 PM.add(createMachineFunctionPrinterPass(&std::cerr, "Final code:\n"));
Misha Brukman86172ab2003-05-27 22:24:48 +0000306}
Brian Gaeked0fde302003-11-11 22:41:34 +0000307