aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-10-27 22:09:17 -0400
committerGitHub <noreply@github.com>2022-10-27 22:09:17 -0400
commit2991e4a454c4d719226fcfc7e8ac8dec44250a7e (patch)
tree2d0abcbd613008f7c07aae6bcad1b656bffb1f4f /src/codegen/llvm.zig
parentbc72ae5e4e6d8f2253aed1316b053ad1022f9f67 (diff)
parent648d34d8eacaf2e35e336abd5b0c50c2ab9bfc94 (diff)
downloadzig-2991e4a454c4d719226fcfc7e8ac8dec44250a7e.tar.gz
zig-2991e4a454c4d719226fcfc7e8ac8dec44250a7e.zip
Merge pull request #13288 from Vexu/opt-slice
Optimize size of optional slices (+ some fixes)
Diffstat (limited to 'src/codegen/llvm.zig')
-rw-r--r--src/codegen/llvm.zig30
1 files changed, 22 insertions, 8 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 1c2d65246f..d92a444ea4 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -1027,7 +1027,9 @@ pub const Object = struct {
dg.addArgAttr(llvm_func, llvm_arg_i, "noalias");
}
}
- dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
+ if (param_ty.zigTypeTag() != .Optional) {
+ dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull");
+ }
if (!ptr_info.mutable) {
dg.addArgAttr(llvm_func, llvm_arg_i, "readonly");
}
@@ -1916,7 +1918,7 @@ pub const Object = struct {
if (ty.castTag(.@"struct")) |payload| {
const struct_obj = payload.data;
- if (struct_obj.layout == .Packed) {
+ if (struct_obj.layout == .Packed and struct_obj.haveFieldTypes()) {
const info = struct_obj.backing_int_ty.intInfo(target);
const dwarf_encoding: c_uint = switch (info.signedness) {
.signed => DW.ATE.signed,
@@ -3117,7 +3119,11 @@ pub const DeclGen = struct {
.slice => {
const param_ty = fn_info.param_types[it.zig_index - 1];
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
- const ptr_ty = param_ty.slicePtrFieldType(&buf);
+ var opt_buf: Type.Payload.ElemType = undefined;
+ const ptr_ty = if (param_ty.zigTypeTag() == .Optional)
+ param_ty.optionalChild(&opt_buf).slicePtrFieldType(&buf)
+ else
+ param_ty.slicePtrFieldType(&buf);
const ptr_llvm_ty = try dg.lowerType(ptr_ty);
const len_llvm_ty = try dg.lowerType(Type.usize);
@@ -5438,10 +5444,11 @@ pub const FuncGen = struct {
const llvm_usize = try self.dg.lowerType(Type.usize);
const len = llvm_usize.constInt(array_ty.arrayLen(), .False);
const slice_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst));
+ const operand = try self.resolveInst(ty_op.operand);
if (!array_ty.hasRuntimeBitsIgnoreComptime()) {
- return self.builder.buildInsertValue(slice_llvm_ty.getUndef(), len, 1, "");
+ const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, "");
+ return self.builder.buildInsertValue(partial, len, 1, "");
}
- const operand = try self.resolveInst(ty_op.operand);
const indices: [2]*llvm.Value = .{
llvm_usize.constNull(), llvm_usize.constNull(),
};
@@ -6320,18 +6327,24 @@ pub const FuncGen = struct {
const operand_ty = self.air.typeOf(un_op);
const optional_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
const optional_llvm_ty = try self.dg.lowerType(optional_ty);
+ var buf: Type.Payload.ElemType = undefined;
+ const payload_ty = optional_ty.optionalChild(&buf);
if (optional_ty.optionalReprIsPayload()) {
const loaded = if (operand_is_ptr)
self.builder.buildLoad(optional_llvm_ty, operand, "")
else
operand;
+ if (payload_ty.isSlice()) {
+ const slice_ptr = self.builder.buildExtractValue(loaded, 0, "");
+ var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;
+ const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(&slice_buf));
+ return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), "");
+ }
return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");
}
comptime assert(optional_layout_version == 3);
- var buf: Type.Payload.ElemType = undefined;
- const payload_ty = optional_ty.optionalChild(&buf);
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
const loaded = if (operand_is_ptr)
self.builder.buildLoad(optional_llvm_ty, operand, "")
@@ -10355,7 +10368,8 @@ const ParamTypeIterator = struct {
.Unspecified, .Inline => {
it.zig_index += 1;
it.llvm_index += 1;
- if (ty.isSlice()) {
+ var buf: Type.Payload.ElemType = undefined;
+ if (ty.isSlice() or (ty.zigTypeTag() == .Optional and ty.optionalChild(&buf).isSlice())) {
return .slice;
} else if (isByRef(ty)) {
return .byref;