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> EnableTrapUnreachable("trap-unreachable", 37 cl::Hidden, cl::ZeroOrMore, cl::init(false), 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 std::unique_ptr<MCAsmBackend> MAB( 169 getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions)); 170 auto FOut = std::make_unique<formatted_raw_ostream>(Out); 171 MCStreamer *S = getTarget().createAsmStreamer( 172 Context, std::move(FOut), Options.MCOptions.AsmVerbose, 173 Options.MCOptions.MCUseDwarfDirectory, InstPrinter, std::move(MCE), 174 std::move(MAB), Options.MCOptions.ShowMCInst); 175 AsmStreamer.reset(S); 176 break; 177 } 178 case CGFT_ObjectFile: { 179 // Create the code emitter for the target if it exists. If not, .o file 180 // emission fails. 181 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, Context); 182 if (!MCE) 183 return make_error<StringError>("createMCCodeEmitter failed", 184 inconvertibleErrorCode()); 185 MCAsmBackend *MAB = 186 getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); 187 if (!MAB) 188 return make_error<StringError>("createMCAsmBackend failed", 189 inconvertibleErrorCode()); 190 191 Triple T(getTargetTriple().str()); 192 AsmStreamer.reset(getTarget().createMCObjectStreamer( 193 T, Context, std::unique_ptr<MCAsmBackend>(MAB), 194 DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut) 195 : MAB->createObjectWriter(Out), 196 std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll, 197 Options.MCOptions.MCIncrementalLinkerCompatible, 198 /*DWARFMustBeAtTheEnd*/ true)); 199 break; 200 } 201 case CGFT_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 LLVMTargetMachine::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 != CGFT_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 LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx, 242 raw_pwrite_stream &Out, 243 bool DisableVerify) { 244 // Add common CodeGen passes. 245 MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(this); 246 TargetPassConfig *PassConfig = 247 addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP); 248 if (!PassConfig) 249 return true; 250 assert(TargetPassConfig::willCompleteCodeGenPipeline() && 251 "Cannot emit MC with limited codegen pipeline"); 252 253 Ctx = &MMIWP->getMMI().getContext(); 254 if (Options.MCOptions.MCSaveTempLabels) 255 Ctx->setAllowTemporaryLabels(false); 256 257 // Create the code emitter for the target if it exists. If not, .o file 258 // emission fails. 259 const MCSubtargetInfo &STI = *getMCSubtargetInfo(); 260 const MCRegisterInfo &MRI = *getMCRegisterInfo(); 261 MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getMCInstrInfo(), *Ctx); 262 MCAsmBackend *MAB = 263 getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); 264 if (!MCE || !MAB) 265 return true; 266 267 const Triple &T = getTargetTriple(); 268 std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer( 269 T, *Ctx, std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(Out), 270 std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll, 271 Options.MCOptions.MCIncrementalLinkerCompatible, 272 /*DWARFMustBeAtTheEnd*/ true)); 273 274 // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. 275 FunctionPass *Printer = 276 getTarget().createAsmPrinter(*this, std::move(AsmStreamer)); 277 if (!Printer) 278 return true; 279 280 PM.add(Printer); 281 PM.add(createFreeMachineFunctionPass()); 282 283 return false; // success! 284 } 285