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"
260b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
270b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
280b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
290b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
300b57cec5SDimitry Andric #include "llvm/Support/FormattedStream.h"
310b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h"
320b57cec5SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
330b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
340b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h"
350b57cec5SDimitry Andric using namespace llvm;
360b57cec5SDimitry Andric
370b57cec5SDimitry Andric static cl::opt<bool> EnableTrapUnreachable("trap-unreachable",
380b57cec5SDimitry Andric cl::Hidden, cl::ZeroOrMore, cl::init(false),
390b57cec5SDimitry Andric cl::desc("Enable generating trap for unreachable"));
400b57cec5SDimitry Andric
initAsmInfo()410b57cec5SDimitry Andric void LLVMTargetMachine::initAsmInfo() {
420b57cec5SDimitry Andric MRI.reset(TheTarget.createMCRegInfo(getTargetTriple().str()));
43af732203SDimitry Andric assert(MRI && "Unable to create reg info");
440b57cec5SDimitry Andric MII.reset(TheTarget.createMCInstrInfo());
45af732203SDimitry Andric assert(MII && "Unable to create instruction info");
460b57cec5SDimitry Andric // FIXME: Having an MCSubtargetInfo on the target machine is a hack due
470b57cec5SDimitry Andric // to some backends having subtarget feature dependent module level
480b57cec5SDimitry Andric // code generation. This is similar to the hack in the AsmPrinter for
490b57cec5SDimitry Andric // module level assembly etc.
500b57cec5SDimitry Andric STI.reset(TheTarget.createMCSubtargetInfo(
510b57cec5SDimitry Andric getTargetTriple().str(), getTargetCPU(), getTargetFeatureString()));
52af732203SDimitry Andric assert(STI && "Unable to create subtarget info");
530b57cec5SDimitry Andric
54480093f4SDimitry Andric MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo(
55480093f4SDimitry Andric *MRI, getTargetTriple().str(), Options.MCOptions);
560b57cec5SDimitry Andric // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0,
570b57cec5SDimitry Andric // and if the old one gets included then MCAsmInfo will be NULL and
580b57cec5SDimitry Andric // we'll crash later.
590b57cec5SDimitry Andric // Provide the user with a useful error message about what's wrong.
600b57cec5SDimitry Andric assert(TmpAsmInfo && "MCAsmInfo not initialized. "
610b57cec5SDimitry Andric "Make sure you include the correct TargetSelect.h"
620b57cec5SDimitry Andric "and that InitializeAllTargetMCs() is being invoked!");
630b57cec5SDimitry Andric
64af732203SDimitry Andric if (Options.BinutilsVersion.first > 0)
65af732203SDimitry Andric TmpAsmInfo->setBinutilsVersion(Options.BinutilsVersion);
66af732203SDimitry Andric
67*5f7ddb14SDimitry Andric if (Options.DisableIntegratedAS) {
680b57cec5SDimitry Andric TmpAsmInfo->setUseIntegratedAssembler(false);
69*5f7ddb14SDimitry Andric // If there is explict option disable integratedAS, we can't use it for
70*5f7ddb14SDimitry Andric // inlineasm either.
71*5f7ddb14SDimitry Andric TmpAsmInfo->setParseInlineAsmUsingAsmParser(false);
72*5f7ddb14SDimitry Andric }
730b57cec5SDimitry Andric
740b57cec5SDimitry Andric TmpAsmInfo->setPreserveAsmComments(Options.MCOptions.PreserveAsmComments);
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric TmpAsmInfo->setCompressDebugSections(Options.CompressDebugSections);
770b57cec5SDimitry Andric
780b57cec5SDimitry Andric TmpAsmInfo->setRelaxELFRelocations(Options.RelaxELFRelocations);
790b57cec5SDimitry Andric
800b57cec5SDimitry Andric if (Options.ExceptionModel != ExceptionHandling::None)
810b57cec5SDimitry Andric TmpAsmInfo->setExceptionsType(Options.ExceptionModel);
820b57cec5SDimitry Andric
830b57cec5SDimitry Andric AsmInfo.reset(TmpAsmInfo);
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric
LLVMTargetMachine(const Target & T,StringRef DataLayoutString,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Reloc::Model RM,CodeModel::Model CM,CodeGenOpt::Level OL)860b57cec5SDimitry Andric LLVMTargetMachine::LLVMTargetMachine(const Target &T,
870b57cec5SDimitry Andric StringRef DataLayoutString,
880b57cec5SDimitry Andric const Triple &TT, StringRef CPU,
890b57cec5SDimitry Andric StringRef FS, const TargetOptions &Options,
900b57cec5SDimitry Andric Reloc::Model RM, CodeModel::Model CM,
910b57cec5SDimitry Andric CodeGenOpt::Level OL)
920b57cec5SDimitry Andric : TargetMachine(T, DataLayoutString, TT, CPU, FS, Options) {
930b57cec5SDimitry Andric this->RM = RM;
940b57cec5SDimitry Andric this->CMModel = CM;
950b57cec5SDimitry Andric this->OptLevel = OL;
960b57cec5SDimitry Andric
970b57cec5SDimitry Andric if (EnableTrapUnreachable)
980b57cec5SDimitry Andric this->Options.TrapUnreachable = true;
990b57cec5SDimitry Andric }
1000b57cec5SDimitry Andric
1010b57cec5SDimitry Andric TargetTransformInfo
getTargetTransformInfo(const Function & F)1020b57cec5SDimitry Andric LLVMTargetMachine::getTargetTransformInfo(const Function &F) {
1030b57cec5SDimitry Andric return TargetTransformInfo(BasicTTIImpl(this, F));
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric
1060b57cec5SDimitry Andric /// addPassesToX helper drives creation and initialization of TargetPassConfig.
1070b57cec5SDimitry Andric static TargetPassConfig *
addPassesToGenerateCode(LLVMTargetMachine & TM,PassManagerBase & PM,bool DisableVerify,MachineModuleInfoWrapperPass & MMIWP)1080b57cec5SDimitry Andric addPassesToGenerateCode(LLVMTargetMachine &TM, PassManagerBase &PM,
1098bcb0991SDimitry Andric bool DisableVerify,
1108bcb0991SDimitry Andric MachineModuleInfoWrapperPass &MMIWP) {
1110b57cec5SDimitry Andric // Targets may override createPassConfig to provide a target-specific
1120b57cec5SDimitry Andric // subclass.
1130b57cec5SDimitry Andric TargetPassConfig *PassConfig = TM.createPassConfig(PM);
1140b57cec5SDimitry Andric // Set PassConfig options provided by TargetMachine.
1150b57cec5SDimitry Andric PassConfig->setDisableVerify(DisableVerify);
1160b57cec5SDimitry Andric PM.add(PassConfig);
1178bcb0991SDimitry Andric PM.add(&MMIWP);
1180b57cec5SDimitry Andric
1190b57cec5SDimitry Andric if (PassConfig->addISelPasses())
1200b57cec5SDimitry Andric return nullptr;
1210b57cec5SDimitry Andric PassConfig->addMachinePasses();
1220b57cec5SDimitry Andric PassConfig->setInitialized();
1230b57cec5SDimitry Andric return PassConfig;
1240b57cec5SDimitry Andric }
1250b57cec5SDimitry Andric
addAsmPrinter(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,MCContext & Context)1260b57cec5SDimitry Andric bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
1270b57cec5SDimitry Andric raw_pwrite_stream &Out,
1280b57cec5SDimitry Andric raw_pwrite_stream *DwoOut,
1290b57cec5SDimitry Andric CodeGenFileType FileType,
1300b57cec5SDimitry Andric MCContext &Context) {
131af732203SDimitry Andric Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
132af732203SDimitry Andric createMCStreamer(Out, DwoOut, FileType, Context);
133af732203SDimitry Andric if (auto Err = MCStreamerOrErr.takeError())
134af732203SDimitry Andric return true;
135af732203SDimitry Andric
136af732203SDimitry Andric // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
137af732203SDimitry Andric FunctionPass *Printer =
138af732203SDimitry Andric getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));
139af732203SDimitry Andric if (!Printer)
140af732203SDimitry Andric return true;
141af732203SDimitry Andric
142af732203SDimitry Andric PM.add(Printer);
143af732203SDimitry Andric return false;
144af732203SDimitry Andric }
145af732203SDimitry Andric
createMCStreamer(raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,MCContext & Context)146af732203SDimitry Andric Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(
147af732203SDimitry Andric raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
148af732203SDimitry Andric MCContext &Context) {
1490b57cec5SDimitry Andric if (Options.MCOptions.MCSaveTempLabels)
1500b57cec5SDimitry Andric Context.setAllowTemporaryLabels(false);
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andric const MCSubtargetInfo &STI = *getMCSubtargetInfo();
1530b57cec5SDimitry Andric const MCAsmInfo &MAI = *getMCAsmInfo();
1540b57cec5SDimitry Andric const MCRegisterInfo &MRI = *getMCRegisterInfo();
1550b57cec5SDimitry Andric const MCInstrInfo &MII = *getMCInstrInfo();
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andric std::unique_ptr<MCStreamer> AsmStreamer;
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andric switch (FileType) {
1600b57cec5SDimitry Andric case CGFT_AssemblyFile: {
1610b57cec5SDimitry Andric MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(
1620b57cec5SDimitry Andric getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI);
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric // Create a code emitter if asked to show the encoding.
1650b57cec5SDimitry Andric std::unique_ptr<MCCodeEmitter> MCE;
1660b57cec5SDimitry Andric if (Options.MCOptions.ShowMCEncoding)
1670b57cec5SDimitry Andric MCE.reset(getTarget().createMCCodeEmitter(MII, MRI, Context));
1680b57cec5SDimitry Andric
1690b57cec5SDimitry Andric std::unique_ptr<MCAsmBackend> MAB(
1700b57cec5SDimitry Andric getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions));
1718bcb0991SDimitry Andric auto FOut = std::make_unique<formatted_raw_ostream>(Out);
1720b57cec5SDimitry Andric MCStreamer *S = getTarget().createAsmStreamer(
1730b57cec5SDimitry Andric Context, std::move(FOut), Options.MCOptions.AsmVerbose,
1740b57cec5SDimitry Andric Options.MCOptions.MCUseDwarfDirectory, InstPrinter, std::move(MCE),
1750b57cec5SDimitry Andric std::move(MAB), Options.MCOptions.ShowMCInst);
1760b57cec5SDimitry Andric AsmStreamer.reset(S);
1770b57cec5SDimitry Andric break;
1780b57cec5SDimitry Andric }
1790b57cec5SDimitry Andric case CGFT_ObjectFile: {
1800b57cec5SDimitry Andric // Create the code emitter for the target if it exists. If not, .o file
1810b57cec5SDimitry Andric // emission fails.
1820b57cec5SDimitry Andric MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, Context);
183af732203SDimitry Andric if (!MCE)
184af732203SDimitry Andric return make_error<StringError>("createMCCodeEmitter failed",
185af732203SDimitry Andric inconvertibleErrorCode());
1860b57cec5SDimitry Andric MCAsmBackend *MAB =
1870b57cec5SDimitry Andric getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
188af732203SDimitry Andric if (!MAB)
189af732203SDimitry Andric return make_error<StringError>("createMCAsmBackend failed",
190af732203SDimitry Andric inconvertibleErrorCode());
1910b57cec5SDimitry Andric
1920b57cec5SDimitry Andric Triple T(getTargetTriple().str());
1930b57cec5SDimitry Andric AsmStreamer.reset(getTarget().createMCObjectStreamer(
1940b57cec5SDimitry Andric T, Context, std::unique_ptr<MCAsmBackend>(MAB),
1950b57cec5SDimitry Andric DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut)
1960b57cec5SDimitry Andric : MAB->createObjectWriter(Out),
1970b57cec5SDimitry Andric std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll,
1980b57cec5SDimitry Andric Options.MCOptions.MCIncrementalLinkerCompatible,
1990b57cec5SDimitry Andric /*DWARFMustBeAtTheEnd*/ true));
2000b57cec5SDimitry Andric break;
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric case CGFT_Null:
2030b57cec5SDimitry Andric // The Null output is intended for use for performance analysis and testing,
2040b57cec5SDimitry Andric // not real users.
2050b57cec5SDimitry Andric AsmStreamer.reset(getTarget().createNullStreamer(Context));
2060b57cec5SDimitry Andric break;
2070b57cec5SDimitry Andric }
2080b57cec5SDimitry Andric
209af732203SDimitry Andric return std::move(AsmStreamer);
2100b57cec5SDimitry Andric }
2110b57cec5SDimitry Andric
addPassesToEmitFile(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,bool DisableVerify,MachineModuleInfoWrapperPass * MMIWP)2128bcb0991SDimitry Andric bool LLVMTargetMachine::addPassesToEmitFile(
2138bcb0991SDimitry Andric PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
2148bcb0991SDimitry Andric CodeGenFileType FileType, bool DisableVerify,
2158bcb0991SDimitry Andric MachineModuleInfoWrapperPass *MMIWP) {
2160b57cec5SDimitry Andric // Add common CodeGen passes.
2178bcb0991SDimitry Andric if (!MMIWP)
2188bcb0991SDimitry Andric MMIWP = new MachineModuleInfoWrapperPass(this);
2190b57cec5SDimitry Andric TargetPassConfig *PassConfig =
2208bcb0991SDimitry Andric addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
2210b57cec5SDimitry Andric if (!PassConfig)
2220b57cec5SDimitry Andric return true;
2230b57cec5SDimitry Andric
224af732203SDimitry Andric if (TargetPassConfig::willCompleteCodeGenPipeline()) {
225af732203SDimitry Andric if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext()))
2260b57cec5SDimitry Andric return true;
227af732203SDimitry Andric } else {
228af732203SDimitry Andric // MIR printing is redundant with -filetype=null.
229af732203SDimitry Andric if (FileType != CGFT_Null)
230af732203SDimitry Andric PM.add(createPrintMIRPass(Out));
231af732203SDimitry Andric }
2320b57cec5SDimitry Andric
2330b57cec5SDimitry Andric PM.add(createFreeMachineFunctionPass());
2340b57cec5SDimitry Andric return false;
2350b57cec5SDimitry Andric }
2360b57cec5SDimitry Andric
2370b57cec5SDimitry Andric /// addPassesToEmitMC - Add passes to the specified pass manager to get
2380b57cec5SDimitry Andric /// machine code emitted with the MCJIT. This method returns true if machine
2390b57cec5SDimitry Andric /// code is not supported. It fills the MCContext Ctx pointer which can be
2400b57cec5SDimitry Andric /// used to build custom MCStreamer.
2410b57cec5SDimitry Andric ///
addPassesToEmitMC(PassManagerBase & PM,MCContext * & Ctx,raw_pwrite_stream & Out,bool DisableVerify)2420b57cec5SDimitry Andric bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
2430b57cec5SDimitry Andric raw_pwrite_stream &Out,
2440b57cec5SDimitry Andric bool DisableVerify) {
2450b57cec5SDimitry Andric // Add common CodeGen passes.
2468bcb0991SDimitry Andric MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(this);
2470b57cec5SDimitry Andric TargetPassConfig *PassConfig =
2488bcb0991SDimitry Andric addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
2490b57cec5SDimitry Andric if (!PassConfig)
2500b57cec5SDimitry Andric return true;
2510b57cec5SDimitry Andric assert(TargetPassConfig::willCompleteCodeGenPipeline() &&
2520b57cec5SDimitry Andric "Cannot emit MC with limited codegen pipeline");
2530b57cec5SDimitry Andric
2548bcb0991SDimitry Andric Ctx = &MMIWP->getMMI().getContext();
2550b57cec5SDimitry Andric if (Options.MCOptions.MCSaveTempLabels)
2560b57cec5SDimitry Andric Ctx->setAllowTemporaryLabels(false);
2570b57cec5SDimitry Andric
2580b57cec5SDimitry Andric // Create the code emitter for the target if it exists. If not, .o file
2590b57cec5SDimitry Andric // emission fails.
2600b57cec5SDimitry Andric const MCSubtargetInfo &STI = *getMCSubtargetInfo();
2610b57cec5SDimitry Andric const MCRegisterInfo &MRI = *getMCRegisterInfo();
2620b57cec5SDimitry Andric MCCodeEmitter *MCE =
2630b57cec5SDimitry Andric getTarget().createMCCodeEmitter(*getMCInstrInfo(), MRI, *Ctx);
2640b57cec5SDimitry Andric MCAsmBackend *MAB =
2650b57cec5SDimitry Andric getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
2660b57cec5SDimitry Andric if (!MCE || !MAB)
2670b57cec5SDimitry Andric return true;
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andric const Triple &T = getTargetTriple();
2700b57cec5SDimitry Andric std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer(
2710b57cec5SDimitry Andric T, *Ctx, std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(Out),
2720b57cec5SDimitry Andric std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll,
2730b57cec5SDimitry Andric Options.MCOptions.MCIncrementalLinkerCompatible,
2740b57cec5SDimitry Andric /*DWARFMustBeAtTheEnd*/ true));
2750b57cec5SDimitry Andric
2760b57cec5SDimitry Andric // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
2770b57cec5SDimitry Andric FunctionPass *Printer =
2780b57cec5SDimitry Andric getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
2790b57cec5SDimitry Andric if (!Printer)
2800b57cec5SDimitry Andric return true;
2810b57cec5SDimitry Andric
2820b57cec5SDimitry Andric PM.add(Printer);
2830b57cec5SDimitry Andric PM.add(createFreeMachineFunctionPass());
2840b57cec5SDimitry Andric
2850b57cec5SDimitry Andric return false; // success!
2860b57cec5SDimitry Andric }
287