| ... | @@ -712,6 +712,7 @@ pub const Object = struct { | ... | @@ -712,6 +712,7 @@ pub const Object = struct { |
| 712 | .byval => { | 712 | .byval => { |
| 713 | const param_ty = fn_info.param_types[it.zig_index - 1]; | 713 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 714 | const param = llvm_func.getParam(llvm_arg_i); | 714 | const param = llvm_func.getParam(llvm_arg_i); |
| | 715 | try args.ensureUnusedCapacity(1); |
| 715 | | 716 | |
| 716 | if (isByRef(param_ty)) { | 717 | if (isByRef(param_ty)) { |
| 717 | const alignment = param_ty.abiAlignment(target); | 718 | const alignment = param_ty.abiAlignment(target); |
| ... | @@ -720,9 +721,9 @@ pub const Object = struct { | ... | @@ -720,9 +721,9 @@ pub const Object = struct { |
| 720 | arg_ptr.setAlignment(alignment); | 721 | arg_ptr.setAlignment(alignment); |
| 721 | const store_inst = builder.buildStore(param, arg_ptr); | 722 | const store_inst = builder.buildStore(param, arg_ptr); |
| 722 | store_inst.setAlignment(alignment); | 723 | store_inst.setAlignment(alignment); |
| 723 | try args.append(arg_ptr); | 724 | args.appendAssumeCapacity(arg_ptr); |
| 724 | } else { | 725 | } else { |
| 725 | try args.append(param); | 726 | args.appendAssumeCapacity(param); |
| 726 | | 727 | |
| 727 | if (param_ty.isPtrAtRuntime()) { | 728 | if (param_ty.isPtrAtRuntime()) { |
| 728 | const ptr_info = param_ty.ptrInfo().data; | 729 | const ptr_info = param_ty.ptrInfo().data; |
| ... | @@ -756,13 +757,15 @@ pub const Object = struct { | ... | @@ -756,13 +757,15 @@ pub const Object = struct { |
| 756 | | 757 | |
| 757 | llvm_arg_i += 1; | 758 | llvm_arg_i += 1; |
| 758 | | 759 | |
| | 760 | try args.ensureUnusedCapacity(1); |
| | 761 | |
| 759 | if (isByRef(param_ty)) { | 762 | if (isByRef(param_ty)) { |
| 760 | try args.append(param); | 763 | args.appendAssumeCapacity(param); |
| 761 | } else { | 764 | } else { |
| 762 | const alignment = param_ty.abiAlignment(target); | 765 | const alignment = param_ty.abiAlignment(target); |
| 763 | const load_inst = builder.buildLoad(param, ""); | 766 | const load_inst = builder.buildLoad(param, ""); |
| 764 | load_inst.setAlignment(alignment); | 767 | load_inst.setAlignment(alignment); |
| 765 | try args.append(load_inst); | 768 | args.appendAssumeCapacity(load_inst); |
| 766 | } | 769 | } |
| 767 | }, | 770 | }, |
| 768 | .abi_sized_int => { | 771 | .abi_sized_int => { |
| ... | @@ -784,14 +787,44 @@ pub const Object = struct { | ... | @@ -784,14 +787,44 @@ pub const Object = struct { |
| 784 | const store_inst = builder.buildStore(param, casted_ptr); | 787 | const store_inst = builder.buildStore(param, casted_ptr); |
| 785 | store_inst.setAlignment(alignment); | 788 | store_inst.setAlignment(alignment); |
| 786 | | 789 | |
| | 790 | try args.ensureUnusedCapacity(1); |
| | 791 | |
| 787 | if (isByRef(param_ty)) { | 792 | if (isByRef(param_ty)) { |
| 788 | try args.append(arg_ptr); | 793 | args.appendAssumeCapacity(arg_ptr); |
| 789 | } else { | 794 | } else { |
| 790 | const load_inst = builder.buildLoad(arg_ptr, ""); | 795 | const load_inst = builder.buildLoad(arg_ptr, ""); |
| 791 | load_inst.setAlignment(alignment); | 796 | load_inst.setAlignment(alignment); |
| 792 | try args.append(load_inst); | 797 | args.appendAssumeCapacity(load_inst); |
| 793 | } | 798 | } |
| 794 | }, | 799 | }, |
| | 800 | .slice => { |
| | 801 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| | 802 | const ptr_info = param_ty.ptrInfo().data; |
| | 803 | |
| | 804 | if (math.cast(u5, it.zig_index - 1)) |i| { |
| | 805 | if (@truncate(u1, fn_info.noalias_bits >> i) != 0) { |
| | 806 | dg.addArgAttr(llvm_func, llvm_arg_i, "noalias"); |
| | 807 | } |
| | 808 | } |
| | 809 | dg.addArgAttr(llvm_func, llvm_arg_i, "nonnull"); |
| | 810 | if (!ptr_info.mutable) { |
| | 811 | dg.addArgAttr(llvm_func, llvm_arg_i, "readonly"); |
| | 812 | } |
| | 813 | if (ptr_info.@"align" != 0) { |
| | 814 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.@"align"); |
| | 815 | } else { |
| | 816 | dg.addArgAttrInt(llvm_func, llvm_arg_i, "align", ptr_info.pointee_type.abiAlignment(target)); |
| | 817 | } |
| | 818 | const ptr_param = llvm_func.getParam(llvm_arg_i); |
| | 819 | llvm_arg_i += 1; |
| | 820 | const len_param = llvm_func.getParam(llvm_arg_i); |
| | 821 | llvm_arg_i += 1; |
| | 822 | |
| | 823 | const slice_llvm_ty = try dg.lowerType(param_ty); |
| | 824 | const partial = builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr_param, 0, ""); |
| | 825 | const aggregate = builder.buildInsertValue(partial, len_param, 1, ""); |
| | 826 | try args.append(aggregate); |
| | 827 | }, |
| 795 | .multiple_llvm_ints => { | 828 | .multiple_llvm_ints => { |
| 796 | const param_ty = fn_info.param_types[it.zig_index - 1]; | 829 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 797 | const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len]; | 830 | const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len]; |
| ... | @@ -2743,6 +2776,17 @@ pub const DeclGen = struct { | ... | @@ -2743,6 +2776,17 @@ pub const DeclGen = struct { |
| 2743 | const abi_size = @intCast(c_uint, param_ty.abiSize(target)); | 2776 | const abi_size = @intCast(c_uint, param_ty.abiSize(target)); |
| 2744 | try llvm_params.append(dg.context.intType(abi_size * 8)); | 2777 | try llvm_params.append(dg.context.intType(abi_size * 8)); |
| 2745 | }, | 2778 | }, |
| | 2779 | .slice => { |
| | 2780 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| | 2781 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| | 2782 | const ptr_ty = param_ty.slicePtrFieldType(&buf); |
| | 2783 | const ptr_llvm_ty = try dg.lowerType(ptr_ty); |
| | 2784 | const len_llvm_ty = try dg.lowerType(Type.usize); |
| | 2785 | |
| | 2786 | try llvm_params.ensureUnusedCapacity(2); |
| | 2787 | llvm_params.appendAssumeCapacity(ptr_llvm_ty); |
| | 2788 | llvm_params.appendAssumeCapacity(len_llvm_ty); |
| | 2789 | }, |
| 2746 | .multiple_llvm_ints => { | 2790 | .multiple_llvm_ints => { |
| 2747 | const param_ty = fn_info.param_types[it.zig_index - 1]; | 2791 | const param_ty = fn_info.param_types[it.zig_index - 1]; |
| 2748 | const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len]; | 2792 | const llvm_ints = it.llvm_types_buffer[0..it.llvm_types_len]; |
| ... | @@ -4205,6 +4249,15 @@ pub const FuncGen = struct { | ... | @@ -4205,6 +4249,15 @@ pub const FuncGen = struct { |
| 4205 | try llvm_args.append(load_inst); | 4249 | try llvm_args.append(load_inst); |
| 4206 | } | 4250 | } |
| 4207 | }, | 4251 | }, |
| | 4252 | .slice => { |
| | 4253 | const arg = args[it.zig_index - 1]; |
| | 4254 | const llvm_arg = try self.resolveInst(arg); |
| | 4255 | const ptr = self.builder.buildExtractValue(llvm_arg, 0, ""); |
| | 4256 | const len = self.builder.buildExtractValue(llvm_arg, 1, ""); |
| | 4257 | try llvm_args.ensureUnusedCapacity(2); |
| | 4258 | llvm_args.appendAssumeCapacity(ptr); |
| | 4259 | llvm_args.appendAssumeCapacity(len); |
| | 4260 | }, |
| 4208 | .multiple_llvm_ints => { | 4261 | .multiple_llvm_ints => { |
| 4209 | const arg = args[it.zig_index - 1]; | 4262 | const arg = args[it.zig_index - 1]; |
| 4210 | const param_ty = self.air.typeOf(arg); | 4263 | const param_ty = self.air.typeOf(arg); |
| ... | @@ -8811,6 +8864,7 @@ const ParamTypeIterator = struct { | ... | @@ -8811,6 +8864,7 @@ const ParamTypeIterator = struct { |
| 8811 | byref, | 8864 | byref, |
| 8812 | abi_sized_int, | 8865 | abi_sized_int, |
| 8813 | multiple_llvm_ints, | 8866 | multiple_llvm_ints, |
| | 8867 | slice, |
| 8814 | }; | 8868 | }; |
| 8815 | | 8869 | |
| 8816 | fn next(it: *ParamTypeIterator) ?Lowering { | 8870 | fn next(it: *ParamTypeIterator) ?Lowering { |
| ... | @@ -8826,7 +8880,9 @@ const ParamTypeIterator = struct { | ... | @@ -8826,7 +8880,9 @@ const ParamTypeIterator = struct { |
| 8826 | .Unspecified, .Inline => { | 8880 | .Unspecified, .Inline => { |
| 8827 | it.zig_index += 1; | 8881 | it.zig_index += 1; |
| 8828 | it.llvm_index += 1; | 8882 | it.llvm_index += 1; |
| 8829 | if (isByRef(ty)) { | 8883 | if (ty.isSlice()) { |
| | 8884 | return .slice; |
| | 8885 | } else if (isByRef(ty)) { |
| 8830 | return .byref; | 8886 | return .byref; |
| 8831 | } else { | 8887 | } else { |
| 8832 | return .byval; | 8888 | return .byval; |