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 GlobalObject;
33class Module;
34class SPIRVSubtarget;
35class Triple;
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 InstructionMetadataOpcode = 5,
46};
47
48class SPIRVAuxDataHandler {
49public:
50 SPIRVAuxDataHandler(AsmPrinter &AP, const Module &M);
51
52 /// Register extension + ext-inst-set; call before output of section 1.
53 void prepareModuleOutput(const SPIRVSubtarget &ST,
54 SPIRV::ModuleAnalysisInfo &MAI);
55
56 /// Emit OpStrings and stage ExtInst records; call in module section 7.
57 void emitAuxDataStrings(SPIRV::ModuleAnalysisInfo &MAI);
58
59 /// Emit the staged ExtInst records; call in module section 10.
60 void emitAuxData(SPIRV::ModuleAnalysisInfo &MAI);
61
62private:
63 // An ExtInst operand is either an already-emitted OpString (Reg valid) or a
64 // ValueAsMetadata constant whose OpConstant is emitted lazily at section 10
65 // (Const set). Exactly one is populated.
66 struct Operand {
67 MCRegister Reg;
68 const Constant *Const = nullptr;
69 };
70 // The Target operand (the OpFunction / OpVariable <id>) is resolved from
71 // GlobalObjMap at emit time, so records keep the GlobalObject, not a reg.
72 struct ExtInstRecord {
73 AuxDataOpcode Opcode;
74 const GlobalObject *Target;
75 SmallVector<Operand, 4> Operands;
76 };
77
78 AsmPrinter &Asm;
79 const Module &Mod;
80
81 SmallVector<const GlobalObject *> LinkagePreservedGOs;
82
83 // Backing storage for non-string-attribute strings; StringRegs keys are
84 // StringRefs into it.
85 BumpPtrAllocator StringAlloc;
86 UniqueStringSaver StringPool{StringAlloc};
87
88 DenseMap<StringRef, MCRegister> StringRegs;
89 DenseMap<const Constant *, MCRegister> ConstantRegs;
90 SmallVector<ExtInstRecord> PendingRecords;
91
92 MCRegister getOrEmitString(StringRef S, SPIRV::ModuleAnalysisInfo &MAI);
93 void collectAttributesFor(const GlobalObject *GO,
94 SPIRV::ModuleAnalysisInfo &MAI);
95 void collectMetadataFor(const GlobalObject *GO, ArrayRef<StringRef> MDNames,
96 SPIRV::ModuleAnalysisInfo &MAI);
97
98 void emitMCInst(MCInst &Inst);
99 MCRegister findOrEmitOpTypeVoid(SPIRV::ModuleAnalysisInfo &MAI);
100 MCRegister findOrEmitOpTypeInt(unsigned BitWidth,
101 SPIRV::ModuleAnalysisInfo &MAI);
102 MCRegister findOrEmitOpTypeUInt32(SPIRV::ModuleAnalysisInfo &MAI);
103 MCRegister findOrEmitOpTypeFloat(unsigned BitWidth,
104 SPIRV::ModuleAnalysisInfo &MAI);
105 MCRegister emitOpConstantUInt32(uint32_t Value, MCRegister UInt32TypeReg,
106 SPIRV::ModuleAnalysisInfo &MAI);
107 MCRegister emitConstant(const Constant *C, SPIRV::ModuleAnalysisInfo &MAI);
108 void emitAuxDataExtInst(AuxDataOpcode Opcode, MCRegister VoidTypeReg,
109 MCRegister ExtSetReg, ArrayRef<MCRegister> Operands,
110 SPIRV::ModuleAnalysisInfo &MAI,
111 bool UseForwardRefs = false);
112};
113
114bool spirvPreserveAuxData(const Triple &TT);
115
116} // namespace llvm
117
118#endif // LLVM_LIB_TARGET_SPIRV_SPIRVAUXDATAHANDLER_H
119