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(...@@ -4618,7 +4618,7 @@ fn analyzeCall(
4618 },4618 },
4619 else => {},4619 else => {},
4620 }4620 }
4621 should_memoize = should_memoize and !arg_val.isComptimeMutablePtr();4621 should_memoize = should_memoize and !arg_val.canMutateComptimeVarState();
4622 memoized_call_key.args[arg_i] = .{4622 memoized_call_key.args[arg_i] = .{
4623 .ty = param_ty,4623 .ty = param_ty,
4624 .val = arg_val,4624 .val = arg_val,
...@@ -4644,7 +4644,7 @@ fn analyzeCall(...@@ -4644,7 +4644,7 @@ fn analyzeCall(
4644 },4644 },
4645 else => {},4645 else => {},
4646 }4646 }
4647 should_memoize = should_memoize and !arg_val.isComptimeMutablePtr();4647 should_memoize = should_memoize and !arg_val.canMutateComptimeVarState();
4648 memoized_call_key.args[arg_i] = .{4648 memoized_call_key.args[arg_i] = .{
4649 .ty = sema.typeOf(uncasted_arg),4649 .ty = sema.typeOf(uncasted_arg),
4650 .val = arg_val,4650 .val = arg_val,
...@@ -13603,7 +13603,8 @@ fn analyzeShuffle(...@@ -13603,7 +13603,8 @@ fn analyzeShuffle(
13603 // in 1 call because these calls to analyzeShuffle guarantee a_len == b_len.13603 // in 1 call because these calls to analyzeShuffle guarantee a_len == b_len.
13604 if (a_len != b_len) {13604 if (a_len != b_len) {
13605 const min_len = std.math.min(a_len, b_len);13605 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
13608 const expand_mask_values = try sema.arena.alloc(Value, max_len);13609 const expand_mask_values = try sema.arena.alloc(Value, max_len);
13609 i = 0;13610 i = 0;
src/value.zig+28
...@@ -1157,6 +1157,7 @@ pub const Value = extern union {...@@ -1157,6 +1157,7 @@ pub const Value = extern union {
1157 ) Allocator.Error!Value {1157 ) Allocator.Error!Value {
1158 switch (ty.zigTypeTag()) {1158 switch (ty.zigTypeTag()) {
1159 .Int => {1159 .Int => {
1160 if (buffer.len == 0) return Value.zero;
1160 const int_info = ty.intInfo(target);1161 const int_info = ty.intInfo(target);
1161 const endian = target.cpu.arch.endian();1162 const endian = target.cpu.arch.endian();
1162 const Limb = std.math.big.Limb;1163 const Limb = std.math.big.Limb;
...@@ -2185,6 +2186,33 @@ pub const Value = extern union {...@@ -2185,6 +2186,33 @@ pub const Value = extern union {
2185 };2186 };
2186 }2187 }
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
2188 /// Gets the decl referenced by this pointer. If the pointer does not point2216 /// Gets the decl referenced by this pointer. If the pointer does not point
2189 /// to a decl, or if it points to some part of a decl (like field_ptr or element_ptr),2217 /// to a decl, or if it points to some part of a decl (like field_ptr or element_ptr),
2190 /// this function returns null.2218 /// this function returns null.