Commit a44085dc2a

Guillaume Wenzek <gwenzek@users.noreply.github.com>
2023-01-03 12:05:09
add -fopt-bisect-limit
1 parent 93bdd04
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 {
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.?,
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,
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,
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,
src/zig_llvm.cpp
@@ -31,6 +31,7 @@
 #include <llvm/IR/Instructions.h>
 #include <llvm/IR/LegacyPassManager.h>
 #include <llvm/IR/Module.h>
+#include <llvm/IR/OptBisect.h>
 #include <llvm/IR/PassManager.h>
 #include <llvm/IR/Verifier.h>
 #include <llvm/InitializePasses.h>
@@ -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<FunctionType>(FunctionTy), GlobalValue::ExternalLinkage, AddressSpace, Name, unwrap(M));
     return wrap(func);
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);
 
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