Home | History | Annotate | Download | only in CodeGen
      1 //===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the LLVMTargetMachine class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "llvm/Target/TargetMachine.h"
     15 #include "llvm/ADT/OwningPtr.h"
     16 #include "llvm/Assembly/PrintModulePass.h"
     17 #include "llvm/CodeGen/AsmPrinter.h"
     18 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
     19 #include "llvm/CodeGen/MachineModuleInfo.h"
     20 #include "llvm/CodeGen/Passes.h"
     21 #include "llvm/MC/MCAsmInfo.h"
     22 #include "llvm/MC/MCContext.h"
     23 #include "llvm/MC/MCInstrInfo.h"
     24 #include "llvm/MC/MCStreamer.h"
     25 #include "llvm/MC/MCSubtargetInfo.h"
     26 #include "llvm/PassManager.h"
     27 #include "llvm/Support/CommandLine.h"
     28 #include "llvm/Support/ErrorHandling.h"
     29 #include "llvm/Support/FormattedStream.h"
     30 #include "llvm/Support/TargetRegistry.h"
     31 #include "llvm/Target/TargetInstrInfo.h"
     32 #include "llvm/Target/TargetLowering.h"
     33 #include "llvm/Target/TargetLoweringObjectFile.h"
     34 #include "llvm/Target/TargetOptions.h"
     35 #include "llvm/Target/TargetRegisterInfo.h"
     36 #include "llvm/Target/TargetSubtargetInfo.h"
     37 #include "llvm/Transforms/Scalar.h"
     38 using namespace llvm;
     39 
     40 // Enable or disable FastISel. Both options are needed, because
     41 // FastISel is enabled by default with -fast, and we wish to be
     42 // able to enable or disable fast-isel independently from -O0.
     43 static cl::opt<cl::boolOrDefault>
     44 EnableFastISelOption("fast-isel", cl::Hidden,
     45   cl::desc("Enable the \"fast\" instruction selector"));
     46 
     47 static cl::opt<bool> ShowMCEncoding("show-mc-encoding", cl::Hidden,
     48     cl::desc("Show encoding in .s output"));
     49 static cl::opt<bool> ShowMCInst("show-mc-inst", cl::Hidden,
     50     cl::desc("Show instruction structure in .s output"));
     51 
     52 static cl::opt<cl::boolOrDefault>
     53 AsmVerbose("asm-verbose", cl::desc("Add comments to directives."),
     54            cl::init(cl::BOU_UNSET));
     55 
     56 static bool getVerboseAsm() {
     57   switch (AsmVerbose) {
     58   case cl::BOU_UNSET: return TargetMachine::getAsmVerbosityDefault();
     59   case cl::BOU_TRUE:  return true;
     60   case cl::BOU_FALSE: return false;
     61   }
     62   llvm_unreachable("Invalid verbose asm state");
     63 }
     64 
     65 void LLVMTargetMachine::initAsmInfo() {
     66   AsmInfo = TheTarget.createMCAsmInfo(*getRegisterInfo(), TargetTriple);
     67   // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0,
     68   // and if the old one gets included then MCAsmInfo will be NULL and
     69   // we'll crash later.
     70   // Provide the user with a useful error message about what's wrong.
     71   assert(AsmInfo && "MCAsmInfo not initialized. "
     72          "Make sure you include the correct TargetSelect.h"
     73          "and that InitializeAllTargetMCs() is being invoked!");
     74 }
     75 
     76 LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple,
     77                                      StringRef CPU, StringRef FS,
     78                                      TargetOptions Options,
     79                                      Reloc::Model RM, CodeModel::Model CM,
     80                                      CodeGenOpt::Level OL)
     81   : TargetMachine(T, Triple, CPU, FS, Options) {
     82   CodeGenInfo = T.createMCCodeGenInfo(Triple, RM, CM, OL);
     83 }
     84 
     85 void LLVMTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
     86   PM.add(createBasicTargetTransformInfoPass(this));
     87 }
     88 
     89 /// addPassesToX helper drives creation and initialization of TargetPassConfig.
     90 static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM,
     91                                           PassManagerBase &PM,
     92                                           bool DisableVerify,
     93                                           AnalysisID StartAfter,
     94                                           AnalysisID StopAfter) {
     95   // Targets may override createPassConfig to provide a target-specific sublass.
     96   TargetPassConfig *PassConfig = TM->createPassConfig(PM);
     97   PassConfig->setStartStopPasses(StartAfter, StopAfter);
     98 
     99   // Set PassConfig options provided by TargetMachine.
    100   PassConfig->setDisableVerify(DisableVerify);
    101 
    102   PM.add(PassConfig);
    103 
    104   PassConfig->addIRPasses();
    105 
    106   PassConfig->addCodeGenPrepare();
    107 
    108   PassConfig->addPassesToHandleExceptions();
    109 
    110   PassConfig->addISelPrepare();
    111 
    112   // Install a MachineModuleInfo class, which is an immutable pass that holds
    113   // all the per-module stuff we're generating, including MCContext.
    114   MachineModuleInfo *MMI =
    115     new MachineModuleInfo(*TM->getMCAsmInfo(), *TM->getRegisterInfo(),
    116                           &TM->getTargetLowering()->getObjFileLowering());
    117   PM.add(MMI);
    118 
    119   // Set up a MachineFunction for the rest of CodeGen to work on.
    120   PM.add(new MachineFunctionAnalysis(*TM));
    121 
    122   // Enable FastISel with -fast, but allow that to be overridden.
    123   if (EnableFastISelOption == cl::BOU_TRUE ||
    124       (TM->getOptLevel() == CodeGenOpt::None &&
    125        EnableFastISelOption != cl::BOU_FALSE))
    126     TM->setFastISel(true);
    127 
    128   // Ask the target for an isel.
    129   if (PassConfig->addInstSelector())
    130     return NULL;
    131 
    132   PassConfig->addMachinePasses();
    133 
    134   PassConfig->setInitialized();
    135 
    136   return &MMI->getContext();
    137 }
    138 
    139 bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
    140                                             formatted_raw_ostream &Out,
    141                                             CodeGenFileType FileType,
    142                                             bool DisableVerify,
    143                                             AnalysisID StartAfter,
    144                                             AnalysisID StopAfter) {
    145   // Add common CodeGen passes.
    146   MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify,
    147                                                StartAfter, StopAfter);
    148   if (!Context)
    149     return true;
    150 
    151   if (StopAfter) {
    152     // FIXME: The intent is that this should eventually write out a YAML file,
    153     // containing the LLVM IR, the machine-level IR (when stopping after a
    154     // machine-level pass), and whatever other information is needed to
    155     // deserialize the code and resume compilation.  For now, just write the
    156     // LLVM IR.
    157     PM.add(createPrintModulePass(&Out));
    158     return false;
    159   }
    160 
    161   if (hasMCSaveTempLabels())
    162     Context->setAllowTemporaryLabels(false);
    163 
    164   const MCAsmInfo &MAI = *getMCAsmInfo();
    165   const MCRegisterInfo &MRI = *getRegisterInfo();
    166   const MCInstrInfo &MII = *getInstrInfo();
    167   const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
    168   OwningPtr<MCStreamer> AsmStreamer;
    169 
    170   switch (FileType) {
    171   case CGFT_AssemblyFile: {
    172     MCInstPrinter *InstPrinter =
    173       getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI,
    174                                       MII, MRI, STI);
    175 
    176     // Create a code emitter if asked to show the encoding.
    177     MCCodeEmitter *MCE = 0;
    178     MCAsmBackend *MAB = 0;
    179     if (ShowMCEncoding) {
    180       MCE = getTarget().createMCCodeEmitter(MII, MRI, STI, *Context);
    181       MAB = getTarget().createMCAsmBackend(getTargetTriple(), TargetCPU);
    182     }
    183 
    184     MCStreamer *S = getTarget().createAsmStreamer(*Context, Out,
    185                                                   getVerboseAsm(),
    186                                                   hasMCUseLoc(),
    187                                                   hasMCUseCFI(),
    188                                                   hasMCUseDwarfDirectory(),
    189                                                   InstPrinter,
    190                                                   MCE, MAB,
    191                                                   ShowMCInst);
    192     AsmStreamer.reset(S);
    193     break;
    194   }
    195   case CGFT_ObjectFile: {
    196     // Create the code emitter for the target if it exists.  If not, .o file
    197     // emission fails.
    198     MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, STI,
    199                                                          *Context);
    200     MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple(),
    201                                                        TargetCPU);
    202     if (MCE == 0 || MAB == 0)
    203       return true;
    204 
    205     AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(),
    206                                                          *Context, *MAB, Out,
    207                                                          MCE, hasMCRelaxAll(),
    208                                                          hasMCNoExecStack()));
    209     AsmStreamer.get()->setAutoInitSections(true);
    210     break;
    211   }
    212   case CGFT_Null:
    213     // The Null output is intended for use for performance analysis and testing,
    214     // not real users.
    215     AsmStreamer.reset(createNullStreamer(*Context));
    216     break;
    217   }
    218 
    219   // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
    220   FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer);
    221   if (Printer == 0)
    222     return true;
    223 
    224   // If successful, createAsmPrinter took ownership of AsmStreamer.
    225   AsmStreamer.take();
    226 
    227   PM.add(Printer);
    228 
    229   return false;
    230 }
    231 
    232 /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
    233 /// get machine code emitted.  This uses a JITCodeEmitter object to handle
    234 /// actually outputting the machine code and resolving things like the address
    235 /// of functions.  This method should returns true if machine code emission is
    236 /// not supported.
    237 ///
    238 bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
    239                                                    JITCodeEmitter &JCE,
    240                                                    bool DisableVerify) {
    241   // Add common CodeGen passes.
    242   MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify, 0, 0);
    243   if (!Context)
    244     return true;
    245 
    246   addCodeEmitter(PM, JCE);
    247 
    248   return false; // success!
    249 }
    250 
    251 /// addPassesToEmitMC - Add passes to the specified pass manager to get
    252 /// machine code emitted with the MCJIT. This method returns true if machine
    253 /// code is not supported. It fills the MCContext Ctx pointer which can be
    254 /// used to build custom MCStreamer.
    255 ///
    256 bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
    257                                           MCContext *&Ctx,
    258                                           raw_ostream &Out,
    259                                           bool DisableVerify) {
    260   // Add common CodeGen passes.
    261   Ctx = addPassesToGenerateCode(this, PM, DisableVerify, 0, 0);
    262   if (!Ctx)
    263     return true;
    264 
    265   if (hasMCSaveTempLabels())
    266     Ctx->setAllowTemporaryLabels(false);
    267 
    268   // Create the code emitter for the target if it exists.  If not, .o file
    269   // emission fails.
    270   const MCRegisterInfo &MRI = *getRegisterInfo();
    271   const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
    272   MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI,
    273                                                        STI, *Ctx);
    274   MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple(), TargetCPU);
    275   if (MCE == 0 || MAB == 0)
    276     return true;
    277 
    278   OwningPtr<MCStreamer> AsmStreamer;
    279   AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(), *Ctx,
    280                                                        *MAB, Out, MCE,
    281                                                        hasMCRelaxAll(),
    282                                                        hasMCNoExecStack()));
    283   AsmStreamer.get()->InitSections();
    284 
    285   // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
    286   FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer);
    287   if (Printer == 0)
    288     return true;
    289 
    290   // If successful, createAsmPrinter took ownership of AsmStreamer.
    291   AsmStreamer.take();
    292 
    293   PM.add(Printer);
    294 
    295   return false; // success!
    296 }
    297