aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
diff options
context:
space:
mode:
authorRobin Voetter <robin@voetter.nl>2021-10-21 16:17:21 +0200
committerRobin Voetter <robin@voetter.nl>2021-10-21 16:24:18 +0200
commit09c7d5aebc4f7fe96a89f93c0cf99cc03977ea5f (patch)
tree7877d79040b38f43aea7fc192546b19d07821bc0 /src/codegen/llvm.zig
parent84876fec582e13707a809c8136bb1eaf92b5da09 (diff)
downloadzig-09c7d5aebc4f7fe96a89f93c0cf99cc03977ea5f.tar.gz
zig-09c7d5aebc4f7fe96a89f93c0cf99cc03977ea5f.zip
stage2: elemPtr for slices
* Restructure elemPtr a bit * New AIR instruction: slice_elem_ptr, which returns a pointer to an element of a slice * Value: adapt elemPtr to work on slices
Diffstat (limited to 'src/codegen/llvm.zig')
-rw-r--r--src/codegen/llvm.zig25
1 files changed, 22 insertions, 3 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index e5356582e2..a607b7a753 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -1760,6 +1760,7 @@ pub const FuncGen = struct {
.array_elem_val => try self.airArrayElemVal(inst),
.slice_elem_val => try self.airSliceElemVal(inst),
+ .slice_elem_ptr => try self.airSliceElemPtr(inst),
.ptr_elem_val => try self.airPtrElemVal(inst),
.ptr_elem_ptr => try self.airPtrElemPtr(inst),
@@ -2157,12 +2158,20 @@ pub const FuncGen = struct {
const slice = try self.resolveInst(bin_op.lhs);
const index = try self.resolveInst(bin_op.rhs);
- const base_ptr = self.builder.buildExtractValue(slice, 0, "");
- const indices: [1]*const llvm.Value = .{index};
- const ptr = self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
+ const ptr = self.sliceElemPtr(slice, index);
return self.load(ptr, slice_ty);
}
+ fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
+ if (self.liveness.isUnused(inst)) return null;
+ const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
+ const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
+
+ const slice = try self.resolveInst(bin_op.lhs);
+ const index = try self.resolveInst(bin_op.rhs);
+ return self.sliceElemPtr(slice, index);
+ }
+
fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
if (self.liveness.isUnused(inst)) return null;
@@ -3575,6 +3584,16 @@ pub const FuncGen = struct {
return self.builder.buildBitCast(union_field_ptr, result_llvm_ty, "");
}
+ fn sliceElemPtr(
+ self: *FuncGen,
+ slice: *const llvm.Value,
+ index: *const llvm.Value,
+ ) *const llvm.Value {
+ const base_ptr = self.builder.buildExtractValue(slice, 0, "");
+ const indices: [1]*const llvm.Value = .{index};
+ return self.builder.buildInBoundsGEP(base_ptr, &indices, indices.len, "");
+ }
+
fn getIntrinsic(self: *FuncGen, name: []const u8) *const llvm.Value {
const id = llvm.lookupIntrinsicID(name.ptr, name.len);
assert(id != 0);