| ... | @@ -6029,16 +6029,15 @@ fn switchExpr( | ... | @@ -6029,16 +6029,15 @@ fn switchExpr( |
| 6029 | const cond_ty_inst = try parent_gz.addUnNode(.typeof, cond, operand_node); | 6029 | const cond_ty_inst = try parent_gz.addUnNode(.typeof, cond, operand_node); |
| 6030 | const item_rl: ResultLoc = .{ .ty = cond_ty_inst }; | 6030 | const item_rl: ResultLoc = .{ .ty = cond_ty_inst }; |
| 6031 | | 6031 | |
| 6032 | // These contain the data that goes into the `extra` array for the SwitchBlock/SwitchBlockMulti. | 6032 | // This contains the data that goes into the `extra` array for the SwitchBlock/SwitchBlockMulti, |
| 6033 | // This is the optional else prong body. | 6033 | // except the first cases_nodes.len slots are a table that indexes payloads later in the array, with |
| 6034 | var special_case_payload = ArrayListUnmanaged(u32){}; | 6034 | // the special case index coming first, then scalar_case_len indexes, then multi_cases_len indexes |
| 6035 | defer special_case_payload.deinit(gpa); | 6035 | var payloads = ArrayListUnmanaged(u32){}; |
| 6036 | // This is all the scalar cases. | 6036 | defer payloads.deinit(gpa); |
| 6037 | var scalar_cases_payload = ArrayListUnmanaged(u32){}; | 6037 | const scalar_case_table: u32 = @boolToInt(special_prong != .none); |
| 6038 | defer scalar_cases_payload.deinit(gpa); | 6038 | const multi_case_table = scalar_case_table + scalar_cases_len; |
| 6039 | // Same deal, but this is only the `extra` data for the multi cases. | 6039 | const case_table_len = multi_case_table + multi_cases_len; |
| 6040 | var multi_cases_payload = ArrayListUnmanaged(u32){}; | 6040 | try payloads.resize(gpa, case_table_len); |
| 6041 | defer multi_cases_payload.deinit(gpa); | | |
| 6042 | | 6041 | |
| 6043 | var block_scope = parent_gz.makeSubBlock(scope); | 6042 | var block_scope = parent_gz.makeSubBlock(scope); |
| 6044 | block_scope.setBreakResultLoc(rl); | 6043 | block_scope.setBreakResultLoc(rl); |
| ... | @@ -6069,13 +6068,6 @@ fn switchExpr( | ... | @@ -6069,13 +6068,6 @@ fn switchExpr( |
| 6069 | | 6068 | |
| 6070 | var capture_val_scope: Scope.LocalVal = undefined; | 6069 | var capture_val_scope: Scope.LocalVal = undefined; |
| 6071 | const sub_scope = blk: { | 6070 | const sub_scope = blk: { |
| 6072 | const capture_index = if (is_multi_case) ci: { | | |
| 6073 | multi_case_index += 1; | | |
| 6074 | break :ci multi_case_index - 1; | | |
| 6075 | } else ci: { | | |
| 6076 | scalar_case_index += 1; | | |
| 6077 | break :ci scalar_case_index - 1; | | |
| 6078 | }; | | |
| 6079 | const payload_token = case.payload_token orelse break :blk &case_scope.base; | 6071 | const payload_token = case.payload_token orelse break :blk &case_scope.base; |
| 6080 | const ident = if (token_tags[payload_token] == .asterisk) | 6072 | const ident = if (token_tags[payload_token] == .asterisk) |
| 6081 | payload_token + 1 | 6073 | payload_token + 1 |
| ... | @@ -6109,6 +6101,7 @@ fn switchExpr( | ... | @@ -6109,6 +6101,7 @@ fn switchExpr( |
| 6109 | 0b10 => .switch_capture_multi, | 6101 | 0b10 => .switch_capture_multi, |
| 6110 | 0b11 => .switch_capture_multi_ref, | 6102 | 0b11 => .switch_capture_multi_ref, |
| 6111 | }; | 6103 | }; |
| | 6104 | const capture_index = if (is_multi_case) multi_case_index else scalar_case_index; |
| 6112 | break :capture try case_scope.add(.{ | 6105 | break :capture try case_scope.add(.{ |
| 6113 | .tag = capture_tag, | 6106 | .tag = capture_tag, |
| 6114 | .data = .{ .switch_capture = .{ | 6107 | .data = .{ .switch_capture = .{ |
| ... | @@ -6129,10 +6122,11 @@ fn switchExpr( | ... | @@ -6129,10 +6122,11 @@ fn switchExpr( |
| 6129 | break :blk &capture_val_scope.base; | 6122 | break :blk &capture_val_scope.base; |
| 6130 | }; | 6123 | }; |
| 6131 | | 6124 | |
| 6132 | if (is_multi_case) { | 6125 | const header_index = @intCast(u32, payloads.items.len); |
| 6133 | // items_len, ranges_len, body_len | 6126 | const body_len_index = if (is_multi_case) blk: { |
| 6134 | const header_index = multi_cases_payload.items.len; | 6127 | payloads.items[multi_case_table + multi_case_index] = header_index; |
| 6135 | try multi_cases_payload.resize(gpa, multi_cases_payload.items.len + 3); | 6128 | multi_case_index += 1; |
| | 6129 | try payloads.resize(gpa, header_index + 3); // items_len, ranges_len, body_len |
| 6136 | | 6130 | |
| 6137 | // items | 6131 | // items |
| 6138 | var items_len: u32 = 0; | 6132 | var items_len: u32 = 0; |
| ... | @@ -6141,7 +6135,7 @@ fn switchExpr( | ... | @@ -6141,7 +6135,7 @@ fn switchExpr( |
| 6141 | items_len += 1; | 6135 | items_len += 1; |
| 6142 | | 6136 | |
| 6143 | const item_inst = try comptimeExpr(parent_gz, scope, item_rl, item_node); | 6137 | const item_inst = try comptimeExpr(parent_gz, scope, item_rl, item_node); |
| 6144 | try multi_cases_payload.append(gpa, @enumToInt(item_inst)); | 6138 | try payloads.append(gpa, @enumToInt(item_inst)); |
| 6145 | } | 6139 | } |
| 6146 | | 6140 | |
| 6147 | // ranges | 6141 | // ranges |
| ... | @@ -6152,57 +6146,43 @@ fn switchExpr( | ... | @@ -6152,57 +6146,43 @@ fn switchExpr( |
| 6152 | | 6146 | |
| 6153 | const first = try comptimeExpr(parent_gz, scope, item_rl, node_datas[range].lhs); | 6147 | const first = try comptimeExpr(parent_gz, scope, item_rl, node_datas[range].lhs); |
| 6154 | const last = try comptimeExpr(parent_gz, scope, item_rl, node_datas[range].rhs); | 6148 | const last = try comptimeExpr(parent_gz, scope, item_rl, node_datas[range].rhs); |
| 6155 | try multi_cases_payload.appendSlice(gpa, &[_]u32{ | 6149 | try payloads.appendSlice(gpa, &[_]u32{ |
| 6156 | @enumToInt(first), @enumToInt(last), | 6150 | @enumToInt(first), @enumToInt(last), |
| 6157 | }); | 6151 | }); |
| 6158 | } | 6152 | } |
| 6159 | | 6153 | |
| 6160 | const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr); | 6154 | payloads.items[header_index] = items_len; |
| 6161 | try checkUsed(parent_gz, &case_scope.base, sub_scope); | 6155 | payloads.items[header_index + 1] = ranges_len; |
| 6162 | if (!parent_gz.refIsNoReturn(case_result)) { | 6156 | break :blk header_index + 2; |
| 6163 | block_scope.break_count += 1; | 6157 | } else if (case_node == special_node) blk: { |
| 6164 | _ = try case_scope.addBreak(.@"break", switch_block, case_result); | 6158 | payloads.items[0] = header_index; |
| 6165 | } | 6159 | try payloads.resize(gpa, header_index + 1); // body_len |
| 6166 | | 6160 | break :blk header_index; |
| 6167 | multi_cases_payload.items[header_index + 0] = items_len; | 6161 | } else blk: { |
| 6168 | multi_cases_payload.items[header_index + 1] = ranges_len; | 6162 | payloads.items[scalar_case_table + scalar_case_index] = header_index; |
| 6169 | multi_cases_payload.items[header_index + 2] = @intCast(u32, case_scope.instructions.items.len); | 6163 | scalar_case_index += 1; |
| 6170 | try multi_cases_payload.appendSlice(gpa, case_scope.instructions.items); | 6164 | try payloads.resize(gpa, header_index + 2); // item, body_len |
| 6171 | } else if (case_node == special_node) { | | |
| 6172 | const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr); | | |
| 6173 | try checkUsed(parent_gz, &case_scope.base, sub_scope); | | |
| 6174 | if (!parent_gz.refIsNoReturn(case_result)) { | | |
| 6175 | block_scope.break_count += 1; | | |
| 6176 | _ = try case_scope.addBreak(.@"break", switch_block, case_result); | | |
| 6177 | } | | |
| 6178 | try special_case_payload.ensureUnusedCapacity(gpa, 1 + // body_len | | |
| 6179 | case_scope.instructions.items.len); | | |
| 6180 | special_case_payload.appendAssumeCapacity(@intCast(u32, case_scope.instructions.items.len)); | | |
| 6181 | special_case_payload.appendSliceAssumeCapacity(case_scope.instructions.items); | | |
| 6182 | } else { | | |
| 6183 | const item_node = case.ast.values[0]; | 6165 | const item_node = case.ast.values[0]; |
| 6184 | const item_inst = try comptimeExpr(parent_gz, scope, item_rl, item_node); | 6166 | const item_inst = try comptimeExpr(parent_gz, scope, item_rl, item_node); |
| 6185 | const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr); | 6167 | payloads.items[header_index] = @enumToInt(item_inst); |
| 6186 | try checkUsed(parent_gz, &case_scope.base, sub_scope); | 6168 | break :blk header_index + 1; |
| 6187 | if (!parent_gz.refIsNoReturn(case_result)) { | 6169 | }; |
| 6188 | block_scope.break_count += 1; | 6170 | |
| 6189 | _ = try case_scope.addBreak(.@"break", switch_block, case_result); | 6171 | const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr); |
| 6190 | } | 6172 | try checkUsed(parent_gz, &case_scope.base, sub_scope); |
| 6191 | try scalar_cases_payload.ensureUnusedCapacity(gpa, 2 + // item + body_len | 6173 | if (!parent_gz.refIsNoReturn(case_result)) { |
| 6192 | case_scope.instructions.items.len); | 6174 | block_scope.break_count += 1; |
| 6193 | scalar_cases_payload.appendAssumeCapacity(@enumToInt(item_inst)); | 6175 | _ = try case_scope.addBreak(.@"break", switch_block, case_result); |
| 6194 | scalar_cases_payload.appendAssumeCapacity(@intCast(u32, case_scope.instructions.items.len)); | | |
| 6195 | scalar_cases_payload.appendSliceAssumeCapacity(case_scope.instructions.items); | | |
| 6196 | } | 6176 | } |
| | 6177 | payloads.items[body_len_index] = @intCast(u32, case_scope.instructions.items.len); |
| | 6178 | try payloads.appendSlice(gpa, case_scope.instructions.items); |
| 6197 | } | 6179 | } |
| 6198 | // Now that the item expressions are generated we can add this. | 6180 | // Now that the item expressions are generated we can add this. |
| 6199 | try parent_gz.instructions.append(gpa, switch_block); | 6181 | try parent_gz.instructions.append(gpa, switch_block); |
| 6200 | | 6182 | |
| 6201 | try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.SwitchBlock).Struct.fields.len + | 6183 | try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.SwitchBlock).Struct.fields.len + |
| 6202 | @boolToInt(multi_cases_len != 0) + | 6184 | @boolToInt(multi_cases_len != 0) + |
| 6203 | special_case_payload.items.len + | 6185 | payloads.items.len - case_table_len); |
| 6204 | scalar_cases_payload.items.len + | | |
| 6205 | multi_cases_payload.items.len); | | |
| 6206 | | 6186 | |
| 6207 | const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.SwitchBlock{ | 6187 | const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.SwitchBlock{ |
| 6208 | .operand = cond, | 6188 | .operand = cond, |
| ... | @@ -6215,62 +6195,58 @@ fn switchExpr( | ... | @@ -6215,62 +6195,58 @@ fn switchExpr( |
| 6215 | }, | 6195 | }, |
| 6216 | }); | 6196 | }); |
| 6217 | | 6197 | |
| 6218 | const zir_datas = astgen.instructions.items(.data); | | |
| 6219 | const zir_tags = astgen.instructions.items(.tag); | | |
| 6220 | | | |
| 6221 | zir_datas[switch_block].pl_node.payload_index = payload_index; | | |
| 6222 | | | |
| 6223 | if (multi_cases_len != 0) { | 6198 | if (multi_cases_len != 0) { |
| 6224 | astgen.extra.appendAssumeCapacity(multi_cases_len); | 6199 | astgen.extra.appendAssumeCapacity(multi_cases_len); |
| 6225 | } | 6200 | } |
| 6226 | | 6201 | |
| 6227 | const strat = rl.strategy(&block_scope); | 6202 | const zir_datas = astgen.instructions.items(.data); |
| 6228 | switch (strat.tag) { | 6203 | const zir_tags = astgen.instructions.items(.tag); |
| 6229 | .break_operand => { | | |
| 6230 | // Switch expressions return `true` for `nodeMayNeedMemoryLocation` thus | | |
| 6231 | // `elide_store_to_block_ptr_instructions` will either be true, | | |
| 6232 | // or all prongs are noreturn. | | |
| 6233 | if (!strat.elide_store_to_block_ptr_instructions) { | | |
| 6234 | astgen.extra.appendSliceAssumeCapacity(special_case_payload.items); | | |
| 6235 | astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items); | | |
| 6236 | astgen.extra.appendSliceAssumeCapacity(multi_cases_payload.items); | | |
| 6237 | return indexToRef(switch_block); | | |
| 6238 | } | | |
| 6239 | | 6204 | |
| 6240 | // There will necessarily be a store_to_block_ptr for | 6205 | zir_datas[switch_block].pl_node.payload_index = payload_index; |
| 6241 | // all prongs, except for prongs that ended with a noreturn instruction. | | |
| 6242 | // Elide all the `store_to_block_ptr` instructions. | | |
| 6243 | | 6206 | |
| 6244 | // The break instructions need to have their operands coerced if the | 6207 | const strat = rl.strategy(&block_scope); |
| 6245 | // switch's result location is a `ty`. In this case we overwrite the | 6208 | for (payloads.items[0..case_table_len]) |start_index, table_index| { |
| 6246 | // `store_to_block_ptr` instruction with an `as` instruction and repurpose | 6209 | var body_len_index = start_index; |
| 6247 | // it as the break operand. | 6210 | var end_index = start_index; |
| | 6211 | if (table_index < scalar_case_table) { |
| | 6212 | end_index += 1; |
| | 6213 | } else if (table_index < multi_case_table) { |
| | 6214 | body_len_index += 1; |
| | 6215 | end_index += 2; |
| | 6216 | } else { |
| | 6217 | body_len_index += 2; |
| | 6218 | const items_len = payloads.items[start_index]; |
| | 6219 | const ranges_len = payloads.items[start_index + 1]; |
| | 6220 | end_index += 3 + items_len + 2 * ranges_len; |
| | 6221 | } |
| 6248 | | 6222 | |
| 6249 | var extra_index: usize = 0; | 6223 | const body_len = payloads.items[body_len_index]; |
| 6250 | if (special_prong != .none) special_prong: { | 6224 | end_index += body_len; |
| 6251 | const body_len_index = extra_index; | 6225 | |
| 6252 | const body_len = special_case_payload.items[extra_index]; | 6226 | switch (strat.tag) { |
| 6253 | extra_index += 1; | 6227 | .break_operand => blk: { |
| 6254 | if (body_len < 2) { | 6228 | // Switch expressions return `true` for `nodeMayNeedMemoryLocation` thus |
| 6255 | extra_index += body_len; | 6229 | // `elide_store_to_block_ptr_instructions` will either be true, |
| 6256 | astgen.extra.appendSliceAssumeCapacity(special_case_payload.items[0..extra_index]); | 6230 | // or all prongs are noreturn. |
| 6257 | break :special_prong; | 6231 | if (!strat.elide_store_to_block_ptr_instructions) |
| 6258 | } | 6232 | break :blk; |
| 6259 | extra_index += body_len - 2; | 6233 | |
| 6260 | const store_inst = special_case_payload.items[extra_index]; | 6234 | // There will necessarily be a store_to_block_ptr for |
| | 6235 | // all prongs, except for prongs that ended with a noreturn instruction. |
| | 6236 | // Elide all the `store_to_block_ptr` instructions. |
| | 6237 | |
| | 6238 | // The break instructions need to have their operands coerced if the |
| | 6239 | // switch's result location is a `ty`. In this case we overwrite the |
| | 6240 | // `store_to_block_ptr` instruction with an `as` instruction and repurpose |
| | 6241 | // it as the break operand. |
| | 6242 | if (body_len < 2) |
| | 6243 | break :blk; |
| | 6244 | const store_inst = payloads.items[end_index - 2]; |
| 6261 | if (zir_tags[store_inst] != .store_to_block_ptr or | 6245 | if (zir_tags[store_inst] != .store_to_block_ptr or |
| 6262 | zir_datas[store_inst].bin.lhs != block_scope.rl_ptr) | 6246 | zir_datas[store_inst].bin.lhs != block_scope.rl_ptr) |
| 6263 | { | 6247 | break :blk; |
| 6264 | extra_index += 2; | 6248 | const break_inst = payloads.items[end_index - 1]; |
| 6265 | astgen.extra.appendSliceAssumeCapacity(special_case_payload.items[0..extra_index]); | | |
| 6266 | break :special_prong; | | |
| 6267 | } | | |
| 6268 | assert(zir_datas[store_inst].bin.lhs == block_scope.rl_ptr); | | |
| 6269 | if (block_scope.rl_ty_inst != .none) { | 6249 | if (block_scope.rl_ty_inst != .none) { |
| 6270 | extra_index += 1; | | |
| 6271 | const break_inst = special_case_payload.items[extra_index]; | | |
| 6272 | extra_index += 1; | | |
| 6273 | astgen.extra.appendSliceAssumeCapacity(special_case_payload.items[0..extra_index]); | | |
| 6274 | zir_tags[store_inst] = .as; | 6250 | zir_tags[store_inst] = .as; |
| 6275 | zir_datas[store_inst].bin = .{ | 6251 | zir_datas[store_inst].bin = .{ |
| 6276 | .lhs = block_scope.rl_ty_inst, | 6252 | .lhs = block_scope.rl_ty_inst, |
| ... | @@ -6278,168 +6254,30 @@ fn switchExpr( | ... | @@ -6278,168 +6254,30 @@ fn switchExpr( |
| 6278 | }; | 6254 | }; |
| 6279 | zir_datas[break_inst].@"break".operand = indexToRef(store_inst); | 6255 | zir_datas[break_inst].@"break".operand = indexToRef(store_inst); |
| 6280 | } else { | 6256 | } else { |
| 6281 | special_case_payload.items[body_len_index] -= 1; | 6257 | payloads.items[body_len_index] -= 1; |
| 6282 | astgen.extra.appendSliceAssumeCapacity(special_case_payload.items[0..extra_index]); | 6258 | astgen.extra.appendSliceAssumeCapacity(payloads.items[start_index .. end_index - 2]); |
| 6283 | extra_index += 1; | 6259 | astgen.extra.appendAssumeCapacity(break_inst); |
| 6284 | astgen.extra.appendAssumeCapacity(special_case_payload.items[extra_index]); | | |
| 6285 | extra_index += 1; | | |
| 6286 | } | | |
| 6287 | } else { | | |
| 6288 | astgen.extra.appendSliceAssumeCapacity(special_case_payload.items[0..extra_index]); | | |
| 6289 | } | | |
| 6290 | extra_index = 0; | | |
| 6291 | var scalar_i: u32 = 0; | | |
| 6292 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { | | |
| 6293 | const start_index = extra_index; | | |
| 6294 | extra_index += 1; | | |
| 6295 | const body_len_index = extra_index; | | |
| 6296 | const body_len = scalar_cases_payload.items[extra_index]; | | |
| 6297 | extra_index += 1; | | |
| 6298 | if (body_len < 2) { | | |
| 6299 | extra_index += body_len; | | |
| 6300 | astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items[start_index..extra_index]); | | |
| 6301 | continue; | 6260 | continue; |
| 6302 | } | 6261 | } |
| 6303 | extra_index += body_len - 2; | 6262 | }, |
| 6304 | const store_inst = scalar_cases_payload.items[extra_index]; | 6263 | .break_void => { |
| 6305 | if (zir_tags[store_inst] != .store_to_block_ptr or | 6264 | assert(!strat.elide_store_to_block_ptr_instructions); |
| 6306 | zir_datas[store_inst].bin.lhs != block_scope.rl_ptr) | 6265 | const last_inst = payloads.items[end_index - 1]; |
| 6307 | { | 6266 | if (zir_tags[last_inst] == .@"break" and |
| 6308 | extra_index += 2; | 6267 | zir_datas[last_inst].@"break".block_inst == switch_block) |
| 6309 | astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items[start_index..extra_index]); | | |
| 6310 | continue; | | |
| 6311 | } | | |
| 6312 | if (block_scope.rl_ty_inst != .none) { | | |
| 6313 | extra_index += 1; | | |
| 6314 | const break_inst = scalar_cases_payload.items[extra_index]; | | |
| 6315 | extra_index += 1; | | |
| 6316 | astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items[start_index..extra_index]); | | |
| 6317 | zir_tags[store_inst] = .as; | | |
| 6318 | zir_datas[store_inst].bin = .{ | | |
| 6319 | .lhs = block_scope.rl_ty_inst, | | |
| 6320 | .rhs = zir_datas[break_inst].@"break".operand, | | |
| 6321 | }; | | |
| 6322 | zir_datas[break_inst].@"break".operand = indexToRef(store_inst); | | |
| 6323 | } else { | | |
| 6324 | scalar_cases_payload.items[body_len_index] -= 1; | | |
| 6325 | astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items[start_index..extra_index]); | | |
| 6326 | extra_index += 1; | | |
| 6327 | astgen.extra.appendAssumeCapacity(scalar_cases_payload.items[extra_index]); | | |
| 6328 | extra_index += 1; | | |
| 6329 | } | | |
| 6330 | } | | |
| 6331 | extra_index = 0; | | |
| 6332 | var multi_i: u32 = 0; | | |
| 6333 | while (multi_i < multi_cases_len) : (multi_i += 1) { | | |
| 6334 | const start_index = extra_index; | | |
| 6335 | const items_len = multi_cases_payload.items[extra_index]; | | |
| 6336 | extra_index += 1; | | |
| 6337 | const ranges_len = multi_cases_payload.items[extra_index]; | | |
| 6338 | extra_index += 1; | | |
| 6339 | const body_len_index = extra_index; | | |
| 6340 | const body_len = multi_cases_payload.items[extra_index]; | | |
| 6341 | extra_index += 1; | | |
| 6342 | extra_index += items_len; | | |
| 6343 | extra_index += 2 * ranges_len; | | |
| 6344 | if (body_len < 2) { | | |
| 6345 | extra_index += body_len; | | |
| 6346 | astgen.extra.appendSliceAssumeCapacity(multi_cases_payload.items[start_index..extra_index]); | | |
| 6347 | continue; | | |
| 6348 | } | | |
| 6349 | extra_index += body_len - 2; | | |
| 6350 | const store_inst = multi_cases_payload.items[extra_index]; | | |
| 6351 | if (zir_tags[store_inst] != .store_to_block_ptr or | | |
| 6352 | zir_datas[store_inst].bin.lhs != block_scope.rl_ptr) | | |
| 6353 | { | | |
| 6354 | extra_index += 2; | | |
| 6355 | astgen.extra.appendSliceAssumeCapacity(multi_cases_payload.items[start_index..extra_index]); | | |
| 6356 | continue; | | |
| 6357 | } | | |
| 6358 | if (block_scope.rl_ty_inst != .none) { | | |
| 6359 | extra_index += 1; | | |
| 6360 | const break_inst = multi_cases_payload.items[extra_index]; | | |
| 6361 | extra_index += 1; | | |
| 6362 | astgen.extra.appendSliceAssumeCapacity(multi_cases_payload.items[start_index..extra_index]); | | |
| 6363 | zir_tags[store_inst] = .as; | | |
| 6364 | zir_datas[store_inst].bin = .{ | | |
| 6365 | .lhs = block_scope.rl_ty_inst, | | |
| 6366 | .rhs = zir_datas[break_inst].@"break".operand, | | |
| 6367 | }; | | |
| 6368 | zir_datas[break_inst].@"break".operand = indexToRef(store_inst); | | |
| 6369 | } else { | | |
| 6370 | assert(zir_datas[store_inst].bin.lhs == block_scope.rl_ptr); | | |
| 6371 | multi_cases_payload.items[body_len_index] -= 1; | | |
| 6372 | astgen.extra.appendSliceAssumeCapacity(multi_cases_payload.items[start_index..extra_index]); | | |
| 6373 | extra_index += 1; | | |
| 6374 | astgen.extra.appendAssumeCapacity(multi_cases_payload.items[extra_index]); | | |
| 6375 | extra_index += 1; | | |
| 6376 | } | | |
| 6377 | } | | |
| 6378 | | | |
| 6379 | const block_ref = indexToRef(switch_block); | | |
| 6380 | switch (rl) { | | |
| 6381 | .ref => return block_ref, | | |
| 6382 | else => return rvalue(parent_gz, rl, block_ref, switch_node), | | |
| 6383 | } | | |
| 6384 | }, | | |
| 6385 | .break_void => { | | |
| 6386 | assert(!strat.elide_store_to_block_ptr_instructions); | | |
| 6387 | astgen.extra.appendSliceAssumeCapacity(special_case_payload.items); | | |
| 6388 | astgen.extra.appendSliceAssumeCapacity(scalar_cases_payload.items); | | |
| 6389 | astgen.extra.appendSliceAssumeCapacity(multi_cases_payload.items); | | |
| 6390 | // Modify all the terminating instruction tags to become `break` variants. | | |
| 6391 | var extra_index: usize = payload_index; | | |
| 6392 | extra_index += 2; | | |
| 6393 | extra_index += @boolToInt(multi_cases_len != 0); | | |
| 6394 | if (special_prong != .none) { | | |
| 6395 | const body_len = astgen.extra.items[extra_index]; | | |
| 6396 | extra_index += 1; | | |
| 6397 | const body = astgen.extra.items[extra_index..][0..body_len]; | | |
| 6398 | extra_index += body_len; | | |
| 6399 | const last = body[body.len - 1]; | | |
| 6400 | if (zir_tags[last] == .@"break" and | | |
| 6401 | zir_datas[last].@"break".block_inst == switch_block) | | |
| 6402 | { | | |
| 6403 | zir_datas[last].@"break".operand = .void_value; | | |
| 6404 | } | | |
| 6405 | } | | |
| 6406 | var scalar_i: u32 = 0; | | |
| 6407 | while (scalar_i < scalar_cases_len) : (scalar_i += 1) { | | |
| 6408 | extra_index += 1; | | |
| 6409 | const body_len = astgen.extra.items[extra_index]; | | |
| 6410 | extra_index += 1; | | |
| 6411 | const body = astgen.extra.items[extra_index..][0..body_len]; | | |
| 6412 | extra_index += body_len; | | |
| 6413 | const last = body[body.len - 1]; | | |
| 6414 | if (zir_tags[last] == .@"break" and | | |
| 6415 | zir_datas[last].@"break".block_inst == switch_block) | | |
| 6416 | { | | |
| 6417 | zir_datas[last].@"break".operand = .void_value; | | |
| 6418 | } | | |
| 6419 | } | | |
| 6420 | var multi_i: u32 = 0; | | |
| 6421 | while (multi_i < multi_cases_len) : (multi_i += 1) { | | |
| 6422 | const items_len = astgen.extra.items[extra_index]; | | |
| 6423 | extra_index += 1; | | |
| 6424 | const ranges_len = astgen.extra.items[extra_index]; | | |
| 6425 | extra_index += 1; | | |
| 6426 | const body_len = astgen.extra.items[extra_index]; | | |
| 6427 | extra_index += 1; | | |
| 6428 | extra_index += items_len; | | |
| 6429 | extra_index += 2 * ranges_len; | | |
| 6430 | const body = astgen.extra.items[extra_index..][0..body_len]; | | |
| 6431 | extra_index += body_len; | | |
| 6432 | const last = body[body.len - 1]; | | |
| 6433 | if (zir_tags[last] == .@"break" and | | |
| 6434 | zir_datas[last].@"break".block_inst == switch_block) | | |
| 6435 | { | 6268 | { |
| 6436 | zir_datas[last].@"break".operand = .void_value; | 6269 | zir_datas[last_inst].@"break".operand = .void_value; |
| 6437 | } | 6270 | } |
| 6438 | } | 6271 | }, |
| | 6272 | } |
| 6439 | | 6273 | |
| 6440 | return indexToRef(switch_block); | 6274 | astgen.extra.appendSliceAssumeCapacity(payloads.items[start_index..end_index]); |
| 6441 | }, | | |
| 6442 | } | 6275 | } |
| | 6276 | |
| | 6277 | const block_ref = indexToRef(switch_block); |
| | 6278 | if (strat.tag == .break_operand and strat.elide_store_to_block_ptr_instructions and rl != .ref) |
| | 6279 | return rvalue(parent_gz, rl, block_ref, switch_node); |
| | 6280 | return block_ref; |
| 6443 | } | 6281 | } |
| 6444 | | 6282 | |
| 6445 | fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 6283 | fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |