31 "spirv-preserve-auxdata",
32 cl::desc(
"Preserve LLVM attributes and metadata as "
33 "NonSemantic.AuxData ExtInst annotations (requires "
34 "SPV_KHR_non_semantic_info)"),
39 AvailableExternally = 0,
42constexpr unsigned NonSemanticAuxDataSet =
43 static_cast<unsigned>(SPIRV::InstructionSet::NonSemantic_AuxData);
47 return F->getAttributes().getFnAttrs();
62 return !F.isDeclaration() &&
63 (F.getAttributes().hasFnAttrs() || F.hasMetadata());
69 SPIRV::Extension::SPV_KHR_relaxed_extended_instruction);
75 "AuxData handler created with AuxData preservation disabled");
78 LinkagePreservedGOs.push_back(&GO);
87 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_non_semantic_info))
89 "SPV_KHR_non_semantic_info extension to be enabled.");
98 if (ST.canUseExtension(
99 SPIRV::Extension::SPV_KHR_relaxed_extended_instruction))
101 SPIRV::Extension::SPV_KHR_relaxed_extended_instruction);
107SPIRVAuxDataHandler::getOrEmitString(
StringRef S,
109 auto [It, Inserted] = StringRegs.try_emplace(S);
122void SPIRVAuxDataHandler::collectAttributesFor(
const GlobalObject *GO,
127 if (
A.isStringAttribute() &&
133 if (
A.isStringAttribute()) {
134 Rec.Operands.push_back({getOrEmitString(
A.getKindAsString(), MAI)});
135 StringRef Val =
A.getValueAsString();
137 Rec.Operands.push_back({getOrEmitString(Val, MAI)});
139 Rec.Operands.push_back(
140 {getOrEmitString(StringPool.save(
A.getAsString()), MAI)});
142 PendingRecords.push_back(std::move(Rec));
146void SPIRVAuxDataHandler::collectMetadataFor(
const GlobalObject *GO,
158 auto CollectOperands =
159 [&](MDNode *MD) -> std::optional<SmallVector<Operand, 4>> {
160 SmallVector<Operand, 4>
Out;
161 for (
const MDOperand &MdOp : MD->operands()) {
164 Out.push_back({getOrEmitString(MDStr->getString(), MAI)});
169 Out.push_back({MCRegister(),
C});
176 for (
const auto &MD : AllMD) {
177 if (MD.first == LLVMContext::MD_dbg)
179 StringRef MDName = MDNames[MD.first];
180 if (MDName ==
"spirv.Decorations" || MDName ==
"spirv.ParameterDecorations")
182 auto Operands = CollectOperands(MD.second);
188 Rec.Operands.push_back({getOrEmitString(MDName, MAI)});
190 PendingRecords.push_back(std::move(Rec));
198 constexpr unsigned AllMDKindsSeen =
199 (1u << (
static_cast<unsigned>(
203 unsigned SeenMask = 0;
205 unsigned Bit = 1u <<
static_cast<unsigned>(Rec.Kind);
210 if (SeenMask == AllMDKindsSeen)
214 Mod.getContext().getMDKindNames(MDNames);
219 collectAttributesFor(&GO, MAI);
220 collectMetadataFor(&GO, MDNames, MAI);
229 MCRegister VoidTypeReg = findOrEmitOpTypeVoid(MAI);
231 for (
const ExtInstRecord &Rec : PendingRecords) {
237 for (
const Operand &
Op : Rec.Operands)
238 Operands.push_back(
Op.Const ? emitConstant(
Op.Const, MAI) :
Op.Reg);
239 emitAuxDataExtInst(Rec.Opcode, VoidTypeReg, ExtSetReg,
Operands, MAI,
252 {TargetReg, MDNameReg}, MAI,
true);
255 if (LinkagePreservedGOs.empty())
258 MCRegister UInt32TypeReg = findOrEmitOpTypeUInt32(MAI);
269 emitOpConstantUInt32(AvailableExternally, UInt32TypeReg, MAI);
271 {TargetReg, AEConstReg}, MAI,
276void SPIRVAuxDataHandler::emitAuxDataExtInst(
AuxDataOpcode Opcode,
281 bool UseForwardRefs) {
283 Inst.
setOpcode(UseForwardRefs ? SPIRV::OpExtInstWithForwardRefsKHR
294void SPIRVAuxDataHandler::emitMCInst(
MCInst &Inst) {
301 if (
MI->getOpcode() == SPIRV::OpTypeVoid)
312SPIRVAuxDataHandler::findOrEmitOpTypeInt(
unsigned BitWidth,
316 constexpr int64_t UnsignedSignedness = 0;
318 if (
MI->getOpcode() == SPIRV::OpTypeInt &&
319 MI->getOperand(1).getImm() ==
static_cast<int64_t
>(
BitWidth) &&
320 MI->getOperand(2).getImm() == UnsignedSignedness)
334 return findOrEmitOpTypeInt(32, MAI);
338SPIRVAuxDataHandler::findOrEmitOpTypeFloat(
unsigned BitWidth,
341 if (
MI->getOpcode() == SPIRV::OpTypeFloat &&
342 MI->getOperand(1).getImm() ==
static_cast<int64_t
>(
BitWidth))
355 auto [It,
Inserted] = ConstantRegs.try_emplace(
C);
363 Bits = CI->getValue();
364 Opcode = SPIRV::OpConstantI;
365 TypeReg = findOrEmitOpTypeInt(
Bits.getBitWidth(), MAI);
368 Bits = CF->getValueAPF().bitcastToAPInt();
369 Opcode = SPIRV::OpConstantF;
370 TypeReg = findOrEmitOpTypeFloat(
Bits.getBitWidth(), MAI);
381 for (
unsigned I = 0;
I < NumWords; ++
I)
383 std::min(32u,
Bits.getBitWidth() -
I * 32),
I * 32)));
385 if (Opcode == SPIRV::OpConstantF &&
Bits.getBitWidth() == 16)
391MCRegister SPIRVAuxDataHandler::emitOpConstantUInt32(
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
static bool canUseForwardRefs(const SPIRV::ModuleAnalysisInfo &MAI)
static cl::opt< bool > SPVPreserveAuxData("spirv-preserve-auxdata", cl::desc("Preserve LLVM attributes and metadata as " "NonSemantic.AuxData ExtInst annotations (requires " "SPV_KHR_non_semantic_info)"), cl::Hidden, cl::init(false))
static bool wasAvailableExternally(const GlobalObject *GO)
static bool hasFunctionAuxData(const Module &M)
#define SPIRV_WAS_AVAILABLE_EXTERNALLY_ATTR
Represent a constant reference to an array (0 or more elements consecutively in memory),...
This class is intended to be used as a driving class for all asm writers.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
This class holds the attributes for a particular argument, parameter, function, or return value.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
This is an important base class in LLVM.
LLVM_ABI void getAllMetadata(SmallVectorImpl< std::pair< unsigned, MDNode * > > &MDs) const
Appends all metadata attached to this value to MDs, sorting by KindID.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Instances of this class represent a single low-level machine instruction.
void setFlags(unsigned F)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
A Module instance is used to store all the information related to an LLVM module.
SPIRVAuxDataHandler(AsmPrinter &AP, const Module &M)
void emitAuxDataStrings(SPIRV::ModuleAnalysisInfo &MAI)
Emit OpStrings and stage ExtInst records; call in module section 7.
void emitAuxData(SPIRV::ModuleAnalysisInfo &MAI)
Emit the staged ExtInst records; call in module section 10.
void prepareModuleOutput(const SPIRVSubtarget &ST, SPIRV::ModuleAnalysisInfo &MAI)
Register extension + ext-inst-set; call before output of section 1.
bool contains(const T &V) const
Check if the SmallSet contains the given element.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
constexpr bool empty() const
Check if the string is empty.
Triple - Helper class for working with autoconf configuration names.
LLVM Value Representation.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void addStringImm(StringRef Str, MCInst &Inst)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ GlobalVariableMetadataOpcode
@ FunctionAttributeOpcode
@ GlobalVariableAttributeOpcode
@ InstructionMetadataOpcode
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool spirvPreserveAuxData(const Triple &TT)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
DWARFExpression::Operation Op
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
MCRegister getExtInstSetReg(unsigned SetNum)
DenseMap< unsigned, MCRegister > ExtInstSetMap
InstrList & getMSInstrs(unsigned MSType)
MCRegister getRegisterAlias(const MachineFunction *MF, Register Reg)
SmallVector< InstrAuxDataRecord > InstrAuxDataRecords
static StringRef getAMDGPUAtomicMDName(AMDGPUAtomicMDKind Kind)
MCRegister getGlobalObjReg(const GlobalObject *GO)
MCRegister getNextIDRegister()
void addExtension(Extension::Extension ToAdd)
const SmallSet< Extension::Extension, 4 > & getExtensions() const