1bb8507e6SMatthias Braun //===-- LLVMTargetMachine.cpp - Implement the LLVMTargetMachine class -----===//
2bb8507e6SMatthias Braun //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bb8507e6SMatthias Braun //
7bb8507e6SMatthias Braun //===----------------------------------------------------------------------===//
8bb8507e6SMatthias Braun //
9bb8507e6SMatthias Braun // This file implements the LLVMTargetMachine class.
10bb8507e6SMatthias Braun //
11bb8507e6SMatthias Braun //===----------------------------------------------------------------------===//
12bb8507e6SMatthias Braun
13bb8507e6SMatthias Braun #include "llvm/Analysis/Passes.h"
14bb8507e6SMatthias Braun #include "llvm/CodeGen/AsmPrinter.h"
15bb8507e6SMatthias Braun #include "llvm/CodeGen/BasicTTIImpl.h"
16bb8507e6SMatthias Braun #include "llvm/CodeGen/MachineModuleInfo.h"
17bb8507e6SMatthias Braun #include "llvm/CodeGen/Passes.h"
18bb8507e6SMatthias Braun #include "llvm/CodeGen/TargetPassConfig.h"
19bb8507e6SMatthias Braun #include "llvm/IR/LegacyPassManager.h"
20bb8507e6SMatthias Braun #include "llvm/MC/MCAsmBackend.h"
21bb8507e6SMatthias Braun #include "llvm/MC/MCAsmInfo.h"
22bb8507e6SMatthias Braun #include "llvm/MC/MCCodeEmitter.h"
23bb8507e6SMatthias Braun #include "llvm/MC/MCContext.h"
24bb8507e6SMatthias Braun #include "llvm/MC/MCInstrInfo.h"
25f7b81db7SPeter Collingbourne #include "llvm/MC/MCObjectWriter.h"
26ef736a1cSserge-sans-paille #include "llvm/MC/MCRegisterInfo.h"
27bb8507e6SMatthias Braun #include "llvm/MC/MCStreamer.h"
28bb8507e6SMatthias Braun #include "llvm/MC/MCSubtargetInfo.h"
2989b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
30bb8507e6SMatthias Braun #include "llvm/Support/CommandLine.h"
31bb8507e6SMatthias Braun #include "llvm/Support/FormattedStream.h"
32bb8507e6SMatthias Braun #include "llvm/Target/TargetMachine.h"
33bb8507e6SMatthias Braun #include "llvm/Target/TargetOptions.h"
34bb8507e6SMatthias Braun using namespace llvm;
35bb8507e6SMatthias Braun
36557efc9aSFangrui Song static cl::opt<bool>
37557efc9aSFangrui Song EnableTrapUnreachable("trap-unreachable", cl::Hidden,
386d9f8c98SDavid Green cl::desc("Enable generating trap for unreachable"));
396d9f8c98SDavid Green
initAsmInfo()40bb8507e6SMatthias Braun void LLVMTargetMachine::initAsmInfo() {
4110a21625SFangrui Song MRI.reset(TheTarget.createMCRegInfo(getTargetTriple().str()));
421756d679SElla Ma assert(MRI && "Unable to create reg info");
4310a21625SFangrui Song MII.reset(TheTarget.createMCInstrInfo());
441756d679SElla Ma assert(MII && "Unable to create instruction info");
45bb8507e6SMatthias Braun // FIXME: Having an MCSubtargetInfo on the target machine is a hack due
46bb8507e6SMatthias Braun // to some backends having subtarget feature dependent module level
47bb8507e6SMatthias Braun // code generation. This is similar to the hack in the AsmPrinter for
48bb8507e6SMatthias Braun // module level assembly etc.
4910a21625SFangrui Song STI.reset(TheTarget.createMCSubtargetInfo(
5010a21625SFangrui Song getTargetTriple().str(), getTargetCPU(), getTargetFeatureString()));
511756d679SElla Ma assert(STI && "Unable to create subtarget info");
52bb8507e6SMatthias Braun
534b63ca13SMirko Brkusanin MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo(
544b63ca13SMirko Brkusanin *MRI, getTargetTriple().str(), Options.MCOptions);
55bb8507e6SMatthias Braun // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0,
56bb8507e6SMatthias Braun // and if the old one gets included then MCAsmInfo will be NULL and
57bb8507e6SMatthias Braun // we'll crash later.
58bb8507e6SMatthias Braun // Provide the user with a useful error message about what's wrong.
59bb8507e6SMatthias Braun assert(TmpAsmInfo && "MCAsmInfo not initialized. "
60bb8507e6SMatthias Braun "Make sure you include the correct TargetSelect.h"
61bb8507e6SMatthias Braun "and that InitializeAllTargetMCs() is being invoked!");
62bb8507e6SMatthias Braun
6334b60d8aSFangrui Song if (Options.BinutilsVersion.first > 0)
6434b60d8aSFangrui Song TmpAsmInfo->setBinutilsVersion(Options.BinutilsVersion);
6534b60d8aSFangrui Song
6603e9dcfdSJinsong Ji if (Options.DisableIntegratedAS) {
67bb8507e6SMatthias Braun TmpAsmInfo->setUseIntegratedAssembler(false);
6803e9dcfdSJinsong Ji // If there is explict option disable integratedAS, we can't use it for
6903e9dcfdSJinsong Ji // inlineasm either.
7003e9dcfdSJinsong Ji TmpAsmInfo->setParseInlineAsmUsingAsmParser(false);
7103e9dcfdSJinsong Ji }
72bb8507e6SMatthias Braun
73bb8507e6SMatthias Braun TmpAsmInfo->setPreserveAsmComments(Options.MCOptions.PreserveAsmComments);
74bb8507e6SMatthias Braun
75bb8507e6SMatthias Braun TmpAsmInfo->setCompressDebugSections(Options.CompressDebugSections);
76bb8507e6SMatthias Braun
77bb8507e6SMatthias Braun TmpAsmInfo->setRelaxELFRelocations(Options.RelaxELFRelocations);
78bb8507e6SMatthias Braun
79bb8507e6SMatthias Braun if (Options.ExceptionModel != ExceptionHandling::None)
80bb8507e6SMatthias Braun TmpAsmInfo->setExceptionsType(Options.ExceptionModel);
81bb8507e6SMatthias Braun
8210a21625SFangrui Song AsmInfo.reset(TmpAsmInfo);
83bb8507e6SMatthias Braun }
84bb8507e6SMatthias Braun
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)85bb8507e6SMatthias Braun LLVMTargetMachine::LLVMTargetMachine(const Target &T,
86bb8507e6SMatthias Braun StringRef DataLayoutString,
87bb8507e6SMatthias Braun const Triple &TT, StringRef CPU,
88bb8507e6SMatthias Braun StringRef FS, const TargetOptions &Options,
89bb8507e6SMatthias Braun Reloc::Model RM, CodeModel::Model CM,
90bb8507e6SMatthias Braun CodeGenOpt::Level OL)
91bb8507e6SMatthias Braun : TargetMachine(T, DataLayoutString, TT, CPU, FS, Options) {
92bb8507e6SMatthias Braun this->RM = RM;
93bb8507e6SMatthias Braun this->CMModel = CM;
94bb8507e6SMatthias Braun this->OptLevel = OL;
956d9f8c98SDavid Green
966d9f8c98SDavid Green if (EnableTrapUnreachable)
976d9f8c98SDavid Green this->Options.TrapUnreachable = true;
98bb8507e6SMatthias Braun }
99bb8507e6SMatthias Braun
10026d11ca4SSanjoy Das TargetTransformInfo
getTargetTransformInfo(const Function & F) const101c4b1a63aSJameson Nash LLVMTargetMachine::getTargetTransformInfo(const Function &F) const {
102bb8507e6SMatthias Braun return TargetTransformInfo(BasicTTIImpl(this, F));
103bb8507e6SMatthias Braun }
104bb8507e6SMatthias Braun
105bb8507e6SMatthias Braun /// addPassesToX helper drives creation and initialization of TargetPassConfig.
106e8f717aeSMatthias Braun static TargetPassConfig *
addPassesToGenerateCode(LLVMTargetMachine & TM,PassManagerBase & PM,bool DisableVerify,MachineModuleInfoWrapperPass & MMIWP)107e8f717aeSMatthias Braun addPassesToGenerateCode(LLVMTargetMachine &TM, PassManagerBase &PM,
108cc382cf7SYuanfang Chen bool DisableVerify,
109cc382cf7SYuanfang Chen MachineModuleInfoWrapperPass &MMIWP) {
110bb8507e6SMatthias Braun // Targets may override createPassConfig to provide a target-specific
111bb8507e6SMatthias Braun // subclass.
112e8f717aeSMatthias Braun TargetPassConfig *PassConfig = TM.createPassConfig(PM);
113bb8507e6SMatthias Braun // Set PassConfig options provided by TargetMachine.
114bb8507e6SMatthias Braun PassConfig->setDisableVerify(DisableVerify);
115bb8507e6SMatthias Braun PM.add(PassConfig);
116cc382cf7SYuanfang Chen PM.add(&MMIWP);
117bb8507e6SMatthias Braun
118bb8507e6SMatthias Braun if (PassConfig->addISelPasses())
119bb8507e6SMatthias Braun return nullptr;
120bb8507e6SMatthias Braun PassConfig->addMachinePasses();
121bb8507e6SMatthias Braun PassConfig->setInitialized();
122e8f717aeSMatthias Braun return PassConfig;
123bb8507e6SMatthias Braun }
124bb8507e6SMatthias Braun
addAsmPrinter(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,MCContext & Context)125bb8507e6SMatthias Braun bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
1269a45114bSPeter Collingbourne raw_pwrite_stream &Out,
1279a45114bSPeter Collingbourne raw_pwrite_stream *DwoOut,
1289a45114bSPeter Collingbourne CodeGenFileType FileType,
129bb8507e6SMatthias Braun MCContext &Context) {
130480936e7SYuanfang Chen Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
131480936e7SYuanfang Chen createMCStreamer(Out, DwoOut, FileType, Context);
132480936e7SYuanfang Chen if (auto Err = MCStreamerOrErr.takeError())
133480936e7SYuanfang Chen return true;
134480936e7SYuanfang Chen
135480936e7SYuanfang Chen // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
136480936e7SYuanfang Chen FunctionPass *Printer =
137480936e7SYuanfang Chen getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));
138480936e7SYuanfang Chen if (!Printer)
139480936e7SYuanfang Chen return true;
140480936e7SYuanfang Chen
141480936e7SYuanfang Chen PM.add(Printer);
142480936e7SYuanfang Chen return false;
143480936e7SYuanfang Chen }
144480936e7SYuanfang Chen
createMCStreamer(raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,MCContext & Context)145480936e7SYuanfang Chen Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(
146480936e7SYuanfang Chen raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
147480936e7SYuanfang Chen MCContext &Context) {
148bb8507e6SMatthias Braun if (Options.MCOptions.MCSaveTempLabels)
149bb8507e6SMatthias Braun Context.setAllowTemporaryLabels(false);
150bb8507e6SMatthias Braun
151bb8507e6SMatthias Braun const MCSubtargetInfo &STI = *getMCSubtargetInfo();
152bb8507e6SMatthias Braun const MCAsmInfo &MAI = *getMCAsmInfo();
153bb8507e6SMatthias Braun const MCRegisterInfo &MRI = *getMCRegisterInfo();
154bb8507e6SMatthias Braun const MCInstrInfo &MII = *getMCInstrInfo();
155bb8507e6SMatthias Braun
156bb8507e6SMatthias Braun std::unique_ptr<MCStreamer> AsmStreamer;
157bb8507e6SMatthias Braun
158bb8507e6SMatthias Braun switch (FileType) {
159bb8507e6SMatthias Braun case CGFT_AssemblyFile: {
160bb8507e6SMatthias Braun MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(
161bb8507e6SMatthias Braun getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI);
162bb8507e6SMatthias Braun
163bb8507e6SMatthias Braun // Create a code emitter if asked to show the encoding.
1641b5533c9SNirav Dave std::unique_ptr<MCCodeEmitter> MCE;
165bb8507e6SMatthias Braun if (Options.MCOptions.ShowMCEncoding)
1662aed07e9SShao-Ce SUN MCE.reset(getTarget().createMCCodeEmitter(MII, Context));
167bb8507e6SMatthias Braun
1680a27622aSAndrew Savonichev bool UseDwarfDirectory = false;
1690a27622aSAndrew Savonichev switch (Options.MCOptions.MCUseDwarfDirectory) {
1700a27622aSAndrew Savonichev case MCTargetOptions::DisableDwarfDirectory:
1710a27622aSAndrew Savonichev UseDwarfDirectory = false;
1720a27622aSAndrew Savonichev break;
1730a27622aSAndrew Savonichev case MCTargetOptions::EnableDwarfDirectory:
1740a27622aSAndrew Savonichev UseDwarfDirectory = true;
1750a27622aSAndrew Savonichev break;
1760a27622aSAndrew Savonichev case MCTargetOptions::DefaultDwarfDirectory:
1770a27622aSAndrew Savonichev UseDwarfDirectory = MAI.enableDwarfFileDirectoryDefault();
1780a27622aSAndrew Savonichev break;
1790a27622aSAndrew Savonichev }
1800a27622aSAndrew Savonichev
1811b5533c9SNirav Dave std::unique_ptr<MCAsmBackend> MAB(
1821b5533c9SNirav Dave getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions));
1830eaee545SJonas Devlieghere auto FOut = std::make_unique<formatted_raw_ostream>(Out);
184bb8507e6SMatthias Braun MCStreamer *S = getTarget().createAsmStreamer(
185bb8507e6SMatthias Braun Context, std::move(FOut), Options.MCOptions.AsmVerbose,
1860a27622aSAndrew Savonichev UseDwarfDirectory, InstPrinter, std::move(MCE), std::move(MAB),
1870a27622aSAndrew Savonichev Options.MCOptions.ShowMCInst);
188bb8507e6SMatthias Braun AsmStreamer.reset(S);
189bb8507e6SMatthias Braun break;
190bb8507e6SMatthias Braun }
191bb8507e6SMatthias Braun case CGFT_ObjectFile: {
192bb8507e6SMatthias Braun // Create the code emitter for the target if it exists. If not, .o file
193bb8507e6SMatthias Braun // emission fails.
1942aed07e9SShao-Ce SUN MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, Context);
195480936e7SYuanfang Chen if (!MCE)
196480936e7SYuanfang Chen return make_error<StringError>("createMCCodeEmitter failed",
197480936e7SYuanfang Chen inconvertibleErrorCode());
198bb8507e6SMatthias Braun MCAsmBackend *MAB =
199b22f751fSAlex Bradbury getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
200480936e7SYuanfang Chen if (!MAB)
201480936e7SYuanfang Chen return make_error<StringError>("createMCAsmBackend failed",
202480936e7SYuanfang Chen inconvertibleErrorCode());
203bb8507e6SMatthias Braun
204bb8507e6SMatthias Braun Triple T(getTargetTriple().str());
205bb8507e6SMatthias Braun AsmStreamer.reset(getTarget().createMCObjectStreamer(
206f7b81db7SPeter Collingbourne T, Context, std::unique_ptr<MCAsmBackend>(MAB),
2079a45114bSPeter Collingbourne DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut)
2089a45114bSPeter Collingbourne : MAB->createObjectWriter(Out),
2099a45114bSPeter Collingbourne std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll,
210bb8507e6SMatthias Braun Options.MCOptions.MCIncrementalLinkerCompatible,
211bb8507e6SMatthias Braun /*DWARFMustBeAtTheEnd*/ true));
212bb8507e6SMatthias Braun break;
213bb8507e6SMatthias Braun }
214bb8507e6SMatthias Braun case CGFT_Null:
215bb8507e6SMatthias Braun // The Null output is intended for use for performance analysis and testing,
216bb8507e6SMatthias Braun // not real users.
217bb8507e6SMatthias Braun AsmStreamer.reset(getTarget().createNullStreamer(Context));
218bb8507e6SMatthias Braun break;
219bb8507e6SMatthias Braun }
220bb8507e6SMatthias Braun
221480936e7SYuanfang Chen return std::move(AsmStreamer);
222bb8507e6SMatthias Braun }
223bb8507e6SMatthias Braun
addPassesToEmitFile(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,bool DisableVerify,MachineModuleInfoWrapperPass * MMIWP)224cc382cf7SYuanfang Chen bool LLVMTargetMachine::addPassesToEmitFile(
225cc382cf7SYuanfang Chen PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
226cc382cf7SYuanfang Chen CodeGenFileType FileType, bool DisableVerify,
227cc382cf7SYuanfang Chen MachineModuleInfoWrapperPass *MMIWP) {
228bb8507e6SMatthias Braun // Add common CodeGen passes.
229cc382cf7SYuanfang Chen if (!MMIWP)
230cc382cf7SYuanfang Chen MMIWP = new MachineModuleInfoWrapperPass(this);
231e8f717aeSMatthias Braun TargetPassConfig *PassConfig =
232cc382cf7SYuanfang Chen addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
233e8f717aeSMatthias Braun if (!PassConfig)
234bb8507e6SMatthias Braun return true;
235bb8507e6SMatthias Braun
2360c1381d7SJay Foad if (TargetPassConfig::willCompleteCodeGenPipeline()) {
2370c1381d7SJay Foad if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext()))
238bb8507e6SMatthias Braun return true;
2390c1381d7SJay Foad } else {
2400c1381d7SJay Foad // MIR printing is redundant with -filetype=null.
2410c1381d7SJay Foad if (FileType != CGFT_Null)
2420c1381d7SJay Foad PM.add(createPrintMIRPass(Out));
2430c1381d7SJay Foad }
244bb8507e6SMatthias Braun
245bb8507e6SMatthias Braun PM.add(createFreeMachineFunctionPass());
246bb8507e6SMatthias Braun return false;
247bb8507e6SMatthias Braun }
248bb8507e6SMatthias Braun
249bb8507e6SMatthias Braun /// addPassesToEmitMC - Add passes to the specified pass manager to get
250bb8507e6SMatthias Braun /// machine code emitted with the MCJIT. This method returns true if machine
251bb8507e6SMatthias Braun /// code is not supported. It fills the MCContext Ctx pointer which can be
252bb8507e6SMatthias Braun /// used to build custom MCStreamer.
253bb8507e6SMatthias Braun ///
addPassesToEmitMC(PassManagerBase & PM,MCContext * & Ctx,raw_pwrite_stream & Out,bool DisableVerify)254bb8507e6SMatthias Braun bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
255bb8507e6SMatthias Braun raw_pwrite_stream &Out,
256bb8507e6SMatthias Braun bool DisableVerify) {
257bb8507e6SMatthias Braun // Add common CodeGen passes.
258cc382cf7SYuanfang Chen MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(this);
259e8f717aeSMatthias Braun TargetPassConfig *PassConfig =
260cc382cf7SYuanfang Chen addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
261e8f717aeSMatthias Braun if (!PassConfig)
262bb8507e6SMatthias Braun return true;
263e8f717aeSMatthias Braun assert(TargetPassConfig::willCompleteCodeGenPipeline() &&
264e8f717aeSMatthias Braun "Cannot emit MC with limited codegen pipeline");
265bb8507e6SMatthias Braun
266cc382cf7SYuanfang Chen Ctx = &MMIWP->getMMI().getContext();
267*d4bcb45dSJez Ng // libunwind is unable to load compact unwind dynamically, so we must generate
268*d4bcb45dSJez Ng // DWARF unwind info for the JIT.
269*d4bcb45dSJez Ng Options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always;
270bb8507e6SMatthias Braun if (Options.MCOptions.MCSaveTempLabels)
271bb8507e6SMatthias Braun Ctx->setAllowTemporaryLabels(false);
272bb8507e6SMatthias Braun
273bb8507e6SMatthias Braun // Create the code emitter for the target if it exists. If not, .o file
274bb8507e6SMatthias Braun // emission fails.
275b22f751fSAlex Bradbury const MCSubtargetInfo &STI = *getMCSubtargetInfo();
276bb8507e6SMatthias Braun const MCRegisterInfo &MRI = *getMCRegisterInfo();
2772aed07e9SShao-Ce SUN MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getMCInstrInfo(), *Ctx);
278bb8507e6SMatthias Braun MCAsmBackend *MAB =
279b22f751fSAlex Bradbury getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
280bb8507e6SMatthias Braun if (!MCE || !MAB)
281bb8507e6SMatthias Braun return true;
282bb8507e6SMatthias Braun
283bb8507e6SMatthias Braun const Triple &T = getTargetTriple();
284bb8507e6SMatthias Braun std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer(
285f7b81db7SPeter Collingbourne T, *Ctx, std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(Out),
286bb8507e6SMatthias Braun std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll,
287bb8507e6SMatthias Braun Options.MCOptions.MCIncrementalLinkerCompatible,
288bb8507e6SMatthias Braun /*DWARFMustBeAtTheEnd*/ true));
289bb8507e6SMatthias Braun
290bb8507e6SMatthias Braun // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
291bb8507e6SMatthias Braun FunctionPass *Printer =
292bb8507e6SMatthias Braun getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
293bb8507e6SMatthias Braun if (!Printer)
294bb8507e6SMatthias Braun return true;
295bb8507e6SMatthias Braun
296bb8507e6SMatthias Braun PM.add(Printer);
297bb8507e6SMatthias Braun PM.add(createFreeMachineFunctionPass());
298bb8507e6SMatthias Braun
299bb8507e6SMatthias Braun return false; // success!
300bb8507e6SMatthias Braun }
301