| author | |
| committer | |
| log | 1fa4a58d2c2a649e528b9424f01f16eac6af376c |
| tree | 841c61dff18b7146194e26b841e3fcc5404a54e9 |
| parent | 41a0b8173147e403c23b2911bdca1438cdd920b6 |
8 files changed, 62 insertions(+), 24 deletions(-)
src/codegen/llvm.zig+2-1| ... | ... | @@ -1126,6 +1126,7 @@ pub const Object = struct { |
| 1126 | 1126 | } else { |
| 1127 | 1127 | _ = self.llvm_module.addAlias( |
| 1128 | 1128 | llvm_global.typeOf(), |
| 1129 | 0, | |
| 1129 | 1130 | llvm_global, |
| 1130 | 1131 | exp_name_z, |
| 1131 | 1132 | ); |
| ... | ... | @@ -2291,7 +2292,7 @@ pub const DeclGen = struct { |
| 2291 | 2292 | dg.addArgAttr(llvm_fn, 0, "noalias"); |
| 2292 | 2293 | |
| 2293 | 2294 | const raw_llvm_ret_ty = try dg.lowerType(fn_info.return_type); |
| 2294 | llvm_fn.addSretAttr(0, raw_llvm_ret_ty); | |
| 2295 | llvm_fn.addSretAttr(raw_llvm_ret_ty); | |
| 2295 | 2296 | } |
| 2296 | 2297 | |
| 2297 | 2298 | const err_return_tracing = fn_info.return_type.isError() and |
src/codegen/llvm/bindings.zig+3-3| ... | ... | @@ -206,7 +206,7 @@ pub const Value = opaque { |
| 206 | 206 | extern fn LLVMDeleteFunction(Fn: *const Value) void; |
| 207 | 207 | |
| 208 | 208 | pub const addSretAttr = ZigLLVMAddSretAttr; |
| 209 | extern fn ZigLLVMAddSretAttr(fn_ref: *const Value, ArgNo: c_uint, type_val: *const Type) void; | |
| 209 | extern fn ZigLLVMAddSretAttr(fn_ref: *const Value, type_val: *const Type) void; | |
| 210 | 210 | |
| 211 | 211 | pub const setCallSret = ZigLLVMSetCallSret; |
| 212 | 212 | extern fn ZigLLVMSetCallSret(Call: *const Value, return_type: *const Type) void; |
| ... | ... | @@ -520,8 +520,8 @@ pub const Builder = opaque { |
| 520 | 520 | pub const buildStore = LLVMBuildStore; |
| 521 | 521 | extern fn LLVMBuildStore(*const Builder, Val: *const Value, Ptr: *const Value) *const Value; |
| 522 | 522 | |
| 523 | pub const buildLoad = LLVMBuildLoad2; | |
| 524 | extern fn LLVMBuildLoad2(*const Builder, Ty: *const Type, PointerVal: *const Value, Name: [*:0]const u8) *const Value; | |
| 523 | pub const buildLoad = LLVMBuildLoad; | |
| 524 | extern fn LLVMBuildLoad(*const Builder, PointerVal: *const Value, Name: [*:0]const u8) *const Value; | |
| 525 | 525 | |
| 526 | 526 | pub const buildNeg = LLVMBuildNeg; |
| 527 | 527 | extern fn LLVMBuildNeg(*const Builder, V: *const Value, Name: [*:0]const u8) *const Value; |
src/main.zig+3-3| ... | ... | @@ -4488,11 +4488,11 @@ pub fn lldMain( |
| 4488 | 4488 | const llvm = @import("codegen/llvm/bindings.zig"); |
| 4489 | 4489 | const argc = @intCast(c_int, argv.len); |
| 4490 | 4490 | if (mem.eql(u8, args[1], "ld.lld")) { |
| 4491 | break :rc llvm.LinkELF(argc, argv.ptr, can_exit_early); | |
| 4491 | break :rc llvm.LinkELF(argc, argv.ptr, can_exit_early, false); | |
| 4492 | 4492 | } else if (mem.eql(u8, args[1], "lld-link")) { |
| 4493 | break :rc llvm.LinkCOFF(argc, argv.ptr, can_exit_early); | |
| 4493 | break :rc llvm.LinkCOFF(argc, argv.ptr, can_exit_early, false); | |
| 4494 | 4494 | } else if (mem.eql(u8, args[1], "wasm-ld")) { |
| 4495 | break :rc llvm.LinkWasm(argc, argv.ptr, can_exit_early); | |
| 4495 | break :rc llvm.LinkWasm(argc, argv.ptr, can_exit_early, false); | |
| 4496 | 4496 | } else { |
| 4497 | 4497 | unreachable; |
| 4498 | 4498 | } |
src/stage1/codegen.cpp+23-12| ... | ... | @@ -638,7 +638,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { |
| 638 | 638 | } else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) { |
| 639 | 639 | // Sret pointers must not be address 0 |
| 640 | 640 | addLLVMArgAttr(llvm_fn, 0, "nonnull"); |
| 641 | ZigLLVMAddSretAttr(llvm_fn, 0, get_llvm_type(g, return_type)); | |
| 641 | ZigLLVMAddSretAttr(llvm_fn, get_llvm_type(g, return_type)); | |
| 642 | 642 | if (cc_want_sret_attr(cc)) { |
| 643 | 643 | addLLVMArgAttr(llvm_fn, 0, "noalias"); |
| 644 | 644 | } |
| ... | ... | @@ -912,10 +912,10 @@ static LLVMValueRef gen_store(CodeGen *g, LLVMValueRef value, LLVMValueRef ptr, |
| 912 | 912 | return gen_store_untyped(g, value, ptr, alignment, ptr_type->data.pointer.is_volatile); |
| 913 | 913 | } |
| 914 | 914 | |
| 915 | static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMTypeRef elem_type, LLVMValueRef ptr, | |
| 916 | uint32_t alignment, bool is_volatile, const char *name) | |
| 915 | static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMValueRef ptr, uint32_t alignment, bool is_volatile, | |
| 916 | const char *name) | |
| 917 | 917 | { |
| 918 | LLVMValueRef result = LLVMBuildLoad2(g->builder, elem_type, ptr, name); | |
| 918 | LLVMValueRef result = LLVMBuildLoad(g->builder, ptr, name); | |
| 919 | 919 | if (is_volatile) LLVMSetVolatile(result, true); |
| 920 | 920 | if (alignment == 0) { |
| 921 | 921 | LLVMSetAlignment(result, LLVMABIAlignmentOfType(g->target_data_ref, LLVMGetElementType(LLVMTypeOf(ptr)))); |
| ... | ... | @@ -927,10 +927,8 @@ static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMTypeRef elem_type, LLVMValu |
| 927 | 927 | |
| 928 | 928 | static LLVMValueRef gen_load(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, const char *name) { |
| 929 | 929 | assert(ptr_type->id == ZigTypeIdPointer); |
| 930 | ZigType *elem_type = ptr_type->data.pointer.child_type; | |
| 931 | 930 | uint32_t alignment = get_ptr_align(g, ptr_type); |
| 932 | return gen_load_untyped(g, get_llvm_type(g, elem_type), ptr, alignment, | |
| 933 | ptr_type->data.pointer.is_volatile, name); | |
| 931 | return gen_load_untyped(g, ptr, alignment, ptr_type->data.pointer.is_volatile, name); | |
| 934 | 932 | } |
| 935 | 933 | |
| 936 | 934 | static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, ZigType *type, ZigType *ptr_type) { |
| ... | ... | @@ -1278,16 +1276,15 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) { |
| 1278 | 1276 | size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index; |
| 1279 | 1277 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, ""); |
| 1280 | 1278 | |
| 1281 | LLVMValueRef len_value = gen_load_untyped(g, usize_type_ref, len_field_ptr, 0, false, ""); | |
| 1282 | LLVMValueRef index_val = gen_load_untyped(g, usize_type_ref, index_field_ptr, 0, false, ""); | |
| 1279 | LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, ""); | |
| 1280 | LLVMValueRef index_val = gen_load_untyped(g, index_field_ptr, 0, false, ""); | |
| 1283 | 1281 | LLVMValueRef len_val_minus_one = LLVMBuildSub(g->builder, len_value, LLVMConstInt(usize_type_ref, 1, false), ""); |
| 1284 | 1282 | LLVMValueRef masked_val = LLVMBuildAnd(g->builder, index_val, len_val_minus_one, ""); |
| 1285 | 1283 | LLVMValueRef address_indices[] = { |
| 1286 | 1284 | masked_val, |
| 1287 | 1285 | }; |
| 1288 | 1286 | |
| 1289 | LLVMTypeRef ptr_to_usize = LLVMPointerType(usize_type_ref, 0); | |
| 1290 | LLVMValueRef ptr_value = gen_load_untyped(g, ptr_to_usize, ptr_field_ptr, 0, false, ""); | |
| 1287 | LLVMValueRef ptr_value = gen_load_untyped(g, ptr_field_ptr, 0, false, ""); | |
| 1291 | 1288 | LLVMValueRef address_slot = LLVMBuildInBoundsGEP(g->builder, ptr_value, address_indices, 1, ""); |
| 1292 | 1289 | |
| 1293 | 1290 | gen_store_untyped(g, address_value, address_slot, 0, false); |
| ... | ... | @@ -5562,6 +5559,7 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A |
| 5562 | 5559 | size_t param_index = 0; |
| 5563 | 5560 | LLVMTypeRef *param_types = heap::c_allocator.allocate<LLVMTypeRef>(input_and_output_count); |
| 5564 | 5561 | LLVMValueRef *param_values = heap::c_allocator.allocate<LLVMValueRef>(input_and_output_count); |
| 5562 | bool *param_needs_attr = heap::c_allocator.allocate<bool>(input_and_output_count); | |
| 5565 | 5563 | for (size_t i = 0; i < asm_expr->output_list.length; i += 1, total_index += 1) { |
| 5566 | 5564 | AsmOutput *asm_output = asm_expr->output_list.at(i); |
| 5567 | 5565 | bool is_return = (asm_output->return_type != nullptr); |
| ... | ... | @@ -5619,6 +5617,8 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A |
| 5619 | 5617 | |
| 5620 | 5618 | param_types[param_index] = type_ref; |
| 5621 | 5619 | param_values[param_index] = value_ref; |
| 5620 | // In the case of indirect inputs, LLVM requires the callsite to have an elementtype(<ty>) attribute. | |
| 5621 | param_needs_attr[param_index] = buf_ptr(asm_input->constraint)[0] == '*'; | |
| 5622 | 5622 | } |
| 5623 | 5623 | for (size_t i = 0; i < asm_expr->clobber_list.length; i += 1, total_index += 1) { |
| 5624 | 5624 | Buf *clobber_buf = asm_expr->clobber_list.at(i); |
| ... | ... | @@ -5658,14 +5658,25 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A |
| 5658 | 5658 | ret_type = get_llvm_type(g, instruction->base.value->type); |
| 5659 | 5659 | } |
| 5660 | 5660 | LLVMTypeRef function_type = LLVMFunctionType(ret_type, param_types, (unsigned)input_and_output_count, false); |
| 5661 | heap::c_allocator.deallocate(param_types, input_and_output_count); | |
| 5662 | 5661 | |
| 5663 | 5662 | bool is_volatile = instruction->has_side_effects || (asm_expr->output_list.length == 0); |
| 5664 | 5663 | LLVMValueRef asm_fn = LLVMGetInlineAsm(function_type, buf_ptr(&llvm_template), buf_len(&llvm_template), |
| 5665 | 5664 | buf_ptr(&constraint_buf), buf_len(&constraint_buf), is_volatile, false, LLVMInlineAsmDialectATT, false); |
| 5666 | 5665 | |
| 5667 | 5666 | LLVMValueRef built_call = LLVMBuildCall(g->builder, asm_fn, param_values, (unsigned)input_and_output_count, ""); |
| 5667 | ||
| 5668 | for (size_t i = 0; i < input_and_output_count; i += 1) { | |
| 5669 | if (param_needs_attr[i]) { | |
| 5670 | LLVMTypeRef elem_ty = LLVMGetElementType(param_types[i]); | |
| 5671 | ZigLLVMSetCallElemTypeAttr(built_call, i, elem_ty); | |
| 5672 | } | |
| 5673 | } | |
| 5674 | ||
| 5675 | ||
| 5676 | ||
| 5677 | heap::c_allocator.deallocate(param_types, input_and_output_count); | |
| 5668 | 5678 | heap::c_allocator.deallocate(param_values, input_and_output_count); |
| 5679 | heap::c_allocator.deallocate(param_needs_attr, input_and_output_count); | |
| 5669 | 5680 | return built_call; |
| 5670 | 5681 | } |
| 5671 | 5682 |
src/stage1/target.cpp+8| ... | ... | @@ -531,6 +531,7 @@ uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch) { |
| 531 | 531 | case ZigLLVM_renderscript32: |
| 532 | 532 | case ZigLLVM_aarch64_32: |
| 533 | 533 | case ZigLLVM_csky: |
| 534 | case ZigLLVM_spirv32: | |
| 534 | 535 | return 32; |
| 535 | 536 | |
| 536 | 537 | case ZigLLVM_aarch64: |
| ... | ... | @@ -554,6 +555,7 @@ uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch) { |
| 554 | 555 | case ZigLLVM_wasm64: |
| 555 | 556 | case ZigLLVM_renderscript64: |
| 556 | 557 | case ZigLLVM_ve: |
| 558 | case ZigLLVM_spirv64: | |
| 557 | 559 | return 64; |
| 558 | 560 | } |
| 559 | 561 | zig_unreachable(); |
| ... | ... | @@ -598,6 +600,7 @@ uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch) { |
| 598 | 600 | case ZigLLVM_wasm32: |
| 599 | 601 | case ZigLLVM_renderscript32: |
| 600 | 602 | case ZigLLVM_csky: |
| 603 | case ZigLLVM_spirv32: | |
| 601 | 604 | return 32; |
| 602 | 605 | |
| 603 | 606 | case ZigLLVM_aarch64: |
| ... | ... | @@ -621,6 +624,7 @@ uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch) { |
| 621 | 624 | case ZigLLVM_wasm64: |
| 622 | 625 | case ZigLLVM_renderscript64: |
| 623 | 626 | case ZigLLVM_ve: |
| 627 | case ZigLLVM_spirv64: | |
| 624 | 628 | return 64; |
| 625 | 629 | |
| 626 | 630 | case ZigLLVM_x86_64: |
| ... | ... | @@ -818,6 +822,8 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) { |
| 818 | 822 | |
| 819 | 823 | case ZigLLVM_wasm32: |
| 820 | 824 | case ZigLLVM_wasm64: |
| 825 | case ZigLLVM_spirv32: | |
| 826 | case ZigLLVM_spirv64: | |
| 821 | 827 | return nullptr; // known to be not available |
| 822 | 828 | |
| 823 | 829 | case ZigLLVM_amdgcn: |
| ... | ... | @@ -919,6 +925,8 @@ bool target_is_arm(const ZigTarget *target) { |
| 919 | 925 | case ZigLLVM_ppcle: |
| 920 | 926 | case ZigLLVM_ppc64: |
| 921 | 927 | case ZigLLVM_ve: |
| 928 | case ZigLLVM_spirv32: | |
| 929 | case ZigLLVM_spirv64: | |
| 922 | 930 | return false; |
| 923 | 931 | } |
| 924 | 932 | zig_unreachable(); |
src/translate_c.zig+1-1| ... | ... | @@ -4810,7 +4810,7 @@ fn transType(c: *Context, scope: *Scope, ty: *const clang.Type, source_loc: clan |
| 4810 | 4810 | .rhs = try transQualType(c, scope, element_qt, source_loc), |
| 4811 | 4811 | }); |
| 4812 | 4812 | }, |
| 4813 | .ExtInt, .ExtVector => { | |
| 4813 | .BitInt, .ExtVector => { | |
| 4814 | 4814 | const type_name = c.str(ty.getTypeClassName()); |
| 4815 | 4815 | return fail(c, error.UnsupportedType, source_loc, "TODO implement translation of type: '{s}'", .{type_name}); |
| 4816 | 4816 | }, |
src/zig_llvm.cpp+19-3| ... | ... | @@ -1064,12 +1064,20 @@ void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_v |
| 1064 | 1064 | func->addParamAttrs(ArgNo + 1, attr_builder); |
| 1065 | 1065 | } |
| 1066 | 1066 | |
| 1067 | void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val) { | |
| 1067 | void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val) { | |
| 1068 | 1068 | Function *func = unwrap<Function>(fn_ref); |
| 1069 | 1069 | AttrBuilder attr_builder(func->getContext()); |
| 1070 | 1070 | Type *llvm_type = unwrap<Type>(type_val); |
| 1071 | 1071 | attr_builder.addStructRetAttr(llvm_type); |
| 1072 | func->addParamAttrs(ArgNo + 1, attr_builder); | |
| 1072 | func->addParamAttrs(AttributeList::ReturnIndex, attr_builder); | |
| 1073 | } | |
| 1074 | ||
| 1075 | void ZigLLVMAddFunctionElemTypeAttr(LLVMValueRef fn_ref, size_t arg_index, LLVMTypeRef elem_ty) { | |
| 1076 | Function *func = unwrap<Function>(fn_ref); | |
| 1077 | AttrBuilder attr_builder(func->getContext()); | |
| 1078 | Type *llvm_type = unwrap<Type>(elem_ty); | |
| 1079 | attr_builder.addTypeAttr(Attribute::ElementType, llvm_type); | |
| 1080 | func->addParamAttrs(AttributeList::FirstArgIndex + arg_index, attr_builder); | |
| 1073 | 1081 | } |
| 1074 | 1082 | |
| 1075 | 1083 | void ZigLLVMAddFunctionAttr(LLVMValueRef fn_ref, const char *attr_name, const char *attr_value) { |
| ... | ... | @@ -1174,7 +1182,15 @@ void ZigLLVMSetTailCall(LLVMValueRef Call) { |
| 1174 | 1182 | void ZigLLVMSetCallSret(LLVMValueRef Call, LLVMTypeRef return_type) { |
| 1175 | 1183 | CallInst *call_inst = unwrap<CallInst>(Call); |
| 1176 | 1184 | Type *llvm_type = unwrap<Type>(return_type); |
| 1177 | call_inst->addParamAttr(1, Attribute::getWithStructRetType(call_inst->getContext(), llvm_type)); | |
| 1185 | call_inst->addParamAttr(AttributeList::ReturnIndex, | |
| 1186 | Attribute::getWithStructRetType(call_inst->getContext(), llvm_type)); | |
| 1187 | } | |
| 1188 | ||
| 1189 | void ZigLLVMSetCallElemTypeAttr(LLVMValueRef Call, size_t arg_index, LLVMTypeRef return_type) { | |
| 1190 | CallInst *call_inst = unwrap<CallInst>(Call); | |
| 1191 | Type *llvm_type = unwrap<Type>(return_type); | |
| 1192 | call_inst->addParamAttr(arg_index, | |
| 1193 | Attribute::get(call_inst->getContext(), Attribute::ElementType, llvm_type)); | |
| 1178 | 1194 | } |
| 1179 | 1195 | |
| 1180 | 1196 | void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) { |
src/zig_llvm.h+3-1| ... | ... | @@ -311,12 +311,14 @@ ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDbgValueIntrinsicAtEnd(struct ZigLLVMDIBu |
| 311 | 311 | ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state); |
| 312 | 312 | ZIG_EXTERN_C void ZigLLVMSetTailCall(LLVMValueRef Call); |
| 313 | 313 | ZIG_EXTERN_C void ZigLLVMSetCallSret(LLVMValueRef Call, LLVMTypeRef return_type); |
| 314 | ZIG_EXTERN_C void ZigLLVMSetCallElemTypeAttr(LLVMValueRef Call, size_t arg_index, LLVMTypeRef return_type); | |
| 314 | 315 | ZIG_EXTERN_C void ZigLLVMFunctionSetPrefixData(LLVMValueRef fn, LLVMValueRef data); |
| 315 | 316 | ZIG_EXTERN_C void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, enum ZigLLVM_CallingConv cc); |
| 316 | 317 | |
| 317 | 318 | ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value); |
| 318 | 319 | ZIG_EXTERN_C void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val); |
| 319 | ZIG_EXTERN_C void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val); | |
| 320 | ZIG_EXTERN_C void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val); | |
| 321 | ZIG_EXTERN_C void ZigLLVMAddFunctionElemTypeAttr(LLVMValueRef fn_ref, size_t arg_index, LLVMTypeRef elem_ty); | |
| 320 | 322 | ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn); |
| 321 | 323 | |
| 322 | 324 | ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv); |