1 //===-- SPIRVAsmPrinter.cpp - SPIR-V LLVM assembly writer ------*- C++ -*--===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains a printer that converts from our internal representation
10 // of machine-dependent LLVM code to the SPIR-V assembly language.
12 //===----------------------------------------------------------------------===//
14 #include "MCTargetDesc/SPIRVInstPrinter.h"
16 #include "SPIRVInstrInfo.h"
17 #include "SPIRVMCInstLower.h"
18 #include "SPIRVModuleAnalysis.h"
19 #include "SPIRVSubtarget.h"
20 #include "SPIRVTargetMachine.h"
21 #include "SPIRVUtils.h"
22 #include "TargetInfo/SPIRVTargetInfo.h"
23 #include "llvm/ADT/DenseMap.h"
24 #include "llvm/Analysis/ValueTracking.h"
25 #include "llvm/CodeGen/AsmPrinter.h"
26 #include "llvm/CodeGen/MachineConstantPool.h"
27 #include "llvm/CodeGen/MachineFunctionPass.h"
28 #include "llvm/CodeGen/MachineInstr.h"
29 #include "llvm/CodeGen/MachineModuleInfo.h"
30 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
31 #include "llvm/MC/MCAsmInfo.h"
32 #include "llvm/MC/MCAssembler.h"
33 #include "llvm/MC/MCInst.h"
34 #include "llvm/MC/MCObjectStreamer.h"
35 #include "llvm/MC/MCSPIRVObjectWriter.h"
36 #include "llvm/MC/MCStreamer.h"
37 #include "llvm/MC/MCSymbol.h"
38 #include "llvm/MC/TargetRegistry.h"
39 #include "llvm/Support/raw_ostream.h"
43 #define DEBUG_TYPE "asm-printer"
46 class SPIRVAsmPrinter
: public AsmPrinter
{
50 explicit SPIRVAsmPrinter(TargetMachine
&TM
,
51 std::unique_ptr
<MCStreamer
> Streamer
)
52 : AsmPrinter(TM
, std::move(Streamer
)), ST(nullptr), TII(nullptr) {}
53 bool ModuleSectionsEmitted
;
54 const SPIRVSubtarget
*ST
;
55 const SPIRVInstrInfo
*TII
;
57 StringRef
getPassName() const override
{ return "SPIRV Assembly Printer"; }
58 void printOperand(const MachineInstr
*MI
, int OpNum
, raw_ostream
&O
);
59 bool PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
60 const char *ExtraCode
, raw_ostream
&O
) override
;
62 void outputMCInst(MCInst
&Inst
);
63 void outputInstruction(const MachineInstr
*MI
);
64 void outputModuleSection(SPIRV::ModuleSectionType MSType
);
65 void outputGlobalRequirements();
66 void outputEntryPoints();
67 void outputDebugSourceAndStrings(const Module
&M
);
68 void outputOpExtInstImports(const Module
&M
);
69 void outputOpMemoryModel();
70 void outputOpFunctionEnd();
71 void outputExtFuncDecls();
72 void outputExecutionModeFromMDNode(Register Reg
, MDNode
*Node
,
73 SPIRV::ExecutionMode::ExecutionMode EM
,
74 unsigned ExpectMDOps
, int64_t DefVal
);
75 void outputExecutionModeFromNumthreadsAttribute(
76 const Register
&Reg
, const Attribute
&Attr
,
77 SPIRV::ExecutionMode::ExecutionMode EM
);
78 void outputExecutionMode(const Module
&M
);
79 void outputAnnotations(const Module
&M
);
80 void outputModuleSections();
82 void emitInstruction(const MachineInstr
*MI
) override
;
83 void emitFunctionEntryLabel() override
{}
84 void emitFunctionHeader() override
;
85 void emitFunctionBodyStart() override
{}
86 void emitFunctionBodyEnd() override
;
87 void emitBasicBlockStart(const MachineBasicBlock
&MBB
) override
;
88 void emitBasicBlockEnd(const MachineBasicBlock
&MBB
) override
{}
89 void emitGlobalVariable(const GlobalVariable
*GV
) override
{}
90 void emitOpLabel(const MachineBasicBlock
&MBB
);
91 void emitEndOfAsmFile(Module
&M
) override
;
92 bool doInitialization(Module
&M
) override
;
94 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
95 SPIRV::ModuleAnalysisInfo
*MAI
;
99 void SPIRVAsmPrinter::getAnalysisUsage(AnalysisUsage
&AU
) const {
100 AU
.addRequired
<SPIRVModuleAnalysis
>();
101 AU
.addPreserved
<SPIRVModuleAnalysis
>();
102 AsmPrinter::getAnalysisUsage(AU
);
105 // If the module has no functions, we need output global info anyway.
106 void SPIRVAsmPrinter::emitEndOfAsmFile(Module
&M
) {
107 if (ModuleSectionsEmitted
== false) {
108 outputModuleSections();
109 ModuleSectionsEmitted
= true;
112 ST
= static_cast<const SPIRVTargetMachine
&>(TM
).getSubtargetImpl();
113 VersionTuple SPIRVVersion
= ST
->getSPIRVVersion();
114 uint32_t Major
= SPIRVVersion
.getMajor();
115 uint32_t Minor
= SPIRVVersion
.getMinor().value_or(0);
116 // Bound is an approximation that accounts for the maximum used register
117 // number and number of generated OpLabels
118 unsigned Bound
= 2 * (ST
->getBound() + 1) + NLabels
;
119 if (MCAssembler
*Asm
= OutStreamer
->getAssemblerPtr())
120 static_cast<SPIRVObjectWriter
&>(Asm
->getWriter())
121 .setBuildVersion(Major
, Minor
, Bound
);
124 void SPIRVAsmPrinter::emitFunctionHeader() {
125 if (ModuleSectionsEmitted
== false) {
126 outputModuleSections();
127 ModuleSectionsEmitted
= true;
129 // Get the subtarget from the current MachineFunction.
130 ST
= &MF
->getSubtarget
<SPIRVSubtarget
>();
131 TII
= ST
->getInstrInfo();
132 const Function
&F
= MF
->getFunction();
135 OutStreamer
->getCommentOS()
136 << "-- Begin function "
137 << GlobalValue::dropLLVMManglingEscape(F
.getName()) << '\n';
140 auto Section
= getObjFileLowering().SectionForGlobal(&F
, TM
);
141 MF
->setSection(Section
);
144 void SPIRVAsmPrinter::outputOpFunctionEnd() {
145 MCInst FunctionEndInst
;
146 FunctionEndInst
.setOpcode(SPIRV::OpFunctionEnd
);
147 outputMCInst(FunctionEndInst
);
150 // Emit OpFunctionEnd at the end of MF and clear BBNumToRegMap.
151 void SPIRVAsmPrinter::emitFunctionBodyEnd() {
152 outputOpFunctionEnd();
153 MAI
->BBNumToRegMap
.clear();
156 void SPIRVAsmPrinter::emitOpLabel(const MachineBasicBlock
&MBB
) {
158 LabelInst
.setOpcode(SPIRV::OpLabel
);
159 LabelInst
.addOperand(MCOperand::createReg(MAI
->getOrCreateMBBRegister(MBB
)));
160 outputMCInst(LabelInst
);
164 void SPIRVAsmPrinter::emitBasicBlockStart(const MachineBasicBlock
&MBB
) {
165 assert(!MBB
.empty() && "MBB is empty!");
167 // If it's the first MBB in MF, it has OpFunction and OpFunctionParameter, so
168 // OpLabel should be output after them.
169 if (MBB
.getNumber() == MF
->front().getNumber()) {
170 for (const MachineInstr
&MI
: MBB
)
171 if (MI
.getOpcode() == SPIRV::OpFunction
)
173 // TODO: this case should be checked by the verifier.
174 report_fatal_error("OpFunction is expected in the front MBB of MF");
179 void SPIRVAsmPrinter::printOperand(const MachineInstr
*MI
, int OpNum
,
181 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
183 switch (MO
.getType()) {
184 case MachineOperand::MO_Register
:
185 O
<< SPIRVInstPrinter::getRegisterName(MO
.getReg());
188 case MachineOperand::MO_Immediate
:
192 case MachineOperand::MO_FPImmediate
:
196 case MachineOperand::MO_MachineBasicBlock
:
197 O
<< *MO
.getMBB()->getSymbol();
200 case MachineOperand::MO_GlobalAddress
:
201 O
<< *getSymbol(MO
.getGlobal());
204 case MachineOperand::MO_BlockAddress
: {
205 MCSymbol
*BA
= GetBlockAddressSymbol(MO
.getBlockAddress());
210 case MachineOperand::MO_ExternalSymbol
:
211 O
<< *GetExternalSymbolSymbol(MO
.getSymbolName());
214 case MachineOperand::MO_JumpTableIndex
:
215 case MachineOperand::MO_ConstantPoolIndex
:
217 llvm_unreachable("<unknown operand type>");
221 bool SPIRVAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
222 const char *ExtraCode
, raw_ostream
&O
) {
223 if (ExtraCode
&& ExtraCode
[0])
224 return true; // Invalid instruction - SPIR-V does not have special modifiers
226 printOperand(MI
, OpNo
, O
);
230 static bool isFuncOrHeaderInstr(const MachineInstr
*MI
,
231 const SPIRVInstrInfo
*TII
) {
232 return TII
->isHeaderInstr(*MI
) || MI
->getOpcode() == SPIRV::OpFunction
||
233 MI
->getOpcode() == SPIRV::OpFunctionParameter
;
236 void SPIRVAsmPrinter::outputMCInst(MCInst
&Inst
) {
237 OutStreamer
->emitInstruction(Inst
, *OutContext
.getSubtargetInfo());
240 void SPIRVAsmPrinter::outputInstruction(const MachineInstr
*MI
) {
241 SPIRVMCInstLower MCInstLowering
;
243 MCInstLowering
.lower(MI
, TmpInst
, MAI
);
244 outputMCInst(TmpInst
);
247 void SPIRVAsmPrinter::emitInstruction(const MachineInstr
*MI
) {
248 SPIRV_MC::verifyInstructionPredicates(MI
->getOpcode(),
249 getSubtargetInfo().getFeatureBits());
251 if (!MAI
->getSkipEmission(MI
))
252 outputInstruction(MI
);
254 // Output OpLabel after OpFunction and OpFunctionParameter in the first MBB.
255 const MachineInstr
*NextMI
= MI
->getNextNode();
256 if (!MAI
->hasMBBRegister(*MI
->getParent()) && isFuncOrHeaderInstr(MI
, TII
) &&
257 (!NextMI
|| !isFuncOrHeaderInstr(NextMI
, TII
))) {
258 assert(MI
->getParent()->getNumber() == MF
->front().getNumber() &&
259 "OpFunction is not in the front MBB of MF");
260 emitOpLabel(*MI
->getParent());
264 void SPIRVAsmPrinter::outputModuleSection(SPIRV::ModuleSectionType MSType
) {
265 for (MachineInstr
*MI
: MAI
->getMSInstrs(MSType
))
266 outputInstruction(MI
);
269 void SPIRVAsmPrinter::outputDebugSourceAndStrings(const Module
&M
) {
270 // Output OpSourceExtensions.
271 for (auto &Str
: MAI
->SrcExt
) {
273 Inst
.setOpcode(SPIRV::OpSourceExtension
);
274 addStringImm(Str
.first(), Inst
);
279 Inst
.setOpcode(SPIRV::OpSource
);
280 Inst
.addOperand(MCOperand::createImm(static_cast<unsigned>(MAI
->SrcLang
)));
282 MCOperand::createImm(static_cast<unsigned>(MAI
->SrcLangVersion
)));
286 void SPIRVAsmPrinter::outputOpExtInstImports(const Module
&M
) {
287 for (auto &CU
: MAI
->ExtInstSetMap
) {
288 unsigned Set
= CU
.first
;
289 Register Reg
= CU
.second
;
291 Inst
.setOpcode(SPIRV::OpExtInstImport
);
292 Inst
.addOperand(MCOperand::createReg(Reg
));
293 addStringImm(getExtInstSetName(
294 static_cast<SPIRV::InstructionSet::InstructionSet
>(Set
)),
300 void SPIRVAsmPrinter::outputOpMemoryModel() {
302 Inst
.setOpcode(SPIRV::OpMemoryModel
);
303 Inst
.addOperand(MCOperand::createImm(static_cast<unsigned>(MAI
->Addr
)));
304 Inst
.addOperand(MCOperand::createImm(static_cast<unsigned>(MAI
->Mem
)));
308 // Before the OpEntryPoints' output, we need to add the entry point's
309 // interfaces. The interface is a list of IDs of global OpVariable instructions.
310 // These declare the set of global variables from a module that form
311 // the interface of this entry point.
312 void SPIRVAsmPrinter::outputEntryPoints() {
313 // Find all OpVariable IDs with required StorageClass.
314 DenseSet
<Register
> InterfaceIDs
;
315 for (MachineInstr
*MI
: MAI
->GlobalVarList
) {
316 assert(MI
->getOpcode() == SPIRV::OpVariable
);
317 auto SC
= static_cast<SPIRV::StorageClass::StorageClass
>(
318 MI
->getOperand(2).getImm());
319 // Before version 1.4, the interface's storage classes are limited to
320 // the Input and Output storage classes. Starting with version 1.4,
321 // the interface's storage classes are all storage classes used in
322 // declaring all global variables referenced by the entry point call tree.
323 if (ST
->isAtLeastSPIRVVer(VersionTuple(1, 4)) ||
324 SC
== SPIRV::StorageClass::Input
|| SC
== SPIRV::StorageClass::Output
) {
325 MachineFunction
*MF
= MI
->getMF();
326 Register Reg
= MAI
->getRegisterAlias(MF
, MI
->getOperand(0).getReg());
327 InterfaceIDs
.insert(Reg
);
331 // Output OpEntryPoints adding interface args to all of them.
332 for (MachineInstr
*MI
: MAI
->getMSInstrs(SPIRV::MB_EntryPoints
)) {
333 SPIRVMCInstLower MCInstLowering
;
335 MCInstLowering
.lower(MI
, TmpInst
, MAI
);
336 for (Register Reg
: InterfaceIDs
) {
337 assert(Reg
.isValid());
338 TmpInst
.addOperand(MCOperand::createReg(Reg
));
340 outputMCInst(TmpInst
);
344 // Create global OpCapability instructions for the required capabilities.
345 void SPIRVAsmPrinter::outputGlobalRequirements() {
346 // Abort here if not all requirements can be satisfied.
347 MAI
->Reqs
.checkSatisfiable(*ST
);
349 for (const auto &Cap
: MAI
->Reqs
.getMinimalCapabilities()) {
351 Inst
.setOpcode(SPIRV::OpCapability
);
352 Inst
.addOperand(MCOperand::createImm(Cap
));
356 // Generate the final OpExtensions with strings instead of enums.
357 for (const auto &Ext
: MAI
->Reqs
.getExtensions()) {
359 Inst
.setOpcode(SPIRV::OpExtension
);
360 addStringImm(getSymbolicOperandMnemonic(
361 SPIRV::OperandCategory::ExtensionOperand
, Ext
),
365 // TODO add a pseudo instr for version number.
368 void SPIRVAsmPrinter::outputExtFuncDecls() {
369 // Insert OpFunctionEnd after each declaration.
370 SmallVectorImpl
<MachineInstr
*>::iterator
371 I
= MAI
->getMSInstrs(SPIRV::MB_ExtFuncDecls
).begin(),
372 E
= MAI
->getMSInstrs(SPIRV::MB_ExtFuncDecls
).end();
373 for (; I
!= E
; ++I
) {
374 outputInstruction(*I
);
375 if ((I
+ 1) == E
|| (*(I
+ 1))->getOpcode() == SPIRV::OpFunction
)
376 outputOpFunctionEnd();
380 // Encode LLVM type by SPIR-V execution mode VecTypeHint.
381 static unsigned encodeVecTypeHint(Type
*Ty
) {
386 if (Ty
->isDoubleTy())
388 if (IntegerType
*IntTy
= dyn_cast
<IntegerType
>(Ty
)) {
389 switch (IntTy
->getIntegerBitWidth()) {
399 llvm_unreachable("invalid integer type");
402 if (FixedVectorType
*VecTy
= dyn_cast
<FixedVectorType
>(Ty
)) {
403 Type
*EleTy
= VecTy
->getElementType();
404 unsigned Size
= VecTy
->getNumElements();
405 return Size
<< 16 | encodeVecTypeHint(EleTy
);
407 llvm_unreachable("invalid type");
410 static void addOpsFromMDNode(MDNode
*MDN
, MCInst
&Inst
,
411 SPIRV::ModuleAnalysisInfo
*MAI
) {
412 for (const MDOperand
&MDOp
: MDN
->operands()) {
413 if (auto *CMeta
= dyn_cast
<ConstantAsMetadata
>(MDOp
)) {
414 Constant
*C
= CMeta
->getValue();
415 if (ConstantInt
*Const
= dyn_cast
<ConstantInt
>(C
)) {
416 Inst
.addOperand(MCOperand::createImm(Const
->getZExtValue()));
417 } else if (auto *CE
= dyn_cast
<Function
>(C
)) {
418 Register FuncReg
= MAI
->getFuncReg(CE
);
419 assert(FuncReg
.isValid());
420 Inst
.addOperand(MCOperand::createReg(FuncReg
));
426 void SPIRVAsmPrinter::outputExecutionModeFromMDNode(
427 Register Reg
, MDNode
*Node
, SPIRV::ExecutionMode::ExecutionMode EM
,
428 unsigned ExpectMDOps
, int64_t DefVal
) {
430 Inst
.setOpcode(SPIRV::OpExecutionMode
);
431 Inst
.addOperand(MCOperand::createReg(Reg
));
432 Inst
.addOperand(MCOperand::createImm(static_cast<unsigned>(EM
)));
433 addOpsFromMDNode(Node
, Inst
, MAI
);
434 // reqd_work_group_size and work_group_size_hint require 3 operands,
435 // if metadata contains less operands, just add a default value
436 unsigned NodeSz
= Node
->getNumOperands();
437 if (ExpectMDOps
> 0 && NodeSz
< ExpectMDOps
)
438 for (unsigned i
= NodeSz
; i
< ExpectMDOps
; ++i
)
439 Inst
.addOperand(MCOperand::createImm(DefVal
));
443 void SPIRVAsmPrinter::outputExecutionModeFromNumthreadsAttribute(
444 const Register
&Reg
, const Attribute
&Attr
,
445 SPIRV::ExecutionMode::ExecutionMode EM
) {
446 assert(Attr
.isValid() && "Function called with an invalid attribute.");
449 Inst
.setOpcode(SPIRV::OpExecutionMode
);
450 Inst
.addOperand(MCOperand::createReg(Reg
));
451 Inst
.addOperand(MCOperand::createImm(static_cast<unsigned>(EM
)));
453 SmallVector
<StringRef
> NumThreads
;
454 Attr
.getValueAsString().split(NumThreads
, ',');
455 assert(NumThreads
.size() == 3 && "invalid numthreads");
456 for (uint32_t i
= 0; i
< 3; ++i
) {
458 [[maybe_unused
]] bool Result
= NumThreads
[i
].getAsInteger(10, V
);
459 assert(!Result
&& "Failed to parse numthreads");
460 Inst
.addOperand(MCOperand::createImm(V
));
466 void SPIRVAsmPrinter::outputExecutionMode(const Module
&M
) {
467 NamedMDNode
*Node
= M
.getNamedMetadata("spirv.ExecutionMode");
469 for (unsigned i
= 0; i
< Node
->getNumOperands(); i
++) {
471 Inst
.setOpcode(SPIRV::OpExecutionMode
);
472 addOpsFromMDNode(cast
<MDNode
>(Node
->getOperand(i
)), Inst
, MAI
);
476 for (auto FI
= M
.begin(), E
= M
.end(); FI
!= E
; ++FI
) {
477 const Function
&F
= *FI
;
478 // Only operands of OpEntryPoint instructions are allowed to be
479 // <Entry Point> operands of OpExecutionMode
480 if (F
.isDeclaration() || !isEntryPoint(F
))
482 Register FReg
= MAI
->getFuncReg(&F
);
483 assert(FReg
.isValid());
484 if (MDNode
*Node
= F
.getMetadata("reqd_work_group_size"))
485 outputExecutionModeFromMDNode(FReg
, Node
, SPIRV::ExecutionMode::LocalSize
,
487 if (Attribute Attr
= F
.getFnAttribute("hlsl.numthreads"); Attr
.isValid())
488 outputExecutionModeFromNumthreadsAttribute(
489 FReg
, Attr
, SPIRV::ExecutionMode::LocalSize
);
490 if (MDNode
*Node
= F
.getMetadata("work_group_size_hint"))
491 outputExecutionModeFromMDNode(FReg
, Node
,
492 SPIRV::ExecutionMode::LocalSizeHint
, 3, 1);
493 if (MDNode
*Node
= F
.getMetadata("intel_reqd_sub_group_size"))
494 outputExecutionModeFromMDNode(FReg
, Node
,
495 SPIRV::ExecutionMode::SubgroupSize
, 0, 0);
496 if (MDNode
*Node
= F
.getMetadata("vec_type_hint")) {
498 Inst
.setOpcode(SPIRV::OpExecutionMode
);
499 Inst
.addOperand(MCOperand::createReg(FReg
));
500 unsigned EM
= static_cast<unsigned>(SPIRV::ExecutionMode::VecTypeHint
);
501 Inst
.addOperand(MCOperand::createImm(EM
));
502 unsigned TypeCode
= encodeVecTypeHint(getMDOperandAsType(Node
, 0));
503 Inst
.addOperand(MCOperand::createImm(TypeCode
));
506 if (ST
->isOpenCLEnv() && !M
.getNamedMetadata("spirv.ExecutionMode") &&
507 !M
.getNamedMetadata("opencl.enable.FP_CONTRACT")) {
509 Inst
.setOpcode(SPIRV::OpExecutionMode
);
510 Inst
.addOperand(MCOperand::createReg(FReg
));
511 unsigned EM
= static_cast<unsigned>(SPIRV::ExecutionMode::ContractionOff
);
512 Inst
.addOperand(MCOperand::createImm(EM
));
518 void SPIRVAsmPrinter::outputAnnotations(const Module
&M
) {
519 outputModuleSection(SPIRV::MB_Annotations
);
520 // Process llvm.global.annotations special global variable.
521 for (auto F
= M
.global_begin(), E
= M
.global_end(); F
!= E
; ++F
) {
522 if ((*F
).getName() != "llvm.global.annotations")
524 const GlobalVariable
*V
= &(*F
);
525 const ConstantArray
*CA
= cast
<ConstantArray
>(V
->getOperand(0));
526 for (Value
*Op
: CA
->operands()) {
527 ConstantStruct
*CS
= cast
<ConstantStruct
>(Op
);
528 // The first field of the struct contains a pointer to
529 // the annotated variable.
530 Value
*AnnotatedVar
= CS
->getOperand(0)->stripPointerCasts();
531 if (!isa
<Function
>(AnnotatedVar
))
532 report_fatal_error("Unsupported value in llvm.global.annotations");
533 Function
*Func
= cast
<Function
>(AnnotatedVar
);
534 Register Reg
= MAI
->getFuncReg(Func
);
535 if (!Reg
.isValid()) {
537 raw_string_ostream
OS(DiagMsg
);
538 AnnotatedVar
->print(OS
);
539 DiagMsg
= "Unknown function in llvm.global.annotations: " + DiagMsg
;
540 report_fatal_error(DiagMsg
.c_str());
543 // The second field contains a pointer to a global annotation string.
545 cast
<GlobalVariable
>(CS
->getOperand(1)->stripPointerCasts());
547 StringRef AnnotationString
;
548 getConstantStringInfo(GV
, AnnotationString
);
550 Inst
.setOpcode(SPIRV::OpDecorate
);
551 Inst
.addOperand(MCOperand::createReg(Reg
));
552 unsigned Dec
= static_cast<unsigned>(SPIRV::Decoration::UserSemantic
);
553 Inst
.addOperand(MCOperand::createImm(Dec
));
554 addStringImm(AnnotationString
, Inst
);
560 void SPIRVAsmPrinter::outputModuleSections() {
561 const Module
*M
= MMI
->getModule();
562 // Get the global subtarget to output module-level info.
563 ST
= static_cast<const SPIRVTargetMachine
&>(TM
).getSubtargetImpl();
564 TII
= ST
->getInstrInfo();
565 MAI
= &SPIRVModuleAnalysis::MAI
;
566 assert(ST
&& TII
&& MAI
&& M
&& "Module analysis is required");
567 // Output instructions according to the Logical Layout of a Module:
568 // 1,2. All OpCapability instructions, then optional OpExtension instructions.
569 outputGlobalRequirements();
570 // 3. Optional OpExtInstImport instructions.
571 outputOpExtInstImports(*M
);
572 // 4. The single required OpMemoryModel instruction.
573 outputOpMemoryModel();
574 // 5. All entry point declarations, using OpEntryPoint.
576 // 6. Execution-mode declarations, using OpExecutionMode or OpExecutionModeId.
577 outputExecutionMode(*M
);
578 // 7a. Debug: all OpString, OpSourceExtension, OpSource, and
579 // OpSourceContinued, without forward references.
580 outputDebugSourceAndStrings(*M
);
581 // 7b. Debug: all OpName and all OpMemberName.
582 outputModuleSection(SPIRV::MB_DebugNames
);
583 // 7c. Debug: all OpModuleProcessed instructions.
584 outputModuleSection(SPIRV::MB_DebugModuleProcessed
);
585 // 8. All annotation instructions (all decorations).
586 outputAnnotations(*M
);
587 // 9. All type declarations (OpTypeXXX instructions), all constant
588 // instructions, and all global variable declarations. This section is
589 // the first section to allow use of: OpLine and OpNoLine debug information;
590 // non-semantic instructions with OpExtInst.
591 outputModuleSection(SPIRV::MB_TypeConstVars
);
592 // 10. All function declarations (functions without a body).
593 outputExtFuncDecls();
594 // 11. All function definitions (functions with a body).
595 // This is done in regular function output.
598 bool SPIRVAsmPrinter::doInitialization(Module
&M
) {
599 ModuleSectionsEmitted
= false;
600 // We need to call the parent's one explicitly.
601 return AsmPrinter::doInitialization(M
);
604 // Force static initialization.
605 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeSPIRVAsmPrinter() {
606 RegisterAsmPrinter
<SPIRVAsmPrinter
> X(getTheSPIRV32Target());
607 RegisterAsmPrinter
<SPIRVAsmPrinter
> Y(getTheSPIRV64Target());
608 RegisterAsmPrinter
<SPIRVAsmPrinter
> Z(getTheSPIRVLogicalTarget());