Skip to content
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 stuff required to elide instruction loading in yklua. #1642

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

vext01
Copy link
Contributor

@vext01 vext01 commented Mar 6, 2025

This includes:

  • Promote support for pointers.
  • Implementing various todo! relating to constant pointers.
  • Optimisations for ptr_add upon const pointers.
  • SpillState support for const pointers.

This includes:

 - Promote support for pointers.
 - Implementing various todo! relating to constant pointers.
 - Optimisations for ptr_add upon const pointers.
 - SpillState support for const pointers.
@vext01
Copy link
Contributor Author

vext01 commented Mar 6, 2025

@ltratt you could help me with a test for the heapvalues.rs change?

I had a brief look, but I don't know this part of the system at all.

// unwrap cannot fail since pointers are sized.
let bitw = self.m.type_(self.m.ptr_tyidx()).bitw().unwrap();

match bitw {
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 an assert masquerading as a todo I think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, just the result of copying code from elsewhere :) Will fix.

self.ra.assign_const_int(iidx, bits, v);
}
VarLocation::ConstPtr(v) => {
// unwrap can't fail because pointers are sized.
Copy link
Contributor

Choose a reason for hiding this comment

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

There is no unwrap here.

// the "pointer index type" before computing the offset.
let cidx = self
.m
.insert_const(Const::Ptr((*cptr as isize + off as isize) as usize))?;
Copy link
Contributor

Choose a reason for hiding this comment

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

We avoid as if at all possible. These should probably be isize::try_from(...).unwrap() (etc.) and you will need to decide if you want saturating_add or wrapped_add etc. to deal with poison cases. + will bork in debug mode when it detects overflow, which is not what we want, particularly as these situations do happen because select later gets rid of the poisoned value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

By as casting the offset to isize we truncate or sign extend, as is (I believe) required by LLVM.

This section of the llvm manual:

The indices are first converted to offsets in the pointer’s index type. If the currently indexed type is a struct type, the struct offset corresponding to the index is sign-extended or truncated to the pointer index type. Otherwise, the index itself is sign-extended or truncated, and then multiplied by the type allocation size (that is, the size rounded up to the ABI alignment) of the currently indexed type.

I must admit, I find this part of the documentation confusing. I hope I've interpreted it correctly.

Copy link
Contributor

Choose a reason for hiding this comment

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

The problem with as is that if you change the types later, it still "works" but does weird things. It's better to use the full type names, as we do elsewhere. Only if you really have to should you use as (regrettably sometimes you do have to; I don't think this is one of those cases, but I might be wrong).

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 think we can split this into two cases: truncate and sign-extend.

todo! the former, since I don't anticipate seeing that any time soon. isize::try_from() the latter.

Copy link
Contributor

Choose a reason for hiding this comment

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

Works for me!

Copy link
Contributor

Choose a reason for hiding this comment

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

BTW, in terms of the + stuff, the BinOp::Add optimisation probably serves as a useful template for this.

@@ -1762,6 +1776,12 @@ mod test {

#[test]
fn opt_ptradd() {
// FIXME: The offset operand of ptr_add should allow specifying a type (e.g. `ptr_add %0,
Copy link
Contributor

Choose a reason for hiding this comment

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

This will need to be fixed in this PR. We need to make the optimiser tests as complete as possible, because reasoning about it is already beyond my pea brain.

@@ -1795,6 +1815,24 @@ mod test {
black_box %0
",
);

// constant pointer optimisations.
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs to test all the edge cases too e.g. adding to the max value etc.

@ltratt
Copy link
Contributor

ltratt commented Mar 6, 2025

This looks good! I do have several comments, mostly because the optimiser has to be kept in tip-top condition. But this is already a solid start!

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