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