Skip to content

Commit ccdbbdb

Browse files
Implements spirv.Decorations and spirv.ParameterDecorations metadata translation (#1346)
This patch adds translation to and from `spirv.Decorations` and `spirv.ParameterDecorations` metadata. These metadata nodes represent global variable and function parameter decorations respectively, allowing explicit decoration in LLVM IR. Signed-off-by: Steffen Larsen <[email protected]>
1 parent d3884d8 commit ccdbbdb

10 files changed

+425
-32
lines changed

lib/SPIRV/SPIRVInternal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ typedef SPIRVMap<spv::Scope, std::string> SPIRVMatrixScopeMap;
289289
#define SPIR_MD_KERNEL_ARG_TYPE_QUAL "kernel_arg_type_qual"
290290
#define SPIR_MD_KERNEL_ARG_NAME "kernel_arg_name"
291291

292+
#define SPIRV_MD_PARAMETER_DECORATIONS "spirv.ParameterDecorations"
293+
#define SPIRV_MD_DECORATIONS "spirv.Decorations"
294+
292295
#define OCL_TYPE_NAME_SAMPLER_T "sampler_t"
293296
#define SPIR_TYPE_NAME_EVENT_T "opencl.event_t"
294297
#define SPIR_TYPE_NAME_CLK_EVENT_T "opencl.clk_event_t"

lib/SPIRV/SPIRVReader.cpp

Lines changed: 120 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ static void addNamedMetadataStringSet(LLVMContext *Context, Module *M,
160160
NamedMD->addOperand(MDNode::get(*Context, ValueVec));
161161
}
162162

163-
static void addOCLKernelArgumentMetadata(
163+
static void addKernelArgumentMetadata(
164164
LLVMContext *Context, const std::string &MDName, SPIRVFunction *BF,
165165
llvm::Function *Fn,
166166
std::function<Metadata *(SPIRVFunctionParameter *)> ForeachFnArg) {
@@ -3570,13 +3570,83 @@ void SPIRVToLLVM::transGlobalAnnotations() {
35703570
}
35713571
}
35723572

3573+
static llvm::MDNode *
3574+
transDecorationsToMetadataList(llvm::LLVMContext *Context,
3575+
std::vector<SPIRVDecorate const *> Decorates) {
3576+
SmallVector<Metadata *, 4> MDs;
3577+
MDs.reserve(Decorates.size());
3578+
for (const auto *Deco : Decorates) {
3579+
std::vector<Metadata *> OPs;
3580+
auto *KindMD = ConstantAsMetadata::get(
3581+
ConstantInt::get(Type::getInt32Ty(*Context), Deco->getDecorateKind()));
3582+
OPs.push_back(KindMD);
3583+
switch (static_cast<size_t>(Deco->getDecorateKind())) {
3584+
case DecorationLinkageAttributes: {
3585+
const auto *const LinkAttrDeco =
3586+
static_cast<const SPIRVDecorateLinkageAttr *>(Deco);
3587+
auto *const LinkNameMD =
3588+
MDString::get(*Context, LinkAttrDeco->getLinkageName());
3589+
auto *const LinkTypeMD = ConstantAsMetadata::get(ConstantInt::get(
3590+
Type::getInt32Ty(*Context), LinkAttrDeco->getLinkageType()));
3591+
OPs.push_back(LinkNameMD);
3592+
OPs.push_back(LinkTypeMD);
3593+
break;
3594+
}
3595+
case DecorationMergeINTEL: {
3596+
const auto MergeAttrLits = Deco->getVecLiteral();
3597+
std::string FirstString = getString(MergeAttrLits);
3598+
std::string SecondString =
3599+
getString(MergeAttrLits.cbegin() + getVec(FirstString).size(),
3600+
MergeAttrLits.cend());
3601+
OPs.push_back(MDString::get(*Context, FirstString));
3602+
OPs.push_back(MDString::get(*Context, SecondString));
3603+
break;
3604+
}
3605+
case DecorationMemoryINTEL:
3606+
case DecorationUserSemantic: {
3607+
auto *const StrMD =
3608+
MDString::get(*Context, getString(Deco->getVecLiteral()));
3609+
OPs.push_back(StrMD);
3610+
break;
3611+
}
3612+
default: {
3613+
for (const SPIRVWord Lit : Deco->getVecLiteral()) {
3614+
auto *const LitMD = ConstantAsMetadata::get(
3615+
ConstantInt::get(Type::getInt32Ty(*Context), Lit));
3616+
OPs.push_back(LitMD);
3617+
}
3618+
break;
3619+
}
3620+
}
3621+
MDs.push_back(MDNode::get(*Context, OPs));
3622+
}
3623+
return MDNode::get(*Context, MDs);
3624+
}
3625+
3626+
void SPIRVToLLVM::transVarDecorationsToMetadata(SPIRVValue *BV, Value *V) {
3627+
if (!BV->isVariable())
3628+
return;
3629+
3630+
if (auto *GV = dyn_cast<GlobalVariable>(V)) {
3631+
std::vector<SPIRVDecorate const *> Decorates = BV->getDecorations();
3632+
if (!Decorates.empty()) {
3633+
MDNode *MDList = transDecorationsToMetadataList(Context, Decorates);
3634+
GV->setMetadata(SPIRV_MD_DECORATIONS, MDList);
3635+
}
3636+
}
3637+
}
3638+
35733639
bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) {
35743640
if (!transAlign(BV, V))
35753641
return false;
35763642

35773643
transIntelFPGADecorations(BV, V);
35783644
transMemAliasingINTELDecorations(BV, V);
35793645

3646+
// Decoration metadata is only enabled in SPIR-V friendly mode
3647+
if (BM->getDesiredBIsRepresentation() == BIsRepresentation::SPIRVFriendlyIR)
3648+
transVarDecorationsToMetadata(BV, V);
3649+
35803650
DbgTran->transDbgInfo(BV, V);
35813651
return true;
35823652
}
@@ -3708,6 +3778,23 @@ static bool transKernelArgTypeMedataFromString(LLVMContext *Ctx,
37083778
return true;
37093779
}
37103780

3781+
void SPIRVToLLVM::transFunctionDecorationsToMetadata(SPIRVFunction *BF,
3782+
Function *F) {
3783+
size_t TotalParameterDecorations = 0;
3784+
BF->foreachArgument([&](SPIRVFunctionParameter *Arg) {
3785+
TotalParameterDecorations += Arg->getNumDecorations();
3786+
});
3787+
if (TotalParameterDecorations == 0)
3788+
return;
3789+
3790+
// Generate metadata for spirv.ParameterDecorations
3791+
addKernelArgumentMetadata(Context, SPIRV_MD_PARAMETER_DECORATIONS, BF, F,
3792+
[=](SPIRVFunctionParameter *Arg) {
3793+
return transDecorationsToMetadataList(
3794+
Context, Arg->getDecorations());
3795+
});
3796+
}
3797+
37113798
bool SPIRVToLLVM::transMetadata() {
37123799
SmallVector<Function *, 2> CtorKernels;
37133800
for (unsigned I = 0, E = BM->getNumFunctions(); I != E; ++I) {
@@ -3719,6 +3806,10 @@ bool SPIRVToLLVM::transMetadata() {
37193806
transVectorComputeMetadata(BF);
37203807
transFPGAFunctionMetadata(BF, F);
37213808

3809+
// Decoration metadata is only enabled in SPIR-V friendly mode
3810+
if (BM->getDesiredBIsRepresentation() == BIsRepresentation::SPIRVFriendlyIR)
3811+
transFunctionDecorationsToMetadata(BF, F);
3812+
37223813
if (BF->hasDecorate(internal::DecorationCallableFunctionINTEL))
37233814
F->addFnAttr(kVCMetadata::VCCallable);
37243815
if (isKernel(BF) &&
@@ -3823,7 +3914,7 @@ bool SPIRVToLLVM::transOCLMetadata(SPIRVFunction *BF) {
38233914
return true;
38243915

38253916
// Generate metadata for kernel_arg_addr_space
3826-
addOCLKernelArgumentMetadata(
3917+
addKernelArgumentMetadata(
38273918
Context, SPIR_MD_KERNEL_ARG_ADDR_SPACE, BF, F,
38283919
[=](SPIRVFunctionParameter *Arg) {
38293920
SPIRVType *ArgTy = Arg->getType();
@@ -3836,31 +3927,31 @@ bool SPIRVToLLVM::transOCLMetadata(SPIRVFunction *BF) {
38363927
ConstantInt::get(Type::getInt32Ty(*Context), AS));
38373928
});
38383929
// Generate metadata for kernel_arg_access_qual
3839-
addOCLKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_ACCESS_QUAL, BF, F,
3840-
[=](SPIRVFunctionParameter *Arg) {
3841-
std::string Qual;
3842-
auto T = Arg->getType();
3843-
if (T->isTypeOCLImage()) {
3844-
auto ST = static_cast<SPIRVTypeImage *>(T);
3845-
Qual = transOCLImageTypeAccessQualifier(ST);
3846-
} else if (T->isTypePipe()) {
3847-
auto PT = static_cast<SPIRVTypePipe *>(T);
3848-
Qual = transOCLPipeTypeAccessQualifier(PT);
3849-
} else
3850-
Qual = "none";
3851-
return MDString::get(*Context, Qual);
3852-
});
3930+
addKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_ACCESS_QUAL, BF, F,
3931+
[=](SPIRVFunctionParameter *Arg) {
3932+
std::string Qual;
3933+
auto *T = Arg->getType();
3934+
if (T->isTypeOCLImage()) {
3935+
auto *ST = static_cast<SPIRVTypeImage *>(T);
3936+
Qual = transOCLImageTypeAccessQualifier(ST);
3937+
} else if (T->isTypePipe()) {
3938+
auto *PT = static_cast<SPIRVTypePipe *>(T);
3939+
Qual = transOCLPipeTypeAccessQualifier(PT);
3940+
} else
3941+
Qual = "none";
3942+
return MDString::get(*Context, Qual);
3943+
});
38533944
// Generate metadata for kernel_arg_type
38543945
if (!transKernelArgTypeMedataFromString(Context, BM, F,
38553946
SPIR_MD_KERNEL_ARG_TYPE))
3856-
addOCLKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_TYPE, BF, F,
3857-
[=](SPIRVFunctionParameter *Arg) {
3858-
return transOCLKernelArgTypeName(Arg);
3859-
});
3947+
addKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_TYPE, BF, F,
3948+
[=](SPIRVFunctionParameter *Arg) {
3949+
return transOCLKernelArgTypeName(Arg);
3950+
});
38603951
// Generate metadata for kernel_arg_type_qual
38613952
if (!transKernelArgTypeMedataFromString(Context, BM, F,
38623953
SPIR_MD_KERNEL_ARG_TYPE_QUAL))
3863-
addOCLKernelArgumentMetadata(
3954+
addKernelArgumentMetadata(
38643955
Context, SPIR_MD_KERNEL_ARG_TYPE_QUAL, BF, F,
38653956
[=](SPIRVFunctionParameter *Arg) {
38663957
std::string Qual;
@@ -3878,17 +3969,16 @@ bool SPIRVToLLVM::transOCLMetadata(SPIRVFunction *BF) {
38783969
return MDString::get(*Context, Qual);
38793970
});
38803971
// Generate metadata for kernel_arg_base_type
3881-
addOCLKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_BASE_TYPE, BF, F,
3882-
[=](SPIRVFunctionParameter *Arg) {
3883-
return transOCLKernelArgTypeName(Arg);
3884-
});
3972+
addKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_BASE_TYPE, BF, F,
3973+
[=](SPIRVFunctionParameter *Arg) {
3974+
return transOCLKernelArgTypeName(Arg);
3975+
});
38853976
// Generate metadata for kernel_arg_name
38863977
if (BM->isGenArgNameMDEnabled()) {
3887-
addOCLKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_NAME, BF, F,
3888-
[=](SPIRVFunctionParameter *Arg) {
3889-
return MDString::get(*Context,
3890-
Arg->getName());
3891-
});
3978+
addKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_NAME, BF, F,
3979+
[=](SPIRVFunctionParameter *Arg) {
3980+
return MDString::get(*Context, Arg->getName());
3981+
});
38923982
}
38933983
// Generate metadata for kernel_arg_buffer_location
38943984
addBufferLocationMetadata(Context, BF, F, [=](SPIRVFunctionParameter *Arg) {

lib/SPIRV/SPIRVReader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ class SPIRVToLLVM {
241241
SmallVectorImpl<Function *> &Funcs);
242242
void transIntelFPGADecorations(SPIRVValue *BV, Value *V);
243243
void transMemAliasingINTELDecorations(SPIRVValue *BV, Value *V);
244+
void transVarDecorationsToMetadata(SPIRVValue *BV, Value *V);
245+
void transFunctionDecorationsToMetadata(SPIRVFunction *BF, Function *F);
244246
}; // class SPIRVToLLVM
245247

246248
} // namespace SPIRV

lib/SPIRV/SPIRVToLLVMDbgTran.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ DINode *SPIRVToLLVMDbgTran::transFunction(const SPIRVExtInst *DebugInst) {
548548
SPIRVFunction *BF = static_cast<SPIRVFunction *>(E);
549549
llvm::Function *F = SPIRVReader->transFunction(BF);
550550
assert(F && "Translation of function failed!");
551-
if (!F->hasMetadata())
551+
if (!F->hasMetadata("dbg"))
552552
F->setMetadata("dbg", DIS);
553553
}
554554
return DIS;
@@ -657,7 +657,7 @@ MDNode *SPIRVToLLVMDbgTran::transGlobalVariable(const SPIRVExtInst *DebugInst) {
657657
SPIRVValue *V = BM->get<SPIRVValue>(Ops[VariableIdx]);
658658
Value *Var = SPIRVReader->transValue(V, nullptr, nullptr);
659659
llvm::GlobalVariable *GV = dyn_cast_or_null<llvm::GlobalVariable>(Var);
660-
if (GV && !GV->hasMetadata())
660+
if (GV && !GV->hasMetadata("dbg"))
661661
GV->addMetadata("dbg", *VarDecl);
662662
}
663663
return VarDecl;

0 commit comments

Comments
 (0)