From a44085dc2ab81877fc71fb50e846454c2694a14c Mon Sep 17 00:00:00 2001 From: Guillaume Wenzek Date: Tue, 3 Jan 2023 12:05:09 +0100 Subject: [PATCH] add -fopt-bisect-limit --- src/Compilation.zig | 2 ++ src/codegen/llvm.zig | 4 ++++ src/codegen/llvm/bindings.zig | 3 +++ src/link.zig | 1 + src/main.zig | 5 +++++ src/zig_llvm.cpp | 13 +++++++++++++ src/zig_llvm.h | 2 ++ tools/stage2_gdb_pretty_printers.py | 5 +++++ 8 files changed, 35 insertions(+) diff --git a/src/Compilation.zig b/src/Compilation.zig index 4c7489c0c8..3aa9663ed5 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -968,6 +968,7 @@ pub const InitOptions = struct { linker_print_gc_sections: bool = false, linker_print_icf_sections: bool = false, linker_print_map: bool = false, + linker_opt_bisect_limit: i32 = -1, each_lib_rpath: ?bool = null, build_id: ?bool = null, disable_c_depfile: bool = false, @@ -1826,6 +1827,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { .print_gc_sections = options.linker_print_gc_sections, .print_icf_sections = options.linker_print_icf_sections, .print_map = options.linker_print_map, + .opt_bisect_limit = options.linker_opt_bisect_limit, .z_nodelete = options.linker_z_nodelete, .z_notext = options.linker_z_notext, .z_defs = options.linker_z_defs, diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index c693beaabf..235949d117 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -520,6 +520,10 @@ pub const Object = struct { if (options.pie) llvm_module.setModulePIELevel(); if (code_model != .Default) llvm_module.setModuleCodeModel(code_model); + if (options.opt_bisect_limit >= 0) { + context.setOptBisectLimit(std.math.lossyCast(c_int, options.opt_bisect_limit)); + } + return Object{ .gpa = gpa, .module = options.module.?, diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index e1f2af3471..c78c951eee 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -85,6 +85,9 @@ pub const Context = opaque { pub const createBuilder = LLVMCreateBuilderInContext; extern fn LLVMCreateBuilderInContext(C: *Context) *Builder; + + pub const setOptBisectLimit = ZigLLVMSetOptBisectLimit; + extern fn ZigLLVMSetOptBisectLimit(C: *Context, limit: c_int) void; }; pub const Value = opaque { diff --git a/src/link.zig b/src/link.zig index 33c5feb727..0a526db0de 100644 --- a/src/link.zig +++ b/src/link.zig @@ -169,6 +169,7 @@ pub const Options = struct { print_gc_sections: bool, print_icf_sections: bool, print_map: bool, + opt_bisect_limit: i32, objects: []Compilation.LinkObject, framework_dirs: []const []const u8, diff --git a/src/main.zig b/src/main.zig index ffb65b43aa..421164de1c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -536,6 +536,7 @@ const usage_build_generic = \\ --test-runner [path] Specify a custom test runner \\ \\Debug Options (Zig Compiler Development): + \\ -fopt-bisect-limit [limit] Only run [limit] first LLVM optimization passes \\ -ftime-report Print timing diagnostics \\ -fstack-report Print stack size diagnostics \\ --verbose-link Display linker invocations @@ -729,6 +730,7 @@ fn buildOutputType( var linker_print_gc_sections: bool = false; var linker_print_icf_sections: bool = false; var linker_print_map: bool = false; + var linker_opt_bisect_limit: i32 = -1; var linker_z_nocopyreloc = false; var linker_z_nodelete = false; var linker_z_notext = false; @@ -1285,6 +1287,8 @@ fn buildOutputType( no_builtin = false; } else if (mem.eql(u8, arg, "-fno-builtin")) { no_builtin = true; + } else if (mem.startsWith(u8, arg, "-fopt-bisect-limit=")) { + linker_opt_bisect_limit = std.math.lossyCast(i32, parseIntSuffix(arg, "-fopt-bisect-limit=".len)); } else if (mem.eql(u8, arg, "--eh-frame-hdr")) { link_eh_frame_hdr = true; } else if (mem.eql(u8, arg, "--emit-relocs")) { @@ -2996,6 +3000,7 @@ fn buildOutputType( .linker_print_gc_sections = linker_print_gc_sections, .linker_print_icf_sections = linker_print_icf_sections, .linker_print_map = linker_print_map, + .linker_opt_bisect_limit = linker_opt_bisect_limit, .linker_global_base = linker_global_base, .linker_export_symbol_names = linker_export_symbol_names.items, .linker_z_nocopyreloc = linker_z_nocopyreloc, diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index c38e311f67..4f73bd2c3c 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -412,6 +413,18 @@ ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref) { return wrap(Type::getTokenTy(*unwrap(context_ref))); } + +ZIG_EXTERN_C void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit) { + // In LLVM15 we just have an OptBisect singleton we can edit. + OptBisect& bisect = getOptBisector(); + bisect.setLimit(limit); + + // In LLVM16 OptBisect will be wrapped in OptPassGate, and will need to be set per context. + // static OptBisect _opt_bisector; + // _opt_bisector.setLimit(limit); + // unwrap(context_ref)->setOptPassGate(_opt_bisector); +} + LLVMValueRef ZigLLVMAddFunctionInAddressSpace(LLVMModuleRef M, const char *Name, LLVMTypeRef FunctionTy, unsigned AddressSpace) { Function* func = Function::Create(unwrap(FunctionTy), GlobalValue::ExternalLinkage, AddressSpace, Name, unwrap(M)); return wrap(func); diff --git a/src/zig_llvm.h b/src/zig_llvm.h index 7f9bd0a161..70c53f61a4 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -67,6 +67,8 @@ ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, co ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); +ZIG_EXTERN_C void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit); + ZIG_EXTERN_C LLVMValueRef ZigLLVMAddFunctionInAddressSpace(LLVMModuleRef M, const char *Name, LLVMTypeRef FunctionTy, unsigned AddressSpace); diff --git a/tools/stage2_gdb_pretty_printers.py b/tools/stage2_gdb_pretty_printers.py index 5eca2fdec2..215b27699f 100644 --- a/tools/stage2_gdb_pretty_printers.py +++ b/tools/stage2_gdb_pretty_printers.py @@ -2,8 +2,13 @@ # put "source /path/to/stage2_gdb_pretty_printers.py" in ~/.gdbinit to load it automatically. import re import gdb.printing + +import sys +from pathlib import Path +sys.path.insert(0, str(Path(__file__).parent)) import stage2_pretty_printers_common as common + class TypePrinter: def __init__(self, val): self.val = val