@@ -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+
35733639bool 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+
37113798bool 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) {
0 commit comments