Avoid wrapping constant allocations in packed structs when not necessary

This way LLVM will set the string merging flag if the alloc is a nul
terminated string, reducing binary sizes.
This commit is contained in:
bjorn3 2025-03-14 15:56:33 +00:00
parent f7b4354283
commit a5fa12b6b9
8 changed files with 26 additions and 25 deletions

View File

@ -364,6 +364,7 @@ pub fn const_alloc_to_gcc<'gcc>(
llvals.push(cx.const_bytes(bytes));
}
// FIXME(bjorn3) avoid wrapping in a struct when there is only a single element.
cx.const_struct(&llvals, true)
}

View File

@ -128,7 +128,7 @@ pub(crate) fn const_alloc_to_llvm<'ll>(
append_chunks_of_init_and_uninit_bytes(&mut llvals, cx, alloc, range);
}
cx.const_struct(&llvals, true)
if let &[data] = &*llvals { data } else { cx.const_struct(&llvals, true) }
}
fn codegen_static_initializer<'ll, 'tcx>(

View File

@ -2,7 +2,7 @@
#![crate_type = "lib"]
const LUT: [u8; 2] = [1, 1];
const LUT: [u8; 4] = [1, 1, 1, 1];
// CHECK-LABEL: @decode
#[no_mangle]
@ -11,5 +11,5 @@ pub fn decode(i: u8) -> u8 {
// CHECK-NEXT: icmp
// CHECK-NEXT: select
// CHECK-NEXT: ret
if i < 2 { LUT[i as usize] } else { 2 }
if i < 4 { LUT[i as usize] } else { 2 }
}

View File

@ -15,7 +15,7 @@
// Make sure that vtables don't have the unnamed_addr attribute when debuginfo is enabled.
// This helps debuggers more reliably map from dyn pointer to concrete type.
// CHECK: @vtable.2 = private constant <{
// CHECK: @vtable.2 = private constant [
// CHECK: @vtable.3 = private constant <{
// CHECK: @vtable.4 = private constant <{

View File

@ -6,72 +6,72 @@
// `#[no_mangle]`d static variables always have external linkage, i.e., no `internal` in their
// definitions
// CHECK: @A = {{(dso_local )?}}local_unnamed_addr constant
// CHECK-DAG: @A = {{(dso_local )?}}local_unnamed_addr constant
#[no_mangle]
static A: u8 = 0;
// CHECK: @B = {{(dso_local )?}}local_unnamed_addr global
// CHECK-DAG: @B = {{(dso_local )?}}local_unnamed_addr global
#[no_mangle]
static mut B: u8 = 0;
// CHECK: @C = {{(dso_local )?}}local_unnamed_addr constant
// CHECK-DAG: @C = {{(dso_local )?}}local_unnamed_addr constant
#[no_mangle]
pub static C: u8 = 0;
// CHECK: @D = {{(dso_local )?}}local_unnamed_addr global
// CHECK-DAG: @D = {{(dso_local )?}}local_unnamed_addr global
#[no_mangle]
pub static mut D: u8 = 0;
mod private {
// CHECK: @E = {{(dso_local )?}}local_unnamed_addr constant
// CHECK-DAG: @E = {{(dso_local )?}}local_unnamed_addr constant
#[no_mangle]
static E: u8 = 0;
// CHECK: @F = {{(dso_local )?}}local_unnamed_addr global
// CHECK-DAG: @F = {{(dso_local )?}}local_unnamed_addr global
#[no_mangle]
static mut F: u8 = 0;
// CHECK: @G = {{(dso_local )?}}local_unnamed_addr constant
// CHECK-DAG: @G = {{(dso_local )?}}local_unnamed_addr constant
#[no_mangle]
pub static G: u8 = 0;
// CHECK: @H = {{(dso_local )?}}local_unnamed_addr global
// CHECK-DAG: @H = {{(dso_local )?}}local_unnamed_addr global
#[no_mangle]
pub static mut H: u8 = 0;
}
const HIDDEN: () = {
// CHECK: @I = {{(dso_local )?}}local_unnamed_addr constant
// CHECK-DAG: @I = {{(dso_local )?}}local_unnamed_addr constant
#[no_mangle]
static I: u8 = 0;
// CHECK: @J = {{(dso_local )?}}local_unnamed_addr global
// CHECK-DAG: @J = {{(dso_local )?}}local_unnamed_addr global
#[no_mangle]
static mut J: u8 = 0;
// CHECK: @K = {{(dso_local )?}}local_unnamed_addr constant
// CHECK-DAG: @K = {{(dso_local )?}}local_unnamed_addr constant
#[no_mangle]
pub static K: u8 = 0;
// CHECK: @L = {{(dso_local )?}}local_unnamed_addr global
// CHECK-DAG: @L = {{(dso_local )?}}local_unnamed_addr global
#[no_mangle]
pub static mut L: u8 = 0;
};
fn x() {
// CHECK: @M = {{(dso_local )?}}local_unnamed_addr constant
// CHECK-DAG: @M = {{(dso_local )?}}local_unnamed_addr constant
#[no_mangle]
static M: fn() = x;
// CHECK: @N = {{(dso_local )?}}local_unnamed_addr global
// CHECK-DAG: @N = {{(dso_local )?}}local_unnamed_addr global
#[no_mangle]
static mut N: u8 = 0;
// CHECK: @O = {{(dso_local )?}}local_unnamed_addr constant
// CHECK-DAG: @O = {{(dso_local )?}}local_unnamed_addr constant
#[no_mangle]
pub static O: u8 = 0;
// CHECK: @P = {{(dso_local )?}}local_unnamed_addr global
// CHECK-DAG: @P = {{(dso_local )?}}local_unnamed_addr global
#[no_mangle]
pub static mut P: u8 = 0;
}

View File

@ -3,7 +3,7 @@
#![crate_type = "lib"]
// CHECK: @VAR1 = {{(dso_local )?}}constant <{ [4 x i8] }> <{ [4 x i8] c"\01\00\00\00" }>, section ".test_one"
// CHECK: @VAR1 = {{(dso_local )?}}constant [4 x i8] c"\01\00\00\00", section ".test_one"
#[no_mangle]
#[link_section = ".test_one"]
#[cfg(target_endian = "little")]

View File

@ -12,7 +12,7 @@ mod aux_mod;
include!("aux_mod.rs");
// Here we check that the expansion of the file!() macro is mapped.
// CHECK: @alloc_5761061597a97f66e13ef2ff92712c4b = private unnamed_addr constant <{ [34 x i8] }> <{ [34 x i8] c"/the/src/remap_path_prefix/main.rs" }>
// CHECK: @alloc_5761061597a97f66e13ef2ff92712c4b = private unnamed_addr constant [34 x i8] c"/the/src/remap_path_prefix/main.rs"
pub static FILE_PATH: &'static str = file!();
fn main() {

View File

@ -11,15 +11,15 @@ pub struct PartiallyUninit {
y: MaybeUninit<[u8; 10]>,
}
// CHECK: [[FULLY_UNINIT:@.*]] = private unnamed_addr constant <{ [10 x i8] }> undef
// CHECK: [[FULLY_UNINIT:@.*]] = private unnamed_addr constant [10 x i8] undef
// CHECK: [[PARTIALLY_UNINIT:@.*]] = private unnamed_addr constant <{ [4 x i8], [12 x i8] }> <{ [4 x i8] c"{{\\EF\\BE\\AD\\DE|\\DE\\AD\\BE\\EF}}", [12 x i8] undef }>, align 4
// This shouldn't contain undef, since it contains more chunks
// than the default value of uninit_const_chunk_threshold.
// CHECK: [[UNINIT_PADDING_HUGE:@.*]] = private unnamed_addr constant <{ [32768 x i8] }> <{ [32768 x i8] c"{{.+}}" }>, align 4
// CHECK: [[UNINIT_PADDING_HUGE:@.*]] = private unnamed_addr constant [32768 x i8] c"{{.+}}", align 4
// CHECK: [[FULLY_UNINIT_HUGE:@.*]] = private unnamed_addr constant <{ [16384 x i8] }> undef
// CHECK: [[FULLY_UNINIT_HUGE:@.*]] = private unnamed_addr constant [16384 x i8] undef
// CHECK-LABEL: @fully_uninit
#[no_mangle]