pub fn brCond(
self: *WipFunction,
cond: Value,
then: Block.Index,
@"else": Block.Index,
weights: enum { none, unpredictable, then_likely, else_likely },
) Allocator.Error!Instruction.Index {
assert(cond.typeOfWip(self) == .i1);
try self.ensureUnusedExtraCapacity(1, Instruction.BrCond, 0);
const instruction = try self.addInst(null, .{
.tag = .br_cond,
.data = self.addExtraAssumeCapacity(Instruction.BrCond{
.cond = cond,
.then = then,
.@"else" = @"else",
.weights = weights: switch (weights) {
.none => .none,
.unpredictable => .unpredictable,
.then_likely, .else_likely => {
const branch_weights_str = try self.builder.metadataString("branch_weights");
const unlikely_const = try self.builder.metadataConstant(try self.builder.intConst(.i32, 1));
const likely_const = try self.builder.metadataConstant(try self.builder.intConst(.i32, 2000));
const weight_vals: [3]Metadata = switch (weights) {
.none, .unpredictable => unreachable,
.then_likely => .{ branch_weights_str.toMetadata(), likely_const, unlikely_const },
.else_likely => .{ branch_weights_str.toMetadata(), unlikely_const, likely_const },
};
break :weights .fromMetadata(try self.builder.metadataTuple(&weight_vals));
},
},
}),
});
then.ptr(self).branches += 1;
@"else".ptr(self).branches += 1;
return instruction;
}