31 AvailableExternally = 0,
34constexpr unsigned NonSemanticAuxDataSet =
35 static_cast<unsigned>(SPIRV::InstructionSet::NonSemantic_AuxData);
39 return F->getAttributes().getFnAttrs();
54 return !F.isDeclaration() &&
55 (F.getAttributes().hasFnAttrs() || F.hasMetadata());
61 SPIRV::Extension::SPV_KHR_relaxed_extended_instruction);
68 LinkagePreservedGOs.push_back(&GO);
77 if (!ST.canUseExtension(SPIRV::Extension::SPV_KHR_non_semantic_info))
79 "SPV_KHR_non_semantic_info extension to be enabled.");
88 if (ST.canUseExtension(
89 SPIRV::Extension::SPV_KHR_relaxed_extended_instruction))
91 SPIRV::Extension::SPV_KHR_relaxed_extended_instruction);
97SPIRVAuxDataHandler::getOrEmitString(
StringRef S,
99 auto [It, Inserted] = StringRegs.try_emplace(S);
112void SPIRVAuxDataHandler::collectAttributesFor(
const GlobalObject *GO,
117 if (
A.isStringAttribute() &&
123 if (
A.isStringAttribute()) {
124 Rec.Operands.push_back({getOrEmitString(
A.getKindAsString(), MAI)});
125 StringRef Val =
A.getValueAsString();
127 Rec.Operands.push_back({getOrEmitString(Val, MAI)});
129 Rec.Operands.push_back(
130 {getOrEmitString(StringPool.save(
A.getAsString()), MAI)});
132 PendingRecords.push_back(std::move(Rec));
136void SPIRVAuxDataHandler::collectMetadataFor(
const GlobalObject *GO,
148 auto CollectOperands =
149 [&](MDNode *MD) -> std::optional<SmallVector<Operand, 4>> {
150 SmallVector<Operand, 4>
Out;
151 for (
const MDOperand &MdOp : MD->operands()) {
154 Out.push_back({getOrEmitString(MDStr->getString(), MAI)});
159 Out.push_back({MCRegister(),
C});
166 for (
const auto &MD : AllMD) {
167 if (MD.first == LLVMContext::MD_dbg)
169 StringRef MDName = MDNames[MD.first];
170 if (MDName ==
"spirv.Decorations" || MDName ==
"spirv.ParameterDecorations")
172 auto Operands = CollectOperands(MD.second);
178 Rec.Operands.push_back({getOrEmitString(MDName, MAI)});
180 PendingRecords.push_back(std::move(Rec));
188 constexpr unsigned AllMDKindsSeen =
189 (1u << (
static_cast<unsigned>(
193 unsigned SeenMask = 0;
195 unsigned Bit = 1u <<
static_cast<unsigned>(Rec.Kind);
200 if (SeenMask == AllMDKindsSeen)
204 Mod.getContext().getMDKindNames(MDNames);
209 collectAttributesFor(&GO, MAI);
210 collectMetadataFor(&GO, MDNames, MAI);
219 MCRegister VoidTypeReg = findOrEmitOpTypeVoid(MAI);
221 for (
const ExtInstRecord &Rec : PendingRecords) {
227 for (
const Operand &
Op : Rec.Operands)
228 Operands.push_back(
Op.Const ? emitConstant(
Op.Const, MAI) :
Op.Reg);
229 emitAuxDataExtInst(Rec.Opcode, VoidTypeReg, ExtSetReg,
Operands, MAI,
242 {TargetReg, MDNameReg}, MAI,
true);
245 if (LinkagePreservedGOs.empty())
248 MCRegister UInt32TypeReg = findOrEmitOpTypeUInt32(MAI);
259 emitOpConstantUInt32(AvailableExternally, UInt32TypeReg, MAI);
261 {TargetReg, AEConstReg}, MAI,
266void SPIRVAuxDataHandler::emitAuxDataExtInst(
AuxDataOpcode Opcode,
271 bool UseForwardRefs) {
273 Inst.
setOpcode(UseForwardRefs ? SPIRV::OpExtInstWithForwardRefsKHR
284void SPIRVAuxDataHandler::emitMCInst(
MCInst &Inst) {
291 if (
MI->getOpcode() == SPIRV::OpTypeVoid)
302SPIRVAuxDataHandler::findOrEmitOpTypeInt(
unsigned BitWidth,
306 constexpr int64_t UnsignedSignedness = 0;
308 if (
MI->getOpcode() == SPIRV::OpTypeInt &&
309 MI->getOperand(1).getImm() ==
static_cast<int64_t
>(
BitWidth) &&
310 MI->getOperand(2).getImm() == UnsignedSignedness)
324 return findOrEmitOpTypeInt(32, MAI);
328SPIRVAuxDataHandler::findOrEmitOpTypeFloat(
unsigned BitWidth,
331 if (
MI->getOpcode() == SPIRV::OpTypeFloat &&
332 MI->getOperand(1).getImm() ==
static_cast<int64_t
>(
BitWidth))
345 auto [It,
Inserted] = ConstantRegs.try_emplace(
C);
353 Bits = CI->getValue();
354 Opcode = SPIRV::OpConstantI;
355 TypeReg = findOrEmitOpTypeInt(
Bits.getBitWidth(), MAI);
358 Bits = CF->getValueAPF().bitcastToAPInt();
359 Opcode = SPIRV::OpConstantF;
360 TypeReg = findOrEmitOpTypeFloat(
Bits.getBitWidth(), MAI);
371 for (
unsigned I = 0;
I < NumWords; ++
I)
373 std::min(32u,
Bits.getBitWidth() -
I * 32),
I * 32)));
375 if (Opcode == SPIRV::OpConstantF &&
Bits.getBitWidth() == 16)
381MCRegister 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 bool canUseForwardRefs(const SPIRV::ModuleAnalysisInfo &MAI)
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.
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.
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.
bool spirvPreserveAuxData(const SPIRVOptions &CLOpts, const Triple &TT)
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