1//===-- SPIRVAuxDataHandler.h - NonSemantic.AuxData emitter -*- 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// Emits NonSemantic.AuxData ExtInst annotations (mirrors SPIRV-LLVM-Translator
10// --spirv-preserve-auxdata).
11// Otherwise, AE-tagged functions emit plain Export linkage via
12// LinkageAttributes.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVAUXDATAHANDLER_H
17#define LLVM_LIB_TARGET_SPIRV_SPIRVAUXDATAHANDLER_H
18
19#include "SPIRVModuleAnalysis.h"
20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/MC/MCRegister.h"
25#include "llvm/Support/Allocator.h"
26#include "llvm/Support/StringSaver.h"
27
28namespace llvm {
29
30class AsmPrinter;
31class Constant;
32class Function;
33class GlobalObject;
34class Module;
35class SPIRVSubtarget;
36
37// Khronos NonSemantic.AuxData opcodes (int64_t to drop casts at MCOperand
38// boundaries).
39enum AuxDataOpcode : int64_t {
40 FunctionMetadataOpcode = 0,
41 FunctionAttributeOpcode = 1,
42 GlobalVariableMetadataOpcode = 2,
43 GlobalVariableAttributeOpcode = 3,
44 LinkageOpcode = 4,
45};
46
47class SPIRVAuxDataHandler {
48public:
49 SPIRVAuxDataHandler(AsmPrinter &AP, const Module &M);
50
51 bool hasWork() const;
52
53 /// Register extension + ext-inst-set; call before output of section 1.
54 void prepareModuleOutput(const SPIRVSubtarget &ST,
55 SPIRV::ModuleAnalysisInfo &MAI);
56
57 /// Emit OpStrings and stage ExtInst records; call in module section 7.
58 void emitAuxDataStrings(SPIRV::ModuleAnalysisInfo &MAI);
59
60 /// Emit the staged ExtInst records; call in module section 10.
61 void emitAuxData(SPIRV::ModuleAnalysisInfo &MAI);
62
63private:
64 // An ExtInst operand is either an already-emitted OpString (Reg valid) or a
65 // ValueAsMetadata constant whose OpConstant is emitted lazily at section 10
66 // (Const set). Exactly one is populated.
67 struct Operand {
68 MCRegister Reg;
69 const Constant *Const = nullptr;
70 };
71 // The Target operand (the OpFunction / OpVariable <id>) is resolved from
72 // GlobalObjMap at emit time, so records keep the GlobalObject, not a reg.
73 struct ExtInstRecord {
74 AuxDataOpcode Opcode;
75 const GlobalObject *Target;
76 SmallVector<Operand, 4> Operands;
77 };
78
79 AsmPrinter &Asm;
80 const Module &Mod;
81
82 SmallVector<const GlobalObject *> LinkagePreservedGOs;
83
84 // Backing storage for non-string-attribute strings; StringRegs keys are
85 // StringRefs into it.
86 BumpPtrAllocator StringAlloc;
87 UniqueStringSaver StringPool{StringAlloc};
88
89 DenseMap<StringRef, MCRegister> StringRegs;
90 DenseMap<const Constant *, MCRegister> ConstantRegs;
91 SmallVector<ExtInstRecord> PendingRecords;
92
93 MCRegister getOrEmitString(StringRef S, SPIRV::ModuleAnalysisInfo &MAI);
94 void collectAttributesFor(const GlobalObject *GO,
95 SPIRV::ModuleAnalysisInfo &MAI);
96 void collectMetadataFor(const GlobalObject *GO, ArrayRef<StringRef> MDNames,
97 SPIRV::ModuleAnalysisInfo &MAI);
98
99 void emitMCInst(MCInst &Inst);
100 MCRegister findOrEmitOpTypeVoid(SPIRV::ModuleAnalysisInfo &MAI);
101 MCRegister findOrEmitOpTypeInt(unsigned BitWidth,
102 SPIRV::ModuleAnalysisInfo &MAI);
103 MCRegister findOrEmitOpTypeUInt32(SPIRV::ModuleAnalysisInfo &MAI);
104 MCRegister findOrEmitOpTypeFloat(unsigned BitWidth,
105 SPIRV::ModuleAnalysisInfo &MAI);
106 MCRegister emitOpConstantUInt32(uint32_t Value, MCRegister UInt32TypeReg,
107 SPIRV::ModuleAnalysisInfo &MAI);
108 MCRegister emitConstant(const Constant *C, SPIRV::ModuleAnalysisInfo &MAI);
109 void emitAuxDataExtInst(AuxDataOpcode Opcode, MCRegister VoidTypeReg,
110 MCRegister ExtSetReg, ArrayRef<MCRegister> Operands,
111 SPIRV::ModuleAnalysisInfo &MAI);
112};
113
114} // namespace llvm
115
116#endif // LLVM_LIB_TARGET_SPIRV_SPIRVAUXDATAHANDLER_H
117