Skip to content

Commit e4ee512

Browse files
steffenlarsenvmaksimo
authored andcommitted
Implements spirv.Decorations and spirv.ParameterDecorations metadata translation (intel#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]> Original commit: KhronosGroup/SPIRV-LLVM-Translator@ccdbbdb
1 parent b3db4ce commit e4ee512

10 files changed

+425
-32
lines changed

llvm-spirv/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"

llvm-spirv/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) {
@@ -3553,13 +3553,83 @@ void SPIRVToLLVM::transGlobalAnnotations() {
35533553
}
35543554
}
35553555

3556+
static llvm::MDNode *
3557+
transDecorationsToMetadataList(llvm::LLVMContext *Context,
3558+
std::vector<SPIRVDecorate const *> Decorates) {
3559+
SmallVector<Metadata *, 4> MDs;
3560+
MDs.reserve(Decorates.size());
3561+
for (const auto *Deco : Decorates) {
3562+
std::vector<Metadata *> OPs;
3563+
auto *KindMD = ConstantAsMetadata::get(
3564+
ConstantInt::get(Type::getInt32Ty(*Context), Deco->getDecorateKind()));
3565+
OPs.push_back(KindMD);
3566+
switch (static_cast<size_t>(Deco->getDecorateKind())) {
3567+
case DecorationLinkageAttributes: {
3568+
const auto *const LinkAttrDeco =
3569+
static_cast<const SPIRVDecorateLinkageAttr *>(Deco);
3570+
auto *const LinkNameMD =
3571+
MDString::get(*Context, LinkAttrDeco->getLinkageName());
3572+
auto *const LinkTypeMD = ConstantAsMetadata::get(ConstantInt::get(
3573+
Type::getInt32Ty(*Context), LinkAttrDeco->getLinkageType()));
3574+
OPs.push_back(LinkNameMD);
3575+
OPs.push_back(LinkTypeMD);
3576+
break;
3577+
}
3578+
case DecorationMergeINTEL: {
3579+
const auto MergeAttrLits = Deco->getVecLiteral();
3580+
std::string FirstString = getString(MergeAttrLits);
3581+
std::string SecondString =
3582+
getString(MergeAttrLits.cbegin() + getVec(FirstString).size(),
3583+
MergeAttrLits.cend());
3584+
OPs.push_back(MDString::get(*Context, FirstString));
3585+
OPs.push_back(MDString::get(*Context, SecondString));
3586+
break;
3587+
}
3588+
case DecorationMemoryINTEL:
3589+
case DecorationUserSemantic: {
3590+
auto *const StrMD =
3591+
MDString::get(*Context, getString(Deco->getVecLiteral()));
3592+
OPs.push_back(StrMD);
3593+
break;
3594+
}
3595+
default: {
3596+
for (const SPIRVWord Lit : Deco->getVecLiteral()) {
3597+
auto *const LitMD = ConstantAsMetadata::get(
3598+
ConstantInt::get(Type::getInt32Ty(*Context), Lit));
3599+
OPs.push_back(LitMD);
3600+
}
3601+
break;
3602+
}
3603+
}
3604+
MDs.push_back(MDNode::get(*Context, OPs));
3605+
}
3606+
return MDNode::get(*Context, MDs);
3607+
}
3608+
3609+
void SPIRVToLLVM::transVarDecorationsToMetadata(SPIRVValue *BV, Value *V) {
3610+
if (!BV->isVariable())
3611+
return;
3612+
3613+
if (auto *GV = dyn_cast<GlobalVariable>(V)) {
3614+
std::vector<SPIRVDecorate const *> Decorates = BV->getDecorations();
3615+
if (!Decorates.empty()) {
3616+
MDNode *MDList = transDecorationsToMetadataList(Context, Decorates);
3617+
GV->setMetadata(SPIRV_MD_DECORATIONS, MDList);
3618+
}
3619+
}
3620+
}
3621+
35563622
bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) {
35573623
if (!transAlign(BV, V))
35583624
return false;
35593625

35603626
transIntelFPGADecorations(BV, V);
35613627
transMemAliasingINTELDecorations(BV, V);
35623628

3629+
// Decoration metadata is only enabled in SPIR-V friendly mode
3630+
if (BM->getDesiredBIsRepresentation() == BIsRepresentation::SPIRVFriendlyIR)
3631+
transVarDecorationsToMetadata(BV, V);
3632+
35633633
DbgTran->transDbgInfo(BV, V);
35643634
return true;
35653635
}
@@ -3691,6 +3761,23 @@ static bool transKernelArgTypeMedataFromString(LLVMContext *Ctx,
36913761
return true;
36923762
}
36933763

3764+
void SPIRVToLLVM::transFunctionDecorationsToMetadata(SPIRVFunction *BF,
3765+
Function *F) {
3766+
size_t TotalParameterDecorations = 0;
3767+
BF->foreachArgument([&](SPIRVFunctionParameter *Arg) {
3768+
TotalParameterDecorations += Arg->getNumDecorations();
3769+
});
3770+
if (TotalParameterDecorations == 0)
3771+
return;
3772+
3773+
// Generate metadata for spirv.ParameterDecorations
3774+
addKernelArgumentMetadata(Context, SPIRV_MD_PARAMETER_DECORATIONS, BF, F,
3775+
[=](SPIRVFunctionParameter *Arg) {
3776+
return transDecorationsToMetadataList(
3777+
Context, Arg->getDecorations());
3778+
});
3779+
}
3780+
36943781
bool SPIRVToLLVM::transMetadata() {
36953782
SmallVector<Function *, 2> CtorKernels;
36963783
for (unsigned I = 0, E = BM->getNumFunctions(); I != E; ++I) {
@@ -3702,6 +3789,10 @@ bool SPIRVToLLVM::transMetadata() {
37023789
transVectorComputeMetadata(BF);
37033790
transFPGAFunctionMetadata(BF, F);
37043791

3792+
// Decoration metadata is only enabled in SPIR-V friendly mode
3793+
if (BM->getDesiredBIsRepresentation() == BIsRepresentation::SPIRVFriendlyIR)
3794+
transFunctionDecorationsToMetadata(BF, F);
3795+
37053796
if (BF->hasDecorate(internal::DecorationCallableFunctionINTEL))
37063797
F->addFnAttr(kVCMetadata::VCCallable);
37073798
if (isKernel(BF) &&
@@ -3806,7 +3897,7 @@ bool SPIRVToLLVM::transOCLMetadata(SPIRVFunction *BF) {
38063897
return true;
38073898

38083899
// Generate metadata for kernel_arg_addr_space
3809-
addOCLKernelArgumentMetadata(
3900+
addKernelArgumentMetadata(
38103901
Context, SPIR_MD_KERNEL_ARG_ADDR_SPACE, BF, F,
38113902
[=](SPIRVFunctionParameter *Arg) {
38123903
SPIRVType *ArgTy = Arg->getType();
@@ -3819,31 +3910,31 @@ bool SPIRVToLLVM::transOCLMetadata(SPIRVFunction *BF) {
38193910
ConstantInt::get(Type::getInt32Ty(*Context), AS));
38203911
});
38213912
// Generate metadata for kernel_arg_access_qual
3822-
addOCLKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_ACCESS_QUAL, BF, F,
3823-
[=](SPIRVFunctionParameter *Arg) {
3824-
std::string Qual;
3825-
auto T = Arg->getType();
3826-
if (T->isTypeOCLImage()) {
3827-
auto ST = static_cast<SPIRVTypeImage *>(T);
3828-
Qual = transOCLImageTypeAccessQualifier(ST);
3829-
} else if (T->isTypePipe()) {
3830-
auto PT = static_cast<SPIRVTypePipe *>(T);
3831-
Qual = transOCLPipeTypeAccessQualifier(PT);
3832-
} else
3833-
Qual = "none";
3834-
return MDString::get(*Context, Qual);
3835-
});
3913+
addKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_ACCESS_QUAL, BF, F,
3914+
[=](SPIRVFunctionParameter *Arg) {
3915+
std::string Qual;
3916+
auto *T = Arg->getType();
3917+
if (T->isTypeOCLImage()) {
3918+
auto *ST = static_cast<SPIRVTypeImage *>(T);
3919+
Qual = transOCLImageTypeAccessQualifier(ST);
3920+
} else if (T->isTypePipe()) {
3921+
auto *PT = static_cast<SPIRVTypePipe *>(T);
3922+
Qual = transOCLPipeTypeAccessQualifier(PT);
3923+
} else
3924+
Qual = "none";
3925+
return MDString::get(*Context, Qual);
3926+
});
38363927
// Generate metadata for kernel_arg_type
38373928
if (!transKernelArgTypeMedataFromString(Context, BM, F,
38383929
SPIR_MD_KERNEL_ARG_TYPE))
3839-
addOCLKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_TYPE, BF, F,
3840-
[=](SPIRVFunctionParameter *Arg) {
3841-
return transOCLKernelArgTypeName(Arg);
3842-
});
3930+
addKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_TYPE, BF, F,
3931+
[=](SPIRVFunctionParameter *Arg) {
3932+
return transOCLKernelArgTypeName(Arg);
3933+
});
38433934
// Generate metadata for kernel_arg_type_qual
38443935
if (!transKernelArgTypeMedataFromString(Context, BM, F,
38453936
SPIR_MD_KERNEL_ARG_TYPE_QUAL))
3846-
addOCLKernelArgumentMetadata(
3937+
addKernelArgumentMetadata(
38473938
Context, SPIR_MD_KERNEL_ARG_TYPE_QUAL, BF, F,
38483939
[=](SPIRVFunctionParameter *Arg) {
38493940
std::string Qual;
@@ -3861,17 +3952,16 @@ bool SPIRVToLLVM::transOCLMetadata(SPIRVFunction *BF) {
38613952
return MDString::get(*Context, Qual);
38623953
});
38633954
// Generate metadata for kernel_arg_base_type
3864-
addOCLKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_BASE_TYPE, BF, F,
3865-
[=](SPIRVFunctionParameter *Arg) {
3866-
return transOCLKernelArgTypeName(Arg);
3867-
});
3955+
addKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_BASE_TYPE, BF, F,
3956+
[=](SPIRVFunctionParameter *Arg) {
3957+
return transOCLKernelArgTypeName(Arg);
3958+
});
38683959
// Generate metadata for kernel_arg_name
38693960
if (BM->isGenArgNameMDEnabled()) {
3870-
addOCLKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_NAME, BF, F,
3871-
[=](SPIRVFunctionParameter *Arg) {
3872-
return MDString::get(*Context,
3873-
Arg->getName());
3874-
});
3961+
addKernelArgumentMetadata(Context, SPIR_MD_KERNEL_ARG_NAME, BF, F,
3962+
[=](SPIRVFunctionParameter *Arg) {
3963+
return MDString::get(*Context, Arg->getName());
3964+
});
38753965
}
38763966
// Generate metadata for kernel_arg_buffer_location
38773967
addBufferLocationMetadata(Context, BF, F, [=](SPIRVFunctionParameter *Arg) {

llvm-spirv/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

llvm-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)