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
This commit is contained in:
@@ -1083,6 +1083,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
|
||||
.ptr_elem_val => try airPtrElemVal(f, inst, "["),
|
||||
.ptr_elem_ptr => try airPtrElemPtr(f, inst),
|
||||
.slice_elem_val => try airSliceElemVal(f, inst, "["),
|
||||
.slice_elem_ptr => try airSliceElemPtr(f, inst),
|
||||
.array_elem_val => try airArrayElemVal(f, inst),
|
||||
|
||||
.unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst),
|
||||
@@ -1165,6 +1166,24 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index, prefix: []const u8) !CVal
|
||||
return local;
|
||||
}
|
||||
|
||||
fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
if (f.liveness.isUnused(inst))
|
||||
return CValue.none;
|
||||
const ty_pl = f.air.instructions.items(.data)[inst].ty_pl;
|
||||
const bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
|
||||
|
||||
const slice = try f.resolveInst(bin_op.lhs);
|
||||
const index = try f.resolveInst(bin_op.rhs);
|
||||
const writer = f.object.writer();
|
||||
const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
|
||||
try writer.writeAll(" = &");
|
||||
try f.writeCValue(writer, slice);
|
||||
try writer.writeByte('[');
|
||||
try f.writeCValue(writer, index);
|
||||
try writer.writeAll("];\n");
|
||||
return local;
|
||||
}
|
||||
|
||||
fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
if (f.liveness.isUnused(inst)) return CValue.none;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user