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