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();
63 LinkagePreservedGOs.push_back(&GO);
75 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_non_semantic_info)) {
78 "SPV_KHR_non_semantic_info extension to be enabled.");
87SPIRVAuxDataHandler::getOrEmitString(
StringRef S,
89 auto [It, Inserted] = StringRegs.try_emplace(S);
102void SPIRVAuxDataHandler::collectAttributesFor(
const GlobalObject *GO,
107 if (
A.isStringAttribute() &&
113 if (
A.isStringAttribute()) {
114 Rec.Operands.push_back({getOrEmitString(
A.getKindAsString(), MAI)});
115 StringRef Val =
A.getValueAsString();
117 Rec.Operands.push_back({getOrEmitString(Val, MAI)});
119 Rec.Operands.push_back(
120 {getOrEmitString(StringPool.save(
A.getAsString()), MAI)});
122 PendingRecords.push_back(std::move(Rec));
126void SPIRVAuxDataHandler::collectMetadataFor(
const GlobalObject *GO,
138 auto CollectOperands =
139 [&](MDNode *MD) -> std::optional<SmallVector<Operand, 4>> {
140 SmallVector<Operand, 4>
Out;
141 for (
const MDOperand &MdOp : MD->operands()) {
144 Out.push_back({getOrEmitString(MDStr->getString(), MAI)});
149 Out.push_back({MCRegister(),
C});
156 for (
const auto &MD : AllMD) {
157 if (MD.first == LLVMContext::MD_dbg)
159 StringRef MDName = MDNames[MD.first];
160 if (MDName ==
"spirv.Decorations" || MDName ==
"spirv.ParameterDecorations")
162 auto Operands = CollectOperands(MD.second);
168 Rec.Operands.push_back({getOrEmitString(MDName, MAI)});
170 PendingRecords.push_back(std::move(Rec));
180 Mod.getContext().getMDKindNames(MDNames);
184 collectAttributesFor(&GO, MAI);
185 collectMetadataFor(&GO, MDNames, MAI);
194 MCRegister VoidTypeReg = findOrEmitOpTypeVoid(MAI);
196 for (
const ExtInstRecord &Rec : PendingRecords) {
202 for (
const Operand &
Op : Rec.Operands)
203 Operands.push_back(
Op.Const ? emitConstant(
Op.Const, MAI) :
Op.Reg);
204 emitAuxDataExtInst(Rec.Opcode, VoidTypeReg, ExtSetReg,
Operands, MAI);
207 if (LinkagePreservedGOs.empty())
210 MCRegister UInt32TypeReg = findOrEmitOpTypeUInt32(MAI);
218 emitOpConstantUInt32(AvailableExternally, UInt32TypeReg, MAI);
220 {TargetReg, AEConstReg}, MAI);
224void SPIRVAuxDataHandler::emitAuxDataExtInst(
AuxDataOpcode Opcode,
240void SPIRVAuxDataHandler::emitMCInst(
MCInst &Inst) {
247 if (
MI->getOpcode() == SPIRV::OpTypeVoid)
258SPIRVAuxDataHandler::findOrEmitOpTypeInt(
unsigned BitWidth,
262 constexpr int64_t UnsignedSignedness = 0;
264 if (
MI->getOpcode() == SPIRV::OpTypeInt &&
265 MI->getOperand(1).getImm() ==
static_cast<int64_t
>(
BitWidth) &&
266 MI->getOperand(2).getImm() == UnsignedSignedness)
280 return findOrEmitOpTypeInt(32, MAI);
284SPIRVAuxDataHandler::findOrEmitOpTypeFloat(
unsigned BitWidth,
287 if (
MI->getOpcode() == SPIRV::OpTypeFloat &&
288 MI->getOperand(1).getImm() ==
static_cast<int64_t
>(
BitWidth))
301 auto [It,
Inserted] = ConstantRegs.try_emplace(
C);
309 Bits = CI->getValue();
310 Opcode = SPIRV::OpConstantI;
311 TypeReg = findOrEmitOpTypeInt(
Bits.getBitWidth(), MAI);
314 Bits = CF->getValueAPF().bitcastToAPInt();
315 Opcode = SPIRV::OpConstantF;
316 TypeReg = findOrEmitOpTypeFloat(
Bits.getBitWidth(), MAI);
327 for (
unsigned I = 0;
I < NumWords; ++
I)
329 std::min(32u,
Bits.getBitWidth() -
I * 32),
I * 32)));
331 if (Opcode == SPIRV::OpConstantF &&
Bits.getBitWidth() == 16)
337MCRegister SPIRVAuxDataHandler::emitOpConstantUInt32(
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 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)
#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.
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.
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
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
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.
MCRegister getExtInstSetReg(unsigned SetNum)
DenseMap< unsigned, MCRegister > ExtInstSetMap
InstrList & getMSInstrs(unsigned MSType)
MCRegister getRegisterAlias(const MachineFunction *MF, Register Reg)
MCRegister getGlobalObjReg(const GlobalObject *GO)
MCRegister getNextIDRegister()
void addExtension(Extension::Extension ToAdd)