authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-11 16:48:44+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-11 16:56:33+02:00
log03b8206f27485f871fc489f884ffbc276d61877c
tree88163b5e6adf255f8b85bddbf77e1d0d4cb5e746
parent01cd4119b032f13899e9b7b30c7e093620058dfd

Sema: make check for whether call should be memoized more thorough


2 files changed, 32 insertions(+), 3 deletions(-)

src/Sema.zig+4-3
......@@ -4618,7 +4618,7 @@ fn analyzeCall(
46184618 },
46194619 else => {},
46204620 }
4621 should_memoize = should_memoize and !arg_val.isComptimeMutablePtr();
4621 should_memoize = should_memoize and !arg_val.canMutateComptimeVarState();
46224622 memoized_call_key.args[arg_i] = .{
46234623 .ty = param_ty,
46244624 .val = arg_val,
......@@ -4644,7 +4644,7 @@ fn analyzeCall(
46444644 },
46454645 else => {},
46464646 }
4647 should_memoize = should_memoize and !arg_val.isComptimeMutablePtr();
4647 should_memoize = should_memoize and !arg_val.canMutateComptimeVarState();
46484648 memoized_call_key.args[arg_i] = .{
46494649 .ty = sema.typeOf(uncasted_arg),
46504650 .val = arg_val,
......@@ -13603,7 +13603,8 @@ fn analyzeShuffle(
1360313603 // in 1 call because these calls to analyzeShuffle guarantee a_len == b_len.
1360413604 if (a_len != b_len) {
1360513605 const min_len = std.math.min(a_len, b_len);
13606 const max_len = std.math.max(a_len, b_len);
13606 const max_src = if (a_len > b_len) a_src else b_src;
13607 const max_len = try sema.usizeCast(block, max_src, std.math.max(a_len, b_len));
1360713608
1360813609 const expand_mask_values = try sema.arena.alloc(Value, max_len);
1360913610 i = 0;
src/value.zig+28
......@@ -1157,6 +1157,7 @@ pub const Value = extern union {
11571157 ) Allocator.Error!Value {
11581158 switch (ty.zigTypeTag()) {
11591159 .Int => {
1160 if (buffer.len == 0) return Value.zero;
11601161 const int_info = ty.intInfo(target);
11611162 const endian = target.cpu.arch.endian();
11621163 const Limb = std.math.big.Limb;
......@@ -2185,6 +2186,33 @@ pub const Value = extern union {
21852186 };
21862187 }
21872188
2189 pub fn canMutateComptimeVarState(val: Value) bool {
2190 if (val.isComptimeMutablePtr()) return true;
2191 switch (val.tag()) {
2192 .repeated => return val.castTag(.repeated).?.data.canMutateComptimeVarState(),
2193 .array => {
2194 const elems = val.cast(Payload.Array).?.data;
2195 for (elems) |elem| {
2196 if (elem.canMutateComptimeVarState()) return true;
2197 }
2198 return false;
2199 },
2200 .eu_payload => return val.castTag(.eu_payload).?.data.canMutateComptimeVarState(),
2201 .eu_payload_ptr => return val.castTag(.eu_payload_ptr).?.data.canMutateComptimeVarState(),
2202 .opt_payload => return val.castTag(.opt_payload).?.data.canMutateComptimeVarState(),
2203 .opt_payload_ptr => return val.castTag(.opt_payload_ptr).?.data.canMutateComptimeVarState(),
2204 .@"struct" => {
2205 const fields = val.cast(Payload.Struct).?.data;
2206 for (fields) |field| {
2207 if (field.canMutateComptimeVarState()) return true;
2208 }
2209 return false;
2210 },
2211 .@"union" => return val.cast(Payload.Union).?.data.val.canMutateComptimeVarState(),
2212 else => return false,
2213 }
2214 }
2215
21882216 /// Gets the decl referenced by this pointer. If the pointer does not point
21892217 /// to a decl, or if it points to some part of a decl (like field_ptr or element_ptr),
21902218 /// this function returns null.