xref: /llvm-project/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp (revision bb3f5e1fed7c6ba733b7f273e93f5d3930976185)
1 //===-- CodeGenTargetMachineImpl.cpp --------------------------------------===//
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 /// \file This file implements the CodeGenTargetMachineImpl class.
10 ///
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/CodeGen/CodeGenTargetMachineImpl.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 CodeGenTargetMachineImpl::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->setFullRegisterNames(Options.MCOptions.PPCUseFullRegisterNames);
81 
82   if (Options.ExceptionModel != ExceptionHandling::None)
83     TmpAsmInfo->setExceptionsType(Options.ExceptionModel);
84 
85   AsmInfo.reset(TmpAsmInfo);
86 }
87 
88 CodeGenTargetMachineImpl::CodeGenTargetMachineImpl(
89     const Target &T, StringRef DataLayoutString, const Triple &TT,
90     StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM,
91     CodeModel::Model CM, CodeGenOptLevel OL)
92     : TargetMachine(T, DataLayoutString, TT, CPU, FS, Options) {
93   this->RM = RM;
94   this->CMModel = CM;
95   this->OptLevel = OL;
96 
97   if (EnableTrapUnreachable)
98     this->Options.TrapUnreachable = true;
99   if (EnableNoTrapAfterNoreturn)
100     this->Options.NoTrapAfterNoreturn = true;
101 }
102 
103 TargetTransformInfo
104 CodeGenTargetMachineImpl::getTargetTransformInfo(const Function &F) const {
105   return TargetTransformInfo(BasicTTIImpl(this, F));
106 }
107 
108 /// addPassesToX helper drives creation and initialization of TargetPassConfig.
109 static TargetPassConfig *
110 addPassesToGenerateCode(CodeGenTargetMachineImpl &TM, PassManagerBase &PM,
111                         bool DisableVerify,
112                         MachineModuleInfoWrapperPass &MMIWP) {
113   // Targets may override createPassConfig to provide a target-specific
114   // subclass.
115   TargetPassConfig *PassConfig = TM.createPassConfig(PM);
116   // Set PassConfig options provided by TargetMachine.
117   PassConfig->setDisableVerify(DisableVerify);
118   PM.add(PassConfig);
119   PM.add(&MMIWP);
120 
121   if (PassConfig->addISelPasses())
122     return nullptr;
123   PassConfig->addMachinePasses();
124   PassConfig->setInitialized();
125   return PassConfig;
126 }
127 
128 bool CodeGenTargetMachineImpl::addAsmPrinter(PassManagerBase &PM,
129                                              raw_pwrite_stream &Out,
130                                              raw_pwrite_stream *DwoOut,
131                                              CodeGenFileType FileType,
132                                              MCContext &Context) {
133   Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
134       createMCStreamer(Out, DwoOut, FileType, Context);
135   if (auto Err = MCStreamerOrErr.takeError())
136     return true;
137 
138   // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
139   FunctionPass *Printer =
140       getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));
141   if (!Printer)
142     return true;
143 
144   PM.add(Printer);
145   return false;
146 }
147 
148 Expected<std::unique_ptr<MCStreamer>>
149 CodeGenTargetMachineImpl::createMCStreamer(raw_pwrite_stream &Out,
150                                            raw_pwrite_stream *DwoOut,
151                                            CodeGenFileType FileType,
152                                            MCContext &Context) {
153   const MCSubtargetInfo &STI = *getMCSubtargetInfo();
154   const MCAsmInfo &MAI = *getMCAsmInfo();
155   const MCRegisterInfo &MRI = *getMCRegisterInfo();
156   const MCInstrInfo &MII = *getMCInstrInfo();
157 
158   std::unique_ptr<MCStreamer> AsmStreamer;
159 
160   switch (FileType) {
161   case CodeGenFileType::AssemblyFile: {
162     MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(
163         getTargetTriple(),
164         Options.MCOptions.OutputAsmVariant.value_or(MAI.getAssemblerDialect()),
165         MAI, MII, MRI);
166 
167     // Create a code emitter if asked to show the encoding.
168     std::unique_ptr<MCCodeEmitter> MCE;
169     if (Options.MCOptions.ShowMCEncoding)
170       MCE.reset(getTarget().createMCCodeEmitter(MII, Context));
171 
172     std::unique_ptr<MCAsmBackend> MAB(
173         getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions));
174     auto FOut = std::make_unique<formatted_raw_ostream>(Out);
175     MCStreamer *S = getTarget().createAsmStreamer(
176         Context, std::move(FOut), InstPrinter, std::move(MCE), std::move(MAB));
177     AsmStreamer.reset(S);
178     break;
179   }
180   case CodeGenFileType::ObjectFile: {
181     // Create the code emitter for the target if it exists.  If not, .o file
182     // emission fails.
183     MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, Context);
184     if (!MCE)
185       return make_error<StringError>("createMCCodeEmitter failed",
186                                      inconvertibleErrorCode());
187     MCAsmBackend *MAB =
188         getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
189     if (!MAB)
190       return make_error<StringError>("createMCAsmBackend failed",
191                                      inconvertibleErrorCode());
192 
193     Triple T(getTargetTriple().str());
194     AsmStreamer.reset(getTarget().createMCObjectStreamer(
195         T, Context, std::unique_ptr<MCAsmBackend>(MAB),
196         DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut)
197                : MAB->createObjectWriter(Out),
198         std::unique_ptr<MCCodeEmitter>(MCE), STI));
199     break;
200   }
201   case CodeGenFileType::Null:
202     // The Null output is intended for use for performance analysis and testing,
203     // not real users.
204     AsmStreamer.reset(getTarget().createNullStreamer(Context));
205     break;
206   }
207 
208   return std::move(AsmStreamer);
209 }
210 
211 bool CodeGenTargetMachineImpl::addPassesToEmitFile(
212     PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
213     CodeGenFileType FileType, bool DisableVerify,
214     MachineModuleInfoWrapperPass *MMIWP) {
215   // Add common CodeGen passes.
216   if (!MMIWP)
217     MMIWP = new MachineModuleInfoWrapperPass(this);
218   TargetPassConfig *PassConfig =
219       addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
220   if (!PassConfig)
221     return true;
222 
223   if (TargetPassConfig::willCompleteCodeGenPipeline()) {
224     if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext()))
225       return true;
226   } else {
227     // MIR printing is redundant with -filetype=null.
228     if (FileType != CodeGenFileType::Null)
229       PM.add(createPrintMIRPass(Out));
230   }
231 
232   PM.add(createFreeMachineFunctionPass());
233   return false;
234 }
235 
236 /// addPassesToEmitMC - Add passes to the specified pass manager to get
237 /// machine code emitted with the MCJIT. This method returns true if machine
238 /// code is not supported. It fills the MCContext Ctx pointer which can be
239 /// used to build custom MCStreamer.
240 ///
241 bool CodeGenTargetMachineImpl::addPassesToEmitMC(PassManagerBase &PM,
242                                                  MCContext *&Ctx,
243                                                  raw_pwrite_stream &Out,
244                                                  bool DisableVerify) {
245   // Add common CodeGen passes.
246   MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(this);
247   TargetPassConfig *PassConfig =
248       addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
249   if (!PassConfig)
250     return true;
251   assert(TargetPassConfig::willCompleteCodeGenPipeline() &&
252          "Cannot emit MC with limited codegen pipeline");
253 
254   Ctx = &MMIWP->getMMI().getContext();
255   // libunwind is unable to load compact unwind dynamically, so we must generate
256   // DWARF unwind info for the JIT.
257   Options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always;
258 
259   // Create the code emitter for the target if it exists.  If not, .o file
260   // emission fails.
261   const MCSubtargetInfo &STI = *getMCSubtargetInfo();
262   const MCRegisterInfo &MRI = *getMCRegisterInfo();
263   std::unique_ptr<MCCodeEmitter> MCE(
264       getTarget().createMCCodeEmitter(*getMCInstrInfo(), *Ctx));
265   if (!MCE)
266     return true;
267   MCAsmBackend *MAB =
268       getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
269   if (!MAB)
270     return true;
271 
272   const Triple &T = getTargetTriple();
273   std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer(
274       T, *Ctx, std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(Out),
275       std::move(MCE), STI));
276 
277   // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
278   FunctionPass *Printer =
279       getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
280   if (!Printer)
281     return true;
282 
283   PM.add(Printer);
284   PM.add(createFreeMachineFunctionPass());
285 
286   return false; // success!
287 }
288