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