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

Simplify type_is_immediate and type_is_fat_ptr #38854

Merged
merged 4 commits into from
Jan 14, 2017

Conversation

Mark-Simulacrum
Copy link
Member

r? @eddyb

}
OperandValue::Pair(..) => bug!("Unexpected Pair operand")
};
let discr = operand.immediate();
Copy link
Member

Choose a reason for hiding this comment

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

You can lift let llval = operand.immediate() out of this if-let-else.

_ => {
false
}
if let Layout::FatPointer { .. } = *ccx.layout_of(ty) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Check that this does not regress rustc performance - this fn is called quite often.

Copy link
Member

Choose a reason for hiding this comment

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

The layouts are cached and sometime during compilation the layout of any type will be requested anyway, so it seems fine to me?

Copy link
Member Author

Choose a reason for hiding this comment

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

I can do some benchmarking with regards to this, but it does feel needless because they are cached.

@eddyb
Copy link
Member

eddyb commented Jan 7, 2017

Oh I didn't r+ this. What happened?

adt::trans_get_discr(&bcx, operand.ty, llptr, None, true)
}
OperandValue::Pair(..) => bug!("Unexpected Pair operand")
};
let (signed, min, max) = match l {
&Layout::CEnum { signed, min, max, .. } => {
Copy link
Member

Choose a reason for hiding this comment

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

Can you do this if-let-else based on Layout and not CastTy?

@Mark-Simulacrum
Copy link
Member Author

Fixed. I can also pull in #38906, or let that be rebased on top of what I've done here once this merges.

@eddyb
Copy link
Member

eddyb commented Jan 7, 2017

@Mark-Simulacrum I'd integrate #38906 (should be a small change to the size check).
You can add Closes #38906 to your description to inflict that effect when this gets merged.
EDIT: Oops, Travis CI failed on that, so don't do it unless you can figure out how to make tests pass.

This has the nice benefit of making it much simpler to work with,
since it now consists of a single match statement.
@Mark-Simulacrum
Copy link
Member Author

Tests pass locally for me.

Layout::UntaggedUnion { .. } |
Layout::RawNullablePointer { .. } |
Layout::StructWrappedNullablePointer { .. } => {
!layout.is_unsized() && type_is_zero_size(ccx, ty)
Copy link
Member

Choose a reason for hiding this comment

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

You should still be checking the layout size.

Copy link
Member

Choose a reason for hiding this comment

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

@eddyb @dotdash’s PR removes that check, essentially causing aggeregates to never be immediate. readding layout size check would go back to square 1.

Copy link
Member

Choose a reason for hiding this comment

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

No, ZSTs are a size check too.

Copy link
Member Author

@Mark-Simulacrum Mark-Simulacrum Jan 12, 2017

Choose a reason for hiding this comment

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

I believe that I've exactly mirrored @dotdash's PR. The previous size comparison changes to a "is_zero_size" check for all types not matched above, which is what the code in this PR currently does. If not, please inform me what I am missing.

 -    match ty.sty {
 -        ty::TyAdt(..) | ty::TyTuple(..) | ty::TyArray(..) | ty::TyClosure(..) => {
 -            let llty = sizing_type_of(ccx, ty);
 -            llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type())
 -        }
 -        _ => type_is_zero_size(ccx, ty)
 -    }
 +    type_is_zero_size(ccx, ty)

Copy link
Member

Choose a reason for hiding this comment

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

What I'm saying is you have a layout and you can get the size directly, i.e. you change the threshold in your original patch.

Copy link
Member Author

Choose a reason for hiding this comment

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

So instead of type_is_zero_size I would use layout.size() == 0 (or the equivalent if there's a method)?

"You change the threshold in your original patch" I don't know what you mean by this...

Copy link
Member

Choose a reason for hiding this comment

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

Yes, that. If you use that it will look like what you had here before, but instead of <= dl.ptr_size.bytes() you'll have == 0.

LLVM usually prefers using memcpys over direct loads/store of first
class aggregates. The check in type_is_immediate to mark certain small
structs was originally part of the code to handle such immediates in
function arguments, and it had a counterpart in load_ty/store_ty to
actually convert small aggregates to integers.

But since then, the ABI handling has been refactored and takes care of
converting small aggregates to integers. During that refactoring, the
code to handle small aggregates in load_ty/store_ty has been removed,
and so we accidentally started using loads/stores on FCA values.

Since type_is_immediate() is no longer responsible for ABI-related
conversions, and using a memcpy even for small aggregates is usually
better than performing a FCA load/store, we can remove that code part
and only handle simple types as immediates there.

This integrates PR rust-lang#38906 onto this branch.

Fixes rust-lang#38906.
@Mark-Simulacrum
Copy link
Member Author

Tests pass locally. I think I resolved @eddyb's last comment.

@eddyb
Copy link
Member

eddyb commented Jan 14, 2017

@bors r+

@bors
Copy link
Contributor

bors commented Jan 14, 2017

📌 Commit 43cf5b9 has been approved by eddyb

@bors
Copy link
Contributor

bors commented Jan 14, 2017

⌛ Testing commit 43cf5b9 with merge d70cd49...

bors added a commit that referenced this pull request Jan 14, 2017
Simplify type_is_immediate and type_is_fat_ptr

r? @eddyb
@bors
Copy link
Contributor

bors commented Jan 14, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: eddyb
Pushing d70cd49 to master...

@bors bors merged commit 43cf5b9 into rust-lang:master Jan 14, 2017
@Mark-Simulacrum Mark-Simulacrum deleted the immediate-refactor branch January 14, 2017 05:00
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.

None yet

6 participants