LLVM API Documentation

SparcV9TargetMachine.cpp

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