LLVM API Documentation
00001 //===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the LLVMTargetMachine class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Target/TargetMachine.h" 00015 00016 #include "llvm/Analysis/Passes.h" 00017 #include "llvm/CodeGen/AsmPrinter.h" 00018 #include "llvm/CodeGen/JumpInstrTables.h" 00019 #include "llvm/CodeGen/MachineFunctionAnalysis.h" 00020 #include "llvm/CodeGen/MachineModuleInfo.h" 00021 #include "llvm/CodeGen/Passes.h" 00022 #include "llvm/IR/IRPrintingPasses.h" 00023 #include "llvm/IR/Verifier.h" 00024 #include "llvm/MC/MCAsmInfo.h" 00025 #include "llvm/MC/MCContext.h" 00026 #include "llvm/MC/MCInstrInfo.h" 00027 #include "llvm/MC/MCStreamer.h" 00028 #include "llvm/MC/MCSubtargetInfo.h" 00029 #include "llvm/PassManager.h" 00030 #include "llvm/Support/CommandLine.h" 00031 #include "llvm/Support/ErrorHandling.h" 00032 #include "llvm/Support/FormattedStream.h" 00033 #include "llvm/Support/TargetRegistry.h" 00034 #include "llvm/Target/TargetInstrInfo.h" 00035 #include "llvm/Target/TargetLowering.h" 00036 #include "llvm/Target/TargetLoweringObjectFile.h" 00037 #include "llvm/Target/TargetOptions.h" 00038 #include "llvm/Target/TargetRegisterInfo.h" 00039 #include "llvm/Target/TargetSubtargetInfo.h" 00040 #include "llvm/Transforms/Scalar.h" 00041 using namespace llvm; 00042 00043 // Enable or disable FastISel. Both options are needed, because 00044 // FastISel is enabled by default with -fast, and we wish to be 00045 // able to enable or disable fast-isel independently from -O0. 00046 static cl::opt<cl::boolOrDefault> 00047 EnableFastISelOption("fast-isel", cl::Hidden, 00048 cl::desc("Enable the \"fast\" instruction selector")); 00049 00050 void LLVMTargetMachine::initAsmInfo() { 00051 MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo( 00052 *getSubtargetImpl()->getRegisterInfo(), getTargetTriple()); 00053 // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0, 00054 // and if the old one gets included then MCAsmInfo will be NULL and 00055 // we'll crash later. 00056 // Provide the user with a useful error message about what's wrong. 00057 assert(TmpAsmInfo && "MCAsmInfo not initialized. " 00058 "Make sure you include the correct TargetSelect.h" 00059 "and that InitializeAllTargetMCs() is being invoked!"); 00060 00061 if (Options.DisableIntegratedAS) 00062 TmpAsmInfo->setUseIntegratedAssembler(false); 00063 00064 if (Options.CompressDebugSections) 00065 TmpAsmInfo->setCompressDebugSections(true); 00066 00067 AsmInfo = TmpAsmInfo; 00068 } 00069 00070 LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple, 00071 StringRef CPU, StringRef FS, 00072 TargetOptions Options, 00073 Reloc::Model RM, CodeModel::Model CM, 00074 CodeGenOpt::Level OL) 00075 : TargetMachine(T, Triple, CPU, FS, Options) { 00076 CodeGenInfo = T.createMCCodeGenInfo(Triple, RM, CM, OL); 00077 } 00078 00079 void LLVMTargetMachine::addAnalysisPasses(PassManagerBase &PM) { 00080 PM.add(createBasicTargetTransformInfoPass(this)); 00081 } 00082 00083 /// addPassesToX helper drives creation and initialization of TargetPassConfig. 00084 static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM, 00085 PassManagerBase &PM, 00086 bool DisableVerify, 00087 AnalysisID StartAfter, 00088 AnalysisID StopAfter) { 00089 00090 // Add internal analysis passes from the target machine. 00091 TM->addAnalysisPasses(PM); 00092 00093 // Targets may override createPassConfig to provide a target-specific 00094 // subclass. 00095 TargetPassConfig *PassConfig = TM->createPassConfig(PM); 00096 PassConfig->setStartStopPasses(StartAfter, StopAfter); 00097 00098 // Set PassConfig options provided by TargetMachine. 00099 PassConfig->setDisableVerify(DisableVerify); 00100 00101 PM.add(PassConfig); 00102 00103 PassConfig->addIRPasses(); 00104 00105 PassConfig->addCodeGenPrepare(); 00106 00107 PassConfig->addPassesToHandleExceptions(); 00108 00109 PassConfig->addISelPrepare(); 00110 00111 // Install a MachineModuleInfo class, which is an immutable pass that holds 00112 // all the per-module stuff we're generating, including MCContext. 00113 MachineModuleInfo *MMI = new MachineModuleInfo( 00114 *TM->getMCAsmInfo(), *TM->getSubtargetImpl()->getRegisterInfo(), 00115 &TM->getSubtargetImpl()->getTargetLowering()->getObjFileLowering()); 00116 PM.add(MMI); 00117 00118 // Set up a MachineFunction for the rest of CodeGen to work on. 00119 PM.add(new MachineFunctionAnalysis(*TM)); 00120 00121 // Enable FastISel with -fast, but allow that to be overridden. 00122 if (EnableFastISelOption == cl::BOU_TRUE || 00123 (TM->getOptLevel() == CodeGenOpt::None && 00124 EnableFastISelOption != cl::BOU_FALSE)) 00125 TM->setFastISel(true); 00126 00127 // Ask the target for an isel. 00128 if (PassConfig->addInstSelector()) 00129 return nullptr; 00130 00131 PassConfig->addMachinePasses(); 00132 00133 PassConfig->setInitialized(); 00134 00135 return &MMI->getContext(); 00136 } 00137 00138 bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, 00139 formatted_raw_ostream &Out, 00140 CodeGenFileType FileType, 00141 bool DisableVerify, 00142 AnalysisID StartAfter, 00143 AnalysisID StopAfter) { 00144 // Passes to handle jumptable function annotations. These can't be handled at 00145 // JIT time, so we don't add them directly to addPassesToGenerateCode. 00146 PM.add(createJumpInstrTableInfoPass()); 00147 PM.add(createJumpInstrTablesPass(Options.JTType)); 00148 00149 // Add common CodeGen passes. 00150 MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify, 00151 StartAfter, StopAfter); 00152 if (!Context) 00153 return true; 00154 00155 if (StopAfter) { 00156 // FIXME: The intent is that this should eventually write out a YAML file, 00157 // containing the LLVM IR, the machine-level IR (when stopping after a 00158 // machine-level pass), and whatever other information is needed to 00159 // deserialize the code and resume compilation. For now, just write the 00160 // LLVM IR. 00161 PM.add(createPrintModulePass(Out)); 00162 return false; 00163 } 00164 00165 if (Options.MCOptions.MCSaveTempLabels) 00166 Context->setAllowTemporaryLabels(false); 00167 00168 const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); 00169 const MCAsmInfo &MAI = *getMCAsmInfo(); 00170 const MCRegisterInfo &MRI = *getSubtargetImpl()->getRegisterInfo(); 00171 const MCInstrInfo &MII = *getSubtargetImpl()->getInstrInfo(); 00172 std::unique_ptr<MCStreamer> AsmStreamer; 00173 00174 switch (FileType) { 00175 case CGFT_AssemblyFile: { 00176 MCInstPrinter *InstPrinter = 00177 getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, 00178 MII, MRI, STI); 00179 00180 // Create a code emitter if asked to show the encoding. 00181 MCCodeEmitter *MCE = nullptr; 00182 if (Options.MCOptions.ShowMCEncoding) 00183 MCE = getTarget().createMCCodeEmitter(MII, MRI, STI, *Context); 00184 00185 MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(), 00186 TargetCPU); 00187 MCStreamer *S = getTarget().createAsmStreamer( 00188 *Context, Out, Options.MCOptions.AsmVerbose, 00189 Options.MCOptions.MCUseDwarfDirectory, InstPrinter, MCE, MAB, 00190 Options.MCOptions.ShowMCInst); 00191 AsmStreamer.reset(S); 00192 break; 00193 } 00194 case CGFT_ObjectFile: { 00195 // Create the code emitter for the target if it exists. If not, .o file 00196 // emission fails. 00197 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, STI, 00198 *Context); 00199 MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(), 00200 TargetCPU); 00201 if (!MCE || !MAB) 00202 return true; 00203 00204 AsmStreamer.reset(getTarget().createMCObjectStreamer( 00205 getTargetTriple(), *Context, *MAB, Out, MCE, STI, 00206 Options.MCOptions.MCRelaxAll, Options.MCOptions.MCNoExecStack)); 00207 break; 00208 } 00209 case CGFT_Null: 00210 // The Null output is intended for use for performance analysis and testing, 00211 // not real users. 00212 AsmStreamer.reset(getTarget().createNullStreamer(*Context)); 00213 break; 00214 } 00215 00216 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. 00217 FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); 00218 if (!Printer) 00219 return true; 00220 00221 // If successful, createAsmPrinter took ownership of AsmStreamer. 00222 AsmStreamer.release(); 00223 00224 PM.add(Printer); 00225 00226 return false; 00227 } 00228 00229 /// addPassesToEmitMC - Add passes to the specified pass manager to get 00230 /// machine code emitted with the MCJIT. This method returns true if machine 00231 /// code is not supported. It fills the MCContext Ctx pointer which can be 00232 /// used to build custom MCStreamer. 00233 /// 00234 bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, 00235 MCContext *&Ctx, 00236 raw_ostream &Out, 00237 bool DisableVerify) { 00238 // Add common CodeGen passes. 00239 Ctx = addPassesToGenerateCode(this, PM, DisableVerify, nullptr, nullptr); 00240 if (!Ctx) 00241 return true; 00242 00243 if (Options.MCOptions.MCSaveTempLabels) 00244 Ctx->setAllowTemporaryLabels(false); 00245 00246 // Create the code emitter for the target if it exists. If not, .o file 00247 // emission fails. 00248 const MCRegisterInfo &MRI = *getSubtargetImpl()->getRegisterInfo(); 00249 const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>(); 00250 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter( 00251 *getSubtargetImpl()->getInstrInfo(), MRI, STI, *Ctx); 00252 MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(), 00253 TargetCPU); 00254 if (!MCE || !MAB) 00255 return true; 00256 00257 std::unique_ptr<MCStreamer> AsmStreamer; 00258 AsmStreamer.reset(getTarget().createMCObjectStreamer( 00259 getTargetTriple(), *Ctx, *MAB, Out, MCE, STI, 00260 Options.MCOptions.MCRelaxAll, Options.MCOptions.MCNoExecStack)); 00261 00262 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. 00263 FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); 00264 if (!Printer) 00265 return true; 00266 00267 // If successful, createAsmPrinter took ownership of AsmStreamer. 00268 AsmStreamer.release(); 00269 00270 PM.add(Printer); 00271 00272 return false; // success! 00273 }