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