Skip to content

Commit b50f20e

Browse files
committed
stage2: Teach Liveness that safety checks do not modify memory
This change adds to Liveness a simple pattern match for the try-like `.condbr` blocks emitted by Sema's safety checks. This allows us to determine that these do not modify memory, which permits us to elide additional loads in the backend. As @Vexu points out in the main issue, this is probably not a complete solution on its own. We'll still want a way to reliably narrow the load/copy when performing several consecutive accesses, such as `foo.arr[x][y].z` Resolves #12215
1 parent a4eb221 commit b50f20e

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

src/Liveness.zig

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,37 @@ pub fn categorizeOperand(
500500
return .complex;
501501
},
502502
.block => {
503+
const extra = air.extraData(Air.Block, air_datas[inst].ty_pl.payload);
504+
const body = air.extra[extra.end..][0..extra.data.body_len];
505+
506+
if (body.len == 1 and air_tags[body[0]] == .cond_br) {
507+
// Peephole optimization for "panic-like" conditionals, which have
508+
// one empty branch and another which calls a `noreturn` function.
509+
// This allows us to infer that safety checks do not modify memory,
510+
// as far as control flow successors are concerned.
511+
512+
const inst_data = air_datas[body[0]].pl_op;
513+
const cond_extra = air.extraData(Air.CondBr, inst_data.payload);
514+
if (cond_extra.data.then_body_len != 1 or cond_extra.data.else_body_len != 1)
515+
return .complex;
516+
517+
for (air.extra[cond_extra.end..][0..2]) |cond_inst| {
518+
if (l.categorizeOperand(air, cond_inst, operand) == .tomb)
519+
return .tomb;
520+
521+
switch (air_tags[cond_inst]) {
522+
.br => { // Breaks immediately back to block
523+
const br = air_datas[cond_inst].br;
524+
if (br.block_inst != inst)
525+
return .complex;
526+
},
527+
.call => {}, // Calls a noreturn function
528+
else => return .complex,
529+
}
530+
}
531+
return .none;
532+
}
533+
503534
return .complex;
504535
},
505536
.@"try" => {

0 commit comments

Comments
 (0)