1 //===-- Sparc.cpp - General implementation file for the Sparc Target ------===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
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.
14 //===----------------------------------------------------------------------===//
16 #include "llvm/Function.h"
17 #include "llvm/PassManager.h"
18 #include "llvm/Assembly/PrintModulePass.h"
19 #include "llvm/CodeGen/InstrSelection.h"
20 #include "llvm/CodeGen/InstrScheduling.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 #include "llvm/CodeGen/MachineFunctionInfo.h"
23 #include "llvm/CodeGen/MachineCodeForInstruction.h"
24 #include "llvm/CodeGen/Passes.h"
25 #include "llvm/Target/TargetMachineImpls.h"
26 #include "llvm/Transforms/Scalar.h"
27 #include "MappingInfo.h"
28 #include "SparcInternals.h"
29 #include "SparcTargetMachine.h"
30 #include "Support/CommandLine.h"
36 static const unsigned ImplicitRegUseList[] = { 0 }; /* not used yet */
37 // Build the MachineInstruction Description Array...
38 const TargetInstrDescriptor SparcMachineInstrDesc[] = {
39 #define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
40 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS) \
41 { OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
42 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS, 0, \
43 ImplicitRegUseList, ImplicitRegUseList },
44 #include "SparcInstr.def"
47 //---------------------------------------------------------------------------
48 // Command line options to control choice of code generation passes.
49 //---------------------------------------------------------------------------
52 cl::opt<bool> DisableSched("disable-sched",
53 cl::desc("Disable local scheduling pass"));
55 cl::opt<bool> DisablePeephole("disable-peephole",
56 cl::desc("Disable peephole optimization pass"));
58 cl::opt<bool> EmitMappingInfo("enable-maps",
59 cl::desc("Emit LLVM-to-MachineCode mapping info to assembly"));
61 cl::opt<bool> DisableStrip("disable-strip",
62 cl::desc("Do not strip the LLVM bytecode in executable"));
64 cl::opt<bool> DumpInput("dump-input",
65 cl::desc("Print bytecode before code generation"),
69 } // End llvm namespace
71 SparcTargetMachine::SparcTargetMachine()
72 : TargetMachine("UltraSparc-Native", false),
79 // addPassesToEmitAssembly - This method controls the entire code generation
80 // process for the ultra sparc.
83 SparcTargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out)
85 // The following 3 passes used to be inserted specially by llc.
86 // Replace malloc and free instructions with library calls.
87 PM.add(createLowerAllocationsPass());
89 // Strip all of the symbols from the bytecode so that it will be smaller...
91 PM.add(createSymbolStrippingPass());
93 // FIXME: implement the switch instruction in the instruction selector.
94 PM.add(createLowerSwitchPass());
96 // FIXME: implement the invoke/unwind instructions!
97 PM.add(createLowerInvokePass());
99 // decompose multi-dimensional array references into single-dim refs
100 PM.add(createDecomposeMultiDimRefsPass());
102 // Construct and initialize the MachineFunction object for this fn.
103 PM.add(createMachineCodeConstructionPass(*this));
105 //Insert empty stackslots in the stack frame of each function
106 //so %fp+offset-8 and %fp+offset-16 are empty slots now!
107 PM.add(createStackSlotsPass(*this));
109 // Specialize LLVM code for this target machine
110 PM.add(createPreSelectionPass(*this));
111 // Run basic dataflow optimizations on LLVM code
112 PM.add(createReassociatePass());
113 PM.add(createLICMPass());
114 PM.add(createGCSEPass());
116 // If LLVM dumping after transformations is requested, add it to the pipeline
118 PM.add(new PrintFunctionPass("Input code to instr. selection:\n",
121 PM.add(createInstructionSelectionPass(*this));
124 PM.add(createInstructionSchedulingWithSSAPass(*this));
126 PM.add(getRegisterAllocator(*this));
128 PM.add(createPrologEpilogInsertionPass());
130 if (!DisablePeephole)
131 PM.add(createPeepholeOptsPass(*this));
134 PM.add(getMappingInfoAsmPrinterPass(Out));
136 // Output assembly language to the .s file. Assembly emission is split into
137 // two parts: Function output and Global value output. This is because
138 // function output is pipelined with all of the rest of code generation stuff,
139 // allowing machine code representations for functions to be free'd after the
140 // function has been emitted.
142 PM.add(createAsmPrinterPass(Out, *this));
143 PM.add(createMachineCodeDestructionPass()); // Free stuff no longer needed
145 // Emit bytecode to the assembly file into its special section next
147 PM.add(createBytecodeAsmPrinterPass(Out));
152 // addPassesToJITCompile - This method controls the JIT method of code
153 // generation for the UltraSparc.
155 bool SparcTargetMachine::addPassesToJITCompile(FunctionPassManager &PM) {
156 const TargetData &TD = getTargetData();
158 PM.add(new TargetData("lli", TD.isLittleEndian(), TD.getPointerSize(),
159 TD.getPointerAlignment(), TD.getDoubleAlignment()));
161 // Replace malloc and free instructions with library calls.
162 // Do this after tracing until lli implements these lib calls.
163 // For now, it will emulate malloc and free internally.
164 PM.add(createLowerAllocationsPass());
166 // FIXME: implement the switch instruction in the instruction selector.
167 PM.add(createLowerSwitchPass());
169 // FIXME: implement the invoke/unwind instructions!
170 PM.add(createLowerInvokePass());
172 // decompose multi-dimensional array references into single-dim refs
173 PM.add(createDecomposeMultiDimRefsPass());
175 // Construct and initialize the MachineFunction object for this fn.
176 PM.add(createMachineCodeConstructionPass(*this));
178 // Specialize LLVM code for this target machine and then
179 // run basic dataflow optimizations on LLVM code.
180 PM.add(createPreSelectionPass(*this));
181 // Run basic dataflow optimizations on LLVM code
182 PM.add(createReassociatePass());
184 // FIXME: these passes crash the FunctionPassManager when being added...
185 //PM.add(createLICMPass());
186 //PM.add(createGCSEPass());
188 PM.add(createInstructionSelectionPass(*this));
190 PM.add(getRegisterAllocator(*this));
191 PM.add(createPrologEpilogInsertionPass());
193 if (!DisablePeephole)
194 PM.add(createPeepholeOptsPass(*this));
196 return false; // success!
199 //----------------------------------------------------------------------------
200 // allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
201 // that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
202 //----------------------------------------------------------------------------
206 TargetMachine *allocateSparcTargetMachine(const Module &M) {
207 return new SparcTargetMachine();