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