Skip to content

Commit afe5787

Browse files
committed
Auto merge of #111768 - oli-obk:pair_const_llvm, r=cjgillot
Optimize scalar and scalar pair representations loaded from ByRef in llvm in rust-lang/rust#105653 I noticed that we were generating suboptimal LLVM IR if we had a `ConstValue::ByRef` that could be represented by a `ScalarPair`. Before rust-lang/rust#105653 this is probably rare, but after it, every slice will go down this suboptimal code path that requires LLVM to untangle a bunch of indirections and translate static allocations that are only used once to read a scalar pair from.
2 parents d9d12d7 + 80efecf commit afe5787

File tree

2 files changed

+20
-39
lines changed

2 files changed

+20
-39
lines changed

src/common.rs

+19-23
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
use gccjit::LValue;
22
use gccjit::{RValue, Type, ToRValue};
3-
use rustc_codegen_ssa::mir::place::PlaceRef;
43
use rustc_codegen_ssa::traits::{
54
BaseTypeMethods,
65
ConstMethods,
7-
DerivedTypeMethods,
86
MiscMethods,
97
StaticMethods,
108
};
119
use rustc_middle::mir::Mutability;
12-
use rustc_middle::ty::layout::{TyAndLayout, LayoutOf};
10+
use rustc_middle::ty::layout::{LayoutOf};
1311
use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
14-
use rustc_target::abi::{self, HasDataLayout, Pointer, Size};
12+
use rustc_target::abi::{self, HasDataLayout, Pointer};
1513

1614
use crate::consts::const_alloc_to_gcc;
1715
use crate::context::CodegenCx;
@@ -240,28 +238,26 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
240238
const_alloc_to_gcc(self, alloc)
241239
}
242240

243-
fn from_const_alloc(&self, layout: TyAndLayout<'tcx>, alloc: ConstAllocation<'tcx>, offset: Size) -> PlaceRef<'tcx, RValue<'gcc>> {
244-
assert_eq!(alloc.inner().align, layout.align.abi);
245-
let ty = self.type_ptr_to(layout.gcc_type(self));
246-
let value =
247-
if layout.size == Size::ZERO {
248-
let value = self.const_usize(alloc.inner().align.bytes());
249-
self.const_bitcast(value, ty)
250-
}
251-
else {
252-
let init = const_alloc_to_gcc(self, alloc);
253-
let base_addr = self.static_addr_of(init, alloc.inner().align, None);
254-
255-
let array = self.const_bitcast(base_addr, self.type_i8p());
256-
let value = self.context.new_array_access(None, array, self.const_usize(offset.bytes())).get_address(None);
257-
self.const_bitcast(value, ty)
258-
};
259-
PlaceRef::new_sized(value, layout)
260-
}
261-
262241
fn const_ptrcast(&self, val: RValue<'gcc>, ty: Type<'gcc>) -> RValue<'gcc> {
263242
self.context.new_cast(None, val, ty)
264243
}
244+
245+
fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> {
246+
if value.get_type() == self.bool_type.make_pointer() {
247+
if let Some(pointee) = typ.get_pointee() {
248+
if pointee.dyncast_vector().is_some() {
249+
panic!()
250+
}
251+
}
252+
}
253+
// NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some
254+
// SIMD builtins require a constant value.
255+
self.bitcast_if_needed(value, typ)
256+
}
257+
258+
fn const_ptr_byte_offset(&self, base_addr: Self::Value, offset: abi::Size) -> Self::Value {
259+
self.context.new_array_access(None, base_addr, self.const_usize(offset.bytes())).get_address(None)
260+
}
265261
}
266262

267263
pub trait SignType<'gcc, 'tcx> {

src/consts.rs

+1-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#[cfg(feature = "master")]
22
use gccjit::FnAttribute;
3-
use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue, Type};
3+
use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue};
44
use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, DerivedTypeMethods, StaticMethods};
55
use rustc_middle::span_bug;
66
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
@@ -16,21 +16,6 @@ use crate::context::CodegenCx;
1616
use crate::errors::InvalidMinimumAlignment;
1717
use crate::type_of::LayoutGccExt;
1818

19-
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
20-
pub fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> {
21-
if value.get_type() == self.bool_type.make_pointer() {
22-
if let Some(pointee) = typ.get_pointee() {
23-
if pointee.dyncast_vector().is_some() {
24-
panic!()
25-
}
26-
}
27-
}
28-
// NOTE: since bitcast makes a value non-constant, don't bitcast if not necessary as some
29-
// SIMD builtins require a constant value.
30-
self.bitcast_if_needed(value, typ)
31-
}
32-
}
33-
3419
fn set_global_alignment<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, gv: LValue<'gcc>, mut align: Align) {
3520
// The target may require greater alignment for globals than the type does.
3621
// Note: GCC and Clang also allow `__attribute__((aligned))` on variables,

0 commit comments

Comments
 (0)