================
@@ -14794,9 +14803,36 @@ void 
ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
   }
 }
 
-static SYCLKernelInfo BuildSYCLKernelInfo(CanQualType KernelNameType,
+static SYCLKernelInfo BuildSYCLKernelInfo(ASTContext &Context,
+                                          CanQualType KernelNameType,
                                           const FunctionDecl *FD) {
-  return {KernelNameType, FD};
+  // Host and device compilation may use different ABIs and different ABIs
+  // may allocate name mangling discriminators differently. A discriminator
+  // override is used to ensure consistent discriminator allocation across
+  // host and device compilation.
+  auto DeviceDiscriminatorOverrider =
+      [](ASTContext &Ctx, const NamedDecl *ND) -> std::optional<unsigned> {
+    if (const auto *RD = dyn_cast<CXXRecordDecl>(ND))
+      if (RD->isLambda())
----------------
tahonermann wrote:

@erichkeane,
> Is this what you're referring to?

Yes.

> If so, I think that does.

Excellent.

> The concern here is that you're using DeviceLambdaManglingNumber, which, at 
> one point when I checked, wasn't actually set for non-instantiated generic 
> lambdas. So the attempt to mangle them would always result in the 'same' 
> mangling number, which doesn't really work. In addition to the above, can you 
> test the following, and make sure it results in proper looking names?

I modified the test (locally) as follows. The use of `decltype` and variables 
is necessary since lambda expressions aren't allowed in contexts that would 
require mangling.
```
  auto lambda = [=](auto) { (void) capture; };
  auto lx2 = [](int){};
  auto lx3 = [](auto){};  // Note, same signature as 'lambda'.
  auto lx4 = [](auto, auto){};
  kernel_single_task<decltype(lambda)>(lambda);
  kernel_single_task<decltype(lx2)>(lambda);
  kernel_single_task<decltype(lx3)>(lambda);
  kernel_single_task<decltype(lx4)>(lambda);
```

That produced the following names for the kernel entry points (with their 
associated demangling):
```
_ZTSZ4mainEUlT_E_
typeinfo name for main::'lambda'(auto)
_ZTSZ4mainEUliE_
typeinfo name for main::'lambda'(int)
_ZTSZ4mainEUlT_E0_
typeinfo name for main::'lambda0'(auto)
_ZTSZ4mainEUlT_T0_E_
typeinfo name for main::'lambda'(auto, auto)
```

I didn't commit this change because this test is intended to validate generated 
code, not the names. An extensive test for names will come in the PR that 
implements our new mangling strategy and it will include additions like those 
above.

> Depending on how types are mangled in some situations we actually mangle the 
> arguments of the lambda, which results in auto being used as the mangling, 
> though my memory on when that happens is vague ATM.

The argument signature is always included in the mangling of the closure type 
as that reduces the need for discriminators. This goes for both generic and 
non-generic lambdas as shown above (only the lambda corresponding to `lx3` gets 
a discriminator bump).

I looked through `clang/lib/AST/ItaniumMangle.cpp` for anything that is 
sensitive to generic lambdas. There are two such locations. 
`CXXNameMangler::mangleLambda()` calls `CXXNameMangler::mangleLambdaSig()` to 
incorporate the lambda signature; this includes any requires clauses on a 
generic lambda. The other is in 
`CXXNameMangler::TemplateArgManglingInfo::isOverloadable()` and is used to 
inform how template arguments are mangled.

https://github.com/llvm/llvm-project/pull/133030
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to