@@ -2970,12 +2970,65 @@ bool SPIRVToLLVM::foreachFuncCtlMask(SourceTy Source, FuncTy Func) {
29702970 return true ;
29712971}
29722972
2973+ void SPIRVToLLVM::transFunctionAttrs (SPIRVFunction *BF, Function *F) {
2974+ if (BF->hasDecorate (DecorationReferencedIndirectlyINTEL))
2975+ F->addFnAttr (" referenced-indirectly" );
2976+ if (isFuncNoUnwind ())
2977+ F->addFnAttr (Attribute::NoUnwind);
2978+ foreachFuncCtlMask (BF, [&](Attribute::AttrKind Attr) { F->addFnAttr (Attr); });
2979+
2980+ for (Function::arg_iterator I = F->arg_begin (), E = F->arg_end (); I != E;
2981+ ++I) {
2982+ auto *BA = BF->getArgument (I->getArgNo ());
2983+ mapValue (BA, &(*I));
2984+ setName (&(*I), BA);
2985+ AttributeMask IllegalAttrs = AttributeFuncs::typeIncompatible (I->getType ());
2986+ BA->foreachAttr ([&](SPIRVFuncParamAttrKind Kind) {
2987+ // Skip this function parameter attribute as it will translated among
2988+ // OpenCL metadata
2989+ if (Kind == FunctionParameterAttributeRuntimeAlignedINTEL)
2990+ return ;
2991+ Attribute::AttrKind LLVMKind = SPIRSPIRVFuncParamAttrMap::rmap (Kind);
2992+ if (IllegalAttrs.contains (LLVMKind))
2993+ return ;
2994+ Type *AttrTy = nullptr ;
2995+ switch (LLVMKind) {
2996+ case Attribute::AttrKind::ByVal:
2997+ case Attribute::AttrKind::StructRet:
2998+ AttrTy = transType (BA->getType ()->getPointerElementType ());
2999+ break ;
3000+ default :
3001+ break ; // do nothing
3002+ }
3003+ // Make sure to use a correct constructor for a typed/typeless attribute
3004+ auto A = AttrTy ? Attribute::get (*Context, LLVMKind, AttrTy)
3005+ : Attribute::get (*Context, LLVMKind);
3006+ I->addAttr (A);
3007+ });
3008+
3009+ AttrBuilder Builder (*Context);
3010+ SPIRVWord MaxOffset = 0 ;
3011+ if (BA->hasDecorate (DecorationMaxByteOffset, 0 , &MaxOffset))
3012+ Builder.addDereferenceableAttr (MaxOffset);
3013+ SPIRVWord AlignmentBytes = 0 ;
3014+ if (BA->hasDecorate (DecorationAlignment, 0 , &AlignmentBytes))
3015+ Builder.addAlignmentAttr (AlignmentBytes);
3016+ I->addAttrs (Builder);
3017+ }
3018+ BF->foreachReturnValueAttr ([&](SPIRVFuncParamAttrKind Kind) {
3019+ if (Kind == FunctionParameterAttributeNoWrite)
3020+ return ;
3021+ F->addRetAttr (SPIRSPIRVFuncParamAttrMap::rmap (Kind));
3022+ });
3023+ }
3024+
29733025Function *SPIRVToLLVM::transFunction (SPIRVFunction *BF) {
29743026 auto Loc = FuncMap.find (BF);
29753027 if (Loc != FuncMap.end ())
29763028 return Loc->second ;
29773029
29783030 auto IsKernel = isKernel (BF);
3031+
29793032 if (IsKernel) {
29803033 // search for a previous function with the same name
29813034 // upgrade it to a kernel and drop this if it's found
@@ -2988,6 +3041,7 @@ Function *SPIRVToLLVM::transFunction(SPIRVFunction *BF) {
29883041 F->setDSOLocal (false );
29893042 F = cast<Function>(mapValue (BF, F));
29903043 mapFunction (BF, F);
3044+ transFunctionAttrs (BF, F);
29913045 return F;
29923046 }
29933047 }
@@ -3036,49 +3090,7 @@ Function *SPIRVToLLVM::transFunction(SPIRVFunction *BF) {
30363090
30373091 F->setCallingConv (IsKernel ? CallingConv::SPIR_KERNEL
30383092 : CallingConv::SPIR_FUNC);
3039- if (BF->hasDecorate (DecorationReferencedIndirectlyINTEL))
3040- F->addFnAttr (" referenced-indirectly" );
3041- if (isFuncNoUnwind ())
3042- F->addFnAttr (Attribute::NoUnwind);
3043- foreachFuncCtlMask (BF, [&](Attribute::AttrKind Attr) { F->addFnAttr (Attr); });
3044-
3045- for (Function::arg_iterator I = F->arg_begin (), E = F->arg_end (); I != E;
3046- ++I) {
3047- auto BA = BF->getArgument (I->getArgNo ());
3048- mapValue (BA, &(*I));
3049- setName (&(*I), BA);
3050- BA->foreachAttr ([&](SPIRVFuncParamAttrKind Kind) {
3051- Attribute::AttrKind LLVMKind = SPIRSPIRVFuncParamAttrMap::rmap (Kind);
3052- Type *AttrTy = nullptr ;
3053- switch (LLVMKind) {
3054- case Attribute::AttrKind::ByVal:
3055- case Attribute::AttrKind::StructRet:
3056- AttrTy = transType (BA->getType ()->getPointerElementType ());
3057- break ;
3058- default :
3059- break ; // do nothing
3060- }
3061- // Make sure to use a correct constructor for a typed/typeless attribute
3062- auto A = AttrTy ? Attribute::get (*Context, LLVMKind, AttrTy)
3063- : Attribute::get (*Context, LLVMKind);
3064- I->addAttr (A);
3065- });
3066-
3067- AttrBuilder Builder (*Context);
3068- SPIRVWord MaxOffset = 0 ;
3069- if (BA->hasDecorate (DecorationMaxByteOffset, 0 , &MaxOffset))
3070- Builder.addDereferenceableAttr (MaxOffset);
3071- SPIRVWord AlignmentBytes = 0 ;
3072- if (BA->hasDecorate (DecorationAlignment, 0 , &AlignmentBytes))
3073- Builder.addAlignmentAttr (AlignmentBytes);
3074- I->addAttrs (Builder);
3075- }
3076- BF->foreachReturnValueAttr ([&](SPIRVFuncParamAttrKind Kind) {
3077- if (Kind == FunctionParameterAttributeNoWrite)
3078- return ;
3079- F->addRetAttr (SPIRSPIRVFuncParamAttrMap::rmap (Kind));
3080- });
3081-
3093+ transFunctionAttrs (BF, F);
30823094 // Creating all basic blocks before creating instructions.
30833095 for (size_t I = 0 , E = BF->getNumBasicBlock (); I != E; ++I) {
30843096 transValue (BF->getBasicBlock (I), F, nullptr );
0 commit comments