LLVM API Documentation
00001 //===-- SparcV9TargetMachine.cpp - SparcV9 Target Machine Implementation --===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Primary interface to machine description for the UltraSPARC. Primarily just 00011 // initializes machine-dependent parameters in class TargetMachine, and creates 00012 // machine-dependent subclasses for classes such as TargetInstrInfo. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "llvm/Function.h" 00017 #include "llvm/PassManager.h" 00018 #include "llvm/Assembly/PrintModulePass.h" 00019 #include "llvm/CodeGen/InstrScheduling.h" 00020 #include "llvm/CodeGen/IntrinsicLowering.h" 00021 #include "llvm/CodeGen/MachineFunction.h" 00022 #include "llvm/CodeGen/Passes.h" 00023 #include "llvm/Target/TargetOptions.h" 00024 #include "llvm/Target/TargetMachineRegistry.h" 00025 #include "llvm/Transforms/Scalar.h" 00026 #include "MappingInfo.h" 00027 #include "MachineFunctionInfo.h" 00028 #include "MachineCodeForInstruction.h" 00029 #include "SparcV9Internals.h" 00030 #include "SparcV9TargetMachine.h" 00031 #include "SparcV9BurgISel.h" 00032 #include "llvm/Support/CommandLine.h" 00033 using namespace llvm; 00034 00035 static const unsigned ImplicitRegUseList[] = { 0 }; /* not used yet */ 00036 // Build the MachineInstruction Description Array... 00037 const TargetInstrDescriptor llvm::SparcV9MachineInstrDesc[] = { 00038 #define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \ 00039 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS) \ 00040 { OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \ 00041 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS, 0, \ 00042 ImplicitRegUseList, ImplicitRegUseList }, 00043 #include "SparcV9Instr.def" 00044 }; 00045 00046 //--------------------------------------------------------------------------- 00047 // Command line options to control choice of code generation passes. 00048 //--------------------------------------------------------------------------- 00049 00050 namespace llvm { 00051 bool EmitMappingInfo = false; 00052 } 00053 00054 namespace { 00055 cl::opt<bool> DisableSched("disable-sched", 00056 cl::desc("Disable local scheduling pass")); 00057 00058 cl::opt<bool> DisablePeephole("disable-peephole", 00059 cl::desc("Disable peephole optimization pass")); 00060 00061 cl::opt<bool, true> EmitMappingInfoOpt("enable-maps", 00062 cl::location(EmitMappingInfo), 00063 cl::init(false), 00064 cl::desc("Emit LLVM-to-MachineCode mapping info to assembly")); 00065 00066 cl::opt<bool> EnableModSched("enable-modsched", 00067 cl::desc("Enable modulo scheduling pass instead of local scheduling"), cl::Hidden); 00068 00069 // Register the target. 00070 RegisterTarget<SparcV9TargetMachine> X("sparcv9", " SPARC V9"); 00071 } 00072 00073 unsigned SparcV9TargetMachine::getJITMatchQuality() { 00074 #if defined(__sparcv9) 00075 return 10; 00076 #else 00077 return 0; 00078 #endif 00079 } 00080 00081 unsigned SparcV9TargetMachine::getModuleMatchQuality(const Module &M) { 00082 if (M.getEndianness() == Module::BigEndian && 00083 M.getPointerSize() == Module::Pointer64) 00084 return 10; // Direct match 00085 else if (M.getEndianness() != Module::AnyEndianness || 00086 M.getPointerSize() != Module::AnyPointerSize) 00087 return 0; // Match for some other target 00088 00089 return getJITMatchQuality()/2; 00090 } 00091 00092 //===---------------------------------------------------------------------===// 00093 // Code generation/destruction passes 00094 //===---------------------------------------------------------------------===// 00095 00096 namespace { 00097 class ConstructMachineFunction : public FunctionPass { 00098 TargetMachine &Target; 00099 public: 00100 ConstructMachineFunction(TargetMachine &T) : Target(T) {} 00101 00102 const char *getPassName() const { 00103 return "ConstructMachineFunction"; 00104 } 00105 00106 bool runOnFunction(Function &F) { 00107 MachineFunction::construct(&F, Target).getInfo<SparcV9FunctionInfo>()->CalculateArgSize(); 00108 return false; 00109 } 00110 }; 00111 00112 struct DestroyMachineFunction : public FunctionPass { 00113 const char *getPassName() const { return "DestroyMachineFunction"; } 00114 00115 static void freeMachineCode(Instruction &I) { 00116 MachineCodeForInstruction::destroy(&I); 00117 } 00118 00119 bool runOnFunction(Function &F) { 00120 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) 00121 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I) 00122 MachineCodeForInstruction::get(I).dropAllReferences(); 00123 00124 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) 00125 for_each(FI->begin(), FI->end(), freeMachineCode); 00126 00127 MachineFunction::destruct(&F); 00128 return false; 00129 } 00130 }; 00131 00132 FunctionPass *createMachineCodeConstructionPass(TargetMachine &Target) { 00133 return new ConstructMachineFunction(Target); 00134 } 00135 } 00136 00137 FunctionPass *llvm::createSparcV9MachineCodeDestructionPass() { 00138 return new DestroyMachineFunction(); 00139 } 00140 00141 00142 SparcV9TargetMachine::SparcV9TargetMachine(const Module &M, 00143 IntrinsicLowering *il) 00144 : TargetMachine("UltraSparcV9-Native", il, false), 00145 schedInfo(*this), 00146 regInfo(*this), 00147 frameInfo(*this), 00148 jitInfo(*this) { 00149 } 00150 00151 /// addPassesToEmitAssembly - This method controls the entire code generation 00152 /// process for the ultra sparc. 00153 /// 00154 bool 00155 SparcV9TargetMachine::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out) 00156 { 00157 // FIXME: Implement efficient support for garbage collection intrinsics. 00158 PM.add(createLowerGCPass()); 00159 00160 // Replace malloc and free instructions with library calls. 00161 PM.add(createLowerAllocationsPass()); 00162 00163 // FIXME: implement the switch instruction in the instruction selector. 00164 PM.add(createLowerSwitchPass()); 00165 00166 // FIXME: implement the invoke/unwind instructions! 00167 PM.add(createLowerInvokePass()); 00168 00169 // decompose multi-dimensional array references into single-dim refs 00170 PM.add(createDecomposeMultiDimRefsPass()); 00171 00172 // Lower LLVM code to the form expected by the SPARCv9 instruction selector. 00173 PM.add(createPreSelectionPass(*this)); 00174 PM.add(createLowerSelectPass()); 00175 00176 // Run basic LLVM dataflow optimizations, to clean up after pre-selection. 00177 PM.add(createReassociatePass()); 00178 PM.add(createLICMPass()); 00179 PM.add(createGCSEPass()); 00180 00181 // If the user's trying to read the generated code, they'll need to see the 00182 // transformed input. 00183 if (PrintMachineCode) 00184 PM.add(new PrintModulePass()); 00185 00186 // Construct and initialize the MachineFunction object for this fn. 00187 PM.add(createMachineCodeConstructionPass(*this)); 00188 00189 // Insert empty stackslots in the stack frame of each function 00190 // so %fp+offset-8 and %fp+offset-16 are empty slots now! 00191 PM.add(createStackSlotsPass(*this)); 00192 00193 PM.add(createSparcV9BurgInstSelector(*this)); 00194 00195 if(PrintMachineCode) 00196 PM.add(createMachineFunctionPrinterPass(&std::cerr, "Before modulo scheduling:\n")); 00197 00198 //Use ModuloScheduling if enabled, otherwise use local scheduling if not disabled. 00199 if(EnableModSched) 00200 PM.add(createModuloSchedulingPass(*this)); 00201 else { 00202 if (!DisableSched) 00203 PM.add(createInstructionSchedulingWithSSAPass(*this)); 00204 } 00205 00206 if (PrintMachineCode) 00207 PM.add(createMachineFunctionPrinterPass(&std::cerr, "Before reg alloc:\n")); 00208 00209 PM.add(getRegisterAllocator(*this)); 00210 00211 if (PrintMachineCode) 00212 PM.add(createMachineFunctionPrinterPass(&std::cerr, "After reg alloc:\n")); 00213 00214 PM.add(createPrologEpilogInsertionPass()); 00215 00216 if (!DisablePeephole) 00217 PM.add(createPeepholeOptsPass(*this)); 00218 00219 if (PrintMachineCode) 00220 PM.add(createMachineFunctionPrinterPass(&std::cerr, "Final code:\n")); 00221 00222 if (EmitMappingInfo) { 00223 PM.add(createInternalGlobalMapperPass()); 00224 PM.add(getMappingInfoAsmPrinterPass(Out)); 00225 } 00226 00227 // Output assembly language to the .s file. Assembly emission is split into 00228 // two parts: Function output and Global value output. This is because 00229 // function output is pipelined with all of the rest of code generation stuff, 00230 // allowing machine code representations for functions to be free'd after the 00231 // function has been emitted. 00232 PM.add(createAsmPrinterPass(Out, *this)); 00233 00234 // Free machine-code IR which is no longer needed: 00235 PM.add(createSparcV9MachineCodeDestructionPass()); 00236 00237 // Emit bytecode to the assembly file into its special section next 00238 if (EmitMappingInfo) 00239 PM.add(createBytecodeAsmPrinterPass(Out)); 00240 00241 return false; 00242 } 00243 00244 /// addPassesToJITCompile - This method controls the JIT method of code 00245 /// generation for the UltraSparcV9. 00246 /// 00247 void SparcV9JITInfo::addPassesToJITCompile(FunctionPassManager &PM) { 00248 // FIXME: Implement efficient support for garbage collection intrinsics. 00249 PM.add(createLowerGCPass()); 00250 00251 // Replace malloc and free instructions with library calls. 00252 PM.add(createLowerAllocationsPass()); 00253 00254 // FIXME: implement the switch instruction in the instruction selector. 00255 PM.add(createLowerSwitchPass()); 00256 00257 // FIXME: implement the invoke/unwind instructions! 00258 PM.add(createLowerInvokePass()); 00259 00260 // decompose multi-dimensional array references into single-dim refs 00261 PM.add(createDecomposeMultiDimRefsPass()); 00262 00263 // Lower LLVM code to the form expected by the SPARCv9 instruction selector. 00264 PM.add(createPreSelectionPass(TM)); 00265 PM.add(createLowerSelectPass()); 00266 00267 // Run basic LLVM dataflow optimizations, to clean up after pre-selection. 00268 PM.add(createReassociatePass()); 00269 // FIXME: these passes crash the FunctionPassManager when being added... 00270 //PM.add(createLICMPass()); 00271 //PM.add(createGCSEPass()); 00272 00273 // If the user's trying to read the generated code, they'll need to see the 00274 // transformed input. 00275 if (PrintMachineCode) 00276 PM.add(new PrintFunctionPass()); 00277 00278 // Construct and initialize the MachineFunction object for this fn. 00279 PM.add(createMachineCodeConstructionPass(TM)); 00280 00281 PM.add(createSparcV9BurgInstSelector(TM)); 00282 00283 if (PrintMachineCode) 00284 PM.add(createMachineFunctionPrinterPass(&std::cerr, "Before reg alloc:\n")); 00285 00286 PM.add(getRegisterAllocator(TM)); 00287 00288 if (PrintMachineCode) 00289 PM.add(createMachineFunctionPrinterPass(&std::cerr, "After reg alloc:\n")); 00290 00291 PM.add(createPrologEpilogInsertionPass()); 00292 00293 if (!DisablePeephole) 00294 PM.add(createPeepholeOptsPass(TM)); 00295 00296 if (PrintMachineCode) 00297 PM.add(createMachineFunctionPrinterPass(&std::cerr, "Final code:\n")); 00298 } 00299