8000 Skip needless calls to get_align in some cases. · rust-lang/rustc_codegen_gcc@25e16c8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 25e16c8

Browse files
committed
Skip needless calls to get_align in some cases.
1 parent 962a08f commit 25e16c8

File tree

2 files changed

+27
-13
lines changed

2 files changed

+27
-13
lines changed

src/builder.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -938,22 +938,29 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
938938
fn load(&mut self, pointee_ty: Type<'gcc>, ptr: RValue<'gcc>, align: Align) -> RValue<'gcc> {
939939
let block = self.llbb();
940940
let function = block.get_function();
941+
// FractalFir: In some cases, we *should* skip the call to get_aligned.
942+
// For example, calling `get_aligned` on a i8 is pointless(since it can only be 1 aligned)
943+
// Calling get_aligned on a `u128`/`i128` leads to issues(TODO: ask Anton what *kind* of issues,
944+
// describe them in detail).
945+
// So, we skip the call to `get_aligned` in such a case. *Ideally*, we could do this for all the types,
946+
// but the GCC APIs to facilitate this just aren't quite there yet.
947+
948+
// This checks that we only skip `get_aligned` on 128 bit ints if they have the correct alignment.
949+
// Otherwise, this may be an under-aligned load, so we will still call get_aligned.
950+
let mut can_skip_align = (pointee_ty == self.cx.u128_type
951+
|| pointee_ty == self.cx.i128_type)
952+
&& align == self.int128_align;
953+
// We can skip the call to `get_aligned` for byte-sized types with alignment of 1.
954+
can_skip_align |=
955+
(pointee_ty == self.cx.u8_type || pointee_ty == self.cx.i8_type) && align.bytes() == 1;
956+
// Skip the call to `get_aligned` when possible.
957+
let aligned_type =
958+
if can_skip_align { pointee_ty } else { pointee_ty.get_aligned(align.bytes()) };
959+
960+
let ptr = self.context.new_cast(self.location, ptr, aligned_type.make_pointer());
941961
// NOTE: instead of returning the dereference here, we have to assign it to a variable in
942962
// the current basic block. Otherwise, it could be used in another basic block, causing a
943963
// dereference after a drop, for instance.
944-
// FIXME(antoyo): this check that we don't call get_aligned() a second time on a type.
945-
// Ideally, we shouldn't need to do this check.
946-
// FractalFir: the `align == self.int128_align` check ensures we *do* call `get_aligned` if
947-
// the alignment of a `u128`/`i128` is not the one mandated by the ABI. This ensures we handle
948-
// under-aligned loads correctly.
949-
let aligned_type = if (pointee_ty == self.cx.u128_type || pointee_ty == self.cx.i128_type)
950-
&& align == self.int128_align
951-
{
952-
pointee_ty
953-
} else {
954-
pointee_ty.get_aligned(align.bytes())
955-
};
956-
let ptr = self.context.new_cast(self.location, ptr, aligned_type.make_pointer());
957964
let deref = ptr.dereference(self.location).to_rvalue();
958965
let loaded_value = function.new_local(
959966
self.location,

src/context.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,13 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
157157
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(rust_type))
158158
.unwrap();
159159
let align = layout.align.abi.bytes();
160+
// For types with size 1, the alignment can be 1 and only 1
161+
// So, we can skip the call to ``get_aligned`.
162+
// In the future, we can add a GCC API to query the type align,
163+
// and call `get_aligned` if and only if that differs from Rust's expectations.
164+
if layout.size.bytes() == 1 {
165+
return context.new_c_type(ctype);
166+
}
160167
#[cfg(feature = "master")]
161168
{
162169
context.new_c_type(ctype).get_aligned(align)

0 commit comments

Comments
 (0)
0