| ... | ... | @@ -206,6 +206,8 @@ pub const Feature = enum { |
| 206 | 206 | expand_array_to_vector, |
| 207 | 207 | /// Replace `ptr_elem_val` with an `ptr_elem_ptr` followed by a `load`. |
| 208 | 208 | expand_ptr_elem_val, |
| 209 | /// Replace `array_to_slice` with a `ptr_cast` followed by a `slice`. |
| 210 | expand_array_to_slice, |
| 209 | 211 | |
| 210 | 212 | /// Replace all arithmetic operations on 16-bit floating-point types with calls to soft-float |
| 211 | 213 | /// routines in compiler_rt, including `fptrunc`/`fpext`/`float_from_int`/`int_from_float` |
| ... | ... | @@ -866,7 +868,6 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void { |
| 866 | 868 | .slice_elem_val, |
| 867 | 869 | .slice_elem_ptr, |
| 868 | 870 | .ptr_elem_ptr, |
| 869 | | .array_to_slice, |
| 870 | 871 | => {}, |
| 871 | 872 | .ptr_elem_val => if (l.features.has(.expand_ptr_elem_val)) { |
| 872 | 873 | continue :inst l.replaceInst(inst, .block, try l.ptrElemValBlockPayload(inst)); |
| ... | ... | @@ -874,6 +875,9 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void { |
| 874 | 875 | .array_to_vector => if (l.features.has(.expand_array_to_vector)) { |
| 875 | 876 | continue :inst l.replaceInst(inst, .block, try l.arrayToVectorBlockPayload(inst)); |
| 876 | 877 | }, |
| 878 | .array_to_slice => if (l.features.has(.expand_array_to_slice)) { |
| 879 | continue :inst l.replaceInst(inst, .block, try l.arrayToSliceBlockPayload(inst)); |
| 880 | }, |
| 877 | 881 | inline .reduce, .reduce_optimized => |air_tag| { |
| 878 | 882 | const reduce = l.air_instructions.items(.data)[@backingInt(inst)].reduce; |
| 879 | 883 | const vector_ty = l.typeOf(reduce.operand); |
| ... | ... | @@ -3059,6 +3063,42 @@ fn arrayToVectorBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air. |
| 3059 | 3063 | } }; |
| 3060 | 3064 | } |
| 3061 | 3065 | |
| 3066 | fn arrayToSliceBlockPayload(l: *Legalize, orig_inst: Air.Inst.Index) Error!Air.Inst.Data { |
| 3067 | const pt = l.pt; |
| 3068 | const zcu = pt.zcu; |
| 3069 | const gpa = zcu.gpa; |
| 3070 | |
| 3071 | const orig_ty_op = l.air_instructions.items(.data)[@backingInt(orig_inst)].ty_op; |
| 3072 | |
| 3073 | const slice_ty = orig_ty_op.ty; |
| 3074 | const ptr_ty = slice_ty.slicePtrFieldType(zcu); |
| 3075 | |
| 3076 | const array_ptr_ty = l.typeOf(orig_ty_op.operand); |
| 3077 | const len = array_ptr_ty.childType(zcu).arrayLen(zcu); |
| 3078 | |
| 3079 | var inst_buf: [3]Air.Inst.Index = undefined; |
| 3080 | var main_block: Block = .init(&inst_buf); |
| 3081 | try l.air_instructions.ensureUnusedCapacity(gpa, inst_buf.len); |
| 3082 | |
| 3083 | const ptr = main_block.addPtrCast(l, ptr_ty, orig_ty_op.operand); |
| 3084 | const result = main_block.add(l, .{ |
| 3085 | .tag = .slice, |
| 3086 | .data = .{ .ty_pl = .{ |
| 3087 | .ty = slice_ty, |
| 3088 | .payload = try l.addExtra(Air.Bin, .{ |
| 3089 | .lhs = ptr, |
| 3090 | .rhs = try pt.intRef(.usize, len), |
| 3091 | }), |
| 3092 | } }, |
| 3093 | }).toRef(); |
| 3094 | |
| 3095 | main_block.addBr(l, orig_inst, result); |
| 3096 | return .{ .ty_pl = .{ |
| 3097 | .ty = slice_ty, |
| 3098 | .payload = try l.addBlockBody(main_block.body()), |
| 3099 | } }; |
| 3100 | } |
| 3101 | |
| 3062 | 3102 | /// Given a `std.math.big.int.Const`, converts it to a `Value` which is a float of type `float_ty` |
| 3063 | 3103 | /// representing the same numeric value. If the integer cannot be exactly represented, `round` |
| 3064 | 3104 | /// decides whether the value should be rounded up or down. If `is_vector`, then `float_ty` is |