Skip to content

[rbi] Fix demangling of sending results. #78612

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

Merged

Conversation

gottesmm
Copy link
Contributor

[rbi] Fix demangling of sending results.

The issue here is that the demangler (since we have a postfix mangling) parses parameters/results/etc and then uses earlier postfix type arguments to attach the relevant types to the parameters/results/etc. Since the flag for a sending result was placed in between the parameters and results, we get an off by one error.

The reason why I originally did it this way is that part of sending was cargo culted from the autodiff parts of the mangling and parts from the async/isolated(any) part of the function type mangling. In this case, I followed the location of the autodiff part of the mangling (which is per parameter) instead of the async/isolated(any) part of the mangling (which are global flags) which is what exposed this issue.

The good thing is if we eventually allow for sending to be placed on individual parameters, we can potentially eliminate seeing this patter in future versions of the ABI by just placing sending onto the parameters instead. This would additionally allow for us to eliminate this offset code by checking for the flag where it is and in such a case, just place it on each parameter as a flag.

rdar://141962865

…}() propagates result options.

I discovered this while trying to figure out why we were dropping a sending bit
when computing a reabstraction thunk in the tests for the following commit. This
turned out to be the reason why.
@gottesmm gottesmm force-pushed the pr-d09f63ed212874b52ff15e2838b55f7462908323 branch from 7e799e9 to 62838d5 Compare January 14, 2025 22:39
@gottesmm gottesmm force-pushed the pr-d09f63ed212874b52ff15e2838b55f7462908323 branch 2 times, most recently from 3a6a5f5 to ebd076d Compare January 14, 2025 23:36
@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

The issue here is that the demangler (since we have a postfix mangling) parses
parameters/results/etc and then uses earlier postfix type arguments to attach
the relevant types to the parameters/results/etc. Since the flag for a sending
result was placed in between the parameters and results, we get an off by one
error.

Rather than fix that specific issue by introducing an offset for the off by one
error, I used the fact that the impl-function part of the mangling is not ABI
and can be modified to move the bit used to signify a sending result to before
the parameters so the whole problem is avoided.

I also while I was doing this looked through the sending result mangling for any
further issues and fixed them as I found them.

rdar://141962865
@gottesmm gottesmm force-pushed the pr-d09f63ed212874b52ff15e2838b55f7462908323 branch from ebd076d to cb2d756 Compare January 14, 2025 23:38
@gottesmm
Copy link
Contributor Author

@swift-ci smoke test

@gottesmm gottesmm merged commit 44a4a67 into swiftlang:main Jan 15, 2025
3 checks passed
@gottesmm gottesmm deleted the pr-d09f63ed212874b52ff15e2838b55f7462908323 branch January 15, 2025 17:58
// E.x.:
//
// func foo() -> sending X // No mangling
// func bar(_ x: () -> sending X) {} // Add to mangling for x
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment implies that impl-function-type mangling is ABI, and it should probably be removed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Sorry! I forgot to remove it.

Copy link
Contributor

@rjmccall rjmccall left a comment

Choose a reason for hiding this comment

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

LGTM other than the misleading comment

}

/// Return a version of this result info with the convention replaced.
SILResultInfo getWithConvention(ResultConvention c) const {
return SILResultInfo(getInterfaceType(), c);
return SILResultInfo(getInterfaceType(), c, getOptions());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I noticed this when I was preparing the test cases for this PR. For some reason we were generating the thunks I was not expecting (since we were losing the sending result bit) and then due to the adjustFunctionType code generation, we were recovering. I tracked down that this was occurring due to SILGenPoly using this API and found this thinko. It didn't change any actual test output though, so I think we have been getting lucky.

Copy link
Contributor Author

@gottesmm gottesmm left a comment

Choose a reason for hiding this comment

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

@rjmccall some context for you

@@ -1093,7 +1093,14 @@ class TypeDecoder {
flags = flags.withSendable();
} else if (child->getText() == "@async") {
flags = flags.withAsync();
} else if (child->getText() == "sending-result") {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is part of the code that I added that handles the legacy demangler code.

}
} else if (child->getKind() == NodeKind::ImplSendingResult) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This block is needed of course since we were not handling ImplSendingResult at all. The reason why it being not there was not an issue is b/c we also place a bit on the individual result info... so we got the appropriate bits from there.

@@ -677,6 +677,10 @@ Type ASTBuilder::createImplFunctionType(
auto type = result.getType()->getCanonicalType();
auto conv = getResultConvention(result.getConvention());
auto options = *getResultOptions(result.getOptions());
// We currently set sending result at the function level, but we set sending
// result on each result.
if (flags.hasSendingResult())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This ensures that we maintain the invariant that I mentioned above that if the flags have a sending result, we also set the options bit on each SILResultInfo to mark them as sending.

// E.x.:
//
// func foo() -> sending X // No mangling
// func bar(_ x: () -> sending X) {} // Add to mangling for x
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Sorry! I forgot to remove it.

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.

2 participants