Skip to content

[SYCL] Update vtable emission logic for device code #16932

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: sycl
Choose a base branch
from

Conversation

jzc
Copy link
Contributor

@jzc jzc commented Feb 7, 2025

There PR aims to fix these two issues:

  1. calls-indirectly attribute propagation doesn't always happen as necessary #15071: separate-vf-defs.cpp / separate-vf-defs-and-calls - The construction kernels were not being recognized by SYCLVirtualFunctionsAnalysisPass (i.e. attaching calls-indirectly to them). They were not being attached because the definitions for the vtables were not being emitted in those compilation units, and SYCLVirtualFunctionsAnalysisPass can only correctly identifies construction kernels by analyzing the vtable definition referenced during object construction.
  2. VTables are propagated into every device image we produce during the split, leading to multiple definitions error #15069: separate-call.cpp - when sycl-post-link was splitting, the vtables were duplicated in the device images. This caused multiple definition errors between the duplicated vtables.

1 is fixed by using MarkVTableUsed on classes that have SYCL indirectly-callable attribute on one of their members, allowing the vtable definition to be generated. (Note: I would have liked to do this MarkVTableUsed call is in SemaSYCL::addSYCLAddIRAttributesFunctionAttr instead of Sema::CheckCompletedCXXClass but I was having an issue that MarkVTableUsed did not update VTablesUsed correctly because at that point the class wasn't recognized as virtual). With this, the vtable definition will be generated, but there is another problem - the functions referenced in the vtables did not have the relevant indirectly-callable attributes. These are usually attached by code gen if the function has a definition, but the definitions of the virtual functions do not necessarily need to be in the same compilation unit as the construction kernels. To fix this, a separate attribute attachment is added when code gen needs the pointer of some function. (The sycl_used_aspects metadata is attached at the same time.)

Since the fix for 1 emit vtables in every device module, we need to change the linkage type of the vtables during device compilation to linkonce_odr, otherwise there could be multiple definition issues in the device link set. This change also happens to fix the issue of 2.

@jzc jzc requested review from a team as code owners February 7, 2025 23:01
@jzc jzc temporarily deployed to WindowsCILock February 7, 2025 23:02 — with GitHub Actions Inactive
Comment on lines +12 to +13
// RUN: %{build} %S/Inputs/call.cpp -o %t.out %helper-includes %O0
// RUN: %{run} %t.out
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// RUN: %{build} %S/Inputs/call.cpp -o %t.out %helper-includes %O0
// RUN: %{run} %t.out
// RUN: %{build} %S/Inputs/call.cpp -o %t2.out %helper-includes %O0
// RUN: %{run} %t2.out

Comment on lines +9 to +10
// RUN: %{build} %S/Inputs/call.cpp %S/Inputs/vf.cpp -o %t.out %helper-includes %O0
// RUN: %{run} %t.out
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// RUN: %{build} %S/Inputs/call.cpp %S/Inputs/vf.cpp -o %t.out %helper-includes %O0
// RUN: %{run} %t.out
// RUN: %{build} %S/Inputs/call.cpp %S/Inputs/vf.cpp -o %t2.out %helper-includes %O0
// RUN: %{run} %t2.out

Comment on lines +11 to +12
// RUN: %{build} %S/Inputs/vf.cpp -o %t.out %helper-includes %O0
// RUN: %{run} %t.out
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// RUN: %{build} %S/Inputs/vf.cpp -o %t.out %helper-includes %O0
// RUN: %{run} %t.out
// RUN: %{build} %S/Inputs/vf.cpp -o %t2.out %helper-includes %O0
// RUN: %{run} %t2.out

Copy link
Contributor

@elizabethandrews elizabethandrews left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FE changes need to be accompanied by FE tests. Please add a few tests.

@@ -3283,6 +3283,18 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
if (const auto *A = FD->getAttr<SYCLUsesAspectsAttr>())
applySYCLAspectsMD(A, getContext(), getLLVMContext(), F,
"sycl_used_aspects");

if (getLangOpts().SYCLIsDevice &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am guessing we should not be adding this attribute in both SetFunctionAttributes and StartFunction. Have you checked if we're duplicating the attribute now? What happens when you remove the code in StartFunction

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants