diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2023-06-24 22:21:43 +0100 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-06-27 01:21:32 -0700 |
| commit | ff37ccd298f0ab28a9d0e0ee1110dadc6db4df1e (patch) | |
| tree | 8b7b2ad4bc95f8cbbfd277fbfd7dfd30a7222b3a /src/codegen/llvm.zig | |
| parent | dae516dbdffaf771e072679a76a6d48f3f0aa182 (diff) | |
| download | zig-ff37ccd298f0ab28a9d0e0ee1110dadc6db4df1e.tar.gz zig-ff37ccd298f0ab28a9d0e0ee1110dadc6db4df1e.zip | |
Air: store interned values in Air.Inst.Ref
Previously, interned values were represented as AIR instructions using
the `interned` tag. Now, the AIR ref directly encodes the InternPool
index. The encoding works as follows:
* If the ref matches one of the static values, it corresponds to the same InternPool index.
* Otherwise, if the MSB is 0, the ref corresponds to an InternPool index.
* Otherwise, if the MSB is 1, the ref corresponds to an AIR instruction index (after removing the MSB).
Note that since most static InternPool indices are low values (the
exceptions being `.none` and `.var_args_param_type`), the first rule is
almost a nop.
Diffstat (limited to 'src/codegen/llvm.zig')
| -rw-r--r-- | src/codegen/llvm.zig | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index e9f29b7253..d42195d7e9 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -4557,7 +4557,7 @@ pub const FuncGen = struct { .vector_store_elem => try self.airVectorStoreElem(inst), - .inferred_alloc, .inferred_alloc_comptime, .interned => unreachable, + .inferred_alloc, .inferred_alloc_comptime => unreachable, .unreach => self.airUnreach(inst), .dbg_stmt => self.airDbgStmt(inst), @@ -5762,19 +5762,22 @@ pub const FuncGen = struct { return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(mod), false); } else { - const lhs_index = Air.refToIndex(bin_op.lhs).?; const elem_llvm_ty = try o.lowerType(elem_ty); - if (self.air.instructions.items(.tag)[lhs_index] == .load) { - const load_data = self.air.instructions.items(.data)[lhs_index]; - const load_ptr = load_data.ty_op.operand; - const load_ptr_tag = self.air.instructions.items(.tag)[Air.refToIndex(load_ptr).?]; - switch (load_ptr_tag) { - .struct_field_ptr, .struct_field_ptr_index_0, .struct_field_ptr_index_1, .struct_field_ptr_index_2, .struct_field_ptr_index_3 => { - const load_ptr_inst = try self.resolveInst(load_ptr); - const gep = self.builder.buildInBoundsGEP(array_llvm_ty, load_ptr_inst, &indices, indices.len, ""); - return self.builder.buildLoad(elem_llvm_ty, gep, ""); - }, - else => {}, + if (Air.refToIndex(bin_op.lhs)) |lhs_index| { + if (self.air.instructions.items(.tag)[lhs_index] == .load) { + const load_data = self.air.instructions.items(.data)[lhs_index]; + const load_ptr = load_data.ty_op.operand; + if (Air.refToIndex(load_ptr)) |load_ptr_index| { + const load_ptr_tag = self.air.instructions.items(.tag)[load_ptr_index]; + switch (load_ptr_tag) { + .struct_field_ptr, .struct_field_ptr_index_0, .struct_field_ptr_index_1, .struct_field_ptr_index_2, .struct_field_ptr_index_3 => { + const load_ptr_inst = try self.resolveInst(load_ptr); + const gep = self.builder.buildInBoundsGEP(array_llvm_ty, load_ptr_inst, &indices, indices.len, ""); + return self.builder.buildLoad(elem_llvm_ty, gep, ""); + }, + else => {}, + } + } } } const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, ""); |
