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