-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Implement [T]::align_to #50319
Implement [T]::align_to #50319
Conversation
r? @BurntSushi (rust_highfive has picked a reviewer for you, use r? to override) |
src/librustc_trans/intrinsic.rs
Outdated
@@ -85,12 +86,12 @@ fn get_simple_intrinsic(cx: &CodegenCx, name: &str) -> Option<ValueRef> { | |||
/// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs, | |||
/// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics, | |||
/// add them to librustc_trans/trans/context.rs | |||
pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>, | |||
pub fn trans_intrinsic_call<'a, 'tcx>(bx: Builder<'a, 'tcx>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the signature of this function changed? From the diff it doesn't look like you really need the ownership.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generating a call to the language item will terminate the block being passed in, so using that block further makes no sense. Passing ownership models this pretty well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this just a refactoring or necessary for the new align_offset
? If it's just refactoring I prefer this being separated into its own commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without the new This change is necessary for implementation of align_offset
this change is not necessary.align_offset
itself.
I’ll probably redo the PR slightly to not use an intrinsic at all – miri will still be able to detect calls to this by looking at langitem defid of the function. |
I think we already do that for some u128 lowerings |
f27ddd1
to
9b7a579
Compare
So, adapting the code was pretty easy, however it seems to have a hard hit on code quality in debug builds. Most notably, constant propagation is not active, so the dead code is not removed, making what should essentially be I’m still going to go with this, because all the issues can be fixed with some const evaluation at a later date. |
I recall that this approach caused some problems with the i128 stuff, since it could get inlined and disappear. (It'd be nice, now that MIRI is merged, so go back and redo the lowering functions as const fn so they wouldn't need to be special at eval time, though last I tried intrinsics couldn't be marked |
const functions can’t do conditional code yet due to #49146. |
☔ The latest upstream changes (presumably #50466) made this pull request unmergeable. Please resolve the merge conflicts. |
Ping from triage @BurntSushi! This PR needs your review. |
Perhaps somebody else from the @rust-lang/libs wants to volunteer to review this? |
Ping from triage! This PR needs a review, can @BurntSushi or someone else from @rust-lang/libs review this? |
This seems like it's a lot of unstable internal details that are unlikely to be stabilized soon so I'm not necessarily reviewing too too closely. @oli-obk does this overall change look ok to you? I think you were one of the original proponents for the intrinsic, right? |
Yes, I already talked with @nagisa every now and then about it and have reviewed the current state last week. This is fine with me, though I can't grok the math, the tests look like it works out.
I created the rfc and initial impl. We still need this for miri to continue working. |
@bors: r+ |
📌 Commit cdc5f33 has been approved by |
⌛ Testing commit cdc5f334616211a3620a2a50239ec11c7b56afa1 with merge 5c5dc122a7cc2ed813958e12c595f67c4ea5c8cd... |
💔 Test failed - status-appveyor |
Keep only the language item. This removes some indirection and makes codegen worse for debug builds, but simplifies code significantly, which is a good tradeoff to make, in my opinion. Besides, the codegen can be improved even further with some constant evaluation improvements that we expect to happen in the future.
@bors r=alexcrichton |
📌 Commit 59bb0fe has been approved by |
⌛ Testing commit 59bb0fe with merge ccd0949aa5b6b143c3f16f7324c19868de26ad2b... |
💔 Test failed - status-travis |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
The job Click to expand the log.
I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
I don’t get this failure. The log just… stops… as if somebody flicked the power switch in Travis’ data centre. |
@bors retry |
Implement [T]::align_to Note that this PR deviates from what is accepted by RFC slightly by making `align_offset` to return an offset in elements, rather than bytes. This is necessary to sanely support `[T]::align_to` and also simply makes more sense™. The caveat is that trying to align a pointer of ZST is now an equivalent to `is_aligned` check, rather than anything else (as no number of ZST elements will align a misaligned ZST pointer). It also implements the `align_to` slightly differently than proposed in the RFC to properly handle cases where size of T and U aren’t co-prime. Furthermore, a promise is made that the slice containing `U`s will be as large as possible (contrary to the RFC) – otherwise the function is quite useless. The implementation uses quite a few underhanded tricks and takes advantage of the fact that alignment is a power-of-two quite heavily to optimise the machine code down to something that results in as few known-expensive instructions as possible. Currently calling `ptr.align_offset` with an unknown-at-compile-time `align` results in code that has just a single "expensive" modulo operation; the rest is "cheap" arithmetic and bitwise ops. cc #44488 @oli-obk As mentioned in the commit message for align_offset, many thanks go to Chris McDonald.
☀️ Test successful - status-appveyor, status-travis |
Note that this PR deviates from what is accepted by RFC slightly by making
align_offset
to return an offset in elements, rather than bytes. This is necessary to sanely support[T]::align_to
and also simply makes more sense™. The caveat is that trying to align a pointer of ZST is now an equivalent tois_aligned
check, rather than anything else (as no number of ZST elements will align a misaligned ZST pointer).It also implements the
align_to
slightly differently than proposed in the RFC to properly handle cases where size of T and U aren’t co-prime.Furthermore, a promise is made that the slice containing
U
s will be as large as possible (contrary to the RFC) – otherwise the function is quite useless.The implementation uses quite a few underhanded tricks and takes advantage of the fact that alignment is a power-of-two quite heavily to optimise the machine code down to something that results in as few known-expensive instructions as possible. Currently calling
ptr.align_offset
with an unknown-at-compile-timealign
results in code that has just a single "expensive" modulo operation; the rest is "cheap" arithmetic and bitwise ops.cc #44488 @oli-obk
As mentioned in the commit message for align_offset, many thanks go to Chris McDonald.