Skip to content

[Async CC] Add constant "pointer" for async func. #34589

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

Conversation

nate-chandler
Copy link
Contributor

@nate-chandler nate-chandler commented Nov 5, 2020

An AsyncFunctionPointer, defined in Task.h, is a struct consisting of two i32s: (1) the relative address of the async function and (2) the size of the async context to be allocated when calling that function.

Here, such structs are emitted for every async SILFunction that is emitted. Furthermore, pointers to these new structs rather than pointers directly to async functions are passed around. The async context size is now read out of these function pointers and used to allocate the async context. This will enable the size constants to be rewritten by an LLVM pass with the ideal storage space to minimize additional allocations.

The following tasks need to be completed before merge:

  • Avoiding AsyncFunctionPointers for partial apply forwarders.
  • Using SILFunction as the value for the AsyncFunctionPointer LinkEntity.
  • Using a LinkEntity for TBDGen of AsyncFunctionPointers.
  • Avoiding extracting function pointers from AsyncFunctionPointers during thin_to_thick and convert_function lowering.
  • Pointer authentication for function pointers.

The following related task will be completed in follow-on PRs:

  • Referring directly to async functions when particular callees are known rather than loading the function pointers from AsyncFunctionPointer structs.

@nate-chandler nate-chandler force-pushed the concurrency/irgen/function-constants branch 2 times, most recently from 54d70ba to be5273a Compare November 5, 2020 16:02
Copy link
Member

@DougGregor DougGregor left a comment

Choose a reason for hiding this comment

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

Very cool!

auto *sizeValue =
llvm::ConstantInt::get(IGF.IGM.Int32Ty, size.getValue());
phiValues.push_back({staticSizeBlock, sizeValue});
auto *ptr = functionPointer.getRawPointer();
Copy link
Contributor

Choose a reason for hiding this comment

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

You need logic for pointer authentication here.

if (kind == KindTy::AsyncFunctionPointer) {
assert(fnType->getRepresentation() != SILFunctionTypeRepresentation::Thick);
}
return forDirect(kind, fnPtr, IGM.getSignature(fnType));
Copy link
Contributor

Choose a reason for hiding this comment

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

This is determinable from the function type, right?

Should we lay the groundwork to make direct calls actually be direct in IR and just also record the context-size pointer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Something like this?

// Have to dig the size out of the AsyncFunctionPointer so that it can be rewritten downstream
%afp = `AsyncFunctionPointer(callee)`
%size_addr = getelementptr %afp, 0, 1
%size = load %size_addr
%context = call @swift_task_alloc(%task, %size)
// But we don't have to dig the function pointer out of the AsyncFunctionPointer because we already know what it is
call @callee(%task, %executor, %context)

switch (Kind) {
case KindTy::Function:
return Value;
case KindTy::AsyncFunctionPointer:
Copy link
Contributor

Choose a reason for hiding this comment

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

Pointer auth logic required.

@nate-chandler nate-chandler force-pushed the concurrency/irgen/function-constants branch 4 times, most recently from b061dcb to 2fef32a Compare November 10, 2020 00:04
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@nate-chandler
Copy link
Contributor Author

@swift-ci please clean test windows platform

@nate-chandler nate-chandler force-pushed the concurrency/irgen/function-constants branch from 2fef32a to 0280141 Compare November 10, 2020 01:55
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@nate-chandler
Copy link
Contributor Author

@swift-ci please clean test windows

@nate-chandler nate-chandler force-pushed the concurrency/irgen/function-constants branch from 0280141 to 27f1d5b Compare November 11, 2020 22:50
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@nate-chandler nate-chandler force-pushed the concurrency/irgen/function-constants branch from 27f1d5b to 4827118 Compare November 11, 2020 22:54
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 4827118

@nate-chandler nate-chandler force-pushed the concurrency/irgen/function-constants branch from 4827118 to fb6045b Compare November 11, 2020 23:57
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@nate-chandler
Copy link
Contributor Author

@swift-ci please clean test windows

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - fb6045bf0959b9ec020054bf1cbb2051d5d4d996

@nate-chandler nate-chandler force-pushed the concurrency/irgen/function-constants branch from fb6045b to 3470f75 Compare November 12, 2020 00:51
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@nate-chandler nate-chandler force-pushed the concurrency/irgen/function-constants branch 3 times, most recently from 67d9e21 to ad74809 Compare November 12, 2020 23:40
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

1 similar comment
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@nate-chandler nate-chandler marked this pull request as ready for review November 13, 2020 02:18
ClassMetadataLayout::getOffsett -> ClassMetadataLayout::getOffset
Two LinkEntities are needed to enable the construction during both IRGen
and TBDGen.
In order to call async functions, instances of the AsyncFunctionPointer
struct must be used.  If those functions are exported from a module, the
AsyncFunctionPointer by means of which the function is to be called must
be exported as well.

For now, the symbol is exported by manually appending the relevant
suffix to the mangled name of the function.
An AsyncFunctionPointer, defined in Task.h, is a struct consisting of
two i32s: (1) the relative address of the async function and (2) the
size of the async context to be allocated when calling that function.

Here, such structs are emitted for every async SILFunction that is
emitted.
While the pointer auth details are worked out, to unblock other work,
disable the tests on arm64e where they will fail until those details are
worked out.
@nate-chandler nate-chandler force-pushed the concurrency/irgen/function-constants branch from ae4dbe3 to 6962874 Compare November 13, 2020 02:20
@nate-chandler
Copy link
Contributor Author

@swift-ci please test

@nate-chandler nate-chandler merged commit 3261e2e into swiftlang:main Nov 13, 2020
@nate-chandler nate-chandler deleted the concurrency/irgen/function-constants branch November 13, 2020 17:57
@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 6962874

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 6962874

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.

5 participants