1 | //===- MC/TargetRegistry.h - Target Registration ----------------*- C++ -*-===// |
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 exposes the TargetRegistry interface, which tools can use to access |
10 | // the appropriate target specific classes (TargetMachine, AsmPrinter, etc.) |
11 | // which have been registered. |
12 | // |
13 | // Target specific class implementations should register themselves using the |
14 | // appropriate TargetRegistry interfaces. |
15 | // |
16 | //===----------------------------------------------------------------------===// |
17 | |
18 | #ifndef LLVM_MC_TARGETREGISTRY_H |
19 | #define LLVM_MC_TARGETREGISTRY_H |
20 | |
21 | #include "llvm-c/DisassemblerTypes.h" |
22 | #include "llvm/ADT/StringRef.h" |
23 | #include "llvm/ADT/iterator_range.h" |
24 | #include "llvm/MC/MCObjectFileInfo.h" |
25 | #include "llvm/Support/CodeGen.h" |
26 | #include "llvm/Support/ErrorHandling.h" |
27 | #include "llvm/Support/FormattedStream.h" |
28 | #include "llvm/TargetParser/Triple.h" |
29 | #include <cassert> |
30 | #include <cstddef> |
31 | #include <iterator> |
32 | #include <memory> |
33 | #include <optional> |
34 | #include <string> |
35 | |
36 | namespace llvm { |
37 | |
38 | class AsmPrinter; |
39 | class MCAsmBackend; |
40 | class MCAsmInfo; |
41 | class MCAsmParser; |
42 | class MCCodeEmitter; |
43 | class MCContext; |
44 | class MCDisassembler; |
45 | class MCInstPrinter; |
46 | class MCInstrAnalysis; |
47 | class MCInstrInfo; |
48 | class MCObjectWriter; |
49 | class MCRegisterInfo; |
50 | class MCRelocationInfo; |
51 | class MCStreamer; |
52 | class MCSubtargetInfo; |
53 | class MCSymbolizer; |
54 | class MCTargetAsmParser; |
55 | class MCTargetOptions; |
56 | class MCTargetStreamer; |
57 | class raw_ostream; |
58 | class TargetMachine; |
59 | class TargetOptions; |
60 | namespace mca { |
61 | class CustomBehaviour; |
62 | class InstrPostProcess; |
63 | class InstrumentManager; |
64 | struct SourceMgr; |
65 | } // namespace mca |
66 | |
67 | MCStreamer *createNullStreamer(MCContext &Ctx); |
68 | // Takes ownership of \p TAB and \p CE. |
69 | |
70 | /// Create a machine code streamer which will print out assembly for the native |
71 | /// target, suitable for compiling with a native assembler. |
72 | /// |
73 | /// \param InstPrint - If given, the instruction printer to use. If not given |
74 | /// the MCInst representation will be printed. This method takes ownership of |
75 | /// InstPrint. |
76 | /// |
77 | /// \param CE - If given, a code emitter to use to show the instruction |
78 | /// encoding inline with the assembly. This method takes ownership of \p CE. |
79 | /// |
80 | /// \param TAB - If given, a target asm backend to use to show the fixup |
81 | /// information in conjunction with encoding information. This method takes |
82 | /// ownership of \p TAB. |
83 | /// |
84 | /// \param ShowInst - Whether to show the MCInst representation inline with |
85 | /// the assembly. |
86 | MCStreamer * |
87 | createAsmStreamer(MCContext &Ctx, std::unique_ptr<formatted_raw_ostream> OS, |
88 | bool isVerboseAsm, bool useDwarfDirectory, |
89 | MCInstPrinter *InstPrint, std::unique_ptr<MCCodeEmitter> &&CE, |
90 | std::unique_ptr<MCAsmBackend> &&TAB, bool ShowInst); |
91 | |
92 | MCStreamer *createELFStreamer(MCContext &Ctx, |
93 | std::unique_ptr<MCAsmBackend> &&TAB, |
94 | std::unique_ptr<MCObjectWriter> &&OW, |
95 | std::unique_ptr<MCCodeEmitter> &&CE, |
96 | bool RelaxAll); |
97 | MCStreamer *createGOFFStreamer(MCContext &Ctx, |
98 | std::unique_ptr<MCAsmBackend> &&TAB, |
99 | std::unique_ptr<MCObjectWriter> &&OW, |
100 | std::unique_ptr<MCCodeEmitter> &&CE, |
101 | bool RelaxAll); |
102 | MCStreamer *createMachOStreamer(MCContext &Ctx, |
103 | std::unique_ptr<MCAsmBackend> &&TAB, |
104 | std::unique_ptr<MCObjectWriter> &&OW, |
105 | std::unique_ptr<MCCodeEmitter> &&CE, |
106 | bool RelaxAll, bool DWARFMustBeAtTheEnd, |
107 | bool LabelSections = false); |
108 | MCStreamer *createWasmStreamer(MCContext &Ctx, |
109 | std::unique_ptr<MCAsmBackend> &&TAB, |
110 | std::unique_ptr<MCObjectWriter> &&OW, |
111 | std::unique_ptr<MCCodeEmitter> &&CE, |
112 | bool RelaxAll); |
113 | MCStreamer *createXCOFFStreamer(MCContext &Ctx, |
114 | std::unique_ptr<MCAsmBackend> &&TAB, |
115 | std::unique_ptr<MCObjectWriter> &&OW, |
116 | std::unique_ptr<MCCodeEmitter> &&CE, |
117 | bool RelaxAll); |
118 | MCStreamer *createSPIRVStreamer(MCContext &Ctx, |
119 | std::unique_ptr<MCAsmBackend> &&TAB, |
120 | std::unique_ptr<MCObjectWriter> &&OW, |
121 | std::unique_ptr<MCCodeEmitter> &&CE, |
122 | bool RelaxAll); |
123 | MCStreamer *createDXContainerStreamer(MCContext &Ctx, |
124 | std::unique_ptr<MCAsmBackend> &&TAB, |
125 | std::unique_ptr<MCObjectWriter> &&OW, |
126 | std::unique_ptr<MCCodeEmitter> &&CE, |
127 | bool RelaxAll); |
128 | |
129 | MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx); |
130 | |
131 | MCSymbolizer *createMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo, |
132 | LLVMSymbolLookupCallback SymbolLookUp, |
133 | void *DisInfo, MCContext *Ctx, |
134 | std::unique_ptr<MCRelocationInfo> &&RelInfo); |
135 | |
136 | mca::CustomBehaviour *createCustomBehaviour(const MCSubtargetInfo &STI, |
137 | const mca::SourceMgr &SrcMgr, |
138 | const MCInstrInfo &MCII); |
139 | |
140 | mca::InstrPostProcess *createInstrPostProcess(const MCSubtargetInfo &STI, |
141 | const MCInstrInfo &MCII); |
142 | |
143 | mca::InstrumentManager *createInstrumentManager(const MCSubtargetInfo &STI, |
144 | const MCInstrInfo &MCII); |
145 | |
146 | /// Target - Wrapper for Target specific information. |
147 | /// |
148 | /// For registration purposes, this is a POD type so that targets can be |
149 | /// registered without the use of static constructors. |
150 | /// |
151 | /// Targets should implement a single global instance of this class (which |
152 | /// will be zero initialized), and pass that instance to the TargetRegistry as |
153 | /// part of their initialization. |
154 | class Target { |
155 | public: |
156 | friend struct TargetRegistry; |
157 | |
158 | using ArchMatchFnTy = bool (*)(Triple::ArchType Arch); |
159 | |
160 | using MCAsmInfoCtorFnTy = MCAsmInfo *(*)(const MCRegisterInfo &MRI, |
161 | const Triple &TT, |
162 | const MCTargetOptions &Options); |
163 | using MCObjectFileInfoCtorFnTy = MCObjectFileInfo *(*)(MCContext &Ctx, |
164 | bool PIC, |
165 | bool LargeCodeModel); |
166 | using MCInstrInfoCtorFnTy = MCInstrInfo *(*)(); |
167 | using MCInstrAnalysisCtorFnTy = MCInstrAnalysis *(*)(const MCInstrInfo *Info); |
168 | using MCRegInfoCtorFnTy = MCRegisterInfo *(*)(const Triple &TT); |
169 | using MCSubtargetInfoCtorFnTy = MCSubtargetInfo *(*)(const Triple &TT, |
170 | StringRef CPU, |
171 | StringRef Features); |
172 | using TargetMachineCtorTy = TargetMachine |
173 | *(*)(const Target &T, const Triple &TT, StringRef CPU, StringRef Features, |
174 | const TargetOptions &Options, std::optional<Reloc::Model> RM, |
175 | std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT); |
176 | // If it weren't for layering issues (this header is in llvm/Support, but |
177 | // depends on MC?) this should take the Streamer by value rather than rvalue |
178 | // reference. |
179 | using AsmPrinterCtorTy = AsmPrinter *(*)( |
180 | TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer); |
181 | using MCAsmBackendCtorTy = MCAsmBackend *(*)(const Target &T, |
182 | const MCSubtargetInfo &STI, |
183 | const MCRegisterInfo &MRI, |
184 | const MCTargetOptions &Options); |
185 | using MCAsmParserCtorTy = MCTargetAsmParser *(*)( |
186 | const MCSubtargetInfo &STI, MCAsmParser &P, const MCInstrInfo &MII, |
187 | const MCTargetOptions &Options); |
188 | using MCDisassemblerCtorTy = MCDisassembler *(*)(const Target &T, |
189 | const MCSubtargetInfo &STI, |
190 | MCContext &Ctx); |
191 | using MCInstPrinterCtorTy = MCInstPrinter *(*)(const Triple &T, |
192 | unsigned SyntaxVariant, |
193 | const MCAsmInfo &MAI, |
194 | const MCInstrInfo &MII, |
195 | const MCRegisterInfo &MRI); |
196 | using MCCodeEmitterCtorTy = MCCodeEmitter *(*)(const MCInstrInfo &II, |
197 | MCContext &Ctx); |
198 | using ELFStreamerCtorTy = |
199 | MCStreamer *(*)(const Triple &T, MCContext &Ctx, |
200 | std::unique_ptr<MCAsmBackend> &&TAB, |
201 | std::unique_ptr<MCObjectWriter> &&OW, |
202 | std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); |
203 | using GOFFStreamerCtorTy = |
204 | MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB, |
205 | std::unique_ptr<MCObjectWriter> &&OW, |
206 | std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); |
207 | using MachOStreamerCtorTy = |
208 | MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB, |
209 | std::unique_ptr<MCObjectWriter> &&OW, |
210 | std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll, |
211 | bool DWARFMustBeAtTheEnd); |
212 | using COFFStreamerCtorTy = |
213 | MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB, |
214 | std::unique_ptr<MCObjectWriter> &&OW, |
215 | std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll, |
216 | bool IncrementalLinkerCompatible); |
217 | using WasmStreamerCtorTy = |
218 | MCStreamer *(*)(const Triple &T, MCContext &Ctx, |
219 | std::unique_ptr<MCAsmBackend> &&TAB, |
220 | std::unique_ptr<MCObjectWriter> &&OW, |
221 | std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); |
222 | using XCOFFStreamerCtorTy = |
223 | MCStreamer *(*)(const Triple &T, MCContext &Ctx, |
224 | std::unique_ptr<MCAsmBackend> &&TAB, |
225 | std::unique_ptr<MCObjectWriter> &&OW, |
226 | std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); |
227 | using SPIRVStreamerCtorTy = |
228 | MCStreamer *(*)(const Triple &T, MCContext &Ctx, |
229 | std::unique_ptr<MCAsmBackend> &&TAB, |
230 | std::unique_ptr<MCObjectWriter> &&OW, |
231 | std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); |
232 | |
233 | using DXContainerStreamerCtorTy = |
234 | MCStreamer *(*)(const Triple &T, MCContext &Ctx, |
235 | std::unique_ptr<MCAsmBackend> &&TAB, |
236 | std::unique_ptr<MCObjectWriter> &&OW, |
237 | std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); |
238 | |
239 | using NullTargetStreamerCtorTy = MCTargetStreamer *(*)(MCStreamer &S); |
240 | using AsmTargetStreamerCtorTy = MCTargetStreamer *(*)( |
241 | MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint, |
242 | bool IsVerboseAsm); |
243 | using ObjectTargetStreamerCtorTy = MCTargetStreamer *(*)( |
244 | MCStreamer &S, const MCSubtargetInfo &STI); |
245 | using MCRelocationInfoCtorTy = MCRelocationInfo *(*)(const Triple &TT, |
246 | MCContext &Ctx); |
247 | using MCSymbolizerCtorTy = MCSymbolizer *(*)( |
248 | const Triple &TT, LLVMOpInfoCallback GetOpInfo, |
249 | LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx, |
250 | std::unique_ptr<MCRelocationInfo> &&RelInfo); |
251 | |
252 | using CustomBehaviourCtorTy = |
253 | mca::CustomBehaviour *(*)(const MCSubtargetInfo &STI, |
254 | const mca::SourceMgr &SrcMgr, |
255 | const MCInstrInfo &MCII); |
256 | |
257 | using InstrPostProcessCtorTy = |
258 | mca::InstrPostProcess *(*)(const MCSubtargetInfo &STI, |
259 | const MCInstrInfo &MCII); |
260 | |
261 | using InstrumentManagerCtorTy = |
262 | mca::InstrumentManager *(*)(const MCSubtargetInfo &STI, |
263 | const MCInstrInfo &MCII); |
264 | |
265 | private: |
266 | /// Next - The next registered target in the linked list, maintained by the |
267 | /// TargetRegistry. |
268 | Target *Next; |
269 | |
270 | /// The target function for checking if an architecture is supported. |
271 | ArchMatchFnTy ArchMatchFn; |
272 | |
273 | /// Name - The target name. |
274 | const char *Name; |
275 | |
276 | /// ShortDesc - A short description of the target. |
277 | const char *ShortDesc; |
278 | |
279 | /// BackendName - The name of the backend implementation. This must match the |
280 | /// name of the 'def X : Target ...' in TableGen. |
281 | const char *BackendName; |
282 | |
283 | /// HasJIT - Whether this target supports the JIT. |
284 | bool HasJIT; |
285 | |
286 | /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if |
287 | /// registered. |
288 | MCAsmInfoCtorFnTy MCAsmInfoCtorFn; |
289 | |
290 | /// Constructor function for this target's MCObjectFileInfo, if registered. |
291 | MCObjectFileInfoCtorFnTy MCObjectFileInfoCtorFn; |
292 | |
293 | /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo, |
294 | /// if registered. |
295 | MCInstrInfoCtorFnTy MCInstrInfoCtorFn; |
296 | |
297 | /// MCInstrAnalysisCtorFn - Constructor function for this target's |
298 | /// MCInstrAnalysis, if registered. |
299 | MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn; |
300 | |
301 | /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo, |
302 | /// if registered. |
303 | MCRegInfoCtorFnTy MCRegInfoCtorFn; |
304 | |
305 | /// MCSubtargetInfoCtorFn - Constructor function for this target's |
306 | /// MCSubtargetInfo, if registered. |
307 | MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn; |
308 | |
309 | /// TargetMachineCtorFn - Construction function for this target's |
310 | /// TargetMachine, if registered. |
311 | TargetMachineCtorTy TargetMachineCtorFn; |
312 | |
313 | /// MCAsmBackendCtorFn - Construction function for this target's |
314 | /// MCAsmBackend, if registered. |
315 | MCAsmBackendCtorTy MCAsmBackendCtorFn; |
316 | |
317 | /// MCAsmParserCtorFn - Construction function for this target's |
318 | /// MCTargetAsmParser, if registered. |
319 | MCAsmParserCtorTy MCAsmParserCtorFn; |
320 | |
321 | /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter, |
322 | /// if registered. |
323 | AsmPrinterCtorTy AsmPrinterCtorFn; |
324 | |
325 | /// MCDisassemblerCtorFn - Construction function for this target's |
326 | /// MCDisassembler, if registered. |
327 | MCDisassemblerCtorTy MCDisassemblerCtorFn; |
328 | |
329 | /// MCInstPrinterCtorFn - Construction function for this target's |
330 | /// MCInstPrinter, if registered. |
331 | MCInstPrinterCtorTy MCInstPrinterCtorFn; |
332 | |
333 | /// MCCodeEmitterCtorFn - Construction function for this target's |
334 | /// CodeEmitter, if registered. |
335 | MCCodeEmitterCtorTy MCCodeEmitterCtorFn; |
336 | |
337 | // Construction functions for the various object formats, if registered. |
338 | COFFStreamerCtorTy COFFStreamerCtorFn = nullptr; |
339 | GOFFStreamerCtorTy GOFFStreamerCtorFn = nullptr; |
340 | MachOStreamerCtorTy MachOStreamerCtorFn = nullptr; |
341 | ELFStreamerCtorTy ELFStreamerCtorFn = nullptr; |
342 | WasmStreamerCtorTy WasmStreamerCtorFn = nullptr; |
343 | XCOFFStreamerCtorTy XCOFFStreamerCtorFn = nullptr; |
344 | SPIRVStreamerCtorTy SPIRVStreamerCtorFn = nullptr; |
345 | DXContainerStreamerCtorTy DXContainerStreamerCtorFn = nullptr; |
346 | |
347 | /// Construction function for this target's null TargetStreamer, if |
348 | /// registered (default = nullptr). |
349 | NullTargetStreamerCtorTy NullTargetStreamerCtorFn = nullptr; |
350 | |
351 | /// Construction function for this target's asm TargetStreamer, if |
352 | /// registered (default = nullptr). |
353 | AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn = nullptr; |
354 | |
355 | /// Construction function for this target's obj TargetStreamer, if |
356 | /// registered (default = nullptr). |
357 | ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn = nullptr; |
358 | |
359 | /// MCRelocationInfoCtorFn - Construction function for this target's |
360 | /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo) |
361 | MCRelocationInfoCtorTy MCRelocationInfoCtorFn = nullptr; |
362 | |
363 | /// MCSymbolizerCtorFn - Construction function for this target's |
364 | /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer) |
365 | MCSymbolizerCtorTy MCSymbolizerCtorFn = nullptr; |
366 | |
367 | /// CustomBehaviourCtorFn - Construction function for this target's |
368 | /// CustomBehaviour, if registered (default = nullptr). |
369 | CustomBehaviourCtorTy CustomBehaviourCtorFn = nullptr; |
370 | |
371 | /// InstrPostProcessCtorFn - Construction function for this target's |
372 | /// InstrPostProcess, if registered (default = nullptr). |
373 | InstrPostProcessCtorTy InstrPostProcessCtorFn = nullptr; |
374 | |
375 | /// InstrumentManagerCtorFn - Construction function for this target's |
376 | /// InstrumentManager, if registered (default = nullptr). |
377 | InstrumentManagerCtorTy InstrumentManagerCtorFn = nullptr; |
378 | |
379 | public: |
380 | Target() = default; |
381 | |
382 | /// @name Target Information |
383 | /// @{ |
384 | |
385 | // getNext - Return the next registered target. |
386 | const Target *getNext() const { return Next; } |
387 | |
388 | /// getName - Get the target name. |
389 | const char *getName() const { return Name; } |
390 | |
391 | /// getShortDescription - Get a short description of the target. |
392 | const char *getShortDescription() const { return ShortDesc; } |
393 | |
394 | /// getBackendName - Get the backend name. |
395 | const char *getBackendName() const { return BackendName; } |
396 | |
397 | /// @} |
398 | /// @name Feature Predicates |
399 | /// @{ |
400 | |
401 | /// hasJIT - Check if this targets supports the just-in-time compilation. |
402 | bool hasJIT() const { return HasJIT; } |
403 | |
404 | /// hasTargetMachine - Check if this target supports code generation. |
405 | bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; } |
406 | |
407 | /// hasMCAsmBackend - Check if this target supports .o generation. |
408 | bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; } |
409 | |
410 | /// hasMCAsmParser - Check if this target supports assembly parsing. |
411 | bool hasMCAsmParser() const { return MCAsmParserCtorFn != nullptr; } |
412 | |
413 | /// @} |
414 | /// @name Feature Constructors |
415 | /// @{ |
416 | |
417 | /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified |
418 | /// target triple. |
419 | /// |
420 | /// \param TheTriple This argument is used to determine the target machine |
421 | /// feature set; it should always be provided. Generally this should be |
422 | /// either the target triple from the module, or the target triple of the |
423 | /// host if that does not exist. |
424 | MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple, |
425 | const MCTargetOptions &Options) const { |
426 | if (!MCAsmInfoCtorFn) |
427 | return nullptr; |
428 | return MCAsmInfoCtorFn(MRI, Triple(TheTriple), Options); |
429 | } |
430 | |
431 | /// Create a MCObjectFileInfo implementation for the specified target |
432 | /// triple. |
433 | /// |
434 | MCObjectFileInfo *createMCObjectFileInfo(MCContext &Ctx, bool PIC, |
435 | bool LargeCodeModel = false) const { |
436 | if (!MCObjectFileInfoCtorFn) { |
437 | MCObjectFileInfo *MOFI = new MCObjectFileInfo(); |
438 | MOFI->initMCObjectFileInfo(MCCtx&: Ctx, PIC, LargeCodeModel); |
439 | return MOFI; |
440 | } |
441 | return MCObjectFileInfoCtorFn(Ctx, PIC, LargeCodeModel); |
442 | } |
443 | |
444 | /// createMCInstrInfo - Create a MCInstrInfo implementation. |
445 | /// |
446 | MCInstrInfo *createMCInstrInfo() const { |
447 | if (!MCInstrInfoCtorFn) |
448 | return nullptr; |
449 | return MCInstrInfoCtorFn(); |
450 | } |
451 | |
452 | /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation. |
453 | /// |
454 | MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const { |
455 | if (!MCInstrAnalysisCtorFn) |
456 | return nullptr; |
457 | return MCInstrAnalysisCtorFn(Info); |
458 | } |
459 | |
460 | /// createMCRegInfo - Create a MCRegisterInfo implementation. |
461 | /// |
462 | MCRegisterInfo *createMCRegInfo(StringRef TT) const { |
463 | if (!MCRegInfoCtorFn) |
464 | return nullptr; |
465 | return MCRegInfoCtorFn(Triple(TT)); |
466 | } |
467 | |
468 | /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation. |
469 | /// |
470 | /// \param TheTriple This argument is used to determine the target machine |
471 | /// feature set; it should always be provided. Generally this should be |
472 | /// either the target triple from the module, or the target triple of the |
473 | /// host if that does not exist. |
474 | /// \param CPU This specifies the name of the target CPU. |
475 | /// \param Features This specifies the string representation of the |
476 | /// additional target features. |
477 | MCSubtargetInfo *createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, |
478 | StringRef Features) const { |
479 | if (!MCSubtargetInfoCtorFn) |
480 | return nullptr; |
481 | return MCSubtargetInfoCtorFn(Triple(TheTriple), CPU, Features); |
482 | } |
483 | |
484 | /// createTargetMachine - Create a target specific machine implementation |
485 | /// for the specified \p Triple. |
486 | /// |
487 | /// \param TT This argument is used to determine the target machine |
488 | /// feature set; it should always be provided. Generally this should be |
489 | /// either the target triple from the module, or the target triple of the |
490 | /// host if that does not exist. |
491 | TargetMachine *createTargetMachine( |
492 | StringRef TT, StringRef CPU, StringRef Features, |
493 | const TargetOptions &Options, std::optional<Reloc::Model> RM, |
494 | std::optional<CodeModel::Model> CM = std::nullopt, |
495 | CodeGenOptLevel OL = CodeGenOptLevel::Default, bool JIT = false) const { |
496 | if (!TargetMachineCtorFn) |
497 | return nullptr; |
498 | return TargetMachineCtorFn(*this, Triple(TT), CPU, Features, Options, RM, |
499 | CM, OL, JIT); |
500 | } |
501 | |
502 | /// createMCAsmBackend - Create a target specific assembly parser. |
503 | MCAsmBackend *createMCAsmBackend(const MCSubtargetInfo &STI, |
504 | const MCRegisterInfo &MRI, |
505 | const MCTargetOptions &Options) const { |
506 | if (!MCAsmBackendCtorFn) |
507 | return nullptr; |
508 | return MCAsmBackendCtorFn(*this, STI, MRI, Options); |
509 | } |
510 | |
511 | /// createMCAsmParser - Create a target specific assembly parser. |
512 | /// |
513 | /// \param Parser The target independent parser implementation to use for |
514 | /// parsing and lexing. |
515 | MCTargetAsmParser *createMCAsmParser(const MCSubtargetInfo &STI, |
516 | MCAsmParser &Parser, |
517 | const MCInstrInfo &MII, |
518 | const MCTargetOptions &Options) const { |
519 | if (!MCAsmParserCtorFn) |
520 | return nullptr; |
521 | return MCAsmParserCtorFn(STI, Parser, MII, Options); |
522 | } |
523 | |
524 | /// createAsmPrinter - Create a target specific assembly printer pass. This |
525 | /// takes ownership of the MCStreamer object. |
526 | AsmPrinter *createAsmPrinter(TargetMachine &TM, |
527 | std::unique_ptr<MCStreamer> &&Streamer) const { |
528 | if (!AsmPrinterCtorFn) |
529 | return nullptr; |
530 | return AsmPrinterCtorFn(TM, std::move(Streamer)); |
531 | } |
532 | |
533 | MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI, |
534 | MCContext &Ctx) const { |
535 | if (!MCDisassemblerCtorFn) |
536 | return nullptr; |
537 | return MCDisassemblerCtorFn(*this, STI, Ctx); |
538 | } |
539 | |
540 | MCInstPrinter *createMCInstPrinter(const Triple &T, unsigned SyntaxVariant, |
541 | const MCAsmInfo &MAI, |
542 | const MCInstrInfo &MII, |
543 | const MCRegisterInfo &MRI) const { |
544 | if (!MCInstPrinterCtorFn) |
545 | return nullptr; |
546 | return MCInstPrinterCtorFn(T, SyntaxVariant, MAI, MII, MRI); |
547 | } |
548 | |
549 | /// createMCCodeEmitter - Create a target specific code emitter. |
550 | MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II, |
551 | MCContext &Ctx) const { |
552 | if (!MCCodeEmitterCtorFn) |
553 | return nullptr; |
554 | return MCCodeEmitterCtorFn(II, Ctx); |
555 | } |
556 | |
557 | /// Create a target specific MCStreamer. |
558 | /// |
559 | /// \param T The target triple. |
560 | /// \param Ctx The target context. |
561 | /// \param TAB The target assembler backend object. Takes ownership. |
562 | /// \param OW The stream object. |
563 | /// \param Emitter The target independent assembler object.Takes ownership. |
564 | /// \param RelaxAll Relax all fixups? |
565 | MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx, |
566 | std::unique_ptr<MCAsmBackend> &&TAB, |
567 | std::unique_ptr<MCObjectWriter> &&OW, |
568 | std::unique_ptr<MCCodeEmitter> &&Emitter, |
569 | const MCSubtargetInfo &STI, bool RelaxAll, |
570 | bool IncrementalLinkerCompatible, |
571 | bool DWARFMustBeAtTheEnd) const { |
572 | MCStreamer *S = nullptr; |
573 | switch (T.getObjectFormat()) { |
574 | case Triple::UnknownObjectFormat: |
575 | llvm_unreachable("Unknown object format" ); |
576 | case Triple::COFF: |
577 | assert((T.isOSWindows() || T.isUEFI()) && |
578 | "only Windows and UEFI COFF are supported" ); |
579 | S = COFFStreamerCtorFn(Ctx, std::move(TAB), std::move(OW), |
580 | std::move(Emitter), RelaxAll, |
581 | IncrementalLinkerCompatible); |
582 | break; |
583 | case Triple::MachO: |
584 | if (MachOStreamerCtorFn) |
585 | S = MachOStreamerCtorFn(Ctx, std::move(TAB), std::move(OW), |
586 | std::move(Emitter), RelaxAll, |
587 | DWARFMustBeAtTheEnd); |
588 | else |
589 | S = createMachOStreamer(Ctx, TAB: std::move(TAB), OW: std::move(OW), |
590 | CE: std::move(Emitter), RelaxAll, |
591 | DWARFMustBeAtTheEnd); |
592 | break; |
593 | case Triple::ELF: |
594 | if (ELFStreamerCtorFn) |
595 | S = ELFStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW), |
596 | std::move(Emitter), RelaxAll); |
597 | else |
598 | S = createELFStreamer(Ctx, TAB: std::move(TAB), OW: std::move(OW), |
599 | CE: std::move(Emitter), RelaxAll); |
600 | break; |
601 | case Triple::Wasm: |
602 | if (WasmStreamerCtorFn) |
603 | S = WasmStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW), |
604 | std::move(Emitter), RelaxAll); |
605 | else |
606 | S = createWasmStreamer(Ctx, TAB: std::move(TAB), OW: std::move(OW), |
607 | CE: std::move(Emitter), RelaxAll); |
608 | break; |
609 | case Triple::GOFF: |
610 | if (GOFFStreamerCtorFn) |
611 | S = GOFFStreamerCtorFn(Ctx, std::move(TAB), std::move(OW), |
612 | std::move(Emitter), RelaxAll); |
613 | else |
614 | S = createGOFFStreamer(Ctx, TAB: std::move(TAB), OW: std::move(OW), |
615 | CE: std::move(Emitter), RelaxAll); |
616 | break; |
617 | case Triple::XCOFF: |
618 | if (XCOFFStreamerCtorFn) |
619 | S = XCOFFStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW), |
620 | std::move(Emitter), RelaxAll); |
621 | else |
622 | S = createXCOFFStreamer(Ctx, TAB: std::move(TAB), OW: std::move(OW), |
623 | CE: std::move(Emitter), RelaxAll); |
624 | break; |
625 | case Triple::SPIRV: |
626 | if (SPIRVStreamerCtorFn) |
627 | S = SPIRVStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW), |
628 | std::move(Emitter), RelaxAll); |
629 | else |
630 | S = createSPIRVStreamer(Ctx, TAB: std::move(TAB), OW: std::move(OW), |
631 | CE: std::move(Emitter), RelaxAll); |
632 | break; |
633 | case Triple::DXContainer: |
634 | if (DXContainerStreamerCtorFn) |
635 | S = DXContainerStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW), |
636 | std::move(Emitter), RelaxAll); |
637 | else |
638 | S = createDXContainerStreamer(Ctx, TAB: std::move(TAB), OW: std::move(OW), |
639 | CE: std::move(Emitter), RelaxAll); |
640 | break; |
641 | } |
642 | if (ObjectTargetStreamerCtorFn) |
643 | ObjectTargetStreamerCtorFn(*S, STI); |
644 | return S; |
645 | } |
646 | |
647 | MCStreamer *createAsmStreamer(MCContext &Ctx, |
648 | std::unique_ptr<formatted_raw_ostream> OS, |
649 | bool IsVerboseAsm, bool UseDwarfDirectory, |
650 | MCInstPrinter *InstPrint, |
651 | std::unique_ptr<MCCodeEmitter> &&CE, |
652 | std::unique_ptr<MCAsmBackend> &&TAB, |
653 | bool ShowInst) const { |
654 | formatted_raw_ostream &OSRef = *OS; |
655 | MCStreamer *S = llvm::createAsmStreamer( |
656 | Ctx, OS: std::move(OS), isVerboseAsm: IsVerboseAsm, useDwarfDirectory: UseDwarfDirectory, InstPrint, |
657 | CE: std::move(CE), TAB: std::move(TAB), ShowInst); |
658 | createAsmTargetStreamer(S&: *S, OS&: OSRef, InstPrint, IsVerboseAsm); |
659 | return S; |
660 | } |
661 | |
662 | MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S, |
663 | formatted_raw_ostream &OS, |
664 | MCInstPrinter *InstPrint, |
665 | bool IsVerboseAsm) const { |
666 | if (AsmTargetStreamerCtorFn) |
667 | return AsmTargetStreamerCtorFn(S, OS, InstPrint, IsVerboseAsm); |
668 | return nullptr; |
669 | } |
670 | |
671 | MCStreamer *createNullStreamer(MCContext &Ctx) const { |
672 | MCStreamer *S = llvm::createNullStreamer(Ctx); |
673 | createNullTargetStreamer(S&: *S); |
674 | return S; |
675 | } |
676 | |
677 | MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) const { |
678 | if (NullTargetStreamerCtorFn) |
679 | return NullTargetStreamerCtorFn(S); |
680 | return nullptr; |
681 | } |
682 | |
683 | /// createMCRelocationInfo - Create a target specific MCRelocationInfo. |
684 | /// |
685 | /// \param TT The target triple. |
686 | /// \param Ctx The target context. |
687 | MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx) const { |
688 | MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn |
689 | ? MCRelocationInfoCtorFn |
690 | : llvm::createMCRelocationInfo; |
691 | return Fn(Triple(TT), Ctx); |
692 | } |
693 | |
694 | /// createMCSymbolizer - Create a target specific MCSymbolizer. |
695 | /// |
696 | /// \param TT The target triple. |
697 | /// \param GetOpInfo The function to get the symbolic information for |
698 | /// operands. |
699 | /// \param SymbolLookUp The function to lookup a symbol name. |
700 | /// \param DisInfo The pointer to the block of symbolic information for above |
701 | /// call |
702 | /// back. |
703 | /// \param Ctx The target context. |
704 | /// \param RelInfo The relocation information for this target. Takes |
705 | /// ownership. |
706 | MCSymbolizer * |
707 | createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo, |
708 | LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, |
709 | MCContext *Ctx, |
710 | std::unique_ptr<MCRelocationInfo> &&RelInfo) const { |
711 | MCSymbolizerCtorTy Fn = |
712 | MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer; |
713 | return Fn(Triple(TT), GetOpInfo, SymbolLookUp, DisInfo, Ctx, |
714 | std::move(RelInfo)); |
715 | } |
716 | |
717 | /// createCustomBehaviour - Create a target specific CustomBehaviour. |
718 | /// This class is used by llvm-mca and requires backend functionality. |
719 | mca::CustomBehaviour *createCustomBehaviour(const MCSubtargetInfo &STI, |
720 | const mca::SourceMgr &SrcMgr, |
721 | const MCInstrInfo &MCII) const { |
722 | if (CustomBehaviourCtorFn) |
723 | return CustomBehaviourCtorFn(STI, SrcMgr, MCII); |
724 | return nullptr; |
725 | } |
726 | |
727 | /// createInstrPostProcess - Create a target specific InstrPostProcess. |
728 | /// This class is used by llvm-mca and requires backend functionality. |
729 | mca::InstrPostProcess *createInstrPostProcess(const MCSubtargetInfo &STI, |
730 | const MCInstrInfo &MCII) const { |
731 | if (InstrPostProcessCtorFn) |
732 | return InstrPostProcessCtorFn(STI, MCII); |
733 | return nullptr; |
734 | } |
735 | |
736 | /// createInstrumentManager - Create a target specific |
737 | /// InstrumentManager. This class is used by llvm-mca and requires |
738 | /// backend functionality. |
739 | mca::InstrumentManager * |
740 | createInstrumentManager(const MCSubtargetInfo &STI, |
741 | const MCInstrInfo &MCII) const { |
742 | if (InstrumentManagerCtorFn) |
743 | return InstrumentManagerCtorFn(STI, MCII); |
744 | return nullptr; |
745 | } |
746 | |
747 | /// @} |
748 | }; |
749 | |
750 | /// TargetRegistry - Generic interface to target specific features. |
751 | struct TargetRegistry { |
752 | // FIXME: Make this a namespace, probably just move all the Register* |
753 | // functions into Target (currently they all just set members on the Target |
754 | // anyway, and Target friends this class so those functions can... |
755 | // function). |
756 | TargetRegistry() = delete; |
757 | |
758 | class iterator { |
759 | friend struct TargetRegistry; |
760 | |
761 | const Target *Current = nullptr; |
762 | |
763 | explicit iterator(Target *T) : Current(T) {} |
764 | |
765 | public: |
766 | using iterator_category = std::forward_iterator_tag; |
767 | using value_type = Target; |
768 | using difference_type = std::ptrdiff_t; |
769 | using pointer = value_type *; |
770 | using reference = value_type &; |
771 | |
772 | iterator() = default; |
773 | |
774 | bool operator==(const iterator &x) const { return Current == x.Current; } |
775 | bool operator!=(const iterator &x) const { return !operator==(x); } |
776 | |
777 | // Iterator traversal: forward iteration only |
778 | iterator &operator++() { // Preincrement |
779 | assert(Current && "Cannot increment end iterator!" ); |
780 | Current = Current->getNext(); |
781 | return *this; |
782 | } |
783 | iterator operator++(int) { // Postincrement |
784 | iterator tmp = *this; |
785 | ++*this; |
786 | return tmp; |
787 | } |
788 | |
789 | const Target &operator*() const { |
790 | assert(Current && "Cannot dereference end iterator!" ); |
791 | return *Current; |
792 | } |
793 | |
794 | const Target *operator->() const { return &operator*(); } |
795 | }; |
796 | |
797 | /// printRegisteredTargetsForVersion - Print the registered targets |
798 | /// appropriately for inclusion in a tool's version output. |
799 | static void printRegisteredTargetsForVersion(raw_ostream &OS); |
800 | |
801 | /// @name Registry Access |
802 | /// @{ |
803 | |
804 | static iterator_range<iterator> targets(); |
805 | |
806 | /// lookupTarget - Lookup a target based on a target triple. |
807 | /// |
808 | /// \param Triple - The triple to use for finding a target. |
809 | /// \param Error - On failure, an error string describing why no target was |
810 | /// found. |
811 | static const Target *lookupTarget(StringRef Triple, std::string &Error); |
812 | |
813 | /// lookupTarget - Lookup a target based on an architecture name |
814 | /// and a target triple. If the architecture name is non-empty, |
815 | /// then the lookup is done by architecture. Otherwise, the target |
816 | /// triple is used. |
817 | /// |
818 | /// \param ArchName - The architecture to use for finding a target. |
819 | /// \param TheTriple - The triple to use for finding a target. The |
820 | /// triple is updated with canonical architecture name if a lookup |
821 | /// by architecture is done. |
822 | /// \param Error - On failure, an error string describing why no target was |
823 | /// found. |
824 | static const Target *lookupTarget(StringRef ArchName, Triple &TheTriple, |
825 | std::string &Error); |
826 | |
827 | /// @} |
828 | /// @name Target Registration |
829 | /// @{ |
830 | |
831 | /// RegisterTarget - Register the given target. Attempts to register a |
832 | /// target which has already been registered will be ignored. |
833 | /// |
834 | /// Clients are responsible for ensuring that registration doesn't occur |
835 | /// while another thread is attempting to access the registry. Typically |
836 | /// this is done by initializing all targets at program startup. |
837 | /// |
838 | /// @param T - The target being registered. |
839 | /// @param Name - The target name. This should be a static string. |
840 | /// @param ShortDesc - A short target description. This should be a static |
841 | /// string. |
842 | /// @param BackendName - The name of the backend. This should be a static |
843 | /// string that is the same for all targets that share a backend |
844 | /// implementation and must match the name used in the 'def X : Target ...' in |
845 | /// TableGen. |
846 | /// @param ArchMatchFn - The arch match checking function for this target. |
847 | /// @param HasJIT - Whether the target supports JIT code |
848 | /// generation. |
849 | static void RegisterTarget(Target &T, const char *Name, const char *ShortDesc, |
850 | const char *BackendName, |
851 | Target::ArchMatchFnTy ArchMatchFn, |
852 | bool HasJIT = false); |
853 | |
854 | /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the |
855 | /// given target. |
856 | /// |
857 | /// Clients are responsible for ensuring that registration doesn't occur |
858 | /// while another thread is attempting to access the registry. Typically |
859 | /// this is done by initializing all targets at program startup. |
860 | /// |
861 | /// @param T - The target being registered. |
862 | /// @param Fn - A function to construct a MCAsmInfo for the target. |
863 | static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) { |
864 | T.MCAsmInfoCtorFn = Fn; |
865 | } |
866 | |
867 | /// Register a MCObjectFileInfo implementation for the given target. |
868 | /// |
869 | /// Clients are responsible for ensuring that registration doesn't occur |
870 | /// while another thread is attempting to access the registry. Typically |
871 | /// this is done by initializing all targets at program startup. |
872 | /// |
873 | /// @param T - The target being registered. |
874 | /// @param Fn - A function to construct a MCObjectFileInfo for the target. |
875 | static void RegisterMCObjectFileInfo(Target &T, |
876 | Target::MCObjectFileInfoCtorFnTy Fn) { |
877 | T.MCObjectFileInfoCtorFn = Fn; |
878 | } |
879 | |
880 | /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the |
881 | /// given target. |
882 | /// |
883 | /// Clients are responsible for ensuring that registration doesn't occur |
884 | /// while another thread is attempting to access the registry. Typically |
885 | /// this is done by initializing all targets at program startup. |
886 | /// |
887 | /// @param T - The target being registered. |
888 | /// @param Fn - A function to construct a MCInstrInfo for the target. |
889 | static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) { |
890 | T.MCInstrInfoCtorFn = Fn; |
891 | } |
892 | |
893 | /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for |
894 | /// the given target. |
895 | static void RegisterMCInstrAnalysis(Target &T, |
896 | Target::MCInstrAnalysisCtorFnTy Fn) { |
897 | T.MCInstrAnalysisCtorFn = Fn; |
898 | } |
899 | |
900 | /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the |
901 | /// given target. |
902 | /// |
903 | /// Clients are responsible for ensuring that registration doesn't occur |
904 | /// while another thread is attempting to access the registry. Typically |
905 | /// this is done by initializing all targets at program startup. |
906 | /// |
907 | /// @param T - The target being registered. |
908 | /// @param Fn - A function to construct a MCRegisterInfo for the target. |
909 | static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) { |
910 | T.MCRegInfoCtorFn = Fn; |
911 | } |
912 | |
913 | /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for |
914 | /// the given target. |
915 | /// |
916 | /// Clients are responsible for ensuring that registration doesn't occur |
917 | /// while another thread is attempting to access the registry. Typically |
918 | /// this is done by initializing all targets at program startup. |
919 | /// |
920 | /// @param T - The target being registered. |
921 | /// @param Fn - A function to construct a MCSubtargetInfo for the target. |
922 | static void RegisterMCSubtargetInfo(Target &T, |
923 | Target::MCSubtargetInfoCtorFnTy Fn) { |
924 | T.MCSubtargetInfoCtorFn = Fn; |
925 | } |
926 | |
927 | /// RegisterTargetMachine - Register a TargetMachine implementation for the |
928 | /// given target. |
929 | /// |
930 | /// Clients are responsible for ensuring that registration doesn't occur |
931 | /// while another thread is attempting to access the registry. Typically |
932 | /// this is done by initializing all targets at program startup. |
933 | /// |
934 | /// @param T - The target being registered. |
935 | /// @param Fn - A function to construct a TargetMachine for the target. |
936 | static void RegisterTargetMachine(Target &T, Target::TargetMachineCtorTy Fn) { |
937 | T.TargetMachineCtorFn = Fn; |
938 | } |
939 | |
940 | /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the |
941 | /// given target. |
942 | /// |
943 | /// Clients are responsible for ensuring that registration doesn't occur |
944 | /// while another thread is attempting to access the registry. Typically |
945 | /// this is done by initializing all targets at program startup. |
946 | /// |
947 | /// @param T - The target being registered. |
948 | /// @param Fn - A function to construct an AsmBackend for the target. |
949 | static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) { |
950 | T.MCAsmBackendCtorFn = Fn; |
951 | } |
952 | |
953 | /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for |
954 | /// the given target. |
955 | /// |
956 | /// Clients are responsible for ensuring that registration doesn't occur |
957 | /// while another thread is attempting to access the registry. Typically |
958 | /// this is done by initializing all targets at program startup. |
959 | /// |
960 | /// @param T - The target being registered. |
961 | /// @param Fn - A function to construct an MCTargetAsmParser for the target. |
962 | static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) { |
963 | T.MCAsmParserCtorFn = Fn; |
964 | } |
965 | |
966 | /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given |
967 | /// target. |
968 | /// |
969 | /// Clients are responsible for ensuring that registration doesn't occur |
970 | /// while another thread is attempting to access the registry. Typically |
971 | /// this is done by initializing all targets at program startup. |
972 | /// |
973 | /// @param T - The target being registered. |
974 | /// @param Fn - A function to construct an AsmPrinter for the target. |
975 | static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) { |
976 | T.AsmPrinterCtorFn = Fn; |
977 | } |
978 | |
979 | /// RegisterMCDisassembler - Register a MCDisassembler implementation for |
980 | /// the given target. |
981 | /// |
982 | /// Clients are responsible for ensuring that registration doesn't occur |
983 | /// while another thread is attempting to access the registry. Typically |
984 | /// this is done by initializing all targets at program startup. |
985 | /// |
986 | /// @param T - The target being registered. |
987 | /// @param Fn - A function to construct an MCDisassembler for the target. |
988 | static void RegisterMCDisassembler(Target &T, |
989 | Target::MCDisassemblerCtorTy Fn) { |
990 | T.MCDisassemblerCtorFn = Fn; |
991 | } |
992 | |
993 | /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the |
994 | /// given target. |
995 | /// |
996 | /// Clients are responsible for ensuring that registration doesn't occur |
997 | /// while another thread is attempting to access the registry. Typically |
998 | /// this is done by initializing all targets at program startup. |
999 | /// |
1000 | /// @param T - The target being registered. |
1001 | /// @param Fn - A function to construct an MCInstPrinter for the target. |
1002 | static void RegisterMCInstPrinter(Target &T, Target::MCInstPrinterCtorTy Fn) { |
1003 | T.MCInstPrinterCtorFn = Fn; |
1004 | } |
1005 | |
1006 | /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the |
1007 | /// given target. |
1008 | /// |
1009 | /// Clients are responsible for ensuring that registration doesn't occur |
1010 | /// while another thread is attempting to access the registry. Typically |
1011 | /// this is done by initializing all targets at program startup. |
1012 | /// |
1013 | /// @param T - The target being registered. |
1014 | /// @param Fn - A function to construct an MCCodeEmitter for the target. |
1015 | static void RegisterMCCodeEmitter(Target &T, Target::MCCodeEmitterCtorTy Fn) { |
1016 | T.MCCodeEmitterCtorFn = Fn; |
1017 | } |
1018 | |
1019 | static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn) { |
1020 | T.COFFStreamerCtorFn = Fn; |
1021 | } |
1022 | |
1023 | static void RegisterGOFFStreamer(Target &T, Target::GOFFStreamerCtorTy Fn) { |
1024 | T.GOFFStreamerCtorFn = Fn; |
1025 | } |
1026 | |
1027 | static void RegisterMachOStreamer(Target &T, Target::MachOStreamerCtorTy Fn) { |
1028 | T.MachOStreamerCtorFn = Fn; |
1029 | } |
1030 | |
1031 | static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn) { |
1032 | T.ELFStreamerCtorFn = Fn; |
1033 | } |
1034 | |
1035 | static void RegisterSPIRVStreamer(Target &T, Target::SPIRVStreamerCtorTy Fn) { |
1036 | T.SPIRVStreamerCtorFn = Fn; |
1037 | } |
1038 | |
1039 | static void RegisterDXContainerStreamer(Target &T, Target::DXContainerStreamerCtorTy Fn) { |
1040 | T.DXContainerStreamerCtorFn = Fn; |
1041 | } |
1042 | |
1043 | static void RegisterWasmStreamer(Target &T, Target::WasmStreamerCtorTy Fn) { |
1044 | T.WasmStreamerCtorFn = Fn; |
1045 | } |
1046 | |
1047 | static void RegisterXCOFFStreamer(Target &T, Target::XCOFFStreamerCtorTy Fn) { |
1048 | T.XCOFFStreamerCtorFn = Fn; |
1049 | } |
1050 | |
1051 | static void RegisterNullTargetStreamer(Target &T, |
1052 | Target::NullTargetStreamerCtorTy Fn) { |
1053 | T.NullTargetStreamerCtorFn = Fn; |
1054 | } |
1055 | |
1056 | static void RegisterAsmTargetStreamer(Target &T, |
1057 | Target::AsmTargetStreamerCtorTy Fn) { |
1058 | T.AsmTargetStreamerCtorFn = Fn; |
1059 | } |
1060 | |
1061 | static void |
1062 | RegisterObjectTargetStreamer(Target &T, |
1063 | Target::ObjectTargetStreamerCtorTy Fn) { |
1064 | T.ObjectTargetStreamerCtorFn = Fn; |
1065 | } |
1066 | |
1067 | /// RegisterMCRelocationInfo - Register an MCRelocationInfo |
1068 | /// implementation for the given target. |
1069 | /// |
1070 | /// Clients are responsible for ensuring that registration doesn't occur |
1071 | /// while another thread is attempting to access the registry. Typically |
1072 | /// this is done by initializing all targets at program startup. |
1073 | /// |
1074 | /// @param T - The target being registered. |
1075 | /// @param Fn - A function to construct an MCRelocationInfo for the target. |
1076 | static void RegisterMCRelocationInfo(Target &T, |
1077 | Target::MCRelocationInfoCtorTy Fn) { |
1078 | T.MCRelocationInfoCtorFn = Fn; |
1079 | } |
1080 | |
1081 | /// RegisterMCSymbolizer - Register an MCSymbolizer |
1082 | /// implementation for the given target. |
1083 | /// |
1084 | /// Clients are responsible for ensuring that registration doesn't occur |
1085 | /// while another thread is attempting to access the registry. Typically |
1086 | /// this is done by initializing all targets at program startup. |
1087 | /// |
1088 | /// @param T - The target being registered. |
1089 | /// @param Fn - A function to construct an MCSymbolizer for the target. |
1090 | static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn) { |
1091 | T.MCSymbolizerCtorFn = Fn; |
1092 | } |
1093 | |
1094 | /// RegisterCustomBehaviour - Register a CustomBehaviour |
1095 | /// implementation for the given target. |
1096 | /// |
1097 | /// Clients are responsible for ensuring that registration doesn't occur |
1098 | /// while another thread is attempting to access the registry. Typically |
1099 | /// this is done by initializing all targets at program startup. |
1100 | /// |
1101 | /// @param T - The target being registered. |
1102 | /// @param Fn - A function to construct a CustomBehaviour for the target. |
1103 | static void RegisterCustomBehaviour(Target &T, |
1104 | Target::CustomBehaviourCtorTy Fn) { |
1105 | T.CustomBehaviourCtorFn = Fn; |
1106 | } |
1107 | |
1108 | /// RegisterInstrPostProcess - Register an InstrPostProcess |
1109 | /// implementation for the given target. |
1110 | /// |
1111 | /// Clients are responsible for ensuring that registration doesn't occur |
1112 | /// while another thread is attempting to access the registry. Typically |
1113 | /// this is done by initializing all targets at program startup. |
1114 | /// |
1115 | /// @param T - The target being registered. |
1116 | /// @param Fn - A function to construct an InstrPostProcess for the target. |
1117 | static void RegisterInstrPostProcess(Target &T, |
1118 | Target::InstrPostProcessCtorTy Fn) { |
1119 | T.InstrPostProcessCtorFn = Fn; |
1120 | } |
1121 | |
1122 | /// RegisterInstrumentManager - Register an InstrumentManager |
1123 | /// implementation for the given target. |
1124 | /// |
1125 | /// Clients are responsible for ensuring that registration doesn't occur |
1126 | /// while another thread is attempting to access the registry. Typically |
1127 | /// this is done by initializing all targets at program startup. |
1128 | /// |
1129 | /// @param T - The target being registered. |
1130 | /// @param Fn - A function to construct an InstrumentManager for the |
1131 | /// target. |
1132 | static void RegisterInstrumentManager(Target &T, |
1133 | Target::InstrumentManagerCtorTy Fn) { |
1134 | T.InstrumentManagerCtorFn = Fn; |
1135 | } |
1136 | |
1137 | /// @} |
1138 | }; |
1139 | |
1140 | //===--------------------------------------------------------------------===// |
1141 | |
1142 | /// RegisterTarget - Helper template for registering a target, for use in the |
1143 | /// target's initialization function. Usage: |
1144 | /// |
1145 | /// |
1146 | /// Target &getTheFooTarget() { // The global target instance. |
1147 | /// static Target TheFooTarget; |
1148 | /// return TheFooTarget; |
1149 | /// } |
1150 | /// extern "C" void LLVMInitializeFooTargetInfo() { |
1151 | /// RegisterTarget<Triple::foo> X(getTheFooTarget(), "foo", "Foo |
1152 | /// description", "Foo" /* Backend Name */); |
1153 | /// } |
1154 | template <Triple::ArchType TargetArchType = Triple::UnknownArch, |
1155 | bool HasJIT = false> |
1156 | struct RegisterTarget { |
1157 | RegisterTarget(Target &T, const char *Name, const char *Desc, |
1158 | const char *BackendName) { |
1159 | TargetRegistry::RegisterTarget(T, Name, ShortDesc: Desc, BackendName, ArchMatchFn: &getArchMatch, |
1160 | HasJIT); |
1161 | } |
1162 | |
1163 | static bool getArchMatch(Triple::ArchType Arch) { |
1164 | return Arch == TargetArchType; |
1165 | } |
1166 | }; |
1167 | |
1168 | /// RegisterMCAsmInfo - Helper template for registering a target assembly info |
1169 | /// implementation. This invokes the static "Create" method on the class to |
1170 | /// actually do the construction. Usage: |
1171 | /// |
1172 | /// extern "C" void LLVMInitializeFooTarget() { |
1173 | /// extern Target TheFooTarget; |
1174 | /// RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget); |
1175 | /// } |
1176 | template <class MCAsmInfoImpl> struct RegisterMCAsmInfo { |
1177 | RegisterMCAsmInfo(Target &T) { |
1178 | TargetRegistry::RegisterMCAsmInfo(T, Fn: &Allocator); |
1179 | } |
1180 | |
1181 | private: |
1182 | static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, const Triple &TT, |
1183 | const MCTargetOptions &Options) { |
1184 | return new MCAsmInfoImpl(TT, Options); |
1185 | } |
1186 | }; |
1187 | |
1188 | /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info |
1189 | /// implementation. This invokes the specified function to do the |
1190 | /// construction. Usage: |
1191 | /// |
1192 | /// extern "C" void LLVMInitializeFooTarget() { |
1193 | /// extern Target TheFooTarget; |
1194 | /// RegisterMCAsmInfoFn X(TheFooTarget, TheFunction); |
1195 | /// } |
1196 | struct RegisterMCAsmInfoFn { |
1197 | RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) { |
1198 | TargetRegistry::RegisterMCAsmInfo(T, Fn); |
1199 | } |
1200 | }; |
1201 | |
1202 | /// Helper template for registering a target object file info implementation. |
1203 | /// This invokes the static "Create" method on the class to actually do the |
1204 | /// construction. Usage: |
1205 | /// |
1206 | /// extern "C" void LLVMInitializeFooTarget() { |
1207 | /// extern Target TheFooTarget; |
1208 | /// RegisterMCObjectFileInfo<FooMCObjectFileInfo> X(TheFooTarget); |
1209 | /// } |
1210 | template <class MCObjectFileInfoImpl> struct RegisterMCObjectFileInfo { |
1211 | RegisterMCObjectFileInfo(Target &T) { |
1212 | TargetRegistry::RegisterMCObjectFileInfo(T, Fn: &Allocator); |
1213 | } |
1214 | |
1215 | private: |
1216 | static MCObjectFileInfo *Allocator(MCContext &Ctx, bool PIC, |
1217 | bool LargeCodeModel = false) { |
1218 | return new MCObjectFileInfoImpl(Ctx, PIC, LargeCodeModel); |
1219 | } |
1220 | }; |
1221 | |
1222 | /// Helper template for registering a target object file info implementation. |
1223 | /// This invokes the specified function to do the construction. Usage: |
1224 | /// |
1225 | /// extern "C" void LLVMInitializeFooTarget() { |
1226 | /// extern Target TheFooTarget; |
1227 | /// RegisterMCObjectFileInfoFn X(TheFooTarget, TheFunction); |
1228 | /// } |
1229 | struct RegisterMCObjectFileInfoFn { |
1230 | RegisterMCObjectFileInfoFn(Target &T, Target::MCObjectFileInfoCtorFnTy Fn) { |
1231 | TargetRegistry::RegisterMCObjectFileInfo(T, Fn); |
1232 | } |
1233 | }; |
1234 | |
1235 | /// RegisterMCInstrInfo - Helper template for registering a target instruction |
1236 | /// info implementation. This invokes the static "Create" method on the class |
1237 | /// to actually do the construction. Usage: |
1238 | /// |
1239 | /// extern "C" void LLVMInitializeFooTarget() { |
1240 | /// extern Target TheFooTarget; |
1241 | /// RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget); |
1242 | /// } |
1243 | template <class MCInstrInfoImpl> struct RegisterMCInstrInfo { |
1244 | RegisterMCInstrInfo(Target &T) { |
1245 | TargetRegistry::RegisterMCInstrInfo(T, Fn: &Allocator); |
1246 | } |
1247 | |
1248 | private: |
1249 | static MCInstrInfo *Allocator() { return new MCInstrInfoImpl(); } |
1250 | }; |
1251 | |
1252 | /// RegisterMCInstrInfoFn - Helper template for registering a target |
1253 | /// instruction info implementation. This invokes the specified function to |
1254 | /// do the construction. Usage: |
1255 | /// |
1256 | /// extern "C" void LLVMInitializeFooTarget() { |
1257 | /// extern Target TheFooTarget; |
1258 | /// RegisterMCInstrInfoFn X(TheFooTarget, TheFunction); |
1259 | /// } |
1260 | struct RegisterMCInstrInfoFn { |
1261 | RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) { |
1262 | TargetRegistry::RegisterMCInstrInfo(T, Fn); |
1263 | } |
1264 | }; |
1265 | |
1266 | /// RegisterMCInstrAnalysis - Helper template for registering a target |
1267 | /// instruction analyzer implementation. This invokes the static "Create" |
1268 | /// method on the class to actually do the construction. Usage: |
1269 | /// |
1270 | /// extern "C" void LLVMInitializeFooTarget() { |
1271 | /// extern Target TheFooTarget; |
1272 | /// RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget); |
1273 | /// } |
1274 | template <class MCInstrAnalysisImpl> struct RegisterMCInstrAnalysis { |
1275 | RegisterMCInstrAnalysis(Target &T) { |
1276 | TargetRegistry::RegisterMCInstrAnalysis(T, Fn: &Allocator); |
1277 | } |
1278 | |
1279 | private: |
1280 | static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) { |
1281 | return new MCInstrAnalysisImpl(Info); |
1282 | } |
1283 | }; |
1284 | |
1285 | /// RegisterMCInstrAnalysisFn - Helper template for registering a target |
1286 | /// instruction analyzer implementation. This invokes the specified function |
1287 | /// to do the construction. Usage: |
1288 | /// |
1289 | /// extern "C" void LLVMInitializeFooTarget() { |
1290 | /// extern Target TheFooTarget; |
1291 | /// RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction); |
1292 | /// } |
1293 | struct RegisterMCInstrAnalysisFn { |
1294 | RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) { |
1295 | TargetRegistry::RegisterMCInstrAnalysis(T, Fn); |
1296 | } |
1297 | }; |
1298 | |
1299 | /// RegisterMCRegInfo - Helper template for registering a target register info |
1300 | /// implementation. This invokes the static "Create" method on the class to |
1301 | /// actually do the construction. Usage: |
1302 | /// |
1303 | /// extern "C" void LLVMInitializeFooTarget() { |
1304 | /// extern Target TheFooTarget; |
1305 | /// RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget); |
1306 | /// } |
1307 | template <class MCRegisterInfoImpl> struct RegisterMCRegInfo { |
1308 | RegisterMCRegInfo(Target &T) { |
1309 | TargetRegistry::RegisterMCRegInfo(T, Fn: &Allocator); |
1310 | } |
1311 | |
1312 | private: |
1313 | static MCRegisterInfo *Allocator(const Triple & /*TT*/) { |
1314 | return new MCRegisterInfoImpl(); |
1315 | } |
1316 | }; |
1317 | |
1318 | /// RegisterMCRegInfoFn - Helper template for registering a target register |
1319 | /// info implementation. This invokes the specified function to do the |
1320 | /// construction. Usage: |
1321 | /// |
1322 | /// extern "C" void LLVMInitializeFooTarget() { |
1323 | /// extern Target TheFooTarget; |
1324 | /// RegisterMCRegInfoFn X(TheFooTarget, TheFunction); |
1325 | /// } |
1326 | struct RegisterMCRegInfoFn { |
1327 | RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) { |
1328 | TargetRegistry::RegisterMCRegInfo(T, Fn); |
1329 | } |
1330 | }; |
1331 | |
1332 | /// RegisterMCSubtargetInfo - Helper template for registering a target |
1333 | /// subtarget info implementation. This invokes the static "Create" method |
1334 | /// on the class to actually do the construction. Usage: |
1335 | /// |
1336 | /// extern "C" void LLVMInitializeFooTarget() { |
1337 | /// extern Target TheFooTarget; |
1338 | /// RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget); |
1339 | /// } |
1340 | template <class MCSubtargetInfoImpl> struct RegisterMCSubtargetInfo { |
1341 | RegisterMCSubtargetInfo(Target &T) { |
1342 | TargetRegistry::RegisterMCSubtargetInfo(T, Fn: &Allocator); |
1343 | } |
1344 | |
1345 | private: |
1346 | static MCSubtargetInfo *Allocator(const Triple & /*TT*/, StringRef /*CPU*/, |
1347 | StringRef /*FS*/) { |
1348 | return new MCSubtargetInfoImpl(); |
1349 | } |
1350 | }; |
1351 | |
1352 | /// RegisterMCSubtargetInfoFn - Helper template for registering a target |
1353 | /// subtarget info implementation. This invokes the specified function to |
1354 | /// do the construction. Usage: |
1355 | /// |
1356 | /// extern "C" void LLVMInitializeFooTarget() { |
1357 | /// extern Target TheFooTarget; |
1358 | /// RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction); |
1359 | /// } |
1360 | struct RegisterMCSubtargetInfoFn { |
1361 | RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) { |
1362 | TargetRegistry::RegisterMCSubtargetInfo(T, Fn); |
1363 | } |
1364 | }; |
1365 | |
1366 | /// RegisterTargetMachine - Helper template for registering a target machine |
1367 | /// implementation, for use in the target machine initialization |
1368 | /// function. Usage: |
1369 | /// |
1370 | /// extern "C" void LLVMInitializeFooTarget() { |
1371 | /// extern Target TheFooTarget; |
1372 | /// RegisterTargetMachine<FooTargetMachine> X(TheFooTarget); |
1373 | /// } |
1374 | template <class TargetMachineImpl> struct RegisterTargetMachine { |
1375 | RegisterTargetMachine(Target &T) { |
1376 | TargetRegistry::RegisterTargetMachine(T, Fn: &Allocator); |
1377 | } |
1378 | |
1379 | private: |
1380 | static TargetMachine * |
1381 | Allocator(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, |
1382 | const TargetOptions &Options, std::optional<Reloc::Model> RM, |
1383 | std::optional<CodeModel::Model> CM, CodeGenOptLevel OL, bool JIT) { |
1384 | return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL, JIT); |
1385 | } |
1386 | }; |
1387 | |
1388 | /// RegisterMCAsmBackend - Helper template for registering a target specific |
1389 | /// assembler backend. Usage: |
1390 | /// |
1391 | /// extern "C" void LLVMInitializeFooMCAsmBackend() { |
1392 | /// extern Target TheFooTarget; |
1393 | /// RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget); |
1394 | /// } |
1395 | template <class MCAsmBackendImpl> struct RegisterMCAsmBackend { |
1396 | RegisterMCAsmBackend(Target &T) { |
1397 | TargetRegistry::RegisterMCAsmBackend(T, Fn: &Allocator); |
1398 | } |
1399 | |
1400 | private: |
1401 | static MCAsmBackend *Allocator(const Target &T, const MCSubtargetInfo &STI, |
1402 | const MCRegisterInfo &MRI, |
1403 | const MCTargetOptions &Options) { |
1404 | return new MCAsmBackendImpl(T, STI, MRI); |
1405 | } |
1406 | }; |
1407 | |
1408 | /// RegisterMCAsmParser - Helper template for registering a target specific |
1409 | /// assembly parser, for use in the target machine initialization |
1410 | /// function. Usage: |
1411 | /// |
1412 | /// extern "C" void LLVMInitializeFooMCAsmParser() { |
1413 | /// extern Target TheFooTarget; |
1414 | /// RegisterMCAsmParser<FooAsmParser> X(TheFooTarget); |
1415 | /// } |
1416 | template <class MCAsmParserImpl> struct RegisterMCAsmParser { |
1417 | RegisterMCAsmParser(Target &T) { |
1418 | TargetRegistry::RegisterMCAsmParser(T, Fn: &Allocator); |
1419 | } |
1420 | |
1421 | private: |
1422 | static MCTargetAsmParser *Allocator(const MCSubtargetInfo &STI, |
1423 | MCAsmParser &P, const MCInstrInfo &MII, |
1424 | const MCTargetOptions &Options) { |
1425 | return new MCAsmParserImpl(STI, P, MII, Options); |
1426 | } |
1427 | }; |
1428 | |
1429 | /// RegisterAsmPrinter - Helper template for registering a target specific |
1430 | /// assembly printer, for use in the target machine initialization |
1431 | /// function. Usage: |
1432 | /// |
1433 | /// extern "C" void LLVMInitializeFooAsmPrinter() { |
1434 | /// extern Target TheFooTarget; |
1435 | /// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget); |
1436 | /// } |
1437 | template <class AsmPrinterImpl> struct RegisterAsmPrinter { |
1438 | RegisterAsmPrinter(Target &T) { |
1439 | TargetRegistry::RegisterAsmPrinter(T, Fn: &Allocator); |
1440 | } |
1441 | |
1442 | private: |
1443 | static AsmPrinter *Allocator(TargetMachine &TM, |
1444 | std::unique_ptr<MCStreamer> &&Streamer) { |
1445 | return new AsmPrinterImpl(TM, std::move(Streamer)); |
1446 | } |
1447 | }; |
1448 | |
1449 | /// RegisterMCCodeEmitter - Helper template for registering a target specific |
1450 | /// machine code emitter, for use in the target initialization |
1451 | /// function. Usage: |
1452 | /// |
1453 | /// extern "C" void LLVMInitializeFooMCCodeEmitter() { |
1454 | /// extern Target TheFooTarget; |
1455 | /// RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget); |
1456 | /// } |
1457 | template <class MCCodeEmitterImpl> struct RegisterMCCodeEmitter { |
1458 | RegisterMCCodeEmitter(Target &T) { |
1459 | TargetRegistry::RegisterMCCodeEmitter(T, Fn: &Allocator); |
1460 | } |
1461 | |
1462 | private: |
1463 | static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/, |
1464 | MCContext & /*Ctx*/) { |
1465 | return new MCCodeEmitterImpl(); |
1466 | } |
1467 | }; |
1468 | |
1469 | } // end namespace llvm |
1470 | |
1471 | #endif // LLVM_MC_TARGETREGISTRY_H |
1472 | |