authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-29 16:25:24-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-29 16:25:58-04:00
log8e939916347888e755d737c579042b034e215aa8
tree7f6d6498c35a53ab1818c62d4716cf3e47263d6e
parent0512beca9d694a667e3ad12a656835b44457fbcd
signaturelock-open Commit is signed but in an unrecognized format.

avoid unnecessarily requiring alignment for array elem pointers


2 files changed, 31 insertions(+), 19 deletions(-)

src/ir.cpp+25-14
......@@ -16899,12 +16899,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1689916899 return ira->codegen->invalid_instruction;
1690016900
1690116901 bool safety_check_on = elem_ptr_instruction->safety_check_on;
16902 if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown)))
16903 return ira->codegen->invalid_instruction;
16904
16905 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type);
16906 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type);
16907 uint64_t ptr_align = get_ptr_align(ira->codegen, return_type);
1690816902 if (instr_is_comptime(casted_elem_index)) {
1690916903 uint64_t index = bigint_as_u64(&casted_elem_index->value.data.x_bigint);
1691016904 if (array_type->id == ZigTypeIdArray) {
......@@ -16918,8 +16912,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1691816912 safety_check_on = false;
1691916913 }
1692016914
16921 {
16915 if (return_type->data.pointer.explicit_alignment != 0) {
1692216916 // figure out the largest alignment possible
16917
16918 if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown)))
16919 return ira->codegen->invalid_instruction;
16920
16921 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type);
16922 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type);
16923 uint64_t ptr_align = get_ptr_align(ira->codegen, return_type);
16924
1692316925 uint64_t chosen_align = abi_align;
1692416926 if (ptr_align >= abi_align) {
1692516927 while (ptr_align > abi_align) {
......@@ -17148,15 +17150,24 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1714817150 case ReqCompTimeNo:
1714917151 break;
1715017152 }
17151 if (ptr_align < abi_align) {
17152 if (elem_size >= ptr_align && elem_size % ptr_align == 0) {
17153 return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align);
17153
17154 if (return_type->data.pointer.explicit_alignment != 0) {
17155 if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown)))
17156 return ira->codegen->invalid_instruction;
17157
17158 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type);
17159 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type);
17160 uint64_t ptr_align = get_ptr_align(ira->codegen, return_type);
17161 if (ptr_align < abi_align) {
17162 if (elem_size >= ptr_align && elem_size % ptr_align == 0) {
17163 return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align);
17164 } else {
17165 // can't get here because guaranteed elem_size >= abi_align
17166 zig_unreachable();
17167 }
1715417168 } else {
17155 // can't get here because guaranteed elem_size >= abi_align
17156 zig_unreachable();
17169 return_type = adjust_ptr_align(ira->codegen, return_type, abi_align);
1715717170 }
17158 } else {
17159 return_type = adjust_ptr_align(ira->codegen, return_type, abi_align);
1716017171 }
1716117172 }
1716217173
std/mem.zig+6-5
......@@ -75,15 +75,16 @@ pub const Allocator = struct {
7575 new_alignment: u29,
7676 ) []u8,
7777
78 /// Call `destroy` with the result.
79 /// Returns undefined memory.
78 /// Returns a pointer to undefined memory.
79 /// Call `destroy` with the result to free the memory.
8080 pub fn create(self: *Allocator, comptime T: type) Error!*T {
8181 if (@sizeOf(T) == 0) return &(T{});
8282 const slice = try self.alloc(T, 1);
8383 return &slice[0];
8484 }
8585
86 /// `ptr` should be the return value of `create`
86 /// `ptr` should be the return value of `create`, or otherwise
87 /// have the same address and alignment property.
8788 pub fn destroy(self: *Allocator, ptr: var) void {
8889 const T = @typeOf(ptr).Child;
8990 if (@sizeOf(T) == 0) return;
......@@ -92,7 +93,7 @@ pub const Allocator = struct {
9293 assert(shrink_result.len == 0);
9394 }
9495
95 pub fn alloc(self: *Allocator, comptime T: type, n: usize) ![]T {
96 pub fn alloc(self: *Allocator, comptime T: type, n: usize) Error![]T {
9697 return self.alignedAlloc(T, @alignOf(T), n);
9798 }
9899
......@@ -101,7 +102,7 @@ pub const Allocator = struct {
101102 comptime T: type,
102103 comptime alignment: u29,
103104 n: usize,
104 ) ![]align(alignment) T {
105 ) Error![]align(alignment) T {
105106 if (n == 0) {
106107 return ([*]align(alignment) T)(undefined)[0..0];
107108 }