From 1c40a4df094132db952157bf28253ed80646ea00 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 16 Dec 2020 17:54:49 +0100 Subject: Update zig_llvm.cpp and other bits Include updates to corresponding zig sources llvm commit b2851aea80e5a8f0cfd6c3c5a56a6b00fb28c6b6 --- src/zig_llvm.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/zig_llvm.cpp') diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 9b1ab71e9a..26d96133e2 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -600,8 +600,9 @@ void ZigLLVMDisposeDIBuilder(ZigLLVMDIBuilder *dbuilder) { } void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, int line, int column, ZigLLVMDIScope *scope) { - unwrap(builder)->SetCurrentDebugLocation(DebugLoc::get( - line, column, reinterpret_cast(scope))); + DIScope* di_scope = reinterpret_cast(scope); + DebugLoc debug_loc = DILocation::get(di_scope->getContext(), line, column, di_scope, nullptr, false); + unwrap(builder)->SetCurrentDebugLocation(debug_loc); } void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder) { @@ -762,7 +763,8 @@ LLVMValueRef ZigLLVMInsertDeclare(ZigLLVMDIBuilder *dibuilder, LLVMValueRef stor } ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScope *scope) { - DebugLoc debug_loc = DebugLoc::get(line, col, reinterpret_cast(scope), nullptr); + DIScope* di_scope = reinterpret_cast(scope); + DebugLoc debug_loc = DILocation::get(di_scope->getContext(), line, col, di_scope, nullptr, false); return reinterpret_cast(debug_loc.get()); } @@ -1180,6 +1182,7 @@ static_assert((Triple::ArchType)ZigLLVM_arc == Triple::arc, ""); static_assert((Triple::ArchType)ZigLLVM_avr == Triple::avr, ""); static_assert((Triple::ArchType)ZigLLVM_bpfel == Triple::bpfel, ""); static_assert((Triple::ArchType)ZigLLVM_bpfeb == Triple::bpfeb, ""); +static_assert((Triple::ArchType)ZigLLVM_csky == Triple::csky, ""); static_assert((Triple::ArchType)ZigLLVM_hexagon == Triple::hexagon, ""); static_assert((Triple::ArchType)ZigLLVM_mips == Triple::mips, ""); static_assert((Triple::ArchType)ZigLLVM_mipsel == Triple::mipsel, ""); @@ -1228,8 +1231,6 @@ static_assert((Triple::VendorType)ZigLLVM_UnknownVendor == Triple::UnknownVendor static_assert((Triple::VendorType)ZigLLVM_Apple == Triple::Apple, ""); static_assert((Triple::VendorType)ZigLLVM_PC == Triple::PC, ""); static_assert((Triple::VendorType)ZigLLVM_SCEI == Triple::SCEI, ""); -static_assert((Triple::VendorType)ZigLLVM_BGP == Triple::BGP, ""); -static_assert((Triple::VendorType)ZigLLVM_BGQ == Triple::BGQ, ""); static_assert((Triple::VendorType)ZigLLVM_Freescale == Triple::Freescale, ""); static_assert((Triple::VendorType)ZigLLVM_IBM == Triple::IBM, ""); static_assert((Triple::VendorType)ZigLLVM_ImaginationTechnologies == Triple::ImaginationTechnologies, ""); @@ -1261,11 +1262,11 @@ static_assert((Triple::OSType)ZigLLVM_NetBSD == Triple::NetBSD, ""); static_assert((Triple::OSType)ZigLLVM_OpenBSD == Triple::OpenBSD, ""); static_assert((Triple::OSType)ZigLLVM_Solaris == Triple::Solaris, ""); static_assert((Triple::OSType)ZigLLVM_Win32 == Triple::Win32, ""); +static_assert((Triple::OSType)ZigLLVM_ZOS == Triple::ZOS, ""); static_assert((Triple::OSType)ZigLLVM_Haiku == Triple::Haiku, ""); static_assert((Triple::OSType)ZigLLVM_Minix == Triple::Minix, ""); static_assert((Triple::OSType)ZigLLVM_RTEMS == Triple::RTEMS, ""); static_assert((Triple::OSType)ZigLLVM_NaCl == Triple::NaCl, ""); -static_assert((Triple::OSType)ZigLLVM_CNK == Triple::CNK, ""); static_assert((Triple::OSType)ZigLLVM_AIX == Triple::AIX, ""); static_assert((Triple::OSType)ZigLLVM_CUDA == Triple::CUDA, ""); static_assert((Triple::OSType)ZigLLVM_NVCL == Triple::NVCL, ""); @@ -1308,6 +1309,7 @@ static_assert((Triple::EnvironmentType)ZigLLVM_LastEnvironmentType == Triple::La static_assert((Triple::ObjectFormatType)ZigLLVM_UnknownObjectFormat == Triple::UnknownObjectFormat, ""); static_assert((Triple::ObjectFormatType)ZigLLVM_COFF == Triple::COFF, ""); static_assert((Triple::ObjectFormatType)ZigLLVM_ELF == Triple::ELF, ""); +static_assert((Triple::ObjectFormatType)ZigLLVM_GOFF == Triple::GOFF, ""); static_assert((Triple::ObjectFormatType)ZigLLVM_MachO == Triple::MachO, ""); static_assert((Triple::ObjectFormatType)ZigLLVM_Wasm == Triple::Wasm, ""); static_assert((Triple::ObjectFormatType)ZigLLVM_XCOFF == Triple::XCOFF, ""); -- cgit v1.2.3 From dc325669e360f7a9dfa24f85a62fa386529dade6 Mon Sep 17 00:00:00 2001 From: Michael Dusan Date: Thu, 25 Feb 2021 21:14:40 -0500 Subject: fix to compile against 12.0.0-rc2 --- src/stage1/target.cpp | 7 +++++++ src/zig_clang_cc1_main.cpp | 3 +-- src/zig_llvm.cpp | 2 ++ src/zig_llvm.h | 2 ++ 4 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src/zig_llvm.cpp') diff --git a/src/stage1/target.cpp b/src/stage1/target.cpp index 0af3827135..bfcde407d5 100644 --- a/src/stage1/target.cpp +++ b/src/stage1/target.cpp @@ -31,6 +31,7 @@ static const ZigLLVM_ArchType arch_list[] = { ZigLLVM_mips64el, // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el ZigLLVM_msp430, // MSP430: msp430 ZigLLVM_ppc, // PPC: powerpc + ZigLLVM_ppcle, // PPCLE: powerpc (little endian) ZigLLVM_ppc64, // PPC64: powerpc64, ppu ZigLLVM_ppc64le, // PPC64LE: powerpc64le ZigLLVM_r600, // R600: AMD GPUs HD2XXX - HD6XXX @@ -134,6 +135,7 @@ static const ZigLLVM_EnvironmentType abi_list[] = { ZigLLVM_GNUEABI, ZigLLVM_GNUEABIHF, ZigLLVM_GNUX32, + ZigLLVM_GNUILP32, ZigLLVM_CODE16, ZigLLVM_EABI, ZigLLVM_EABIHF, @@ -484,6 +486,7 @@ uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch) { case ZigLLVM_mipsel: case ZigLLVM_nvptx: case ZigLLVM_ppc: + case ZigLLVM_ppcle: case ZigLLVM_r600: case ZigLLVM_riscv32: case ZigLLVM_sparc: @@ -550,6 +553,7 @@ uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch) { case ZigLLVM_mipsel: case ZigLLVM_nvptx: case ZigLLVM_ppc: + case ZigLLVM_ppcle: case ZigLLVM_r600: case ZigLLVM_riscv32: case ZigLLVM_sparc: @@ -800,6 +804,7 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) { case ZigLLVM_riscv64: case ZigLLVM_mipsel: case ZigLLVM_ppc: + case ZigLLVM_ppcle: case ZigLLVM_ppc64: case ZigLLVM_ppc64le: return "sp"; @@ -904,6 +909,7 @@ bool target_is_arm(const ZigTarget *target) { case ZigLLVM_wasm64: case ZigLLVM_xcore: case ZigLLVM_ppc: + case ZigLLVM_ppcle: case ZigLLVM_ppc64: case ZigLLVM_ve: return false; @@ -1097,6 +1103,7 @@ const char *target_libc_generic_name(const ZigTarget *target) { case ZigLLVM_GNUEABI: case ZigLLVM_GNUEABIHF: case ZigLLVM_GNUX32: + case ZigLLVM_GNUILP32: return "glibc"; case ZigLLVM_Musl: case ZigLLVM_MuslEABI: diff --git a/src/zig_clang_cc1_main.cpp b/src/zig_clang_cc1_main.cpp index 0872015e0a..0918860015 100644 --- a/src/zig_clang_cc1_main.cpp +++ b/src/zig_clang_cc1_main.cpp @@ -251,8 +251,7 @@ int cc1_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { if (auto profilerOutput = Clang->createOutputFile(Path.str(), /*Binary=*/false, - /*RemoveFileOnSignal=*/false, "", - /*Extension=*/"json", + /*RemoveFileOnSignal=*/false, /*useTemporary=*/false)) { llvm::timeTraceProfilerWrite(*profilerOutput); diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 26d96133e2..8ae021f905 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -1190,6 +1190,7 @@ static_assert((Triple::ArchType)ZigLLVM_mips64 == Triple::mips64, ""); static_assert((Triple::ArchType)ZigLLVM_mips64el == Triple::mips64el, ""); static_assert((Triple::ArchType)ZigLLVM_msp430 == Triple::msp430, ""); static_assert((Triple::ArchType)ZigLLVM_ppc == Triple::ppc, ""); +static_assert((Triple::ArchType)ZigLLVM_ppcle == Triple::ppcle, ""); static_assert((Triple::ArchType)ZigLLVM_ppc64 == Triple::ppc64, ""); static_assert((Triple::ArchType)ZigLLVM_ppc64le == Triple::ppc64le, ""); static_assert((Triple::ArchType)ZigLLVM_r600 == Triple::r600, ""); @@ -1291,6 +1292,7 @@ static_assert((Triple::EnvironmentType)ZigLLVM_GNUABI64 == Triple::GNUABI64, "") static_assert((Triple::EnvironmentType)ZigLLVM_GNUEABI == Triple::GNUEABI, ""); static_assert((Triple::EnvironmentType)ZigLLVM_GNUEABIHF == Triple::GNUEABIHF, ""); static_assert((Triple::EnvironmentType)ZigLLVM_GNUX32 == Triple::GNUX32, ""); +static_assert((Triple::EnvironmentType)ZigLLVM_GNUILP32 == Triple::GNUILP32, ""); static_assert((Triple::EnvironmentType)ZigLLVM_CODE16 == Triple::CODE16, ""); static_assert((Triple::EnvironmentType)ZigLLVM_EABI == Triple::EABI, ""); static_assert((Triple::EnvironmentType)ZigLLVM_EABIHF == Triple::EABIHF, ""); diff --git a/src/zig_llvm.h b/src/zig_llvm.h index cae34ebc2d..78f42a9167 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -296,6 +296,7 @@ enum ZigLLVM_ArchType { ZigLLVM_mips64el, // MIPS64EL: mips64el, mips64r6el, mipsn32el, mipsn32r6el ZigLLVM_msp430, // MSP430: msp430 ZigLLVM_ppc, // PPC: powerpc + ZigLLVM_ppcle, // PPCLE: powerpc (little endian) ZigLLVM_ppc64, // PPC64: powerpc64, ppu ZigLLVM_ppc64le, // PPC64LE: powerpc64le ZigLLVM_r600, // R600: AMD GPUs HD2XXX - HD6XXX @@ -408,6 +409,7 @@ enum ZigLLVM_EnvironmentType { ZigLLVM_GNUEABI, ZigLLVM_GNUEABIHF, ZigLLVM_GNUX32, + ZigLLVM_GNUILP32, ZigLLVM_CODE16, ZigLLVM_EABI, ZigLLVM_EABIHF, -- cgit v1.2.3 From 685b5c26b703d54381a74b71361816ad85ec8584 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 26 Feb 2021 13:32:04 -0700 Subject: stage1: upgrade to new LLVM sret attribute requirement LLVM 12 requires sret attributes to have the struct type as a parameter, and provides no C function for supplying it. Therefore, we must add another C++ wrapper API for adding the sret attribute. Fixes ability to build from source in the llvm12 branch. --- src/stage1/codegen.cpp | 2 +- src/zig_llvm.cpp | 10 ++++++++++ src/zig_llvm.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src/zig_llvm.cpp') diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index fcb3282d06..3e9fbe20dd 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -549,7 +549,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { } else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) { // Sret pointers must not be address 0 addLLVMArgAttr(llvm_fn, 0, "nonnull"); - addLLVMArgAttr(llvm_fn, 0, "sret"); + ZigLLVMAddSRetAttr(llvm_fn, get_llvm_type(g, fn_type->data.fn.fn_type_id.return_type)); if (cc_want_sret_attr(cc)) { addLLVMArgAttr(llvm_fn, 0, "noalias"); } diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index b4bdf7c033..9b10f25d47 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -802,6 +802,16 @@ void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_v func->setAttributes(new_attr_set); } +void ZigLLVMAddSRetAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val) { + Function *func = unwrap(fn_ref); + const AttributeList attr_set = func->getAttributes(); + AttrBuilder attr_builder; + Type *llvm_type = unwrap(type_val); + attr_builder.addStructRetAttr(llvm_type); + const AttributeList new_attr_set = attr_set.addAttributes(func->getContext(), 1, attr_builder); + func->setAttributes(new_attr_set); +} + void ZigLLVMAddFunctionAttr(LLVMValueRef fn_ref, const char *attr_name, const char *attr_value) { Function *func = unwrap(fn_ref); const AttributeList attr_set = func->getAttributes(); diff --git a/src/zig_llvm.h b/src/zig_llvm.h index fc9f39d9e9..78909ad019 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -269,6 +269,7 @@ ZIG_EXTERN_C void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, enum ZigL ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value); ZIG_EXTERN_C void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val); +ZIG_EXTERN_C void ZigLLVMAddSRetAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val); ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn); ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv); -- cgit v1.2.3 From 431801707fa661a70660787ee499530d093d513b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 26 Feb 2021 13:47:33 -0700 Subject: Revert "stage1: upgrade to new LLVM sret attribute requirement" This reverts commit 685b5c26b703d54381a74b71361816ad85ec8584. @LemonBoy has a better patch, so reverting this to merge that one. --- src/stage1/codegen.cpp | 2 +- src/zig_llvm.cpp | 10 ---------- src/zig_llvm.h | 1 - 3 files changed, 1 insertion(+), 12 deletions(-) (limited to 'src/zig_llvm.cpp') diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 3e9fbe20dd..fcb3282d06 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -549,7 +549,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { } else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) { // Sret pointers must not be address 0 addLLVMArgAttr(llvm_fn, 0, "nonnull"); - ZigLLVMAddSRetAttr(llvm_fn, get_llvm_type(g, fn_type->data.fn.fn_type_id.return_type)); + addLLVMArgAttr(llvm_fn, 0, "sret"); if (cc_want_sret_attr(cc)) { addLLVMArgAttr(llvm_fn, 0, "noalias"); } diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 9b10f25d47..b4bdf7c033 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -802,16 +802,6 @@ void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_v func->setAttributes(new_attr_set); } -void ZigLLVMAddSRetAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val) { - Function *func = unwrap(fn_ref); - const AttributeList attr_set = func->getAttributes(); - AttrBuilder attr_builder; - Type *llvm_type = unwrap(type_val); - attr_builder.addStructRetAttr(llvm_type); - const AttributeList new_attr_set = attr_set.addAttributes(func->getContext(), 1, attr_builder); - func->setAttributes(new_attr_set); -} - void ZigLLVMAddFunctionAttr(LLVMValueRef fn_ref, const char *attr_name, const char *attr_value) { Function *func = unwrap(fn_ref); const AttributeList attr_set = func->getAttributes(); diff --git a/src/zig_llvm.h b/src/zig_llvm.h index 78909ad019..fc9f39d9e9 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -269,7 +269,6 @@ ZIG_EXTERN_C void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, enum ZigL ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value); ZIG_EXTERN_C void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val); -ZIG_EXTERN_C void ZigLLVMAddSRetAttr(LLVMValueRef fn_ref, LLVMTypeRef type_val); ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn); ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv); -- cgit v1.2.3 From b706b9bce798666937b7cafde9d778085cbf4e2f Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 26 Feb 2021 15:24:08 +0100 Subject: stage1: Fix emission of sret annotation for LLVM LLVM12 deprecated `sret` and replaced it with the `sret()` form. Closes #8075 --- src/stage1/codegen.cpp | 4 ++-- src/zig_llvm.cpp | 12 +++++++++++- src/zig_llvm.h | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) (limited to 'src/zig_llvm.cpp') diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index fcb3282d06..389ede91b7 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -549,7 +549,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { } else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) { // Sret pointers must not be address 0 addLLVMArgAttr(llvm_fn, 0, "nonnull"); - addLLVMArgAttr(llvm_fn, 0, "sret"); + ZigLLVMAddSretAttr(llvm_fn, 0, get_llvm_type(g, return_type)); if (cc_want_sret_attr(cc)) { addLLVMArgAttr(llvm_fn, 0, "noalias"); } @@ -1972,7 +1972,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ switch (fn_walk->id) { case FnWalkIdAttrs: if (abi_class != X64CABIClass_MEMORY_nobyval) { - ZigLLVMAddByValAttr(llvm_fn, fn_walk->data.attrs.gen_i + 1, get_llvm_type(g, ty)); + ZigLLVMAddByValAttr(llvm_fn, fn_walk->data.attrs.gen_i, get_llvm_type(g, ty)); addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); } else if (g->zig_target->arch == ZigLLVM_aarch64 || g->zig_target->arch == ZigLLVM_aarch64_be) diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index b4bdf7c033..55e507c6d0 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -798,7 +798,17 @@ void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_v AttrBuilder attr_builder; Type *llvm_type = unwrap(type_val); attr_builder.addByValAttr(llvm_type); - const AttributeList new_attr_set = attr_set.addAttributes(func->getContext(), ArgNo, attr_builder); + const AttributeList new_attr_set = attr_set.addAttributes(func->getContext(), ArgNo + 1, attr_builder); + func->setAttributes(new_attr_set); +} + +void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val) { + Function *func = unwrap(fn_ref); + const AttributeList attr_set = func->getAttributes(); + AttrBuilder attr_builder; + Type *llvm_type = unwrap(type_val); + attr_builder.addStructRetAttr(llvm_type); + const AttributeList new_attr_set = attr_set.addAttributes(func->getContext(), ArgNo + 1, attr_builder); func->setAttributes(new_attr_set); } diff --git a/src/zig_llvm.h b/src/zig_llvm.h index fc9f39d9e9..c8ffa32e81 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -269,6 +269,7 @@ ZIG_EXTERN_C void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, enum ZigL ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value); ZIG_EXTERN_C void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val); +ZIG_EXTERN_C void ZigLLVMAddSretAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val); ZIG_EXTERN_C void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn); ZIG_EXTERN_C void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv); -- cgit v1.2.3 From 72404db31f76635f11d0aa4dcc02c149ef885b3d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 28 Feb 2021 22:01:13 -0700 Subject: stage1: update to LLVM 12 sret callsite requirements Without this, the LLVM IR that zig generates cannot be compiled by LLVM. --- src/stage1/codegen.cpp | 8 +------- src/zig_llvm.cpp | 9 +++++++++ src/zig_llvm.h | 1 + 3 files changed, 11 insertions(+), 7 deletions(-) (limited to 'src/zig_llvm.cpp') diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 389ede91b7..1338f58e30 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -4037,12 +4037,6 @@ static void gen_set_stack_pointer(CodeGen *g, LLVMValueRef aligned_end_addr) { LLVMBuildCall(g->builder, write_register_fn_val, params, 2, ""); } -static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) { - unsigned attr_kind_id = LLVMGetEnumAttributeKindForName("sret", 4); - LLVMAttributeRef sret_attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), attr_kind_id, 0); - LLVMAddCallSiteAttribute(call_instr, 1, sret_attr); -} - static void render_async_spills(CodeGen *g) { ZigType *fn_type = g->cur_fn->type_entry; ZigType *import = get_scope_import(&g->cur_fn->fndef_scope->base); @@ -4558,7 +4552,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn } else if (!ret_has_bits) { return nullptr; } else if (first_arg_ret) { - set_call_instr_sret(g, result); + ZigLLVMSetCallSret(result, get_llvm_type(g, src_return_type)); return result_loc; } else if (handle_is_ptr(g, src_return_type)) { LLVMValueRef store_instr = LLVMBuildStore(g->builder, result, result_loc); diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 55e507c6d0..5a7d60f83b 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -940,6 +940,15 @@ void ZigLLVMSetTailCall(LLVMValueRef Call) { unwrap(Call)->setTailCallKind(CallInst::TCK_MustTail); } +void ZigLLVMSetCallSret(LLVMValueRef Call, LLVMTypeRef return_type) { + const AttributeList attr_set = unwrap(Call)->getAttributes(); + AttrBuilder attr_builder; + Type *llvm_type = unwrap(return_type); + attr_builder.addStructRetAttr(llvm_type); + const AttributeList new_attr_set = attr_set.addAttributes(unwrap(Call)->getContext(), 1, attr_builder); + unwrap(Call)->setAttributes(new_attr_set); +} + void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) { unwrap(function)->setPrefixData(unwrap(data)); } diff --git a/src/zig_llvm.h b/src/zig_llvm.h index c8ffa32e81..0d08980835 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -264,6 +264,7 @@ ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigne ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state); ZIG_EXTERN_C void ZigLLVMSetTailCall(LLVMValueRef Call); +ZIG_EXTERN_C void ZigLLVMSetCallSret(LLVMValueRef Call, LLVMTypeRef return_type); ZIG_EXTERN_C void ZigLLVMFunctionSetPrefixData(LLVMValueRef fn, LLVMValueRef data); ZIG_EXTERN_C void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, enum ZigLLVM_CallingConv cc); -- cgit v1.2.3 From 0d53a2bff01750f9220bcc861d662b2c5f304506 Mon Sep 17 00:00:00 2001 From: Min-Yih Hsu Date: Mon, 29 Mar 2021 18:13:07 -0700 Subject: llvm new-pm: Port LLVM 11.x-based changes to LLVM 12.x Now zig will use new PM for optimization by default. --- src/zig_llvm.cpp | 205 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 112 insertions(+), 93 deletions(-) (limited to 'src/zig_llvm.cpp') diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 5a7d60f83b..c4ef5e8704 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -20,6 +20,7 @@ #pragma GCC diagnostic ignored "-Winit-list-lifetime" #endif +#include #include #include #include @@ -30,9 +31,12 @@ #include #include #include +#include #include #include #include +#include +#include #include #include #include @@ -54,6 +58,9 @@ #include #include #include +#include +#include +#include #include @@ -190,12 +197,12 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM { TimePassesIsEnabled = time_report; - raw_fd_ostream *dest_asm = nullptr; - raw_fd_ostream *dest_bin = nullptr; + raw_fd_ostream *dest_asm_ptr = nullptr; + raw_fd_ostream *dest_bin_ptr = nullptr; if (asm_filename) { std::error_code EC; - dest_asm = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::F_None); + dest_asm_ptr = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::F_None); if (EC) { *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); return true; @@ -203,116 +210,128 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM } if (bin_filename) { std::error_code EC; - dest_bin = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::F_None); + dest_bin_ptr = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::F_None); if (EC) { *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); return true; } } - TargetMachine* target_machine = reinterpret_cast(targ_machine_ref); - target_machine->setO0WantsFastISel(true); - - Module* module = unwrap(module_ref); - - PassManagerBuilder *PMBuilder = new(std::nothrow) PassManagerBuilder(); - if (PMBuilder == nullptr) { - *error_message = strdup("memory allocation failure"); - return true; - } - PMBuilder->OptLevel = target_machine->getOptLevel(); - PMBuilder->SizeLevel = is_small ? 2 : 0; - - PMBuilder->DisableTailCalls = is_debug; - PMBuilder->DisableUnrollLoops = is_debug; - PMBuilder->SLPVectorize = !is_debug; - PMBuilder->LoopVectorize = !is_debug; - PMBuilder->LoopsInterleaved = !PMBuilder->DisableUnrollLoops; - PMBuilder->RerollLoops = !is_debug; - // Leaving NewGVN as default (off) because when on it caused issue #673 - //PMBuilder->NewGVN = !is_debug; - PMBuilder->DisableGVNLoadPRE = is_debug; - PMBuilder->VerifyInput = assertions_on; - PMBuilder->VerifyOutput = assertions_on; - PMBuilder->MergeFunctions = !is_debug; - PMBuilder->PrepareForLTO = lto; - PMBuilder->PrepareForThinLTO = false; - PMBuilder->PerformThinLTO = false; - - TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple())); - PMBuilder->LibraryInfo = &tlii; - - if (is_debug) { - PMBuilder->Inliner = createAlwaysInlinerLegacyPass(false); - } else { - target_machine->adjustPassManager(*PMBuilder); - - PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, addDiscriminatorsPass); - PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel, false); + std::unique_ptr dest_asm(dest_asm_ptr), + dest_bin(dest_bin_ptr); + + TargetMachine &target_machine = *reinterpret_cast(targ_machine_ref); + target_machine.setO0WantsFastISel(true); + + Module &module = *unwrap(module_ref); + + PipelineTuningOptions pipeline_opts; + pipeline_opts.LoopUnrolling = !is_debug; + pipeline_opts.SLPVectorization = !is_debug; + pipeline_opts.LoopVectorization = !is_debug; + pipeline_opts.LoopInterleaving = !is_debug; + + PassInstrumentationCallbacks instr_callbacks; + StandardInstrumentations std_instrumentations(false); + std_instrumentations.registerCallbacks(instr_callbacks); + + PassBuilder pass_builder(false, &target_machine, pipeline_opts, + None, &instr_callbacks); + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + + LoopAnalysisManager loop_am; + FunctionAnalysisManager function_am; + CGSCCAnalysisManager cgscc_am; + ModuleAnalysisManager module_am; + + // Register the AA manager first so that our version is the one used + function_am.registerPass([&] { + return pass_builder.buildDefaultAAPipeline(); + }); + + Triple target_triple(module.getTargetTriple()); + auto tlii = std::make_unique(target_triple); + function_am.registerPass([&] { return TargetLibraryAnalysis(*tlii); }); + + pass_builder.registerModuleAnalyses(module_am); + pass_builder.registerCGSCCAnalyses(cgscc_am); + pass_builder.registerFunctionAnalyses(function_am); + pass_builder.registerLoopAnalyses(loop_am); + pass_builder.crossRegisterProxies(loop_am, function_am, + cgscc_am, module_am); + + if (!is_debug) { + pass_builder.registerPipelineStartEPCallback( + [](ModulePassManager &module_pm, OptimizationLevel OL) { + module_pm.addPass( + createModuleToFunctionPassAdaptor(AddDiscriminatorsPass())); + }); } if (tsan) { - PMBuilder->addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); - PMBuilder->addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); + pass_builder.registerOptimizerLastEPCallback( + [](ModulePassManager &module_pm, OptimizationLevel level) { + // Will be enabled regardless of optimization level + module_pm.addPass(ThreadSanitizerPass()); + }); } - // Set up the per-function pass manager. - legacy::FunctionPassManager FPM = legacy::FunctionPassManager(module); - auto tliwp = new(std::nothrow) TargetLibraryInfoWrapperPass(tlii); - FPM.add(tliwp); - FPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); - if (assertions_on) { - FPM.add(createVerifierPass()); + ModulePassManager module_pm; + // FIXME: NewPM can not detach speed level from size level + // we can't create something like "maximum speed level and optimal size level" + // which is what the original code wanted to achieve + OptimizationLevel opt_level; + if (is_debug) + opt_level = OptimizationLevel::O0; + else if (is_small) + opt_level = OptimizationLevel::Oz; + else + opt_level = OptimizationLevel::O3; + + if (lto) { + module_pm = pass_builder.buildLTOPreLinkDefaultPipeline(opt_level); + module_pm.addPass(CanonicalizeAliasesPass()); + module_pm.addPass(NameAnonGlobalPass()); + } else { + module_pm = pass_builder.buildPerModuleDefaultPipeline(opt_level); } - PMBuilder->populateFunctionPassManager(FPM); - - { - // Set up the per-module pass manager. - legacy::PassManager MPM; - MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); - PMBuilder->populateModulePassManager(MPM); - - // Set output passes. - if (dest_bin && !lto) { - if (target_machine->addPassesToEmitFile(MPM, *dest_bin, nullptr, CGFT_ObjectFile)) { - *error_message = strdup("TargetMachine can't emit an object file"); - return true; - } - } - if (dest_asm) { - if (target_machine->addPassesToEmitFile(MPM, *dest_asm, nullptr, CGFT_AssemblyFile)) { - *error_message = strdup("TargetMachine can't emit an assembly file"); - return true; - } - } - - // run per function optimization passes - FPM.doInitialization(); - for (Function &F : *module) - if (!F.isDeclaration()) - FPM.run(F); - FPM.doFinalization(); - MPM.run(*module); + // Unfortunately we don't have new PM for code generation + legacy::PassManager codegen_pm; + codegen_pm.add( + createTargetTransformInfoWrapperPass(target_machine.getTargetIRAnalysis())); - if (llvm_ir_filename) { - if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) { - return true; - } + if (dest_bin && !lto) { + if (target_machine.addPassesToEmitFile(codegen_pm, *dest_bin, nullptr, CGFT_ObjectFile)) { + *error_message = strdup("TargetMachine can't emit an object file"); + return true; } - if (dest_bin && lto) { - WriteBitcodeToFile(*module, *dest_bin); + } + if (dest_asm) { + if (target_machine.addPassesToEmitFile(codegen_pm, *dest_asm, nullptr, CGFT_AssemblyFile)) { + *error_message = strdup("TargetMachine can't emit an assembly file"); + return true; } + } - if (time_report) { - TimerGroup::printAll(errs()); - } + // optimization + module_pm.run(module, module_am); - // MPM goes out of scope and writes to the out streams + // code generation + codegen_pm.run(module); + + if (llvm_ir_filename) { + if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) { + return true; + } + } + if (dest_bin && lto) { + WriteBitcodeToFile(module, *dest_bin); } - delete dest_asm; - delete dest_bin; + if (time_report) { + TimerGroup::printAll(errs()); + } return false; } -- cgit v1.2.3 From 94383d14df77fa638dac14f4b2bda5a2e3f21c5c Mon Sep 17 00:00:00 2001 From: Min-Yih Hsu Date: Tue, 30 Mar 2021 13:34:20 -0700 Subject: llvm new-pm: Add missing pipeline option and Passes - Enable MergeFunctionsPass in non-debug build. - Verify input and output IR when the assertion is turned on. - Add AlwaysInlinePass in debug build. - Add more comments. --- src/zig_llvm.cpp | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'src/zig_llvm.cpp') diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index c4ef5e8704..7c07796480 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -195,6 +195,8 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM bool is_small, bool time_report, bool tsan, bool lto, const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename) { + // TODO: Maybe we should collect time trace rather than using timer + // to get a more hierarchical timeline view TimePassesIsEnabled = time_report; raw_fd_ostream *dest_asm_ptr = nullptr; @@ -225,12 +227,15 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM Module &module = *unwrap(module_ref); + // Pipeline configurations PipelineTuningOptions pipeline_opts; pipeline_opts.LoopUnrolling = !is_debug; pipeline_opts.SLPVectorization = !is_debug; pipeline_opts.LoopVectorization = !is_debug; pipeline_opts.LoopInterleaving = !is_debug; + pipeline_opts.MergeFunctions = !is_debug; + // Instrumentations PassInstrumentationCallbacks instr_callbacks; StandardInstrumentations std_instrumentations(false); std_instrumentations.registerCallbacks(instr_callbacks); @@ -253,6 +258,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM auto tlii = std::make_unique(target_triple); function_am.registerPass([&] { return TargetLibraryAnalysis(*tlii); }); + // Initialize the AnalysisManagers pass_builder.registerModuleAnalyses(module_am); pass_builder.registerCGSCCAnalyses(cgscc_am); pass_builder.registerFunctionAnalyses(function_am); @@ -260,7 +266,29 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM pass_builder.crossRegisterProxies(loop_am, function_am, cgscc_am, module_am); - if (!is_debug) { + // IR verification + if (assertions_on) { + // Verify the input + pass_builder.registerPipelineStartEPCallback( + [](ModulePassManager &module_pm, OptimizationLevel OL) { + module_pm.addPass(VerifierPass()); + }); + // Verify the output + pass_builder.registerOptimizerLastEPCallback( + [](ModulePassManager &module_pm, OptimizationLevel OL) { + module_pm.addPass(VerifierPass()); + }); + } + + // Passes for either debug or release build + if (is_debug) { + // NOTE: Always inliner will go away (in debug build) + // when the self-hosted compiler becomes mature. + pass_builder.registerPipelineStartEPCallback( + [](ModulePassManager &module_pm, OptimizationLevel OL) { + module_pm.addPass(AlwaysInlinerPass()); + }); + } else { pass_builder.registerPipelineStartEPCallback( [](ModulePassManager &module_pm, OptimizationLevel OL) { module_pm.addPass( @@ -268,19 +296,17 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM }); } + // Thread sanitizer if (tsan) { pass_builder.registerOptimizerLastEPCallback( [](ModulePassManager &module_pm, OptimizationLevel level) { - // Will be enabled regardless of optimization level module_pm.addPass(ThreadSanitizerPass()); }); } ModulePassManager module_pm; - // FIXME: NewPM can not detach speed level from size level - // we can't create something like "maximum speed level and optimal size level" - // which is what the original code wanted to achieve OptimizationLevel opt_level; + // Setting up the optimization level if (is_debug) opt_level = OptimizationLevel::O0; else if (is_small) @@ -288,6 +314,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM else opt_level = OptimizationLevel::O3; + // Initialize the PassManager if (lto) { module_pm = pass_builder.buildLTOPreLinkDefaultPipeline(opt_level); module_pm.addPass(CanonicalizeAliasesPass()); @@ -314,10 +341,10 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM } } - // optimization + // Optimization phase module_pm.run(module, module_am); - // code generation + // Code generation phase codegen_pm.run(module); if (llvm_ir_filename) { @@ -325,6 +352,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM return true; } } + if (dest_bin && lto) { WriteBitcodeToFile(module, *dest_bin); } -- cgit v1.2.3 From ba1bea2fe87b73a53a3ecd729789853dcc56affe Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 2 Apr 2021 12:10:39 -0700 Subject: zig_llvm.cpp: remove dead code --- src/zig_llvm.cpp | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/zig_llvm.cpp') diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 7c07796480..d26dc97874 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -98,14 +98,6 @@ char *ZigLLVMGetNativeFeatures(void) { return strdup((const char *)StringRef(features.getString()).bytes_begin()); } -static void addDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createAddDiscriminatorsPass()); -} - -static void addThreadSanitizerPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createThreadSanitizerLegacyPassPass()); -} - #ifndef NDEBUG static const bool assertions_on = true; #else -- cgit v1.2.3 From 09008125e7944ae01bb907f2eb8dbff41d7a0715 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 2 Apr 2021 14:35:01 -0700 Subject: Revert back to the old LLVM PassManager See #8418 This reverts commit ba1bea2fe87b73a53a3ecd729789853dcc56affe. This reverts commit 94383d14df77fa638dac14f4b2bda5a2e3f21c5c. This reverts commit 0d53a2bff01750f9220bcc861d662b2c5f304506. --- src/zig_llvm.cpp | 231 +++++++++++++++++++++++-------------------------------- 1 file changed, 96 insertions(+), 135 deletions(-) (limited to 'src/zig_llvm.cpp') diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index d26dc97874..5a7d60f83b 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -20,7 +20,6 @@ #pragma GCC diagnostic ignored "-Winit-list-lifetime" #endif -#include #include #include #include @@ -31,12 +30,9 @@ #include #include #include -#include #include #include #include -#include -#include #include #include #include @@ -58,9 +54,6 @@ #include #include #include -#include -#include -#include #include @@ -98,6 +91,14 @@ char *ZigLLVMGetNativeFeatures(void) { return strdup((const char *)StringRef(features.getString()).bytes_begin()); } +static void addDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { + PM.add(createAddDiscriminatorsPass()); +} + +static void addThreadSanitizerPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { + PM.add(createThreadSanitizerLegacyPassPass()); +} + #ifndef NDEBUG static const bool assertions_on = true; #else @@ -187,16 +188,14 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM bool is_small, bool time_report, bool tsan, bool lto, const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename) { - // TODO: Maybe we should collect time trace rather than using timer - // to get a more hierarchical timeline view TimePassesIsEnabled = time_report; - raw_fd_ostream *dest_asm_ptr = nullptr; - raw_fd_ostream *dest_bin_ptr = nullptr; + raw_fd_ostream *dest_asm = nullptr; + raw_fd_ostream *dest_bin = nullptr; if (asm_filename) { std::error_code EC; - dest_asm_ptr = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::F_None); + dest_asm = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::F_None); if (EC) { *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); return true; @@ -204,155 +203,117 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM } if (bin_filename) { std::error_code EC; - dest_bin_ptr = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::F_None); + dest_bin = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::F_None); if (EC) { *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); return true; } } - std::unique_ptr dest_asm(dest_asm_ptr), - dest_bin(dest_bin_ptr); - - TargetMachine &target_machine = *reinterpret_cast(targ_machine_ref); - target_machine.setO0WantsFastISel(true); - - Module &module = *unwrap(module_ref); - - // Pipeline configurations - PipelineTuningOptions pipeline_opts; - pipeline_opts.LoopUnrolling = !is_debug; - pipeline_opts.SLPVectorization = !is_debug; - pipeline_opts.LoopVectorization = !is_debug; - pipeline_opts.LoopInterleaving = !is_debug; - pipeline_opts.MergeFunctions = !is_debug; - - // Instrumentations - PassInstrumentationCallbacks instr_callbacks; - StandardInstrumentations std_instrumentations(false); - std_instrumentations.registerCallbacks(instr_callbacks); - - PassBuilder pass_builder(false, &target_machine, pipeline_opts, - None, &instr_callbacks); - using OptimizationLevel = typename PassBuilder::OptimizationLevel; - - LoopAnalysisManager loop_am; - FunctionAnalysisManager function_am; - CGSCCAnalysisManager cgscc_am; - ModuleAnalysisManager module_am; - - // Register the AA manager first so that our version is the one used - function_am.registerPass([&] { - return pass_builder.buildDefaultAAPipeline(); - }); - - Triple target_triple(module.getTargetTriple()); - auto tlii = std::make_unique(target_triple); - function_am.registerPass([&] { return TargetLibraryAnalysis(*tlii); }); - - // Initialize the AnalysisManagers - pass_builder.registerModuleAnalyses(module_am); - pass_builder.registerCGSCCAnalyses(cgscc_am); - pass_builder.registerFunctionAnalyses(function_am); - pass_builder.registerLoopAnalyses(loop_am); - pass_builder.crossRegisterProxies(loop_am, function_am, - cgscc_am, module_am); - - // IR verification - if (assertions_on) { - // Verify the input - pass_builder.registerPipelineStartEPCallback( - [](ModulePassManager &module_pm, OptimizationLevel OL) { - module_pm.addPass(VerifierPass()); - }); - // Verify the output - pass_builder.registerOptimizerLastEPCallback( - [](ModulePassManager &module_pm, OptimizationLevel OL) { - module_pm.addPass(VerifierPass()); - }); + TargetMachine* target_machine = reinterpret_cast(targ_machine_ref); + target_machine->setO0WantsFastISel(true); + + Module* module = unwrap(module_ref); + + PassManagerBuilder *PMBuilder = new(std::nothrow) PassManagerBuilder(); + if (PMBuilder == nullptr) { + *error_message = strdup("memory allocation failure"); + return true; } + PMBuilder->OptLevel = target_machine->getOptLevel(); + PMBuilder->SizeLevel = is_small ? 2 : 0; + + PMBuilder->DisableTailCalls = is_debug; + PMBuilder->DisableUnrollLoops = is_debug; + PMBuilder->SLPVectorize = !is_debug; + PMBuilder->LoopVectorize = !is_debug; + PMBuilder->LoopsInterleaved = !PMBuilder->DisableUnrollLoops; + PMBuilder->RerollLoops = !is_debug; + // Leaving NewGVN as default (off) because when on it caused issue #673 + //PMBuilder->NewGVN = !is_debug; + PMBuilder->DisableGVNLoadPRE = is_debug; + PMBuilder->VerifyInput = assertions_on; + PMBuilder->VerifyOutput = assertions_on; + PMBuilder->MergeFunctions = !is_debug; + PMBuilder->PrepareForLTO = lto; + PMBuilder->PrepareForThinLTO = false; + PMBuilder->PerformThinLTO = false; + + TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple())); + PMBuilder->LibraryInfo = &tlii; - // Passes for either debug or release build if (is_debug) { - // NOTE: Always inliner will go away (in debug build) - // when the self-hosted compiler becomes mature. - pass_builder.registerPipelineStartEPCallback( - [](ModulePassManager &module_pm, OptimizationLevel OL) { - module_pm.addPass(AlwaysInlinerPass()); - }); + PMBuilder->Inliner = createAlwaysInlinerLegacyPass(false); } else { - pass_builder.registerPipelineStartEPCallback( - [](ModulePassManager &module_pm, OptimizationLevel OL) { - module_pm.addPass( - createModuleToFunctionPassAdaptor(AddDiscriminatorsPass())); - }); + target_machine->adjustPassManager(*PMBuilder); + + PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, addDiscriminatorsPass); + PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel, false); } - // Thread sanitizer if (tsan) { - pass_builder.registerOptimizerLastEPCallback( - [](ModulePassManager &module_pm, OptimizationLevel level) { - module_pm.addPass(ThreadSanitizerPass()); - }); + PMBuilder->addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); + PMBuilder->addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); } - ModulePassManager module_pm; - OptimizationLevel opt_level; - // Setting up the optimization level - if (is_debug) - opt_level = OptimizationLevel::O0; - else if (is_small) - opt_level = OptimizationLevel::Oz; - else - opt_level = OptimizationLevel::O3; - - // Initialize the PassManager - if (lto) { - module_pm = pass_builder.buildLTOPreLinkDefaultPipeline(opt_level); - module_pm.addPass(CanonicalizeAliasesPass()); - module_pm.addPass(NameAnonGlobalPass()); - } else { - module_pm = pass_builder.buildPerModuleDefaultPipeline(opt_level); + // Set up the per-function pass manager. + legacy::FunctionPassManager FPM = legacy::FunctionPassManager(module); + auto tliwp = new(std::nothrow) TargetLibraryInfoWrapperPass(tlii); + FPM.add(tliwp); + FPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); + if (assertions_on) { + FPM.add(createVerifierPass()); } - - // Unfortunately we don't have new PM for code generation - legacy::PassManager codegen_pm; - codegen_pm.add( - createTargetTransformInfoWrapperPass(target_machine.getTargetIRAnalysis())); - - if (dest_bin && !lto) { - if (target_machine.addPassesToEmitFile(codegen_pm, *dest_bin, nullptr, CGFT_ObjectFile)) { - *error_message = strdup("TargetMachine can't emit an object file"); - return true; + PMBuilder->populateFunctionPassManager(FPM); + + { + // Set up the per-module pass manager. + legacy::PassManager MPM; + MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); + PMBuilder->populateModulePassManager(MPM); + + // Set output passes. + if (dest_bin && !lto) { + if (target_machine->addPassesToEmitFile(MPM, *dest_bin, nullptr, CGFT_ObjectFile)) { + *error_message = strdup("TargetMachine can't emit an object file"); + return true; + } } - } - if (dest_asm) { - if (target_machine.addPassesToEmitFile(codegen_pm, *dest_asm, nullptr, CGFT_AssemblyFile)) { - *error_message = strdup("TargetMachine can't emit an assembly file"); - return true; + if (dest_asm) { + if (target_machine->addPassesToEmitFile(MPM, *dest_asm, nullptr, CGFT_AssemblyFile)) { + *error_message = strdup("TargetMachine can't emit an assembly file"); + return true; + } } - } - // Optimization phase - module_pm.run(module, module_am); + // run per function optimization passes + FPM.doInitialization(); + for (Function &F : *module) + if (!F.isDeclaration()) + FPM.run(F); + FPM.doFinalization(); - // Code generation phase - codegen_pm.run(module); + MPM.run(*module); - if (llvm_ir_filename) { - if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) { - return true; + if (llvm_ir_filename) { + if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) { + return true; + } + } + if (dest_bin && lto) { + WriteBitcodeToFile(*module, *dest_bin); } - } - if (dest_bin && lto) { - WriteBitcodeToFile(module, *dest_bin); - } + if (time_report) { + TimerGroup::printAll(errs()); + } - if (time_report) { - TimerGroup::printAll(errs()); + // MPM goes out of scope and writes to the out streams } + delete dest_asm; + delete dest_bin; + return false; } -- cgit v1.2.3 From 10c2b36444788ae0518dfc8908a4821f4e60ed67 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Tue, 6 Apr 2021 16:02:18 +0200 Subject: stage1: Work around a small problem in LLVM API The missing initializer for a single field in the TargetOptions class was enough to turn the stack protectors into hot garbage. Fixes #8408 --- src/zig_llvm.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/zig_llvm.cpp') diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 5a7d60f83b..12ae9de75e 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -153,6 +153,11 @@ LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Tri } TargetOptions opt; + + // Work around the missing initialization of this field in the default + // constructor. Use -1 so that the default value is used. + opt.StackProtectorGuardOffset = (unsigned)-1; + opt.FunctionSections = function_sections; switch (float_abi) { case ZigLLVMABITypeDefault: -- cgit v1.2.3 From 6b3eaa62e86d2652cf0b0802d704ab16d148c2ce Mon Sep 17 00:00:00 2001 From: Min-Yih Hsu Date: Mon, 5 Apr 2021 13:26:15 -0700 Subject: Revert "Revert back to the old LLVM PassManager" This reverts commit 09008125e7944ae01bb907f2eb8dbff41d7a0715. --- src/zig_llvm.cpp | 231 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 135 insertions(+), 96 deletions(-) (limited to 'src/zig_llvm.cpp') diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 12ae9de75e..0d60d7a4ac 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -20,6 +20,7 @@ #pragma GCC diagnostic ignored "-Winit-list-lifetime" #endif +#include #include #include #include @@ -30,9 +31,12 @@ #include #include #include +#include #include #include #include +#include +#include #include #include #include @@ -54,6 +58,9 @@ #include #include #include +#include +#include +#include #include @@ -91,14 +98,6 @@ char *ZigLLVMGetNativeFeatures(void) { return strdup((const char *)StringRef(features.getString()).bytes_begin()); } -static void addDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createAddDiscriminatorsPass()); -} - -static void addThreadSanitizerPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { - PM.add(createThreadSanitizerLegacyPassPass()); -} - #ifndef NDEBUG static const bool assertions_on = true; #else @@ -193,14 +192,16 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM bool is_small, bool time_report, bool tsan, bool lto, const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename) { + // TODO: Maybe we should collect time trace rather than using timer + // to get a more hierarchical timeline view TimePassesIsEnabled = time_report; - raw_fd_ostream *dest_asm = nullptr; - raw_fd_ostream *dest_bin = nullptr; + raw_fd_ostream *dest_asm_ptr = nullptr; + raw_fd_ostream *dest_bin_ptr = nullptr; if (asm_filename) { std::error_code EC; - dest_asm = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::F_None); + dest_asm_ptr = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::F_None); if (EC) { *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); return true; @@ -208,116 +209,154 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM } if (bin_filename) { std::error_code EC; - dest_bin = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::F_None); + dest_bin_ptr = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::F_None); if (EC) { *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); return true; } } - TargetMachine* target_machine = reinterpret_cast(targ_machine_ref); - target_machine->setO0WantsFastISel(true); - - Module* module = unwrap(module_ref); - - PassManagerBuilder *PMBuilder = new(std::nothrow) PassManagerBuilder(); - if (PMBuilder == nullptr) { - *error_message = strdup("memory allocation failure"); - return true; + std::unique_ptr dest_asm(dest_asm_ptr), + dest_bin(dest_bin_ptr); + + TargetMachine &target_machine = *reinterpret_cast(targ_machine_ref); + target_machine.setO0WantsFastISel(true); + + Module &module = *unwrap(module_ref); + + // Pipeline configurations + PipelineTuningOptions pipeline_opts; + pipeline_opts.LoopUnrolling = !is_debug; + pipeline_opts.SLPVectorization = !is_debug; + pipeline_opts.LoopVectorization = !is_debug; + pipeline_opts.LoopInterleaving = !is_debug; + pipeline_opts.MergeFunctions = !is_debug; + + // Instrumentations + PassInstrumentationCallbacks instr_callbacks; + StandardInstrumentations std_instrumentations(false); + std_instrumentations.registerCallbacks(instr_callbacks); + + PassBuilder pass_builder(false, &target_machine, pipeline_opts, + None, &instr_callbacks); + using OptimizationLevel = typename PassBuilder::OptimizationLevel; + + LoopAnalysisManager loop_am; + FunctionAnalysisManager function_am; + CGSCCAnalysisManager cgscc_am; + ModuleAnalysisManager module_am; + + // Register the AA manager first so that our version is the one used + function_am.registerPass([&] { + return pass_builder.buildDefaultAAPipeline(); + }); + + Triple target_triple(module.getTargetTriple()); + auto tlii = std::make_unique(target_triple); + function_am.registerPass([&] { return TargetLibraryAnalysis(*tlii); }); + + // Initialize the AnalysisManagers + pass_builder.registerModuleAnalyses(module_am); + pass_builder.registerCGSCCAnalyses(cgscc_am); + pass_builder.registerFunctionAnalyses(function_am); + pass_builder.registerLoopAnalyses(loop_am); + pass_builder.crossRegisterProxies(loop_am, function_am, + cgscc_am, module_am); + + // IR verification + if (assertions_on) { + // Verify the input + pass_builder.registerPipelineStartEPCallback( + [](ModulePassManager &module_pm, OptimizationLevel OL) { + module_pm.addPass(VerifierPass()); + }); + // Verify the output + pass_builder.registerOptimizerLastEPCallback( + [](ModulePassManager &module_pm, OptimizationLevel OL) { + module_pm.addPass(VerifierPass()); + }); } - PMBuilder->OptLevel = target_machine->getOptLevel(); - PMBuilder->SizeLevel = is_small ? 2 : 0; - - PMBuilder->DisableTailCalls = is_debug; - PMBuilder->DisableUnrollLoops = is_debug; - PMBuilder->SLPVectorize = !is_debug; - PMBuilder->LoopVectorize = !is_debug; - PMBuilder->LoopsInterleaved = !PMBuilder->DisableUnrollLoops; - PMBuilder->RerollLoops = !is_debug; - // Leaving NewGVN as default (off) because when on it caused issue #673 - //PMBuilder->NewGVN = !is_debug; - PMBuilder->DisableGVNLoadPRE = is_debug; - PMBuilder->VerifyInput = assertions_on; - PMBuilder->VerifyOutput = assertions_on; - PMBuilder->MergeFunctions = !is_debug; - PMBuilder->PrepareForLTO = lto; - PMBuilder->PrepareForThinLTO = false; - PMBuilder->PerformThinLTO = false; - - TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple())); - PMBuilder->LibraryInfo = &tlii; + // Passes for either debug or release build if (is_debug) { - PMBuilder->Inliner = createAlwaysInlinerLegacyPass(false); + // NOTE: Always inliner will go away (in debug build) + // when the self-hosted compiler becomes mature. + pass_builder.registerPipelineStartEPCallback( + [](ModulePassManager &module_pm, OptimizationLevel OL) { + module_pm.addPass(AlwaysInlinerPass()); + }); } else { - target_machine->adjustPassManager(*PMBuilder); - - PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, addDiscriminatorsPass); - PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel, false); + pass_builder.registerPipelineStartEPCallback( + [](ModulePassManager &module_pm, OptimizationLevel OL) { + module_pm.addPass( + createModuleToFunctionPassAdaptor(AddDiscriminatorsPass())); + }); } + // Thread sanitizer if (tsan) { - PMBuilder->addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); - PMBuilder->addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); + pass_builder.registerOptimizerLastEPCallback( + [](ModulePassManager &module_pm, OptimizationLevel level) { + module_pm.addPass(ThreadSanitizerPass()); + }); } - // Set up the per-function pass manager. - legacy::FunctionPassManager FPM = legacy::FunctionPassManager(module); - auto tliwp = new(std::nothrow) TargetLibraryInfoWrapperPass(tlii); - FPM.add(tliwp); - FPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); - if (assertions_on) { - FPM.add(createVerifierPass()); + ModulePassManager module_pm; + OptimizationLevel opt_level; + // Setting up the optimization level + if (is_debug) + opt_level = OptimizationLevel::O0; + else if (is_small) + opt_level = OptimizationLevel::Oz; + else + opt_level = OptimizationLevel::O3; + + // Initialize the PassManager + if (lto) { + module_pm = pass_builder.buildLTOPreLinkDefaultPipeline(opt_level); + module_pm.addPass(CanonicalizeAliasesPass()); + module_pm.addPass(NameAnonGlobalPass()); + } else { + module_pm = pass_builder.buildPerModuleDefaultPipeline(opt_level); } - PMBuilder->populateFunctionPassManager(FPM); - - { - // Set up the per-module pass manager. - legacy::PassManager MPM; - MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); - PMBuilder->populateModulePassManager(MPM); - - // Set output passes. - if (dest_bin && !lto) { - if (target_machine->addPassesToEmitFile(MPM, *dest_bin, nullptr, CGFT_ObjectFile)) { - *error_message = strdup("TargetMachine can't emit an object file"); - return true; - } - } - if (dest_asm) { - if (target_machine->addPassesToEmitFile(MPM, *dest_asm, nullptr, CGFT_AssemblyFile)) { - *error_message = strdup("TargetMachine can't emit an assembly file"); - return true; - } - } - - // run per function optimization passes - FPM.doInitialization(); - for (Function &F : *module) - if (!F.isDeclaration()) - FPM.run(F); - FPM.doFinalization(); - MPM.run(*module); + // Unfortunately we don't have new PM for code generation + legacy::PassManager codegen_pm; + codegen_pm.add( + createTargetTransformInfoWrapperPass(target_machine.getTargetIRAnalysis())); - if (llvm_ir_filename) { - if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) { - return true; - } + if (dest_bin && !lto) { + if (target_machine.addPassesToEmitFile(codegen_pm, *dest_bin, nullptr, CGFT_ObjectFile)) { + *error_message = strdup("TargetMachine can't emit an object file"); + return true; } - if (dest_bin && lto) { - WriteBitcodeToFile(*module, *dest_bin); + } + if (dest_asm) { + if (target_machine.addPassesToEmitFile(codegen_pm, *dest_asm, nullptr, CGFT_AssemblyFile)) { + *error_message = strdup("TargetMachine can't emit an assembly file"); + return true; } + } - if (time_report) { - TimerGroup::printAll(errs()); + // Optimization phase + module_pm.run(module, module_am); + + // Code generation phase + codegen_pm.run(module); + + if (llvm_ir_filename) { + if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) { + return true; } + } - // MPM goes out of scope and writes to the out streams + if (dest_bin && lto) { + WriteBitcodeToFile(module, *dest_bin); } - delete dest_asm; - delete dest_bin; + if (time_report) { + TimerGroup::printAll(errs()); + } return false; } -- cgit v1.2.3 From 52d871844c643f396a2bddee0753d24ff71ca3bb Mon Sep 17 00:00:00 2001 From: Min-Yih Hsu Date: Fri, 9 Apr 2021 13:00:46 -0700 Subject: llvm new-pm: Build O0 pipeline in the correct way Use `PassBuilder::buildO0DefaultPipeline` to build pipeline for -O0 in replacement of `PassBuilder::buildPerModuleDefaultPipeline`. This affects both normal and LTO settings. Two redundant Passes - which were added by accident - were also removed from LTO pipeline. --- src/zig_llvm.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'src/zig_llvm.cpp') diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 0d60d7a4ac..7866537c64 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -277,15 +277,8 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM }); } - // Passes for either debug or release build - if (is_debug) { - // NOTE: Always inliner will go away (in debug build) - // when the self-hosted compiler becomes mature. - pass_builder.registerPipelineStartEPCallback( - [](ModulePassManager &module_pm, OptimizationLevel OL) { - module_pm.addPass(AlwaysInlinerPass()); - }); - } else { + // Passes specific for release build + if (!is_debug) { pass_builder.registerPipelineStartEPCallback( [](ModulePassManager &module_pm, OptimizationLevel OL) { module_pm.addPass( @@ -312,10 +305,10 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM opt_level = OptimizationLevel::O3; // Initialize the PassManager - if (lto) { + if (opt_level == OptimizationLevel::O0) { + module_pm = pass_builder.buildO0DefaultPipeline(opt_level, lto); + } else if (lto) { module_pm = pass_builder.buildLTOPreLinkDefaultPipeline(opt_level); - module_pm.addPass(CanonicalizeAliasesPass()); - module_pm.addPass(NameAnonGlobalPass()); } else { module_pm = pass_builder.buildPerModuleDefaultPipeline(opt_level); } -- cgit v1.2.3