| author | |
| committer | |
| log | 23d7921758524f76f2157e6f8a5823da2511396a |
| tree | 14f71cfd47fb4b26d48c5c5a662e3bfd61be84b0 |
| parent | cb54e9a3c20783863cf346dc935e2940d26d26d0 |
If a `loop` ends with a `noreturn` instruction, then it cannot loop and
will be emitted as a `block` instead.2 files changed, 20 insertions(+), 9 deletions(-)
src/Air.zig+7-2| ... | @@ -221,11 +221,16 @@ pub const Inst = struct { | ... | @@ -221,11 +221,16 @@ pub const Inst = struct { |
| 221 | /// Reinterpret the memory representation of a value as a different type. | 221 | /// Reinterpret the memory representation of a value as a different type. |
| 222 | /// Uses the `ty_op` field. | 222 | /// Uses the `ty_op` field. |
| 223 | bitcast, | 223 | bitcast, |
| 224 | /// Uses the `ty_pl` field with payload `Block`. | 224 | /// Uses the `ty_pl` field with payload `Block`. A block runs its body which always ends |
| 225 | /// with a `noreturn` instruction, so the only way to proceed to the code after the `block` | ||
| 226 | /// is to encounter a `br` that targets this `block`. If the `block` type is `noreturn`, | ||
| 227 | /// then there do not exist any `br` instructions targetting this `block`. | ||
| 225 | block, | 228 | block, |
| 226 | /// A labeled block of code that loops forever. At the end of the body it is implied | 229 | /// A labeled block of code that loops forever. At the end of the body it is implied |
| 227 | /// to repeat; no explicit "repeat" instruction terminates loop bodies. | 230 | /// to repeat; no explicit "repeat" instruction terminates loop bodies. |
| 228 | /// Result type is always noreturn; no instructions in a block follow this one. | 231 | /// Result type is always `noreturn`; no instructions in a block follow this one. |
| 232 | /// The body never ends with a `noreturn` instruction, so the "repeat" operation | ||
| 233 | /// is always statically reachable. | ||
| 229 | /// Uses the `ty_pl` field. Payload is `Block`. | 234 | /// Uses the `ty_pl` field. Payload is `Block`. |
| 230 | loop, | 235 | loop, |
| 231 | /// Return from a block with a result. | 236 | /// Return from a block with a result. |
src/Sema.zig+13-7| ... | @@ -5294,14 +5294,20 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -5294,14 +5294,20 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError |
| 5294 | 5294 | ||
| 5295 | try sema.analyzeBody(&loop_block, body); | 5295 | try sema.analyzeBody(&loop_block, body); |
| 5296 | 5296 | ||
| 5297 | try child_block.instructions.append(gpa, loop_inst); | 5297 | if (sema.typeOf(Air.indexToRef(loop_block.instructions.items[loop_block.instructions.items.len - 1])).isNoReturn()) { |
| 5298 | // If the loop ended with a noreturn terminator, then there is no way for it to loop, | ||
| 5299 | // so we can just use the block instead. | ||
| 5300 | try child_block.instructions.appendSlice(gpa, loop_block.instructions.items); | ||
| 5301 | } else { | ||
| 5302 | try child_block.instructions.append(gpa, loop_inst); | ||
| 5298 | 5303 | ||
| 5299 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + | 5304 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 5300 | loop_block.instructions.items.len); | 5305 | loop_block.instructions.items.len); |
| 5301 | sema.air_instructions.items(.data)[loop_inst].ty_pl.payload = sema.addExtraAssumeCapacity( | 5306 | sema.air_instructions.items(.data)[loop_inst].ty_pl.payload = sema.addExtraAssumeCapacity( |
| 5302 | Air.Block{ .body_len = @intCast(u32, loop_block.instructions.items.len) }, | 5307 | Air.Block{ .body_len = @intCast(u32, loop_block.instructions.items.len) }, |
| 5303 | ); | 5308 | ); |
| 5304 | sema.air_extra.appendSliceAssumeCapacity(loop_block.instructions.items); | 5309 | sema.air_extra.appendSliceAssumeCapacity(loop_block.instructions.items); |
| 5310 | } | ||
| 5305 | return sema.analyzeBlockBody(parent_block, src, &child_block, merges); | 5311 | return sema.analyzeBlockBody(parent_block, src, &child_block, merges); |
| 5306 | } | 5312 | } |
| 5307 | 5313 |