| ... | @@ -14,87 +14,163 @@ const Mir = @import("Mir.zig"); | ... | @@ -14,87 +14,163 @@ const Mir = @import("Mir.zig"); |
| 14 | air: Air, | 14 | air: Air, |
| 15 | liveness: Liveness, | 15 | liveness: Liveness, |
| 16 | gpa: Allocator, | 16 | gpa: Allocator, |
| 17 | spork8: *Spork8, | | |
| 18 | pt: Zcu.PerThread, | 17 | pt: Zcu.PerThread, |
| 19 | owner_nav: InternPool.Nav.Index, | 18 | owner_nav: InternPool.Nav.Index, |
| 20 | func_index: InternPool.Index, | 19 | func_index: InternPool.Index, |
| 21 | mir_instructions: *std.MultiArrayList(Mir.Inst), | 20 | mir_instructions: std.MultiArrayList(Mir.Inst), |
| 22 | /// Contains extra data for MIR | 21 | /// Contains extra data for MIR |
| 23 | mir_extra: *std.ArrayListUnmanaged(u32), | 22 | mir_extra: std.ArrayListUnmanaged(u32), |
| 24 | start_mir_extra_off: u32, | 23 | |
| 25 | | 24 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { |
| 26 | pub const Error = error{ | 25 | return comptime &.initMany(&.{ |
| 27 | OutOfMemory, | 26 | .expand_bit_cast_safe, |
| 28 | /// Compiler was asked to operate on a number larger than supported. | 27 | .expand_int_cast_safe, |
| 29 | Overflow, | 28 | .expand_int_from_float_safe, |
| 30 | /// Indicates the error is already stored in Zcu `failed_codegen`. | 29 | .expand_int_from_float_optimized_safe, |
| 31 | CodegenFail, | 30 | .expand_add_safe, |
| 32 | }; | 31 | .expand_sub_safe, |
| 33 | | 32 | .expand_mul_safe, |
| 34 | pub const Function = extern struct { | 33 | |
| 35 | /// Index into `Spork8.mir_instructions`. | 34 | .expand_packed_load, |
| 36 | mir_off: u32, | 35 | .expand_packed_store, |
| 37 | /// This is unused except for as a safety slice bound and could be removed. | 36 | .expand_packed_agg_field_val, |
| 38 | mir_len: u32, | 37 | .expand_packed_aggregate_init, |
| 39 | /// Index into `Spork8.mir_extra`. | 38 | .expand_array_to_vector, |
| 40 | mir_extra_off: u32, | 39 | |
| 41 | /// This is unused except for as a safety slice bound and could be removed. | 40 | .scalarize_add, |
| 42 | mir_extra_len: u32, | 41 | .scalarize_add_optimized, |
| 43 | }; | 42 | .scalarize_add_wrap, |
| | 43 | .scalarize_add_sat, |
| | 44 | .scalarize_sub, |
| | 45 | .scalarize_sub_optimized, |
| | 46 | .scalarize_sub_wrap, |
| | 47 | .scalarize_sub_sat, |
| | 48 | .scalarize_mul, |
| | 49 | .scalarize_mul_optimized, |
| | 50 | .scalarize_mul_wrap, |
| | 51 | .scalarize_mul_sat, |
| | 52 | .scalarize_div_float, |
| | 53 | .scalarize_div_float_optimized, |
| | 54 | .scalarize_div_trunc, |
| | 55 | .scalarize_div_trunc_optimized, |
| | 56 | .scalarize_div_floor, |
| | 57 | .scalarize_div_floor_optimized, |
| | 58 | .scalarize_div_ceil, |
| | 59 | .scalarize_div_ceil_optimized, |
| | 60 | .scalarize_div_exact, |
| | 61 | .scalarize_div_exact_optimized, |
| | 62 | .scalarize_rem, |
| | 63 | .scalarize_rem_optimized, |
| | 64 | .scalarize_mod, |
| | 65 | .scalarize_mod_optimized, |
| | 66 | .scalarize_max, |
| | 67 | .scalarize_min, |
| | 68 | .scalarize_add_with_overflow, |
| | 69 | .scalarize_sub_with_overflow, |
| | 70 | .scalarize_mul_with_overflow, |
| | 71 | .scalarize_shl_with_overflow, |
| | 72 | .scalarize_bit_and, |
| | 73 | .scalarize_bit_or, |
| | 74 | .scalarize_shr, |
| | 75 | .scalarize_shr_exact, |
| | 76 | .scalarize_shl, |
| | 77 | .scalarize_shl_exact, |
| | 78 | .scalarize_shl_sat, |
| | 79 | .scalarize_xor, |
| | 80 | .scalarize_not, |
| | 81 | .scalarize_clz, |
| | 82 | .scalarize_ctz, |
| | 83 | .scalarize_popcount, |
| | 84 | .scalarize_byte_swap, |
| | 85 | .scalarize_bit_reverse, |
| | 86 | .scalarize_sqrt, |
| | 87 | .scalarize_sin, |
| | 88 | .scalarize_cos, |
| | 89 | .scalarize_tan, |
| | 90 | .scalarize_exp, |
| | 91 | .scalarize_exp2, |
| | 92 | .scalarize_log, |
| | 93 | .scalarize_log2, |
| | 94 | .scalarize_log10, |
| | 95 | .scalarize_abs, |
| | 96 | .scalarize_floor, |
| | 97 | .scalarize_ceil, |
| | 98 | .scalarize_round, |
| | 99 | .scalarize_trunc_float, |
| | 100 | .scalarize_neg, |
| | 101 | .scalarize_neg_optimized, |
| | 102 | .scalarize_cmp_vector, |
| | 103 | .scalarize_cmp_vector_optimized, |
| | 104 | .scalarize_fptrunc, |
| | 105 | .scalarize_fpext, |
| | 106 | .scalarize_int_cast, |
| | 107 | .scalarize_ptr_cast, |
| | 108 | .scalarize_ptr_from_int, |
| | 109 | .scalarize_int_from_ptr, |
| | 110 | .scalarize_trunc, |
| | 111 | .scalarize_int_from_float, |
| | 112 | .scalarize_int_from_float_optimized, |
| | 113 | .scalarize_float_from_int, |
| | 114 | .scalarize_reduce, |
| | 115 | .scalarize_reduce_optimized, |
| | 116 | .scalarize_shuffle_one, |
| | 117 | .scalarize_shuffle_two, |
| | 118 | .scalarize_select, |
| | 119 | .scalarize_mul_add, |
| | 120 | |
| | 121 | .scalarize_bit_cast_padded_elems, |
| | 122 | }); |
| | 123 | } |
| 44 | | 124 | |
| 45 | pub fn function( | 125 | pub fn generate( |
| 46 | spork8: *Spork8, | 126 | bin_file: *link.File, |
| 47 | pt: Zcu.PerThread, | 127 | pt: Zcu.PerThread, |
| 48 | func_index: InternPool.Index, | 128 | func_index: InternPool.Index, |
| 49 | air: Air, | 129 | air: *const Air, |
| 50 | liveness: Liveness, | 130 | liveness: *const ?Air.Liveness, |
| 51 | ) Error!Function { | 131 | ) link.Error!Mir { |
| | 132 | _ = bin_file; |
| 52 | const zcu = pt.zcu; | 133 | const zcu = pt.zcu; |
| 53 | const gpa = zcu.gpa; | 134 | const gpa = zcu.gpa; |
| 54 | const func_info = zcu.funcInfo(func_index); | 135 | const cg = zcu.funcInfo(func_index); |
| 55 | | 136 | |
| 56 | var code_gen: CodeGen = .{ | 137 | var code_gen: CodeGen = .{ |
| 57 | .gpa = gpa, | 138 | .gpa = gpa, |
| 58 | .pt = pt, | 139 | .pt = pt, |
| 59 | .air = air, | 140 | .air = air.*, |
| 60 | .liveness = liveness, | 141 | .liveness = liveness.*.?, |
| 61 | .owner_nav = func_info.owner_nav, | 142 | .owner_nav = cg.owner_nav, |
| 62 | .spork8 = spork8, | | |
| 63 | .func_index = func_index, | 143 | .func_index = func_index, |
| 64 | .mir_instructions = &spork8.mir_instructions, | 144 | .mir_instructions = .empty, |
| 65 | .mir_extra = &spork8.mir_extra, | 145 | .mir_extra = .empty, |
| 66 | .start_mir_extra_off = @intCast(spork8.mir_extra.items.len), | | |
| 67 | }; | 146 | }; |
| 68 | defer code_gen.deinit(); | 147 | defer code_gen.deinit(); |
| 69 | | 148 | |
| 70 | return functionInner(&code_gen) catch |err| switch (err) { | 149 | return generateInner(&code_gen) catch |err| switch (err) { |
| 71 | error.CodegenFail => return error.CodegenFail, | 150 | error.AlreadyReported, |
| 72 | else => |e| return code_gen.fail("failed to generate function: {s}", .{@errorName(e)}), | 151 | error.OutOfMemory, |
| | 152 | => |e| return e, |
| 73 | }; | 153 | }; |
| 74 | } | 154 | } |
| 75 | | 155 | |
| 76 | fn deinit(cg: *CodeGen) void { | 156 | pub fn deinit(cg: *CodeGen) void { |
| 77 | cg.* = undefined; | 157 | cg.* = undefined; |
| 78 | } | 158 | } |
| 79 | | 159 | |
| 80 | const InnerError = error{ | 160 | const InnerError = error{ |
| 81 | CodegenFail, | 161 | AlreadyReported, |
| 82 | OutOfMemory, | 162 | OutOfMemory, |
| 83 | }; | 163 | }; |
| 84 | | 164 | |
| 85 | fn functionInner(cg: *CodeGen) InnerError!Function { | 165 | fn generateInner(cg: *CodeGen) InnerError!Mir { |
| 86 | const spork8 = cg.spork8; | | |
| 87 | | | |
| 88 | const start_mir_off: u32 = @intCast(spork8.mir_instructions.len); | | |
| 89 | | | |
| 90 | // Generate MIR for function body | 166 | // Generate MIR for function body |
| 91 | try cg.genBody(cg.air.getMainBody()); | 167 | try cg.genBody(cg.air.getMainBody()); |
| 92 | | 168 | |
| | 169 | try cg.mir_extra.shrinkToLen(cg.gpa); |
| | 170 | |
| 93 | return .{ | 171 | return .{ |
| 94 | .mir_off = start_mir_off, | 172 | .instructions = cg.mir_instructions.toOwnedSlice(), |
| 95 | .mir_len = @intCast(spork8.mir_instructions.len - start_mir_off), | 173 | .extra = cg.mir_extra.toOwnedSliceAssert(), |
| 96 | .mir_extra_off = cg.start_mir_extra_off, | | |
| 97 | .mir_extra_len = cg.extraLen(), | | |
| 98 | }; | 174 | }; |
| 99 | } | 175 | } |
| 100 | | 176 | |
| ... | @@ -130,8 +206,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -130,8 +206,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 130 | .div_floor, | 206 | .div_floor, |
| 131 | .bit_and, | 207 | .bit_and, |
| 132 | .bit_or, | 208 | .bit_or, |
| 133 | .bool_and, | | |
| 134 | .bool_or, | | |
| 135 | .rem, | 209 | .rem, |
| 136 | .mod, | 210 | .mod, |
| 137 | .shl, | 211 | .shl, |
| ... | @@ -177,13 +251,11 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -177,13 +251,11 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 177 | .cmp_neq, | 251 | .cmp_neq, |
| 178 | | 252 | |
| 179 | .cmp_vector, | 253 | .cmp_vector, |
| 180 | .cmp_lt_errors_len, | | |
| 181 | | 254 | |
| 182 | .array_elem_val, | 255 | .array_elem_val, |
| 183 | .array_to_slice, | 256 | .array_to_slice, |
| 184 | .alloc, | 257 | .alloc, |
| 185 | .arg, | 258 | .arg, |
| 186 | .bitcast, | | |
| 187 | .block, | 259 | .block, |
| 188 | .trap, | 260 | .trap, |
| 189 | .breakpoint, | 261 | .breakpoint, |
| ... | @@ -191,7 +263,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -191,7 +263,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 191 | .repeat, | 263 | .repeat, |
| 192 | .switch_dispatch, | 264 | .switch_dispatch, |
| 193 | .cond_br, | 265 | .cond_br, |
| 194 | .intcast, | | |
| 195 | .fptrunc, | 266 | .fptrunc, |
| 196 | .fpext, | 267 | .fpext, |
| 197 | .int_from_float, | 268 | .int_from_float, |
| ... | @@ -241,7 +312,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -241,7 +312,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 241 | .ret_load, | 312 | .ret_load, |
| 242 | .splat, | 313 | .splat, |
| 243 | .select, | 314 | .select, |
| 244 | .shuffle, | | |
| 245 | .reduce, | 315 | .reduce, |
| 246 | .aggregate_init, | 316 | .aggregate_init, |
| 247 | .union_init, | 317 | .union_init, |
| ... | @@ -266,7 +336,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -266,7 +336,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 266 | .struct_field_ptr_index_1, | 336 | .struct_field_ptr_index_1, |
| 267 | .struct_field_ptr_index_2, | 337 | .struct_field_ptr_index_2, |
| 268 | .struct_field_ptr_index_3, | 338 | .struct_field_ptr_index_3, |
| 269 | .struct_field_val, | | |
| 270 | .field_parent_ptr, | 339 | .field_parent_ptr, |
| 271 | | 340 | |
| 272 | .switch_br, | 341 | .switch_br, |
| ... | @@ -303,7 +372,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -303,7 +372,6 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 303 | .save_err_return_trace_index, | 372 | .save_err_return_trace_index, |
| 304 | .is_named_enum_value, | 373 | .is_named_enum_value, |
| 305 | .addrspace_cast, | 374 | .addrspace_cast, |
| 306 | .vector_store_elem, | | |
| 307 | .c_va_arg, | 375 | .c_va_arg, |
| 308 | .c_va_copy, | 376 | .c_va_copy, |
| 309 | .c_va_end, | 377 | .c_va_end, |
| ... | @@ -341,7 +409,31 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -341,7 +409,31 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 341 | .add_safe, | 409 | .add_safe, |
| 342 | .sub_safe, | 410 | .sub_safe, |
| 343 | .mul_safe, | 411 | .mul_safe, |
| 344 | .intcast_safe, | 412 | .div_ceil, |
| | 413 | .div_ceil_optimized, |
| | 414 | .bit_cast, |
| | 415 | .bit_cast_safe, |
| | 416 | .ptr_cast, |
| | 417 | .ptr_from_int, |
| | 418 | .int_from_ptr, |
| | 419 | .error_cast, |
| | 420 | .error_from_int, |
| | 421 | .int_from_error, |
| | 422 | .union_from_enum, |
| | 423 | .int_cast, |
| | 424 | .int_cast_safe, |
| | 425 | .agg_field_val, |
| | 426 | .array_to_vector, |
| | 427 | .int_from_float_safe, |
| | 428 | .int_from_float_optimized_safe, |
| | 429 | .shuffle_one, |
| | 430 | .shuffle_two, |
| | 431 | .cmp_lte_errors_len, |
| | 432 | .runtime_nav_ptr, |
| | 433 | .spirv_runtime_array_len, |
| | 434 | .legalize_vec_store_elem, |
| | 435 | .legalize_vec_elem_val, |
| | 436 | .legalize_compiler_rt_call, |
| 345 | => |tag| return cg.fail("TODO: implement spork8 inst: {s}", .{@tagName(tag)}), | 437 | => |tag| return cg.fail("TODO: implement spork8 inst: {s}", .{@tagName(tag)}), |
| 346 | | 438 | |
| 347 | .work_item_id, | 439 | .work_item_id, |
| ... | @@ -356,7 +448,7 @@ fn airUnreachable(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -356,7 +448,7 @@ fn airUnreachable(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 356 | _ = inst; | 448 | _ = inst; |
| 357 | } | 449 | } |
| 358 | | 450 | |
| 359 | fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { | 451 | fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } { |
| 360 | const zcu = cg.pt.zcu; | 452 | const zcu = cg.pt.zcu; |
| 361 | const func = zcu.funcInfo(cg.func_index); | 453 | const func = zcu.funcInfo(cg.func_index); |
| 362 | return zcu.codegenFail(func.owner_nav, fmt, args); | 454 | return zcu.codegenFail(func.owner_nav, fmt, args); |