avoid unnecessarily requiring alignment for array elem pointers
parent
0512beca9d
commit
8e93991634
39
src/ir.cpp
39
src/ir.cpp
|
@ -16899,12 +16899,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
|
||||||
return ira->codegen->invalid_instruction;
|
return ira->codegen->invalid_instruction;
|
||||||
|
|
||||||
bool safety_check_on = elem_ptr_instruction->safety_check_on;
|
bool safety_check_on = elem_ptr_instruction->safety_check_on;
|
||||||
if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown)))
|
|
||||||
return ira->codegen->invalid_instruction;
|
|
||||||
|
|
||||||
uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type);
|
|
||||||
uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type);
|
|
||||||
uint64_t ptr_align = get_ptr_align(ira->codegen, return_type);
|
|
||||||
if (instr_is_comptime(casted_elem_index)) {
|
if (instr_is_comptime(casted_elem_index)) {
|
||||||
uint64_t index = bigint_as_u64(&casted_elem_index->value.data.x_bigint);
|
uint64_t index = bigint_as_u64(&casted_elem_index->value.data.x_bigint);
|
||||||
if (array_type->id == ZigTypeIdArray) {
|
if (array_type->id == ZigTypeIdArray) {
|
||||||
|
@ -16918,8 +16912,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
|
||||||
safety_check_on = false;
|
safety_check_on = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if (return_type->data.pointer.explicit_alignment != 0) {
|
||||||
// figure out the largest alignment possible
|
// figure out the largest alignment possible
|
||||||
|
|
||||||
|
if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown)))
|
||||||
|
return ira->codegen->invalid_instruction;
|
||||||
|
|
||||||
|
uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type);
|
||||||
|
uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type);
|
||||||
|
uint64_t ptr_align = get_ptr_align(ira->codegen, return_type);
|
||||||
|
|
||||||
uint64_t chosen_align = abi_align;
|
uint64_t chosen_align = abi_align;
|
||||||
if (ptr_align >= abi_align) {
|
if (ptr_align >= abi_align) {
|
||||||
while (ptr_align > abi_align) {
|
while (ptr_align > abi_align) {
|
||||||
|
@ -17148,15 +17150,24 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
|
||||||
case ReqCompTimeNo:
|
case ReqCompTimeNo:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ptr_align < abi_align) {
|
|
||||||
if (elem_size >= ptr_align && elem_size % ptr_align == 0) {
|
if (return_type->data.pointer.explicit_alignment != 0) {
|
||||||
return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align);
|
if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown)))
|
||||||
|
return ira->codegen->invalid_instruction;
|
||||||
|
|
||||||
|
uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type);
|
||||||
|
uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type);
|
||||||
|
uint64_t ptr_align = get_ptr_align(ira->codegen, return_type);
|
||||||
|
if (ptr_align < abi_align) {
|
||||||
|
if (elem_size >= ptr_align && elem_size % ptr_align == 0) {
|
||||||
|
return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align);
|
||||||
|
} else {
|
||||||
|
// can't get here because guaranteed elem_size >= abi_align
|
||||||
|
zig_unreachable();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// can't get here because guaranteed elem_size >= abi_align
|
return_type = adjust_ptr_align(ira->codegen, return_type, abi_align);
|
||||||
zig_unreachable();
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return_type = adjust_ptr_align(ira->codegen, return_type, abi_align);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
std/mem.zig
11
std/mem.zig
|
@ -75,15 +75,16 @@ pub const Allocator = struct {
|
||||||
new_alignment: u29,
|
new_alignment: u29,
|
||||||
) []u8,
|
) []u8,
|
||||||
|
|
||||||
/// Call `destroy` with the result.
|
/// Returns a pointer to undefined memory.
|
||||||
/// Returns undefined memory.
|
/// Call `destroy` with the result to free the memory.
|
||||||
pub fn create(self: *Allocator, comptime T: type) Error!*T {
|
pub fn create(self: *Allocator, comptime T: type) Error!*T {
|
||||||
if (@sizeOf(T) == 0) return &(T{});
|
if (@sizeOf(T) == 0) return &(T{});
|
||||||
const slice = try self.alloc(T, 1);
|
const slice = try self.alloc(T, 1);
|
||||||
return &slice[0];
|
return &slice[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `ptr` should be the return value of `create`
|
/// `ptr` should be the return value of `create`, or otherwise
|
||||||
|
/// have the same address and alignment property.
|
||||||
pub fn destroy(self: *Allocator, ptr: var) void {
|
pub fn destroy(self: *Allocator, ptr: var) void {
|
||||||
const T = @typeOf(ptr).Child;
|
const T = @typeOf(ptr).Child;
|
||||||
if (@sizeOf(T) == 0) return;
|
if (@sizeOf(T) == 0) return;
|
||||||
|
@ -92,7 +93,7 @@ pub const Allocator = struct {
|
||||||
assert(shrink_result.len == 0);
|
assert(shrink_result.len == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc(self: *Allocator, comptime T: type, n: usize) ![]T {
|
pub fn alloc(self: *Allocator, comptime T: type, n: usize) Error![]T {
|
||||||
return self.alignedAlloc(T, @alignOf(T), n);
|
return self.alignedAlloc(T, @alignOf(T), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ pub const Allocator = struct {
|
||||||
comptime T: type,
|
comptime T: type,
|
||||||
comptime alignment: u29,
|
comptime alignment: u29,
|
||||||
n: usize,
|
n: usize,
|
||||||
) ![]align(alignment) T {
|
) Error![]align(alignment) T {
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
return ([*]align(alignment) T)(undefined)[0..0];
|
return ([*]align(alignment) T)(undefined)[0..0];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue