1 //===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===// 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 // This file implements the LLVMTargetMachine class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/Analysis/Passes.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 void LLVMTargetMachine::initAsmInfo() { 41 MRI.reset(TheTarget.createMCRegInfo(getTargetTriple().str())); 42 assert(MRI && "Unable to create reg info"); 43 MII.reset(TheTarget.createMCInstrInfo()); 44 assert(MII && "Unable to create instruction info"); 45 // FIXME: Having an MCSubtargetInfo on the target machine is a hack due 46 // to some backends having subtarget feature dependent module level 47 // code generation. This is similar to the hack in the AsmPrinter for 48 // module level assembly etc. 49 STI.reset(TheTarget.createMCSubtargetInfo( 50 getTargetTriple().str(), getTargetCPU(), getTargetFeatureString())); 51 assert(STI && "Unable to create subtarget info"); 52 53 MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo( 54 *MRI, getTargetTriple().str(), Options.MCOptions); 55 // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0, 56 // and if the old one gets included then MCAsmInfo will be NULL and 57 // we'll crash later. 58 // Provide the user with a useful error message about what's wrong. 59 assert(TmpAsmInfo && "MCAsmInfo not initialized. " 60 "Make sure you include the correct TargetSelect.h" 61 "and that InitializeAllTargetMCs() is being invoked!"); 62 63 if (Options.BinutilsVersion.first > 0) 64 TmpAsmInfo->setBinutilsVersion(Options.BinutilsVersion); 65 66 if (Options.DisableIntegratedAS) { 67 TmpAsmInfo->setUseIntegratedAssembler(false); 68 // If there is explict option disable integratedAS, we can't use it for 69 // inlineasm either. 70 TmpAsmInfo->setParseInlineAsmUsingAsmParser(false); 71 } 72 73 TmpAsmInfo->setPreserveAsmComments(Options.MCOptions.PreserveAsmComments); 74 75 TmpAsmInfo->setCompressDebugSections(Options.CompressDebugSections); 76 77 TmpAsmInfo->setRelaxELFRelocations(Options.RelaxELFRelocations); 78 79 if (Options.ExceptionModel != ExceptionHandling::None) 80 TmpAsmInfo->setExceptionsType(Options.ExceptionModel); 81 82 AsmInfo.reset(TmpAsmInfo); 83 } 84 85 LLVMTargetMachine::LLVMTargetMachine(const Target &T, 86 StringRef DataLayoutString, 87 const Triple &TT, StringRef CPU, 88 StringRef FS, const TargetOptions &Options, 89 Reloc::Model RM, CodeModel::Model CM, 90 CodeGenOpt::Level OL) 91 : TargetMachine(T, DataLayoutString, TT, CPU, FS, Options) { 92 this->RM = RM; 93 this->CMModel = CM; 94 this->OptLevel = OL; 95 96 if (EnableTrapUnreachable) 97 this->Options.TrapUnreachable = true; 98 } 99 100 TargetTransformInfo 101 LLVMTargetMachine::getTargetTransformInfo(const Function &F) const { 102 return TargetTransformInfo(BasicTTIImpl(this, F)); 103 } 104 105 /// addPassesToX helper drives creation and initialization of TargetPassConfig. 106 static TargetPassConfig * 107 addPassesToGenerateCode(LLVMTargetMachine &TM, PassManagerBase &PM, 108 bool DisableVerify, 109 MachineModuleInfoWrapperPass &MMIWP) { 110 // Targets may override createPassConfig to provide a target-specific 111 // subclass. 112 TargetPassConfig *PassConfig = TM.createPassConfig(PM); 113 // Set PassConfig options provided by TargetMachine. 114 PassConfig->setDisableVerify(DisableVerify); 115 PM.add(PassConfig); 116 PM.add(&MMIWP); 117 118 if (PassConfig->addISelPasses()) 119 return nullptr; 120 PassConfig->addMachinePasses(); 121 PassConfig->setInitialized(); 122 return PassConfig; 123 } 124 125 bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM, 126 raw_pwrite_stream &Out, 127 raw_pwrite_stream *DwoOut, 128 CodeGenFileType FileType, 129 MCContext &Context) { 130 Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr = 131 createMCStreamer(Out, DwoOut, FileType, Context); 132 if (auto Err = MCStreamerOrErr.takeError()) 133 return true; 134 135 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. 136 FunctionPass *Printer = 137 getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr)); 138 if (!Printer) 139 return true; 140 141 PM.add(Printer); 142 return false; 143 } 144 145 Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer( 146 raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType, 147 MCContext &Context) { 148 if (Options.MCOptions.MCSaveTempLabels) 149 Context.setAllowTemporaryLabels(false); 150 151 const MCSubtargetInfo &STI = *getMCSubtargetInfo(); 152 const MCAsmInfo &MAI = *getMCAsmInfo(); 153 const MCRegisterInfo &MRI = *getMCRegisterInfo(); 154 const MCInstrInfo &MII = *getMCInstrInfo(); 155 156 std::unique_ptr<MCStreamer> AsmStreamer; 157 158 switch (FileType) { 159 case CGFT_AssemblyFile: { 160 MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter( 161 getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI); 162 163 // Create a code emitter if asked to show the encoding. 164 std::unique_ptr<MCCodeEmitter> MCE; 165 if (Options.MCOptions.ShowMCEncoding) 166 MCE.reset(getTarget().createMCCodeEmitter(MII, Context)); 167 168 bool UseDwarfDirectory = false; 169 switch (Options.MCOptions.MCUseDwarfDirectory) { 170 case MCTargetOptions::DisableDwarfDirectory: 171 UseDwarfDirectory = false; 172 break; 173 case MCTargetOptions::EnableDwarfDirectory: 174 UseDwarfDirectory = true; 175 break; 176 case MCTargetOptions::DefaultDwarfDirectory: 177 UseDwarfDirectory = MAI.enableDwarfFileDirectoryDefault(); 178 break; 179 } 180 181 std::unique_ptr<MCAsmBackend> MAB( 182 getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions)); 183 auto FOut = std::make_unique<formatted_raw_ostream>(Out); 184 MCStreamer *S = getTarget().createAsmStreamer( 185 Context, std::move(FOut), Options.MCOptions.AsmVerbose, 186 UseDwarfDirectory, InstPrinter, std::move(MCE), std::move(MAB), 187 Options.MCOptions.ShowMCInst); 188 AsmStreamer.reset(S); 189 break; 190 } 191 case CGFT_ObjectFile: { 192 // Create the code emitter for the target if it exists. If not, .o file 193 // emission fails. 194 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, Context); 195 if (!MCE) 196 return make_error<StringError>("createMCCodeEmitter failed", 197 inconvertibleErrorCode()); 198 MCAsmBackend *MAB = 199 getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); 200 if (!MAB) 201 return make_error<StringError>("createMCAsmBackend failed", 202 inconvertibleErrorCode()); 203 204 Triple T(getTargetTriple().str()); 205 AsmStreamer.reset(getTarget().createMCObjectStreamer( 206 T, Context, std::unique_ptr<MCAsmBackend>(MAB), 207 DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut) 208 : MAB->createObjectWriter(Out), 209 std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll, 210 Options.MCOptions.MCIncrementalLinkerCompatible, 211 /*DWARFMustBeAtTheEnd*/ true)); 212 break; 213 } 214 case CGFT_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 LLVMTargetMachine::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 != CGFT_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 LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx, 255 raw_pwrite_stream &Out, 256 bool DisableVerify) { 257 // Add common CodeGen passes. 258 MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(this); 259 TargetPassConfig *PassConfig = 260 addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP); 261 if (!PassConfig) 262 return true; 263 assert(TargetPassConfig::willCompleteCodeGenPipeline() && 264 "Cannot emit MC with limited codegen pipeline"); 265 266 Ctx = &MMIWP->getMMI().getContext(); 267 // libunwind is unable to load compact unwind dynamically, so we must generate 268 // DWARF unwind info for the JIT. 269 Options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always; 270 if (Options.MCOptions.MCSaveTempLabels) 271 Ctx->setAllowTemporaryLabels(false); 272 273 // Create the code emitter for the target if it exists. If not, .o file 274 // emission fails. 275 const MCSubtargetInfo &STI = *getMCSubtargetInfo(); 276 const MCRegisterInfo &MRI = *getMCRegisterInfo(); 277 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getMCInstrInfo(), *Ctx); 278 MCAsmBackend *MAB = 279 getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); 280 if (!MCE || !MAB) 281 return true; 282 283 const Triple &T = getTargetTriple(); 284 std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer( 285 T, *Ctx, std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(Out), 286 std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll, 287 Options.MCOptions.MCIncrementalLinkerCompatible, 288 /*DWARFMustBeAtTheEnd*/ true)); 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