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...@@ -16899,12 +16899,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
16899 return ira->codegen->invalid_instruction;16899 return ira->codegen->invalid_instruction;
1690016900
16901 bool safety_check_on = elem_ptr_instruction->safety_check_on;16901 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);
16908 if (instr_is_comptime(casted_elem_index)) {16902 if (instr_is_comptime(casted_elem_index)) {
16909 uint64_t index = bigint_as_u64(&casted_elem_index->value.data.x_bigint);16903 uint64_t index = bigint_as_u64(&casted_elem_index->value.data.x_bigint);
16910 if (array_type->id == ZigTypeIdArray) {16904 if (array_type->id == ZigTypeIdArray) {
...@@ -16918,8 +16912,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -16918,8 +16912,16 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
16918 safety_check_on = false;16912 safety_check_on = false;
16919 }16913 }
1692016914
16921 {16915 if (return_type->data.pointer.explicit_alignment != 0) {
16922 // figure out the largest alignment possible16916 // 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
16923 uint64_t chosen_align = abi_align;16925 uint64_t chosen_align = abi_align;
16924 if (ptr_align >= abi_align) {16926 if (ptr_align >= abi_align) {
16925 while (ptr_align > abi_align) {16927 while (ptr_align > abi_align) {
...@@ -17148,15 +17150,24 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17148,15 +17150,24 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17148 case ReqCompTimeNo:17150 case ReqCompTimeNo:
17149 break;17151 break;
17150 }17152 }
17151 if (ptr_align < abi_align) {17153
17152 if (elem_size >= ptr_align && elem_size % ptr_align == 0) {17154 if (return_type->data.pointer.explicit_alignment != 0) {
17153 return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align);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 }
17154 } else {17168 } else {
17155 // can't get here because guaranteed elem_size >= abi_align17169 return_type = adjust_ptr_align(ira->codegen, return_type, abi_align);
17156 zig_unreachable();
17157 }17170 }
17158 } else {
17159 return_type = adjust_ptr_align(ira->codegen, return_type, abi_align);
17160 }17171 }
17161 }17172 }
1716217173
std/mem.zig+6-5
...@@ -75,15 +75,16 @@ pub const Allocator = struct {...@@ -75,15 +75,16 @@ pub const Allocator = struct {
75 new_alignment: u29,75 new_alignment: u29,
76 ) []u8,76 ) []u8,
7777
78 /// Call `destroy` with the result.78 /// Returns a pointer to undefined memory.
79 /// Returns undefined memory.79 /// Call `destroy` with the result to free the memory.
80 pub fn create(self: *Allocator, comptime T: type) Error!*T {80 pub fn create(self: *Allocator, comptime T: type) Error!*T {
81 if (@sizeOf(T) == 0) return &(T{});81 if (@sizeOf(T) == 0) return &(T{});
82 const slice = try self.alloc(T, 1);82 const slice = try self.alloc(T, 1);
83 return &slice[0];83 return &slice[0];
84 }84 }
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.
87 pub fn destroy(self: *Allocator, ptr: var) void {88 pub fn destroy(self: *Allocator, ptr: var) void {
88 const T = @typeOf(ptr).Child;89 const T = @typeOf(ptr).Child;
89 if (@sizeOf(T) == 0) return;90 if (@sizeOf(T) == 0) return;
...@@ -92,7 +93,7 @@ pub const Allocator = struct {...@@ -92,7 +93,7 @@ pub const Allocator = struct {
92 assert(shrink_result.len == 0);93 assert(shrink_result.len == 0);
93 }94 }
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 {
96 return self.alignedAlloc(T, @alignOf(T), n);97 return self.alignedAlloc(T, @alignOf(T), n);
97 }98 }
9899
...@@ -101,7 +102,7 @@ pub const Allocator = struct {...@@ -101,7 +102,7 @@ pub const Allocator = struct {
101 comptime T: type,102 comptime T: type,
102 comptime alignment: u29,103 comptime alignment: u29,
103 n: usize,104 n: usize,
104 ) ![]align(alignment) T {105 ) Error![]align(alignment) T {
105 if (n == 0) {106 if (n == 0) {
106 return ([*]align(alignment) T)(undefined)[0..0];107 return ([*]align(alignment) T)(undefined)[0..0];
107 }108 }