Commit 0784d38984

mlugg <mlugg@mlugg.co.uk>
2024-02-04 18:46:04
compiler: lock incremental dependency tracking behind --debug-incremental
This logic (currently) has a non-trivial cost (particularly in terms of peak RSS) for tracking dependencies. Until incremental compilation is in use in the wild, it doesn't make sense for users to pay that cost.
1 parent 0d8207c
src/Compilation.zig
@@ -156,6 +156,7 @@ time_report: bool,
 stack_report: bool,
 debug_compiler_runtime_libs: bool,
 debug_compile_errors: bool,
+debug_incremental: bool,
 job_queued_compiler_rt_lib: bool = false,
 job_queued_compiler_rt_obj: bool = false,
 job_queued_update_builtin_zig: bool,
@@ -1079,6 +1080,7 @@ pub const CreateOptions = struct {
     verbose_llvm_cpu_features: bool = false,
     debug_compiler_runtime_libs: bool = false,
     debug_compile_errors: bool = false,
+    debug_incremental: bool = false,
     /// Normally when you create a `Compilation`, Zig will automatically build
     /// and link in required dependencies, such as compiler-rt and libc. When
     /// building such dependencies themselves, this flag must be set to avoid
@@ -1508,6 +1510,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
             .test_name_prefix = options.test_name_prefix,
             .debug_compiler_runtime_libs = options.debug_compiler_runtime_libs,
             .debug_compile_errors = options.debug_compile_errors,
+            .debug_incremental = options.debug_incremental,
             .libcxx_abi_version = options.libcxx_abi_version,
             .root_name = root_name,
             .sysroot = sysroot,
src/main.zig
@@ -3255,6 +3255,7 @@ fn buildOutputType(
         .cache_mode = cache_mode,
         .subsystem = subsystem,
         .debug_compile_errors = debug_compile_errors,
+        .debug_incremental = debug_incremental,
         .enable_link_snapshots = enable_link_snapshots,
         .install_name = install_name,
         .entitlements = entitlements,
src/Module.zig
@@ -3139,6 +3139,8 @@ fn markDeclDependenciesPotentiallyOutdated(zcu: *Zcu, decl_index: Decl.Index) !v
 }
 
 pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?InternPool.Depender {
+    if (!zcu.comp.debug_incremental) return null;
+
     if (zcu.outdated.count() == 0 and zcu.potentially_outdated.count() == 0) {
         log.debug("findOutdatedToAnalyze: no outdated depender", .{});
         return null;
src/Sema.zig
@@ -2788,11 +2788,13 @@ fn zirStructDecl(
     new_decl.owns_tv = true;
     errdefer mod.abortAnonDecl(new_decl_index);
 
-    try ip.addDependency(
-        sema.gpa,
-        InternPool.Depender.wrap(.{ .decl = new_decl_index }),
-        .{ .src_hash = try ip.trackZir(sema.gpa, block.getFileScope(mod), inst) },
-    );
+    if (sema.mod.comp.debug_incremental) {
+        try ip.addDependency(
+            sema.gpa,
+            InternPool.Depender.wrap(.{ .decl = new_decl_index }),
+            .{ .src_hash = try ip.trackZir(sema.gpa, block.getFileScope(mod), inst) },
+        );
+    }
 
     const new_namespace_index = try mod.createNamespace(.{
         .parent = block.namespace.toOptional(),
@@ -2978,11 +2980,13 @@ fn zirEnumDecl(
     new_decl.owns_tv = true;
     errdefer if (!done) mod.abortAnonDecl(new_decl_index);
 
-    try mod.intern_pool.addDependency(
-        sema.gpa,
-        InternPool.Depender.wrap(.{ .decl = new_decl_index }),
-        .{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) },
-    );
+    if (sema.mod.comp.debug_incremental) {
+        try mod.intern_pool.addDependency(
+            sema.gpa,
+            InternPool.Depender.wrap(.{ .decl = new_decl_index }),
+            .{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) },
+        );
+    }
 
     const new_namespace_index = try mod.createNamespace(.{
         .parent = block.namespace.toOptional(),
@@ -3237,11 +3241,13 @@ fn zirUnionDecl(
     new_decl.owns_tv = true;
     errdefer mod.abortAnonDecl(new_decl_index);
 
-    try mod.intern_pool.addDependency(
-        sema.gpa,
-        InternPool.Depender.wrap(.{ .decl = new_decl_index }),
-        .{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) },
-    );
+    if (sema.mod.comp.debug_incremental) {
+        try mod.intern_pool.addDependency(
+            sema.gpa,
+            InternPool.Depender.wrap(.{ .decl = new_decl_index }),
+            .{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) },
+        );
+    }
 
     const new_namespace_index = try mod.createNamespace(.{
         .parent = block.namespace.toOptional(),
@@ -3336,11 +3342,13 @@ fn zirOpaqueDecl(
     new_decl.owns_tv = true;
     errdefer mod.abortAnonDecl(new_decl_index);
 
-    try mod.intern_pool.addDependency(
-        sema.gpa,
-        InternPool.Depender.wrap(.{ .decl = new_decl_index }),
-        .{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) },
-    );
+    if (sema.mod.comp.debug_incremental) {
+        try mod.intern_pool.addDependency(
+            sema.gpa,
+            InternPool.Depender.wrap(.{ .decl = new_decl_index }),
+            .{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) },
+        );
+    }
 
     const new_namespace_index = try mod.createNamespace(.{
         .parent = block.namespace.toOptional(),
@@ -32435,7 +32443,7 @@ fn analyzeDeclRefInner(sema: *Sema, decl_index: InternPool.DeclIndex, analyze_fn
 
     const decl = mod.declPtr(decl_index);
     const decl_tv = try decl.typedValue();
-    // TODO: if this is a `decl_ref`, only depend on decl type
+    // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type
     try sema.declareDependency(.{ .decl_val = decl_index });
     const ptr_ty = try sema.ptrType(.{
         .child = decl_tv.ty.toIntern(),
@@ -38925,6 +38933,7 @@ fn ptrType(sema: *Sema, info: InternPool.Key.PtrType) CompileError!Type {
 }
 
 pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
+    if (!sema.mod.comp.debug_incremental) return;
     const depender = InternPool.Depender.wrap(
         if (sema.owner_func_index != .none)
             .{ .func = sema.owner_func_index }