Skip to content

Commit d9742ac

Browse files
committed
Sema: detect one-possible-value types after function calls
produces better Air for backends
1 parent 7999374 commit d9742ac

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

src/Air.zig

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,20 @@ pub const Inst = struct {
11411141
pub fn toType(ref: Ref) Type {
11421142
return .fromInterned(ref.toInterned().?);
11431143
}
1144+
1145+
pub fn fromIntern(ip_index: InternPool.Index) Ref {
1146+
return switch (ip_index) {
1147+
.none => .none,
1148+
else => {
1149+
assert(@intFromEnum(ip_index) >> 31 == 0);
1150+
return @enumFromInt(@as(u31, @intCast(@intFromEnum(ip_index))));
1151+
},
1152+
};
1153+
}
1154+
1155+
pub fn fromValue(v: Value) Ref {
1156+
return .fromIntern(v.toIntern());
1157+
}
11441158
};
11451159

11461160
/// All instructions have an 8-byte payload, which is contained within
@@ -1754,13 +1768,7 @@ pub fn deinit(air: *Air, gpa: std.mem.Allocator) void {
17541768
}
17551769

17561770
pub fn internedToRef(ip_index: InternPool.Index) Inst.Ref {
1757-
return switch (ip_index) {
1758-
.none => .none,
1759-
else => {
1760-
assert(@intFromEnum(ip_index) >> 31 == 0);
1761-
return @enumFromInt(@as(u31, @intCast(@intFromEnum(ip_index))));
1762-
},
1763-
};
1771+
return .fromIntern(ip_index);
17641772
}
17651773

17661774
/// Returns `null` if runtime-known.

src/Sema.zig

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8060,7 +8060,7 @@ fn analyzeCall(
80608060
};
80618061

80628062
try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).@"struct".fields.len + runtime_args.len);
8063-
const result = try block.addInst(.{
8063+
const maybe_opv = try block.addInst(.{
80648064
.tag = call_tag,
80658065
.data = .{ .pl_op = .{
80668066
.operand = runtime_func,
@@ -8072,7 +8072,7 @@ fn analyzeCall(
80728072
sema.appendRefsAssumeCapacity(runtime_args);
80738073

80748074
if (ensure_result_used) {
8075-
try sema.ensureResultUsed(block, sema.typeOf(result), call_src);
8075+
try sema.ensureResultUsed(block, sema.typeOf(maybe_opv), call_src);
80768076
}
80778077

80788078
if (call_tag == .call_always_tail) {
@@ -8082,10 +8082,10 @@ fn analyzeCall(
80828082
.pointer => func_or_ptr_ty.childType(zcu),
80838083
else => unreachable,
80848084
};
8085-
return sema.handleTailCall(block, call_src, runtime_func_ty, result);
8085+
return sema.handleTailCall(block, call_src, runtime_func_ty, maybe_opv);
80868086
}
80878087

8088-
if (resolved_ret_ty.toIntern() == .noreturn_type) {
8088+
if (ip.isNoReturn(resolved_ret_ty.toIntern())) {
80898089
const want_check = c: {
80908090
if (!block.wantSafety()) break :c false;
80918091
if (func_val != null) break :c false;
@@ -8099,6 +8099,11 @@ fn analyzeCall(
80998099
return .unreachable_value;
81008100
}
81018101

8102+
const result: Air.Inst.Ref = if (try sema.typeHasOnePossibleValue(sema.typeOf(maybe_opv))) |opv|
8103+
.fromValue(opv)
8104+
else
8105+
maybe_opv;
8106+
81028107
return result;
81038108
}
81048109

@@ -8335,7 +8340,7 @@ fn analyzeCall(
83358340
break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, &inlining.merges, need_debug_scope);
83368341
};
83378342

8338-
const result: Air.Inst.Ref = if (try sema.resolveValue(result_raw)) |result_val| r: {
8343+
const maybe_opv: Air.Inst.Ref = if (try sema.resolveValue(result_raw)) |result_val| r: {
83398344
const val_resolved = try sema.resolveAdHocInferredErrorSet(block, call_src, result_val.toIntern());
83408345
break :r Air.internedToRef(val_resolved);
83418346
} else r: {
@@ -8347,7 +8352,7 @@ fn analyzeCall(
83478352
};
83488353

83498354
if (block.isComptime()) {
8350-
const result_val = (try sema.resolveValue(result)).?;
8355+
const result_val = (try sema.resolveValue(maybe_opv)).?;
83518356
if (want_memoize and sema.allow_memoize and !result_val.canMutateComptimeVarState(zcu)) {
83528357
_ = try pt.intern(.{ .memoized_call = .{
83538358
.func = func_val.?.toIntern(),
@@ -8359,10 +8364,10 @@ fn analyzeCall(
83598364
}
83608365

83618366
if (ensure_result_used) {
8362-
try sema.ensureResultUsed(block, sema.typeOf(result), call_src);
8367+
try sema.ensureResultUsed(block, sema.typeOf(maybe_opv), call_src);
83638368
}
83648369

8365-
return result;
8370+
return maybe_opv;
83668371
}
83678372

83688373
fn handleTailCall(sema: *Sema, block: *Block, call_src: LazySrcLoc, func_ty: Type, result: Air.Inst.Ref) !Air.Inst.Ref {

0 commit comments

Comments
 (0)