diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-12-27 01:14:50 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-12-27 01:14:50 -0700 |
| commit | c8fb36b36cd8368e84752770edf720e6e91ed997 (patch) | |
| tree | db0821f54a28f552240d27becaf4b1538b613d2e /src/codegen/c.zig | |
| parent | f41b9cdb6d7f954495ffca168108ddd38bf27353 (diff) | |
| download | zig-c8fb36b36cd8368e84752770edf720e6e91ed997.tar.gz zig-c8fb36b36cd8368e84752770edf720e6e91ed997.zip | |
stage2: LLVM backend: implement `@tagName` for enums
Introduced a new AIR instruction: `tag_name`. Reasons to do this
instead of lowering it in Sema to a switch, function call, array
lookup, or if-else tower:
* Sema is a bottleneck; do less work in Sema whenever possible.
* If any optimization passes run, and the operand to becomes
comptime-known, then it could change to have a comptime result
value instead of lowering to a function or array or something which
would then have to be garbage-collected.
* Backends may want to choose to use a function and a switch branch,
or they may want to use a different strategy.
Codegen for `@tagName` is implemented for the LLVM backend but not any
others yet.
Introduced some new `Type` tags:
* `const_slice_u8_sentinel_0`
* `manyptr_const_u8_sentinel_0`
The motivation for this was to make typeof() on the tag_name AIR
instruction non-allocating.
A bunch more enum tests are passing now.
Diffstat (limited to 'src/codegen/c.zig')
| -rw-r--r-- | src/codegen/c.zig | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 86ec58457f..56df9a86cb 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1230,6 +1230,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .clz => try airBuiltinCall(f, inst, "clz"), .ctz => try airBuiltinCall(f, inst, "ctz"), .popcount => try airBuiltinCall(f, inst, "popcount"), + .tag_name => try airTagName(f, inst), .int_to_float, .float_to_int, @@ -2914,6 +2915,24 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { return local; } +fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { + if (f.liveness.isUnused(inst)) return CValue.none; + + const un_op = f.air.instructions.items(.data)[inst].un_op; + const writer = f.object.writer(); + const inst_ty = f.air.typeOfIndex(inst); + const operand = try f.resolveInst(un_op); + const local = try f.allocLocal(inst_ty, .Const); + + try writer.writeAll(" = "); + + _ = operand; + _ = local; + return f.fail("TODO: C backend: implement airTagName", .{}); + //try writer.writeAll(";\n"); + //return local; +} + fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 { return switch (order) { .Unordered => "memory_order_relaxed", |
