diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-08-21 20:42:45 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-08-21 20:47:42 -0700 |
| commit | f378b0adce80aa6f85d9bf6bf97172426de2c719 (patch) | |
| tree | 68a460620cb480de283afe9e64d4ea8b9a0fbd7d /src/codegen/llvm.zig | |
| parent | 2b40815a220bbbd657bfa441e304090f11f1eb4c (diff) | |
| download | zig-f378b0adce80aa6f85d9bf6bf97172426de2c719.tar.gz zig-f378b0adce80aa6f85d9bf6bf97172426de2c719.zip | |
stage2: comptime function with the same args is memoized
* Introduce `memoized_calls` to `Module` which stores all the comptime
function calls that are cached. It is keyed on the `*Fn` and the
comptime arguments, but it does not yet properly detect comptime function
pointers and avoid memoizing in this case. So it will have false
positives for when a comptime function call mutates data through a
pointer parameter.
* Sema: Add a new helper function: `resolveConstMaybeUndefVal`
* Value: add `enumToInt` method and use it in `zirEnumToInt`. It is
also used by the hashing function.
* Value: fix representation of optionals to match error unions.
Previously it would not handle nested optionals correctly. Now it
matches the memory layout of error unions and supports nested
optionals properly. This required changes in all the backends for
generating optional constants.
* TypedValue gains `eql` and `hash` methods.
* Value: Implement hashing for floats, optionals, and enums.
Additionally, the zig type tag is added to the hash, where it was not
previously, so that values of differing types will get different
hashes.
Diffstat (limited to 'src/codegen/llvm.zig')
| -rw-r--r-- | src/codegen/llvm.zig | 33 |
1 files changed, 14 insertions, 19 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 745fb036db..b80dcf0feb 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -810,27 +810,22 @@ pub const DeclGen = struct { return self.todo("handle more array values", .{}); }, .Optional => { - if (!tv.ty.isPtrLikeOptional()) { - var buf: Type.Payload.ElemType = undefined; - const child_type = tv.ty.optionalChild(&buf); - const llvm_child_type = try self.llvmType(child_type); - - if (tv.val.tag() == .null_value) { - var optional_values: [2]*const llvm.Value = .{ - llvm_child_type.constNull(), - self.context.intType(1).constNull(), - }; - return self.context.constStruct(&optional_values, optional_values.len, .False); - } else { - var optional_values: [2]*const llvm.Value = .{ - try self.genTypedValue(.{ .ty = child_type, .val = tv.val }), - self.context.intType(1).constAllOnes(), - }; - return self.context.constStruct(&optional_values, optional_values.len, .False); - } - } else { + if (tv.ty.isPtrLikeOptional()) { return self.todo("implement const of optional pointer", .{}); } + var buf: Type.Payload.ElemType = undefined; + const payload_type = tv.ty.optionalChild(&buf); + const is_pl = !tv.val.isNull(); + const llvm_i1 = self.context.intType(1); + + const fields: [2]*const llvm.Value = .{ + try self.genTypedValue(.{ + .ty = payload_type, + .val = if (tv.val.castTag(.opt_payload)) |pl| pl.data else Value.initTag(.undef), + }), + if (is_pl) llvm_i1.constAllOnes() else llvm_i1.constNull(), + }; + return self.context.constStruct(&fields, fields.len, .False); }, .Fn => { const fn_decl = switch (tv.val.tag()) { |
