10b57cec5SDimitry Andric //===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the LLVMTargetMachine class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/Analysis/Passes.h" 140b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 150b57cec5SDimitry Andric #include "llvm/CodeGen/BasicTTIImpl.h" 160b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 170b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h" 180b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 190b57cec5SDimitry Andric #include "llvm/IR/LegacyPassManager.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h" 250b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h" 2681ad6265SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 270b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 280b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 29349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 300b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 310b57cec5SDimitry Andric #include "llvm/Support/FormattedStream.h" 320b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 330b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 340b57cec5SDimitry Andric using namespace llvm; 350b57cec5SDimitry Andric 3681ad6265SDimitry Andric static cl::opt<bool> 3781ad6265SDimitry Andric EnableTrapUnreachable("trap-unreachable", cl::Hidden, 380b57cec5SDimitry Andric cl::desc("Enable generating trap for unreachable")); 390b57cec5SDimitry Andric 405f757f3fSDimitry Andric static cl::opt<bool> EnableNoTrapAfterNoreturn( 415f757f3fSDimitry Andric "no-trap-after-noreturn", cl::Hidden, 425f757f3fSDimitry Andric cl::desc("Do not emit a trap instruction for 'unreachable' IR instructions " 435f757f3fSDimitry Andric "after noreturn calls, even if --trap-unreachable is set.")); 445f757f3fSDimitry Andric 450b57cec5SDimitry Andric void LLVMTargetMachine::initAsmInfo() { 460b57cec5SDimitry Andric MRI.reset(TheTarget.createMCRegInfo(getTargetTriple().str())); 47e8d8bef9SDimitry Andric assert(MRI && "Unable to create reg info"); 480b57cec5SDimitry Andric MII.reset(TheTarget.createMCInstrInfo()); 49e8d8bef9SDimitry Andric assert(MII && "Unable to create instruction info"); 500b57cec5SDimitry Andric // FIXME: Having an MCSubtargetInfo on the target machine is a hack due 510b57cec5SDimitry Andric // to some backends having subtarget feature dependent module level 520b57cec5SDimitry Andric // code generation. This is similar to the hack in the AsmPrinter for 530b57cec5SDimitry Andric // module level assembly etc. 540b57cec5SDimitry Andric STI.reset(TheTarget.createMCSubtargetInfo( 550b57cec5SDimitry Andric getTargetTriple().str(), getTargetCPU(), getTargetFeatureString())); 56e8d8bef9SDimitry Andric assert(STI && "Unable to create subtarget info"); 570b57cec5SDimitry Andric 58480093f4SDimitry Andric MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo( 59480093f4SDimitry Andric *MRI, getTargetTriple().str(), Options.MCOptions); 600b57cec5SDimitry Andric // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0, 610b57cec5SDimitry Andric // and if the old one gets included then MCAsmInfo will be NULL and 620b57cec5SDimitry Andric // we'll crash later. 630b57cec5SDimitry Andric // Provide the user with a useful error message about what's wrong. 640b57cec5SDimitry Andric assert(TmpAsmInfo && "MCAsmInfo not initialized. " 650b57cec5SDimitry Andric "Make sure you include the correct TargetSelect.h" 660b57cec5SDimitry Andric "and that InitializeAllTargetMCs() is being invoked!"); 670b57cec5SDimitry Andric 68e8d8bef9SDimitry Andric if (Options.BinutilsVersion.first > 0) 69e8d8bef9SDimitry Andric TmpAsmInfo->setBinutilsVersion(Options.BinutilsVersion); 70e8d8bef9SDimitry Andric 71fe6060f1SDimitry Andric if (Options.DisableIntegratedAS) { 720b57cec5SDimitry Andric TmpAsmInfo->setUseIntegratedAssembler(false); 73fe6060f1SDimitry Andric // If there is explict option disable integratedAS, we can't use it for 74fe6060f1SDimitry Andric // inlineasm either. 75fe6060f1SDimitry Andric TmpAsmInfo->setParseInlineAsmUsingAsmParser(false); 76fe6060f1SDimitry Andric } 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric TmpAsmInfo->setPreserveAsmComments(Options.MCOptions.PreserveAsmComments); 790b57cec5SDimitry Andric 805f757f3fSDimitry Andric TmpAsmInfo->setFullRegisterNames(Options.MCOptions.PPCUseFullRegisterNames); 815f757f3fSDimitry Andric 820b57cec5SDimitry Andric if (Options.ExceptionModel != ExceptionHandling::None) 830b57cec5SDimitry Andric TmpAsmInfo->setExceptionsType(Options.ExceptionModel); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric AsmInfo.reset(TmpAsmInfo); 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric LLVMTargetMachine::LLVMTargetMachine(const Target &T, 890b57cec5SDimitry Andric StringRef DataLayoutString, 900b57cec5SDimitry Andric const Triple &TT, StringRef CPU, 910b57cec5SDimitry Andric StringRef FS, const TargetOptions &Options, 920b57cec5SDimitry Andric Reloc::Model RM, CodeModel::Model CM, 935f757f3fSDimitry Andric CodeGenOptLevel OL) 940b57cec5SDimitry Andric : TargetMachine(T, DataLayoutString, TT, CPU, FS, Options) { 950b57cec5SDimitry Andric this->RM = RM; 960b57cec5SDimitry Andric this->CMModel = CM; 970b57cec5SDimitry Andric this->OptLevel = OL; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric if (EnableTrapUnreachable) 1000b57cec5SDimitry Andric this->Options.TrapUnreachable = true; 1015f757f3fSDimitry Andric if (EnableNoTrapAfterNoreturn) 1025f757f3fSDimitry Andric this->Options.NoTrapAfterNoreturn = true; 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric TargetTransformInfo 10681ad6265SDimitry Andric LLVMTargetMachine::getTargetTransformInfo(const Function &F) const { 1070b57cec5SDimitry Andric return TargetTransformInfo(BasicTTIImpl(this, F)); 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric /// addPassesToX helper drives creation and initialization of TargetPassConfig. 1110b57cec5SDimitry Andric static TargetPassConfig * 1120b57cec5SDimitry Andric addPassesToGenerateCode(LLVMTargetMachine &TM, PassManagerBase &PM, 1138bcb0991SDimitry Andric bool DisableVerify, 1148bcb0991SDimitry Andric MachineModuleInfoWrapperPass &MMIWP) { 1150b57cec5SDimitry Andric // Targets may override createPassConfig to provide a target-specific 1160b57cec5SDimitry Andric // subclass. 1170b57cec5SDimitry Andric TargetPassConfig *PassConfig = TM.createPassConfig(PM); 1180b57cec5SDimitry Andric // Set PassConfig options provided by TargetMachine. 1190b57cec5SDimitry Andric PassConfig->setDisableVerify(DisableVerify); 1200b57cec5SDimitry Andric PM.add(PassConfig); 1218bcb0991SDimitry Andric PM.add(&MMIWP); 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric if (PassConfig->addISelPasses()) 1240b57cec5SDimitry Andric return nullptr; 1250b57cec5SDimitry Andric PassConfig->addMachinePasses(); 1260b57cec5SDimitry Andric PassConfig->setInitialized(); 1270b57cec5SDimitry Andric return PassConfig; 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM, 1310b57cec5SDimitry Andric raw_pwrite_stream &Out, 1320b57cec5SDimitry Andric raw_pwrite_stream *DwoOut, 1330b57cec5SDimitry Andric CodeGenFileType FileType, 1340b57cec5SDimitry Andric MCContext &Context) { 135e8d8bef9SDimitry Andric Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr = 136e8d8bef9SDimitry Andric createMCStreamer(Out, DwoOut, FileType, Context); 137e8d8bef9SDimitry Andric if (auto Err = MCStreamerOrErr.takeError()) 138e8d8bef9SDimitry Andric return true; 139e8d8bef9SDimitry Andric 140e8d8bef9SDimitry Andric // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. 141e8d8bef9SDimitry Andric FunctionPass *Printer = 142e8d8bef9SDimitry Andric getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr)); 143e8d8bef9SDimitry Andric if (!Printer) 144e8d8bef9SDimitry Andric return true; 145e8d8bef9SDimitry Andric 146e8d8bef9SDimitry Andric PM.add(Printer); 147e8d8bef9SDimitry Andric return false; 148e8d8bef9SDimitry Andric } 149e8d8bef9SDimitry Andric 150e8d8bef9SDimitry Andric Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer( 151e8d8bef9SDimitry Andric raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType, 152e8d8bef9SDimitry Andric MCContext &Context) { 1530b57cec5SDimitry Andric const MCSubtargetInfo &STI = *getMCSubtargetInfo(); 1540b57cec5SDimitry Andric const MCAsmInfo &MAI = *getMCAsmInfo(); 1550b57cec5SDimitry Andric const MCRegisterInfo &MRI = *getMCRegisterInfo(); 1560b57cec5SDimitry Andric const MCInstrInfo &MII = *getMCInstrInfo(); 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric std::unique_ptr<MCStreamer> AsmStreamer; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric switch (FileType) { 1615f757f3fSDimitry Andric case CodeGenFileType::AssemblyFile: { 1620b57cec5SDimitry Andric MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter( 1630b57cec5SDimitry Andric getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric // Create a code emitter if asked to show the encoding. 1660b57cec5SDimitry Andric std::unique_ptr<MCCodeEmitter> MCE; 1670b57cec5SDimitry Andric if (Options.MCOptions.ShowMCEncoding) 16881ad6265SDimitry Andric MCE.reset(getTarget().createMCCodeEmitter(MII, Context)); 16981ad6265SDimitry Andric 1700b57cec5SDimitry Andric std::unique_ptr<MCAsmBackend> MAB( 1710b57cec5SDimitry Andric getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions)); 1728bcb0991SDimitry Andric auto FOut = std::make_unique<formatted_raw_ostream>(Out); 1730b57cec5SDimitry Andric MCStreamer *S = getTarget().createAsmStreamer( 174*0fca6ea1SDimitry Andric Context, std::move(FOut), InstPrinter, std::move(MCE), std::move(MAB)); 1750b57cec5SDimitry Andric AsmStreamer.reset(S); 1760b57cec5SDimitry Andric break; 1770b57cec5SDimitry Andric } 1785f757f3fSDimitry Andric case CodeGenFileType::ObjectFile: { 1790b57cec5SDimitry Andric // Create the code emitter for the target if it exists. If not, .o file 1800b57cec5SDimitry Andric // emission fails. 18181ad6265SDimitry Andric MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, Context); 182e8d8bef9SDimitry Andric if (!MCE) 183e8d8bef9SDimitry Andric return make_error<StringError>("createMCCodeEmitter failed", 184e8d8bef9SDimitry Andric inconvertibleErrorCode()); 1850b57cec5SDimitry Andric MCAsmBackend *MAB = 1860b57cec5SDimitry Andric getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); 187e8d8bef9SDimitry Andric if (!MAB) 188e8d8bef9SDimitry Andric return make_error<StringError>("createMCAsmBackend failed", 189e8d8bef9SDimitry Andric inconvertibleErrorCode()); 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric Triple T(getTargetTriple().str()); 1920b57cec5SDimitry Andric AsmStreamer.reset(getTarget().createMCObjectStreamer( 1930b57cec5SDimitry Andric T, Context, std::unique_ptr<MCAsmBackend>(MAB), 1940b57cec5SDimitry Andric DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut) 1950b57cec5SDimitry Andric : MAB->createObjectWriter(Out), 196*0fca6ea1SDimitry Andric std::unique_ptr<MCCodeEmitter>(MCE), STI)); 1970b57cec5SDimitry Andric break; 1980b57cec5SDimitry Andric } 1995f757f3fSDimitry Andric case CodeGenFileType::Null: 2000b57cec5SDimitry Andric // The Null output is intended for use for performance analysis and testing, 2010b57cec5SDimitry Andric // not real users. 2020b57cec5SDimitry Andric AsmStreamer.reset(getTarget().createNullStreamer(Context)); 2030b57cec5SDimitry Andric break; 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric 206e8d8bef9SDimitry Andric return std::move(AsmStreamer); 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric 2098bcb0991SDimitry Andric bool LLVMTargetMachine::addPassesToEmitFile( 2108bcb0991SDimitry Andric PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, 2118bcb0991SDimitry Andric CodeGenFileType FileType, bool DisableVerify, 2128bcb0991SDimitry Andric MachineModuleInfoWrapperPass *MMIWP) { 2130b57cec5SDimitry Andric // Add common CodeGen passes. 2148bcb0991SDimitry Andric if (!MMIWP) 2158bcb0991SDimitry Andric MMIWP = new MachineModuleInfoWrapperPass(this); 2160b57cec5SDimitry Andric TargetPassConfig *PassConfig = 2178bcb0991SDimitry Andric addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP); 2180b57cec5SDimitry Andric if (!PassConfig) 2190b57cec5SDimitry Andric return true; 2200b57cec5SDimitry Andric 221e8d8bef9SDimitry Andric if (TargetPassConfig::willCompleteCodeGenPipeline()) { 222e8d8bef9SDimitry Andric if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext())) 2230b57cec5SDimitry Andric return true; 224e8d8bef9SDimitry Andric } else { 225e8d8bef9SDimitry Andric // MIR printing is redundant with -filetype=null. 2265f757f3fSDimitry Andric if (FileType != CodeGenFileType::Null) 227e8d8bef9SDimitry Andric PM.add(createPrintMIRPass(Out)); 228e8d8bef9SDimitry Andric } 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric PM.add(createFreeMachineFunctionPass()); 2310b57cec5SDimitry Andric return false; 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric /// addPassesToEmitMC - Add passes to the specified pass manager to get 2350b57cec5SDimitry Andric /// machine code emitted with the MCJIT. This method returns true if machine 2360b57cec5SDimitry Andric /// code is not supported. It fills the MCContext Ctx pointer which can be 2370b57cec5SDimitry Andric /// used to build custom MCStreamer. 2380b57cec5SDimitry Andric /// 2390b57cec5SDimitry Andric bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx, 2400b57cec5SDimitry Andric raw_pwrite_stream &Out, 2410b57cec5SDimitry Andric bool DisableVerify) { 2420b57cec5SDimitry Andric // Add common CodeGen passes. 2438bcb0991SDimitry Andric MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(this); 2440b57cec5SDimitry Andric TargetPassConfig *PassConfig = 2458bcb0991SDimitry Andric addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP); 2460b57cec5SDimitry Andric if (!PassConfig) 2470b57cec5SDimitry Andric return true; 2480b57cec5SDimitry Andric assert(TargetPassConfig::willCompleteCodeGenPipeline() && 2490b57cec5SDimitry Andric "Cannot emit MC with limited codegen pipeline"); 2500b57cec5SDimitry Andric 2518bcb0991SDimitry Andric Ctx = &MMIWP->getMMI().getContext(); 25281ad6265SDimitry Andric // libunwind is unable to load compact unwind dynamically, so we must generate 25381ad6265SDimitry Andric // DWARF unwind info for the JIT. 25481ad6265SDimitry Andric Options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always; 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric // Create the code emitter for the target if it exists. If not, .o file 2570b57cec5SDimitry Andric // emission fails. 2580b57cec5SDimitry Andric const MCSubtargetInfo &STI = *getMCSubtargetInfo(); 2590b57cec5SDimitry Andric const MCRegisterInfo &MRI = *getMCRegisterInfo(); 26006c3fb27SDimitry Andric std::unique_ptr<MCCodeEmitter> MCE( 26106c3fb27SDimitry Andric getTarget().createMCCodeEmitter(*getMCInstrInfo(), *Ctx)); 262*0fca6ea1SDimitry Andric MCAsmBackend *MAB = 263*0fca6ea1SDimitry Andric getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions); 2640b57cec5SDimitry Andric if (!MCE || !MAB) 2650b57cec5SDimitry Andric return true; 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric const Triple &T = getTargetTriple(); 2680b57cec5SDimitry Andric std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer( 269*0fca6ea1SDimitry Andric T, *Ctx, std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(Out), 270*0fca6ea1SDimitry Andric std::move(MCE), STI)); 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. 2730b57cec5SDimitry Andric FunctionPass *Printer = 2740b57cec5SDimitry Andric getTarget().createAsmPrinter(*this, std::move(AsmStreamer)); 2750b57cec5SDimitry Andric if (!Printer) 2760b57cec5SDimitry Andric return true; 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric PM.add(Printer); 2790b57cec5SDimitry Andric PM.add(createFreeMachineFunctionPass()); 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric return false; // success! 2820b57cec5SDimitry Andric } 283