================
@@ -33,3 +40,102 @@ CIRGenFunction::emitSYCLKernelCallStmt(const 
SYCLKernelCallStmt &s) {
   // of the original function body.
   return emitStmt(s.getKernelLaunchStmt(), /*useCurrentScope=*/true);
 }
+
+// Emit the body of a SYCL kernel caller offload entry point. Mirrors the tail
+// of generateCode, but is driven by an OutlinedFunctionDecl and an explicit
+// argument list rather than a FunctionDecl.
+void CIRGenFunction::emitSYCLKernelCaller(
+    const OutlinedFunctionDecl *outlinedFnDecl, cir::FuncOp funcOp,
+    cir::FuncType funcType, FunctionArgList &args) {
+  const Stmt *body = outlinedFnDecl->getBody();
+  SourceLocation loc = outlinedFnDecl->getLocation();
+  SourceRange bodyRange = body->getSourceRange();
+
+  // Synthesized entry point: no FunctionDecl, emitted with an empty 
GlobalDecl.
+  curGD = GlobalDecl();
+
+  SourceLocRAIIObject fnLoc{*this, loc.isValid() ? getLoc(loc)
+                                                 : builder.getUnknownLoc()};
+
+  mlir::Location fusedLoc = getLoc(bodyRange);
+  mlir::Block *entryBB = funcOp.addEntryBlock();
+
+  SymTableScopeTy varScope(symbolTable);
+  {
+    LexicalScope lexScope(*this, fusedLoc, entryBB);
+    startFunction(GlobalDecl(), getContext().VoidTy, funcOp, funcType, args,
+                  loc, bodyRange.getBegin());
+    if (mlir::failed(emitFunctionBody(body)))
+      return;
+    if (mlir::failed(funcOp.verifyBody()))
+      return;
+    finishFunction(body->getEndLoc());
+  }
+
+  eraseEmptyAndUnusedBlocks(funcOp);
+}
+
+void CIRGenModule::emitSYCLKernelCaller(const FunctionDecl *kernelEntryPointFn,
+                                        ASTContext &ctx) {
+  assert(ctx.getLangOpts().SYCLIsDevice &&
+         "SYCL kernel caller offload entry point functions can only be emitted"
+         " during device compilation");
+
+  const auto *kernelEntryPointAttr =
+      kernelEntryPointFn->getAttr<SYCLKernelEntryPointAttr>();
+  assert(kernelEntryPointAttr && "Missing sycl_kernel_entry_point attribute");
+  assert(!kernelEntryPointAttr->isInvalidAttr() &&
+         "sycl_kernel_entry_point attribute is invalid");
+
+  // Find the SYCLKernelCallStmt.
+  SYCLKernelCallStmt *kernelCallStmt =
+      cast<SYCLKernelCallStmt>(kernelEntryPointFn->getBody());
+
+  // Retrieve the SYCL kernel caller parameters from the OutlinedFunctionDecl.
+  FunctionArgList args;
+  const OutlinedFunctionDecl *outlinedFnDecl =
+      kernelCallStmt->getOutlinedFunctionDecl();
+  args.append(outlinedFnDecl->param_begin(), outlinedFnDecl->param_end());
+
+  // Compute the function info and CIR function type.
+  const CIRGenFunctionInfo &fnInfo =
+      getTypes().arrangeDeviceKernelCallerDeclaration(ctx.VoidTy, args);
+  cir::FuncType funcType = getTypes().getFunctionType(fnInfo);
+
+  // Retrieve the generated name for the SYCL kernel caller function.
+  CanQualType kernelNameType =
+      ctx.getCanonicalType(kernelEntryPointAttr->getKernelName());
+  const SYCLKernelInfo &kernelInfo = ctx.getSYCLKernelInfo(kernelNameType);
+
+  // Synthesized from the OutlinedFunctionDecl, not a FunctionDecl, so create
+  // the function directly with a null FunctionDecl (mirrors classic CodeGen's
+  // llvm::Function::Create).
+  cir::FuncOp funcOp = createCIRFunction(
----------------
Men-cotton wrote:

The synthesized function is created directly with `createCIRFunction()` but 
never passed through `setCIRFunctionAttributes()`. Consequently, it misses 
generic attributes such as convergent, unlike classic CodeGen’s 
`SetLLVMFunctionAttributes(GlobalDecl(), FnInfo, ...)`.

Could we invoke the shared attribute path here?

https://github.com/llvm/llvm-project/pull/213771
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to