avoid unnecessarily requiring alignment for array elem pointers

master
Andrew Kelley 2019-08-29 16:25:24 -04:00
parent 0512beca9d
commit 8e93991634
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
2 changed files with 31 additions and 19 deletions

View File

@ -16899,12 +16899,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
return ira->codegen->invalid_instruction;
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)) {
uint64_t index = bigint_as_u64(&casted_elem_index->value.data.x_bigint);
if (array_type->id == ZigTypeIdArray) {
@ -16918,8 +16912,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
safety_check_on = false;
}
{
if (return_type->data.pointer.explicit_alignment != 0) {
// 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;
if (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:
break;
}
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);
if (return_type->data.pointer.explicit_alignment != 0) {
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 {
// can't get here because guaranteed elem_size >= abi_align
zig_unreachable();
return_type = adjust_ptr_align(ira->codegen, return_type, abi_align);
}
} else {
return_type = adjust_ptr_align(ira->codegen, return_type, abi_align);
}
}

View File

@ -75,15 +75,16 @@ pub const Allocator = struct {
new_alignment: u29,
) []u8,
/// Call `destroy` with the result.
/// Returns undefined memory.
/// Returns a pointer to undefined memory.
/// Call `destroy` with the result to free the memory.
pub fn create(self: *Allocator, comptime T: type) Error!*T {
if (@sizeOf(T) == 0) return &(T{});
const slice = try self.alloc(T, 1);
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 {
const T = @typeOf(ptr).Child;
if (@sizeOf(T) == 0) return;
@ -92,7 +93,7 @@ pub const Allocator = struct {
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);
}
@ -101,7 +102,7 @@ pub const Allocator = struct {
comptime T: type,
comptime alignment: u29,
n: usize,
) ![]align(alignment) T {
) Error![]align(alignment) T {
if (n == 0) {
return ([*]align(alignment) T)(undefined)[0..0];
}