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"
2681ad6265SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
270b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
280b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
29349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
300b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
310b57cec5SDimitry Andric #include "llvm/Support/FormattedStream.h"
320b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
330b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h"
340b57cec5SDimitry Andric using namespace llvm;
350b57cec5SDimitry Andric 
3681ad6265SDimitry Andric static cl::opt<bool>
3781ad6265SDimitry Andric     EnableTrapUnreachable("trap-unreachable", cl::Hidden,
380b57cec5SDimitry Andric                           cl::desc("Enable generating trap for unreachable"));
390b57cec5SDimitry Andric 
405f757f3fSDimitry Andric static cl::opt<bool> EnableNoTrapAfterNoreturn(
415f757f3fSDimitry Andric     "no-trap-after-noreturn", cl::Hidden,
425f757f3fSDimitry Andric     cl::desc("Do not emit a trap instruction for 'unreachable' IR instructions "
435f757f3fSDimitry Andric              "after noreturn calls, even if --trap-unreachable is set."));
445f757f3fSDimitry Andric 
initAsmInfo()450b57cec5SDimitry Andric void LLVMTargetMachine::initAsmInfo() {
460b57cec5SDimitry Andric   MRI.reset(TheTarget.createMCRegInfo(getTargetTriple().str()));
47e8d8bef9SDimitry Andric   assert(MRI && "Unable to create reg info");
480b57cec5SDimitry Andric   MII.reset(TheTarget.createMCInstrInfo());
49e8d8bef9SDimitry Andric   assert(MII && "Unable to create instruction info");
500b57cec5SDimitry Andric   // FIXME: Having an MCSubtargetInfo on the target machine is a hack due
510b57cec5SDimitry Andric   // to some backends having subtarget feature dependent module level
520b57cec5SDimitry Andric   // code generation. This is similar to the hack in the AsmPrinter for
530b57cec5SDimitry Andric   // module level assembly etc.
540b57cec5SDimitry Andric   STI.reset(TheTarget.createMCSubtargetInfo(
550b57cec5SDimitry Andric       getTargetTriple().str(), getTargetCPU(), getTargetFeatureString()));
56e8d8bef9SDimitry Andric   assert(STI && "Unable to create subtarget info");
570b57cec5SDimitry Andric 
58480093f4SDimitry Andric   MCAsmInfo *TmpAsmInfo = TheTarget.createMCAsmInfo(
59480093f4SDimitry Andric       *MRI, getTargetTriple().str(), Options.MCOptions);
600b57cec5SDimitry Andric   // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0,
610b57cec5SDimitry Andric   // and if the old one gets included then MCAsmInfo will be NULL and
620b57cec5SDimitry Andric   // we'll crash later.
630b57cec5SDimitry Andric   // Provide the user with a useful error message about what's wrong.
640b57cec5SDimitry Andric   assert(TmpAsmInfo && "MCAsmInfo not initialized. "
650b57cec5SDimitry Andric          "Make sure you include the correct TargetSelect.h"
660b57cec5SDimitry Andric          "and that InitializeAllTargetMCs() is being invoked!");
670b57cec5SDimitry Andric 
68e8d8bef9SDimitry Andric   if (Options.BinutilsVersion.first > 0)
69e8d8bef9SDimitry Andric     TmpAsmInfo->setBinutilsVersion(Options.BinutilsVersion);
70e8d8bef9SDimitry Andric 
71fe6060f1SDimitry Andric   if (Options.DisableIntegratedAS) {
720b57cec5SDimitry Andric     TmpAsmInfo->setUseIntegratedAssembler(false);
73fe6060f1SDimitry Andric     // If there is explict option disable integratedAS, we can't use it for
74fe6060f1SDimitry Andric     // inlineasm either.
75fe6060f1SDimitry Andric     TmpAsmInfo->setParseInlineAsmUsingAsmParser(false);
76fe6060f1SDimitry Andric   }
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   TmpAsmInfo->setPreserveAsmComments(Options.MCOptions.PreserveAsmComments);
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   TmpAsmInfo->setCompressDebugSections(Options.CompressDebugSections);
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   TmpAsmInfo->setRelaxELFRelocations(Options.RelaxELFRelocations);
830b57cec5SDimitry Andric 
845f757f3fSDimitry Andric   TmpAsmInfo->setFullRegisterNames(Options.MCOptions.PPCUseFullRegisterNames);
855f757f3fSDimitry Andric 
860b57cec5SDimitry Andric   if (Options.ExceptionModel != ExceptionHandling::None)
870b57cec5SDimitry Andric     TmpAsmInfo->setExceptionsType(Options.ExceptionModel);
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   AsmInfo.reset(TmpAsmInfo);
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric 
LLVMTargetMachine(const Target & T,StringRef DataLayoutString,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Reloc::Model RM,CodeModel::Model CM,CodeGenOptLevel OL)920b57cec5SDimitry Andric LLVMTargetMachine::LLVMTargetMachine(const Target &T,
930b57cec5SDimitry Andric                                      StringRef DataLayoutString,
940b57cec5SDimitry Andric                                      const Triple &TT, StringRef CPU,
950b57cec5SDimitry Andric                                      StringRef FS, const TargetOptions &Options,
960b57cec5SDimitry Andric                                      Reloc::Model RM, CodeModel::Model CM,
975f757f3fSDimitry Andric                                      CodeGenOptLevel OL)
980b57cec5SDimitry Andric     : TargetMachine(T, DataLayoutString, TT, CPU, FS, Options) {
990b57cec5SDimitry Andric   this->RM = RM;
1000b57cec5SDimitry Andric   this->CMModel = CM;
1010b57cec5SDimitry Andric   this->OptLevel = OL;
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   if (EnableTrapUnreachable)
1040b57cec5SDimitry Andric     this->Options.TrapUnreachable = true;
1055f757f3fSDimitry Andric   if (EnableNoTrapAfterNoreturn)
1065f757f3fSDimitry Andric     this->Options.NoTrapAfterNoreturn = true;
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric TargetTransformInfo
getTargetTransformInfo(const Function & F) const11081ad6265SDimitry Andric LLVMTargetMachine::getTargetTransformInfo(const Function &F) const {
1110b57cec5SDimitry Andric   return TargetTransformInfo(BasicTTIImpl(this, F));
1120b57cec5SDimitry Andric }
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric /// addPassesToX helper drives creation and initialization of TargetPassConfig.
1150b57cec5SDimitry Andric static TargetPassConfig *
addPassesToGenerateCode(LLVMTargetMachine & TM,PassManagerBase & PM,bool DisableVerify,MachineModuleInfoWrapperPass & MMIWP)1160b57cec5SDimitry Andric addPassesToGenerateCode(LLVMTargetMachine &TM, PassManagerBase &PM,
1178bcb0991SDimitry Andric                         bool DisableVerify,
1188bcb0991SDimitry Andric                         MachineModuleInfoWrapperPass &MMIWP) {
1190b57cec5SDimitry Andric   // Targets may override createPassConfig to provide a target-specific
1200b57cec5SDimitry Andric   // subclass.
1210b57cec5SDimitry Andric   TargetPassConfig *PassConfig = TM.createPassConfig(PM);
1220b57cec5SDimitry Andric   // Set PassConfig options provided by TargetMachine.
1230b57cec5SDimitry Andric   PassConfig->setDisableVerify(DisableVerify);
1240b57cec5SDimitry Andric   PM.add(PassConfig);
1258bcb0991SDimitry Andric   PM.add(&MMIWP);
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   if (PassConfig->addISelPasses())
1280b57cec5SDimitry Andric     return nullptr;
1290b57cec5SDimitry Andric   PassConfig->addMachinePasses();
1300b57cec5SDimitry Andric   PassConfig->setInitialized();
1310b57cec5SDimitry Andric   return PassConfig;
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric 
addAsmPrinter(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,MCContext & Context)1340b57cec5SDimitry Andric bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,
1350b57cec5SDimitry Andric                                       raw_pwrite_stream &Out,
1360b57cec5SDimitry Andric                                       raw_pwrite_stream *DwoOut,
1370b57cec5SDimitry Andric                                       CodeGenFileType FileType,
1380b57cec5SDimitry Andric                                       MCContext &Context) {
139e8d8bef9SDimitry Andric   Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
140e8d8bef9SDimitry Andric       createMCStreamer(Out, DwoOut, FileType, Context);
141e8d8bef9SDimitry Andric   if (auto Err = MCStreamerOrErr.takeError())
142e8d8bef9SDimitry Andric     return true;
143e8d8bef9SDimitry Andric 
144e8d8bef9SDimitry Andric   // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
145e8d8bef9SDimitry Andric   FunctionPass *Printer =
146e8d8bef9SDimitry Andric       getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));
147e8d8bef9SDimitry Andric   if (!Printer)
148e8d8bef9SDimitry Andric     return true;
149e8d8bef9SDimitry Andric 
150e8d8bef9SDimitry Andric   PM.add(Printer);
151e8d8bef9SDimitry Andric   return false;
152e8d8bef9SDimitry Andric }
153e8d8bef9SDimitry Andric 
createMCStreamer(raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,MCContext & Context)154e8d8bef9SDimitry Andric Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(
155e8d8bef9SDimitry Andric     raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
156e8d8bef9SDimitry Andric     MCContext &Context) {
1570b57cec5SDimitry Andric   if (Options.MCOptions.MCSaveTempLabels)
1580b57cec5SDimitry Andric     Context.setAllowTemporaryLabels(false);
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   const MCSubtargetInfo &STI = *getMCSubtargetInfo();
1610b57cec5SDimitry Andric   const MCAsmInfo &MAI = *getMCAsmInfo();
1620b57cec5SDimitry Andric   const MCRegisterInfo &MRI = *getMCRegisterInfo();
1630b57cec5SDimitry Andric   const MCInstrInfo &MII = *getMCInstrInfo();
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric   std::unique_ptr<MCStreamer> AsmStreamer;
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   switch (FileType) {
1685f757f3fSDimitry Andric   case CodeGenFileType::AssemblyFile: {
1690b57cec5SDimitry Andric     MCInstPrinter *InstPrinter = getTarget().createMCInstPrinter(
1700b57cec5SDimitry Andric         getTargetTriple(), MAI.getAssemblerDialect(), MAI, MII, MRI);
1710b57cec5SDimitry Andric 
1720b57cec5SDimitry Andric     // Create a code emitter if asked to show the encoding.
1730b57cec5SDimitry Andric     std::unique_ptr<MCCodeEmitter> MCE;
1740b57cec5SDimitry Andric     if (Options.MCOptions.ShowMCEncoding)
17581ad6265SDimitry Andric       MCE.reset(getTarget().createMCCodeEmitter(MII, Context));
17681ad6265SDimitry Andric 
17781ad6265SDimitry Andric     bool UseDwarfDirectory = false;
17881ad6265SDimitry Andric     switch (Options.MCOptions.MCUseDwarfDirectory) {
17981ad6265SDimitry Andric     case MCTargetOptions::DisableDwarfDirectory:
18081ad6265SDimitry Andric       UseDwarfDirectory = false;
18181ad6265SDimitry Andric       break;
18281ad6265SDimitry Andric     case MCTargetOptions::EnableDwarfDirectory:
18381ad6265SDimitry Andric       UseDwarfDirectory = true;
18481ad6265SDimitry Andric       break;
18581ad6265SDimitry Andric     case MCTargetOptions::DefaultDwarfDirectory:
18681ad6265SDimitry Andric       UseDwarfDirectory = MAI.enableDwarfFileDirectoryDefault();
18781ad6265SDimitry Andric       break;
18881ad6265SDimitry Andric     }
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric     std::unique_ptr<MCAsmBackend> MAB(
1910b57cec5SDimitry Andric         getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions));
1928bcb0991SDimitry Andric     auto FOut = std::make_unique<formatted_raw_ostream>(Out);
1930b57cec5SDimitry Andric     MCStreamer *S = getTarget().createAsmStreamer(
1940b57cec5SDimitry Andric         Context, std::move(FOut), Options.MCOptions.AsmVerbose,
19581ad6265SDimitry Andric         UseDwarfDirectory, InstPrinter, std::move(MCE), std::move(MAB),
19681ad6265SDimitry Andric         Options.MCOptions.ShowMCInst);
1970b57cec5SDimitry Andric     AsmStreamer.reset(S);
1980b57cec5SDimitry Andric     break;
1990b57cec5SDimitry Andric   }
2005f757f3fSDimitry Andric   case CodeGenFileType::ObjectFile: {
2010b57cec5SDimitry Andric     // Create the code emitter for the target if it exists.  If not, .o file
2020b57cec5SDimitry Andric     // emission fails.
20381ad6265SDimitry Andric     MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, Context);
204e8d8bef9SDimitry Andric     if (!MCE)
205e8d8bef9SDimitry Andric       return make_error<StringError>("createMCCodeEmitter failed",
206e8d8bef9SDimitry Andric                                      inconvertibleErrorCode());
2070b57cec5SDimitry Andric     MCAsmBackend *MAB =
2080b57cec5SDimitry Andric         getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
209e8d8bef9SDimitry Andric     if (!MAB)
210e8d8bef9SDimitry Andric       return make_error<StringError>("createMCAsmBackend failed",
211e8d8bef9SDimitry Andric                                      inconvertibleErrorCode());
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric     Triple T(getTargetTriple().str());
2140b57cec5SDimitry Andric     AsmStreamer.reset(getTarget().createMCObjectStreamer(
2150b57cec5SDimitry Andric         T, Context, std::unique_ptr<MCAsmBackend>(MAB),
2160b57cec5SDimitry Andric         DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut)
2170b57cec5SDimitry Andric                : MAB->createObjectWriter(Out),
2180b57cec5SDimitry Andric         std::unique_ptr<MCCodeEmitter>(MCE), STI, Options.MCOptions.MCRelaxAll,
2190b57cec5SDimitry Andric         Options.MCOptions.MCIncrementalLinkerCompatible,
2200b57cec5SDimitry Andric         /*DWARFMustBeAtTheEnd*/ true));
2210b57cec5SDimitry Andric     break;
2220b57cec5SDimitry Andric   }
2235f757f3fSDimitry Andric   case CodeGenFileType::Null:
2240b57cec5SDimitry Andric     // The Null output is intended for use for performance analysis and testing,
2250b57cec5SDimitry Andric     // not real users.
2260b57cec5SDimitry Andric     AsmStreamer.reset(getTarget().createNullStreamer(Context));
2270b57cec5SDimitry Andric     break;
2280b57cec5SDimitry Andric   }
2290b57cec5SDimitry Andric 
230e8d8bef9SDimitry Andric   return std::move(AsmStreamer);
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric 
addPassesToEmitFile(PassManagerBase & PM,raw_pwrite_stream & Out,raw_pwrite_stream * DwoOut,CodeGenFileType FileType,bool DisableVerify,MachineModuleInfoWrapperPass * MMIWP)2338bcb0991SDimitry Andric bool LLVMTargetMachine::addPassesToEmitFile(
2348bcb0991SDimitry Andric     PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
2358bcb0991SDimitry Andric     CodeGenFileType FileType, bool DisableVerify,
2368bcb0991SDimitry Andric     MachineModuleInfoWrapperPass *MMIWP) {
2370b57cec5SDimitry Andric   // Add common CodeGen passes.
2388bcb0991SDimitry Andric   if (!MMIWP)
2398bcb0991SDimitry Andric     MMIWP = new MachineModuleInfoWrapperPass(this);
2400b57cec5SDimitry Andric   TargetPassConfig *PassConfig =
2418bcb0991SDimitry Andric       addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
2420b57cec5SDimitry Andric   if (!PassConfig)
2430b57cec5SDimitry Andric     return true;
2440b57cec5SDimitry Andric 
245e8d8bef9SDimitry Andric   if (TargetPassConfig::willCompleteCodeGenPipeline()) {
246e8d8bef9SDimitry Andric     if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext()))
2470b57cec5SDimitry Andric       return true;
248e8d8bef9SDimitry Andric   } else {
249e8d8bef9SDimitry Andric     // MIR printing is redundant with -filetype=null.
2505f757f3fSDimitry Andric     if (FileType != CodeGenFileType::Null)
251e8d8bef9SDimitry Andric       PM.add(createPrintMIRPass(Out));
252e8d8bef9SDimitry Andric   }
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric   PM.add(createFreeMachineFunctionPass());
2550b57cec5SDimitry Andric   return false;
2560b57cec5SDimitry Andric }
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric /// addPassesToEmitMC - Add passes to the specified pass manager to get
2590b57cec5SDimitry Andric /// machine code emitted with the MCJIT. This method returns true if machine
2600b57cec5SDimitry Andric /// code is not supported. It fills the MCContext Ctx pointer which can be
2610b57cec5SDimitry Andric /// used to build custom MCStreamer.
2620b57cec5SDimitry Andric ///
addPassesToEmitMC(PassManagerBase & PM,MCContext * & Ctx,raw_pwrite_stream & Out,bool DisableVerify)2630b57cec5SDimitry Andric bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
2640b57cec5SDimitry Andric                                           raw_pwrite_stream &Out,
2650b57cec5SDimitry Andric                                           bool DisableVerify) {
2660b57cec5SDimitry Andric   // Add common CodeGen passes.
2678bcb0991SDimitry Andric   MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(this);
2680b57cec5SDimitry Andric   TargetPassConfig *PassConfig =
2698bcb0991SDimitry Andric       addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
2700b57cec5SDimitry Andric   if (!PassConfig)
2710b57cec5SDimitry Andric     return true;
2720b57cec5SDimitry Andric   assert(TargetPassConfig::willCompleteCodeGenPipeline() &&
2730b57cec5SDimitry Andric          "Cannot emit MC with limited codegen pipeline");
2740b57cec5SDimitry Andric 
2758bcb0991SDimitry Andric   Ctx = &MMIWP->getMMI().getContext();
27681ad6265SDimitry Andric   // libunwind is unable to load compact unwind dynamically, so we must generate
27781ad6265SDimitry Andric   // DWARF unwind info for the JIT.
27881ad6265SDimitry Andric   Options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always;
2790b57cec5SDimitry Andric   if (Options.MCOptions.MCSaveTempLabels)
2800b57cec5SDimitry Andric     Ctx->setAllowTemporaryLabels(false);
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric   // Create the code emitter for the target if it exists.  If not, .o file
2830b57cec5SDimitry Andric   // emission fails.
2840b57cec5SDimitry Andric   const MCSubtargetInfo &STI = *getMCSubtargetInfo();
2850b57cec5SDimitry Andric   const MCRegisterInfo &MRI = *getMCRegisterInfo();
28606c3fb27SDimitry Andric   std::unique_ptr<MCCodeEmitter> MCE(
28706c3fb27SDimitry Andric       getTarget().createMCCodeEmitter(*getMCInstrInfo(), *Ctx));
28806c3fb27SDimitry Andric   std::unique_ptr<MCAsmBackend> MAB(
28906c3fb27SDimitry Andric       getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions));
2900b57cec5SDimitry Andric   if (!MCE || !MAB)
2910b57cec5SDimitry Andric     return true;
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   const Triple &T = getTargetTriple();
2940b57cec5SDimitry Andric   std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer(
29506c3fb27SDimitry Andric       T, *Ctx, std::move(MAB), MAB->createObjectWriter(Out), std::move(MCE),
29606c3fb27SDimitry Andric       STI, Options.MCOptions.MCRelaxAll,
2970b57cec5SDimitry Andric       Options.MCOptions.MCIncrementalLinkerCompatible,
2980b57cec5SDimitry Andric       /*DWARFMustBeAtTheEnd*/ true));
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
3010b57cec5SDimitry Andric   FunctionPass *Printer =
3020b57cec5SDimitry Andric       getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
3030b57cec5SDimitry Andric   if (!Printer)
3040b57cec5SDimitry Andric     return true;
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   PM.add(Printer);
3070b57cec5SDimitry Andric   PM.add(createFreeMachineFunctionPass());
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   return false; // success!
3100b57cec5SDimitry Andric }
311