1 //===-- CodeGenTargetMachineImpl.cpp --------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file This file implements the CodeGenTargetMachineImpl class. 10 /// 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/CodeGen/CodeGenTargetMachineImpl.h" 14 #include "llvm/CodeGen/AsmPrinter.h" 15 #include "llvm/CodeGen/BasicTTIImpl.h" 16 #include "llvm/CodeGen/MachineModuleInfo.h" 17 #include "llvm/CodeGen/Passes.h" 18 #include "llvm/CodeGen/TargetPassConfig.h" 19 #include "llvm/IR/LegacyPassManager.h" 20 #include "llvm/MC/MCAsmBackend.h" 21 #include "llvm/MC/MCAsmInfo.h" 22 #include "llvm/MC/MCCodeEmitter.h" 23 #include "llvm/MC/MCContext.h" 24 #include "llvm/MC/MCInstPrinter.h" 25 #include "llvm/MC/MCInstrInfo.h" 26 #include "llvm/MC/MCObjectWriter.h" 27 #include "llvm/MC/MCRegisterInfo.h" 28 #include "llvm/MC/MCStreamer.h" 29 #include "llvm/MC/MCSubtargetInfo.h" 30 #include "llvm/MC/TargetRegistry.h" 31 #include "llvm/Support/CommandLine.h" 32 #include "llvm/Support/FormattedStream.h" 33 #include "llvm/Target/RegisterTargetPassConfigCallback.h" 34 #include "llvm/Target/TargetMachine.h" 35 #include "llvm/Target/TargetOptions.h" 36 using namespace llvm; 37 38 static cl::opt<bool> 39 EnableTrapUnreachable("trap-unreachable", cl::Hidden, 40 cl::desc("Enable generating trap for unreachable")); 41 42 static cl::opt<bool> EnableNoTrapAfterNoreturn( 43 "no-trap-after-noreturn", cl::Hidden, 44 cl::desc("Do not emit a trap instruction for 'unreachable' IR instructions " 45 "after noreturn calls, even if --trap-unreachable is set.")); 46 47 void CodeGenTargetMachineImpl::initAsmInfo() { 48 MRI.reset(TheTarget.createMCRegInfo(getTargetTriple().str())); 49 assert(MRI && "Unable to create reg info"); 50 MII.reset(TheTarget.createMCInstrInfo()); 51 assert(MII && "Unable to create instruction info"); 52 // FIXME: Having an MCSubtargetInfo on the target machine is a hack due 53 // to some backends having subtarget feature dependent module level 54 // code generation. This is similar to the hack in the AsmPrinter for 55 // module level assembly etc. 56 STI.reset(TheTarget.createMCSubtargetInfo( 57 getTargetTriple().str(), getTargetCPU(), getTargetFeatureString())); 58 assert(STI && "Unable to create subtarget info"); 59 60 MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo( 61 *MRI, getTargetTriple().str(), Options.MCOptions); 62 // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0, 63 // and if the old one gets included then MCAsmInfo will be NULL and 64 // we'll crash later. 65 // Provide the user with a useful error message about what's wrong. 66 assert(TmpAsmInfo && "MCAsmInfo not initialized. " 67 "Make sure you include the correct TargetSelect.h" 68 "and that InitializeAllTargetMCs() is being invoked!"); 69 70 if (Options.BinutilsVersion.first > 0) 71 TmpAsmInfo->setBinutilsVersion(Options.BinutilsVersion); 72 73 if (Options.DisableIntegratedAS) { 74 TmpAsmInfo->setUseIntegratedAssembler(false); 75 // If there is explict option disable integratedAS, we can't use it for 76 // inlineasm either. 77 TmpAsmInfo->setParseInlineAsmUsingAsmParser(false); 78 } 79 80 TmpAsmInfo->setPreserveAsmComments(Options.MCOptions.PreserveAsmComments); 81 82 TmpAsmInfo->setFullRegisterNames(Options.MCOptions.PPCUseFullRegisterNames); 83 84 assert(TmpAsmInfo->getExceptionHandlingType() == 85 getTargetTriple().getDefaultExceptionHandling() && 86 "MCAsmInfo and Triple disagree on default exception handling type"); 87 88 if (Options.ExceptionModel != ExceptionHandling::None) 89 TmpAsmInfo->setExceptionsType(Options.ExceptionModel); 90 91 AsmInfo.reset(TmpAsmInfo); 92 } 93 94 CodeGenTargetMachineImpl::CodeGenTargetMachineImpl( 95 const Target &T, StringRef DataLayoutString, const Triple &TT, 96 StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, 97 CodeModel::Model CM, CodeGenOptLevel OL) 98 : TargetMachine(T, DataLayoutString, TT, CPU, FS, Options) { 99 this->RM = RM; 100 this->CMModel = CM; 101 this->OptLevel = OL; 102 103 if (EnableTrapUnreachable) 104 this->Options.TrapUnreachable = true; 105 if (EnableNoTrapAfterNoreturn) 106 this->Options.NoTrapAfterNoreturn = true; 107 } 108 109 TargetTransformInfo 110 CodeGenTargetMachineImpl::getTargetTransformInfo(const Function &F) const { 111 return TargetTransformInfo(std::make_unique<BasicTTIImpl>(this, F)); 112 } 113 114 /// addPassesToX helper drives creation and initialization of TargetPassConfig. 115 static TargetPassConfig * 116 addPassesToGenerateCode(CodeGenTargetMachineImpl &TM, PassManagerBase &PM, 117 bool DisableVerify, 118 MachineModuleInfoWrapperPass &MMIWP) { 119 // Targets may override createPassConfig to provide a target-specific 120 // subclass. 121 TargetPassConfig *PassConfig = TM.createPassConfig(PM); 122 // Set PassConfig options provided by TargetMachine. 123 PassConfig->setDisableVerify(DisableVerify); 124 PM.add(PassConfig); 125 PM.add(&MMIWP); 126 invokeGlobalTargetPassConfigCallbacks(TM, PM, PassConfig); 127 128 if (PassConfig->addISelPasses()) 129 return nullptr; 130 PassConfig->addMachinePasses(); 131 PassConfig->setInitialized(); 132 return PassConfig; 133 } 134 135 bool CodeGenTargetMachineImpl::addAsmPrinter(PassManagerBase &PM, 136 raw_pwrite_stream &Out, 137 raw_pwrite_stream *DwoOut, 138 CodeGenFileType FileType, 139 MCContext &Context) { 140 Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr = 141 createMCStreamer(Out, DwoOut, FileType, Context); 142 if (!MCStreamerOrErr) { 143 Context.reportError(SMLoc(), toString(MCStreamerOrErr.takeError())); 144 return true; 145 } 146 147 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. 148 FunctionPass *Printer = 149 getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr)); 150 if (!Printer) 151 return true; 152 153 PM.add(Printer); 154 return false; 155 } 156 157 Expected<std::unique_ptr<MCStreamer>> 158 CodeGenTargetMachineImpl::createMCStreamer(raw_pwrite_stream &Out, 159 raw_pwrite_stream *DwoOut, 160 CodeGenFileType FileType, 161 MCContext &Context) { 162 const MCSubtargetInfo &STI = *getMCSubtargetInfo(); 163 const MCAsmInfo &MAI = *getMCAsmInfo(); 164 const MCRegisterInfo &MRI = *getMCRegisterInfo(); 165 const MCInstrInfo &MII = *getMCInstrInfo(); 166 167 std::unique_ptr<MCStreamer> AsmStreamer; 168 169 switch (FileType) { 170 case CodeGenFileType::AssemblyFile: { 171 std::unique_ptr<MCInstPrinter> InstPrinter(getTarget().createMCInstPrinter( 172 getTargetTriple(), 173 Options.MCOptions.OutputAsmVariant.value_or(MAI.getAssemblerDialect()), 174 MAI, MII, MRI)); 175 for (StringRef Opt : Options.MCOptions.InstPrinterOptions) 176 if (!InstPrinter->applyTargetSpecificCLOption(Opt)) 177 return createStringError("invalid InstPrinter option '" + Opt + "'"); 178 179 // Create a code emitter if asked to show the encoding. 180 std::unique_ptr<MCCodeEmitter> MCE; 181 if (Options.MCOptions.ShowMCEncoding) 182 MCE.reset(getTarget().createMCCodeEmitter(MII, Context)); 183 184 std::unique_ptr<MCAsmBackend> MAB( 185 getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions)); 186 auto FOut = std::make_unique<formatted_raw_ostream>(Out); 187 MCStreamer *S = getTarget().createAsmStreamer( 188 Context, std::move(FOut), std::move(InstPrinter), std::move(MCE), 189 std::move(MAB)); 190 AsmStreamer.reset(S); 191 break; 192 } 193 case CodeGenFileType::ObjectFile: { 194 // Create the code emitter for the target if it exists. If not, .o file 195 // emission fails. 196 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, Context); 197 if (!MCE) 198 return make_error<StringError>("createMCCodeEmitter failed", 199 inconvertibleErrorCode()); 200 MCAsmBackend *MAB = 201 getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); 202 if (!MAB) 203 return make_error<StringError>("createMCAsmBackend failed", 204 inconvertibleErrorCode()); 205 206 Triple T(getTargetTriple()); 207 AsmStreamer.reset(getTarget().createMCObjectStreamer( 208 T, Context, std::unique_ptr<MCAsmBackend>(MAB), 209 DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut) 210 : MAB->createObjectWriter(Out), 211 std::unique_ptr<MCCodeEmitter>(MCE), STI)); 212 break; 213 } 214 case CodeGenFileType::Null: 215 // The Null output is intended for use for performance analysis and testing, 216 // not real users. 217 AsmStreamer.reset(getTarget().createNullStreamer(Context)); 218 break; 219 } 220 221 return std::move(AsmStreamer); 222 } 223 224 bool CodeGenTargetMachineImpl::addPassesToEmitFile( 225 PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, 226 CodeGenFileType FileType, bool DisableVerify, 227 MachineModuleInfoWrapperPass *MMIWP) { 228 // Add common CodeGen passes. 229 if (!MMIWP) 230 MMIWP = new MachineModuleInfoWrapperPass(this); 231 TargetPassConfig *PassConfig = 232 addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP); 233 if (!PassConfig) 234 return true; 235 236 if (TargetPassConfig::willCompleteCodeGenPipeline()) { 237 if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext())) 238 return true; 239 } else { 240 // MIR printing is redundant with -filetype=null. 241 if (FileType != CodeGenFileType::Null) 242 PM.add(createPrintMIRPass(Out)); 243 } 244 245 PM.add(createFreeMachineFunctionPass()); 246 return false; 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 CodeGenTargetMachineImpl::addPassesToEmitMC(PassManagerBase &PM, 255 MCContext *&Ctx, 256 raw_pwrite_stream &Out, 257 bool DisableVerify) { 258 // Add common CodeGen passes. 259 MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(this); 260 TargetPassConfig *PassConfig = 261 addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP); 262 if (!PassConfig) 263 return true; 264 assert(TargetPassConfig::willCompleteCodeGenPipeline() && 265 "Cannot emit MC with limited codegen pipeline"); 266 267 Ctx = &MMIWP->getMMI().getContext(); 268 // libunwind is unable to load compact unwind dynamically, so we must generate 269 // DWARF unwind info for the JIT. 270 Options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always; 271 272 // Create the code emitter for the target if it exists. If not, .o file 273 // emission fails. 274 const MCSubtargetInfo &STI = *getMCSubtargetInfo(); 275 const MCRegisterInfo &MRI = *getMCRegisterInfo(); 276 std::unique_ptr<MCCodeEmitter> MCE( 277 getTarget().createMCCodeEmitter(*getMCInstrInfo(), *Ctx)); 278 if (!MCE) 279 return true; 280 MCAsmBackend *MAB = 281 getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); 282 if (!MAB) 283 return true; 284 285 const Triple &T = getTargetTriple(); 286 std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer( 287 T, *Ctx, std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(Out), 288 std::move(MCE), STI)); 289 290 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. 291 FunctionPass *Printer = 292 getTarget().createAsmPrinter(*this, std::move(AsmStreamer)); 293 if (!Printer) 294 return true; 295 296 PM.add(Printer); 297 PM.add(createFreeMachineFunctionPass()); 298 299 return false; // success! 300 } 301