Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upUse ty::layout for ABI computation instead of LLVM types. #40658
Conversation
rust-highfive
assigned
pnkfelix
Mar 19, 2017
This comment has been minimized.
This comment has been minimized.
|
r? @pnkfelix (rust_highfive has picked a reviewer for you, use r? to override) |
This comment has been minimized.
This comment has been minimized.
eddyb
referenced this pull request
Mar 19, 2017
Merged
Implementation of repr struct alignment RFC 1358. #39999
eddyb
force-pushed the
eddyb:lay-more-out
branch
2 times, most recently
from
f55fb66
to
c91c10a
Mar 20, 2017
nagisa
reviewed
Mar 20, 2017
|
Some nits gathered over the day. |
| @@ -1087,25 +1089,33 @@ impl<'a, 'gcx, 'tcx> Layout { | |||
| // Arrays and slices. | |||
| ty::TyArray(element, count) => { | |||
| let element = element.layout(infcx)?; | |||
| let element_size = element.size(dl); | |||
| let count = count as u64; | |||
This comment has been minimized.
This comment has been minimized.
nagisa
Mar 20, 2017
Contributor
The cast is not necessary and is possibly dangerous (e.g. after a type in the declaration changes)
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Mar 23, 2017
Contributor
if we care, maybe make fn usize_to_u64(x: usize) and then do usize_to_u64(count)?
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 24, 2017
Author
Member
LOL. I'll add a whole variable dealing with this fact and a comment on it.
| i: usize, | ||
| variant_index: Option<usize>) | ||
| -> Size { | ||
| match *self { |
This comment has been minimized.
This comment has been minimized.
|
|
||
| ty::TyTuple(tys, _) => tys[i], | ||
|
|
||
| // SIMD vector types. |
This comment has been minimized.
This comment has been minimized.
nagisa
Mar 20, 2017
Contributor
Assumes that all fields of a some vector must be the same (true for LLVM but not true for some architectures/proposals such as for RISC-V)
Not a big issue (also we discussed this on IRC already)
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 20, 2017
Author
Member
Oh, just to be super clear: ty::layout already assumes uniform vectors.
We'd have to overhaul it a bit when that assumption breaks down anyway.
| } | ||
| } | ||
| // Currently supported vector size (AVX). | ||
| const LARGEST_VECTOR_SIZE: usize = 256; |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 20, 2017
Author
Member
Right, I meant AVX. AVX512 is different from AVX like SSE3 is different from SSE.
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 20, 2017
Author
Member
Also cc @BurntSushi on what stance we should have in terms of ABI compat.
eddyb
reviewed
Mar 20, 2017
| Scalar { .. } | | ||
| CEnum { .. } | | ||
| UntaggedUnion { .. } | | ||
| RawNullablePointer { .. } => { |
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 20, 2017
Author
Member
debug_assert i==0, perhaps?
You mean here? I might just take this out, except for UntaggedUnion. It was meant for something I abandoned.
This comment has been minimized.
This comment has been minimized.
|
|
eddyb
force-pushed the
eddyb:lay-more-out
branch
2 times, most recently
from
b3001b2
to
6ac00de
Mar 21, 2017
This was referenced Mar 21, 2017
This comment has been minimized.
This comment has been minimized.
rust-highfive
assigned
nikomatsakis
and unassigned
pnkfelix
Mar 23, 2017
arielb1
reviewed
Mar 24, 2017
| @@ -1087,25 +1089,33 @@ impl<'a, 'gcx, 'tcx> Layout { | |||
| // Arrays and slices. | |||
| ty::TyArray(element, count) => { | |||
| let element = element.layout(infcx)?; | |||
| let element_size = element.size(dl); | |||
| let count = count as u64; | |||
This comment has been minimized.
This comment has been minimized.
| pub fn size_of(&self, ty: Ty<'tcx>) -> machine::llsize { | ||
| let layout = self.layout_of(ty); | ||
| layout.size(&self.tcx().data_layout).bytes() as machine::llsize | ||
| } | ||
| } | ||
|
|
||
| fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> String { |
This comment has been minimized.
This comment has been minimized.
| @@ -202,6 +202,16 @@ impl TargetDataLayout { | |||
| } | |||
| } | |||
|
|
|||
| pub trait HasDataLayout: Copy { | |||
This comment has been minimized.
This comment has been minimized.
| } | ||
| } | ||
|
|
||
| pub trait LayoutTyper<'tcx>: HasTyCtxt<'tcx> { |
This comment has been minimized.
This comment has been minimized.
arielb1
Mar 24, 2017
Contributor
This looks like a rather heavy abstraction - it is only used for .field, which is only called from trans::abi, which already defines LayoutExt. I'll move Layout::field to LayoutExt and remove this trait.
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 24, 2017
Author
Member
The abstraction exists so we can pull out the ABI computation into a separate crate, so the heaviness is intentional.
This comment has been minimized.
This comment has been minimized.
| pub fn of(infcx: &InferCtxt<'a, 'gcx, 'tcx>, ty: Ty<'gcx>) | ||
| -> Result<Self, LayoutError<'gcx>> { | ||
| let ty = normalize_associated_type(infcx, ty); | ||
| pub trait HasTyCtxt<'tcx>: HasDataLayout { |
This comment has been minimized.
This comment has been minimized.
arielb1
Mar 24, 2017
Contributor
If you are defining this trait, maybe move it to ty::fold and make TypeFolder a subtrait? Can you add a blanket impl<T: HasTyCtxt> HasDataLayout for T? Is there any place that needs data layout but does not have a tcx (aka do we need HasDataLayout)?
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 24, 2017
Author
Member
I tried that and it required weird inexpressible region bounds to work, sadly.
| @@ -133,32 +134,279 @@ impl ArgAttributes { | |||
| } | |||
| } | |||
|
|
|||
| pub trait CastTarget { | |||
This comment has been minimized.
This comment has been minimized.
arielb1
Mar 24, 2017
•
Contributor
Any reason this is a trait rather than an enum (Reg | RegPair | Uniform)? That would make moving away from LLVM easier.
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 24, 2017
Author
Member
I wanted to make sure it works first, and the trait allows replacing with an enum later, but maybe I should do it now.
This comment has been minimized.
This comment has been minimized.
arielb1
requested changes
Mar 24, 2017
|
Looks excellent. I should look at this last commit more but I have to go. |
|
|
||
| // ADTs. | ||
| ty::TyAdt(def, _) => { | ||
| let v = if def.is_enum() { |
This comment has been minimized.
This comment has been minimized.
arielb1
Mar 24, 2017
Contributor
I'll say "what about univariant enums" but you appear to have fixed this in the next commit.
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 24, 2017
Author
Member
I'll move it back (rebasing was painful when fixing that but now it should be fine.
| ty::TyNever | | ||
| ty::TyFnDef(..) | | ||
| ty::TyDynamic(..) => { | ||
| ty::TyFnPtr(_) => { | ||
| bug!("TyLayout::field_type({:?}): not applicable", self) |
This comment has been minimized.
This comment has been minimized.
arielb1
Mar 24, 2017
•
Contributor
bug and comment are wrong - function is called field_count, and TyDynamic is not a ZST. OTOH, non-ADT/arrays have 0 fields, so presumably you should always return 0 for them (+TyStr).
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 24, 2017
Author
Member
It mostly has to match the Layout variant (maybe I should match on that instead).
| } | ||
| } | ||
| RegKind::Vector => { | ||
| // Try to pick an integer at least twice as small. |
This comment has been minimized.
This comment has been minimized.
arielb1
Mar 24, 2017
Contributor
What's the motivation for this? AFAICT this seems to be used only for SSE/AVX on amd64 SysV, so the if statement can never be hit. If LLVM really does not care about the type of the vector elements as long as it has the right length, why not use [u8; N] everywhere? Or [u64; N] because all SIMD is a multiple of 64 bits.
This comment has been minimized.
This comment has been minimized.
| use rustc::ty::layout::{self, Layout, TyLayout, Size}; | ||
|
|
||
| #[derive(Clone, Copy, PartialEq, Debug)] | ||
| enum Class { |
This comment has been minimized.
This comment has been minimized.
| SSEDv, | ||
| SSEInt(/* bitwidth */ u64), | ||
| LoneF32, | ||
| Sse, |
This comment has been minimized.
This comment has been minimized.
arielb1
Mar 24, 2017
Contributor
Might be worth commenting that this also includes AVX (yes I know the spec calls this Sse).
This comment has been minimized.
This comment has been minimized.
arielb1
Mar 24, 2017
Contributor
Also, LoneF32 is also an Sse in the spec - the only difference is that we want to tell LLVM that only the lowest 32 bits matter. I'll make it a field of the enum.
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 25, 2017
Author
Member
There's a more elegant way to handle this (last Sse with only 4 bytes of data left, only way to get LoneF32 anyway, unless you have weird padding). I'll try to implement it.
Also, clang does somewhat complex type recovery - I don't think we care, as this is for FFI.
nikomatsakis
reviewed
Mar 24, 2017
| @@ -1513,6 +1531,59 @@ impl<'a, 'gcx, 'tcx> Layout { | |||
| } | |||
| } | |||
| } | |||
|
|
|||
| pub fn field_offset(&self, | |||
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Mar 24, 2017
Contributor
Seems like some comments, or better choice of names, would be good here. e.g. what is i -- the index of the field, I guess? variant_index is for structs/enums? (I'd also find the opposite order of those parameters more intuitive, but I can't say why -- I guess because the i is defined relative to variant_index)
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 24, 2017
Author
Member
We'll hopefully eventually remove variant_index by adding variant types, so I'm not sure how much I care about it.
This comment has been minimized.
This comment has been minimized.
arielb1
requested changes
Mar 24, 2017
|
Most changes should be fixed in a separate PR, but I don't like the "pirate" pair of floats feature in this PR. |
| } | ||
| } | ||
|
|
||
| pub trait LayoutTyper<'tcx>: HasTyCtxt<'tcx> { |
This comment has been minimized.
This comment has been minimized.
| self.layout.field_offset(cx, i, self.variant_index) | ||
| } | ||
|
|
||
| pub fn field_count<C: HasTyCtxt<'tcx>>(&self, cx: C) -> usize { |
This comment has been minimized.
This comment has been minimized.
| @@ -133,32 +134,279 @@ impl ArgAttributes { | |||
| } | |||
| } | |||
|
|
|||
| pub trait CastTarget { | |||
This comment has been minimized.
This comment has been minimized.
| return; | ||
| } | ||
|
|
||
| // Pairs of floats. |
This comment has been minimized.
This comment has been minimized.
arielb1
Mar 24, 2017
Contributor
This is not present in the original code. Random micro-optimization?
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 25, 2017
•
Author
Member
Oh I meant to find that issue and mention it in the description. This is a long-wanted feature and now it's easy to implement so I just did it when I rewrote that code.
| let fields = variant.field_index_by_increasing_offset().map(|i| fields[i as usize]); | ||
| if sizing { | ||
| fields.filter(|ty| !dst || cx.shared().type_is_sized(*ty)) | ||
| .map(|ty| type_of::sizing_type_of(cx, ty)).collect() | ||
| bug!() |
This comment has been minimized.
This comment has been minimized.
arielb1
Mar 24, 2017
Contributor
nit: remove the sizing and dst parameters? They don't seem to be used anywhere.
This comment has been minimized.
This comment has been minimized.
| let size = ret.layout.size(ccx); | ||
| let bits = size.bits(); | ||
| if bits <= 128 { | ||
| let unit = if bits <= 8 { |
This comment has been minimized.
This comment has been minimized.
arielb1
Mar 24, 2017
Contributor
can't this logic be lifted to abi? It appears to be used in several places, including the Rust ABI.
| SSEDv, | ||
| SSEInt(/* bitwidth */ u64), | ||
| LoneF32, | ||
| Sse, |
This comment has been minimized.
This comment has been minimized.
arielb1
Mar 24, 2017
Contributor
Also, LoneF32 is also an Sse in the spec - the only difference is that we want to tell LLVM that only the lowest 32 bits matter. I'll make it a field of the enum.
|
|
||
| #[derive(Clone, Copy, PartialEq, Debug)] | ||
| enum Class { | ||
| None, |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| @@ -121,13 +121,13 @@ pub fn unsafe_slice(_: &[UnsafeInner]) { | |||
| fn str(_: &[u8]) { | |||
| } | |||
|
|
|||
| // CHECK: @trait_borrow(i8* nonnull, void (i8*)** noalias nonnull readonly) | |||
| // CHECK: @trait_borrow({}* nonnull, {}* noalias nonnull readonly) | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
eddyb
Mar 25, 2017
Author
Member
Those problems were only around C FFI were LLVM was looking for a specific signature, IIRC.
i.e. Not unit pointers were the problem but any pointer thst wasn't i8*.
This comment has been minimized.
This comment has been minimized.
|
@bors r+ |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Mar 25, 2017
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Mar 25, 2017
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@bors r=arielb1 |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Apr 8, 2017
This comment has been minimized.
This comment has been minimized.
|
@bors r- retry |
eddyb
force-pushed the
eddyb:lay-more-out
branch
from
1759358
to
a8dd65a
Apr 8, 2017
This comment has been minimized.
This comment has been minimized.
|
@bors r=arielb1 |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Apr 9, 2017
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@bors retry
|
This comment has been minimized.
This comment has been minimized.
|
This is the log of the error (there are multiple like these:
This is not related to the out-of-disk-space errors. There’s still plenty left. cc @alexcrichton this one is new. |
This comment has been minimized.
This comment has been minimized.
|
@bors r- Aaaaah there's an LLVM error in there, thanks! |
eddyb
referenced this pull request
Apr 9, 2017
Open
Support splitting Phi and Select over arrays. #178
This comment has been minimized.
This comment has been minimized.
|
This appears to be an emscripten bug, which I've filed as emscripten-core/emscripten-fastcomp#178. |
eddyb
force-pushed the
eddyb:lay-more-out
branch
from
a8dd65a
to
f0636b6
Apr 9, 2017
This comment has been minimized.
This comment has been minimized.
|
@bors r=arielb1 |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Apr 9, 2017
This comment has been minimized.
This comment has been minimized.
|
|
eddyb commentedMar 19, 2017
•
edited
This is the first step in creating a backend-agnostic library for computing call ABI details from signatures.
I wanted to open the PR before attempting to move
cabi_*from trans to avoid rebase churn in #39999.EDIT: As I suspected, #39999 needs this PR to fully work (see #39999 (comment)).
The first 3 commits add more APIs to
ty::layoutand replace non-ABI uses ofsizing_type_of.These APIs are probably usable by other backends, and miri too (cc @stoklund @solson).
The last commit rewrites
rustc_trans::cabi_*to usety::layoutand newrustc_trans::abiAPIs.Also, during the process, a couple trivial bugs were identified and fixed:
msp430,nvptx,nvptx64: type sizes in bytes were compared with32and64x86(fastcall):f64was incorrectly not treated the same way asf32Although not urgent, this PR also uses the more general "homogenous aggregate" logic to fix #32045.