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