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