@@ -2527,17 +2527,61 @@ static RValue EmitHipStdParUnsupportedBuiltin(CodeGenFunction *CGF,
25272527 return RValue::get (CGF->Builder .CreateCall (UBF, Args));
25282528}
25292529
2530- static const SYCLKernelInfo *GetSYCLKernelInfo (ASTContext &Ctx,
2531- const CallExpr *E) {
2532- // Argument to the builtin is a type trait which is used to retrieve the
2533- // kernel name type.
2534- // FIXME: Improve the comment.
2530+ static const CanQualType GetKernelNameType (ASTContext &Ctx, const CallExpr *E) {
2531+ // The first argument to the builtin is an object that designates
2532+ // the SYCL kernel. The argument is evaluated and its value is
2533+ // discarded; the SYCL kernel is identified based on the argument
2534+ // type. The argument type is required to be a class or structure
2535+ // with a member typedef or type alias named 'type'. The target
2536+ // type of the 'type' member is the SYCL kernel name type.
25352537 RecordDecl *RD = E->getArg (0 )->getType ()->castAs <RecordType>()->getDecl ();
25362538 IdentifierTable &IdentTable = Ctx.Idents ;
25372539 auto Name = DeclarationName (&(IdentTable.get (" type" )));
25382540 NamedDecl *ND = (RD->lookup (Name)).front ();
25392541 TypedefNameDecl *TD = cast<TypedefNameDecl>(ND);
2540- CanQualType KernelNameType = Ctx.getCanonicalType (TD->getUnderlyingType ());
2542+ return Ctx.getCanonicalType (TD->getUnderlyingType ());
2543+ }
2544+
2545+ static llvm::GlobalVariable *
2546+ EmitKernelNameGlobal (CodeGenModule &CGM, ASTContext &Ctx, const CallExpr *E) {
2547+ CanQualType KernelNameType = GetKernelNameType (Ctx, E);
2548+
2549+ // SmallString<256> KernelNameSymbol;
2550+ // llvm::raw_svector_ostream Out(KernelNameSymbol);
2551+ // The mangling used for the name of the global variable storing the offload
2552+ // kernel name is identical to the mangling of the offload kernel name.
2553+ // CGM.getCXXABI().getMangleContext().mangleSYCLKernelCallerName(KernelNameType,
2554+ // Out);
2555+ //
2556+
2557+ auto DeviceDiscriminatorOverrider =
2558+ [](ASTContext &Ctx, const NamedDecl *ND) -> UnsignedOrNone {
2559+ if (const auto *RD = dyn_cast<CXXRecordDecl>(ND))
2560+ if (RD->isLambda ())
2561+ return RD->getDeviceLambdaManglingNumber ();
2562+ return std::nullopt ;
2563+ };
2564+ std::unique_ptr<MangleContext> MC{ItaniumMangleContext::create (
2565+ Ctx, Ctx.getDiagnostics (), DeviceDiscriminatorOverrider)};
2566+
2567+ SmallString<256 > KernelNameSymbol;
2568+ llvm::raw_svector_ostream Out (KernelNameSymbol);
2569+ // llvm::raw_string_ostream Out(KernelNameSymbol);
2570+ MC->mangleCanonicalTypeName (KernelNameType, Out);
2571+
2572+ llvm::GlobalVariable *GV = new llvm::GlobalVariable (
2573+ CGM.getModule (), CGM.GlobalsInt8PtrTy ,
2574+ /* isConstant=*/ true , llvm::GlobalValue::ExternalLinkage, nullptr ,
2575+ KernelNameSymbol);
2576+
2577+ CGM.AddSYCLKernelNameSymbol (KernelNameType, GV);
2578+
2579+ return GV;
2580+ }
2581+
2582+ static const SYCLKernelInfo *GetSYCLKernelInfo (ASTContext &Ctx,
2583+ const CallExpr *E) {
2584+ CanQualType KernelNameType = GetKernelNameType (Ctx, E);
25412585
25422586 // Retrieve KernelInfo using the kernel name.
25432587 return Ctx.findSYCLKernelInfo (KernelNameType);
@@ -6237,21 +6281,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
62376281 return RValue::get (Str.getPointer ());
62386282 }
62396283 case Builtin::BI__builtin_sycl_kernel_name: {
6240- ASTContext &Ctx = getContext ();
6241- // Argument to the builtin is a kernel_id_t type trait which is used
6242- // to retrieve the kernel name type.
6243- RecordDecl *RD = E->getArg (0 )->getType ()->castAs <RecordType>()->getDecl ();
6244- IdentifierTable &IdentTable = Ctx.Idents ;
6245- auto Name = DeclarationName (&(IdentTable.get (" type" )));
6246- NamedDecl *ND = (RD->lookup (Name)).front ();
6247- TypeAliasDecl *TD = cast<TypeAliasDecl>(ND);
6248- QualType KernelNameType = TD->getUnderlyingType ().getCanonicalType ();
6249-
6250- // Retrieve the mangled name corresponding to kernel name type.
6251- const SYCLKernelInfo *KernelInfo = Ctx.findSYCLKernelInfo (KernelNameType);
6252- assert (KernelInfo && " Type does not correspond to a SYCL kernel name." );
6253-
6254- // Emit the mangled name.
6284+ // Retrieve the kernel info corresponding to kernel name type.
6285+ const SYCLKernelInfo *KernelInfo = GetSYCLKernelInfo (getContext (), E);
6286+
6287+ // This indicates that the builtin was called before the kernel was
6288+ // invoked. In this case, a global variable is declared, and returned
6289+ // as the result of the call to the builtin. This global variable is
6290+ // later initialized to hold the name of the offload kernel when kernel
6291+ // invocation is processed.
6292+ if (!KernelInfo)
6293+ return RValue::get (EmitKernelNameGlobal (CGM, getContext (), E));
6294+
6295+ // Emit the mangled name from KernelInfo if available.
62556296 auto Str = CGM.GetAddrOfConstantCString (KernelInfo->GetKernelName (), " " );
62566297 return RValue::get (Str.getPointer ());
62576298 }
0 commit comments