| ... | @@ -2661,10 +2661,9 @@ pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void { | ... | @@ -2661,10 +2661,9 @@ pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void { |
| 2661 | } | 2661 | } |
| 2662 | // If this is a Decl and was not previously PO, we must recursively | 2662 | // If this is a Decl and was not previously PO, we must recursively |
| 2663 | // mark dependencies on its tyval as PO. | 2663 | // mark dependencies on its tyval as PO. |
| 2664 | if (opt_po_entry == null) switch (depender.unwrap()) { | 2664 | if (opt_po_entry == null) { |
| 2665 | .decl => |decl_index| try zcu.markDeclDependenciesPotentiallyOutdated(decl_index), | 2665 | try zcu.markTransitiveDependersPotentiallyOutdated(depender); |
| 2666 | .func => {}, | 2666 | } |
| 2667 | }; | | |
| 2668 | } | 2667 | } |
| 2669 | } | 2668 | } |
| 2670 | | 2669 | |
| ... | @@ -2694,15 +2693,19 @@ fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void { | ... | @@ -2694,15 +2693,19 @@ fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void { |
| 2694 | // as no longer PO. | 2693 | // as no longer PO. |
| 2695 | switch (depender.unwrap()) { | 2694 | switch (depender.unwrap()) { |
| 2696 | .decl => |decl_index| try zcu.markPoDependeeUpToDate(.{ .decl_val = decl_index }), | 2695 | .decl => |decl_index| try zcu.markPoDependeeUpToDate(.{ .decl_val = decl_index }), |
| 2697 | .func => {}, | 2696 | .func => |func_index| try zcu.markPoDependeeUpToDate(.{ .func_ies = func_index }), |
| 2698 | } | 2697 | } |
| 2699 | } | 2698 | } |
| 2700 | } | 2699 | } |
| 2701 | | 2700 | |
| 2702 | /// Given a Decl which is newly outdated or PO, mark all dependers which depend | 2701 | /// Given a Depender which is newly outdated or PO, mark all Dependers which may |
| 2703 | /// on its tyval as PO. | 2702 | /// in turn be PO, due to a dependency on the original Depender's tyval or IES. |
| 2704 | fn markDeclDependenciesPotentiallyOutdated(zcu: *Zcu, decl_index: Decl.Index) !void { | 2703 | fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: InternPool.Depender) !void { |
| 2705 | var it = zcu.intern_pool.dependencyIterator(.{ .decl_val = decl_index }); | 2704 | var it = zcu.intern_pool.dependencyIterator(switch (maybe_outdated.unwrap()) { |
| | 2705 | .decl => |decl_index| .{ .decl_val = decl_index }, // TODO: also `decl_ref` deps when introduced |
| | 2706 | .func => |func_index| .{ .func_ies = func_index }, |
| | 2707 | }); |
| | 2708 | |
| 2706 | while (it.next()) |po| { | 2709 | while (it.next()) |po| { |
| 2707 | if (zcu.outdated.getPtr(po)) |po_dep_count| { | 2710 | if (zcu.outdated.getPtr(po)) |po_dep_count| { |
| 2708 | // This dependency is already outdated, but it now has one more PO | 2711 | // This dependency is already outdated, but it now has one more PO |
| ... | @@ -2719,14 +2722,9 @@ fn markDeclDependenciesPotentiallyOutdated(zcu: *Zcu, decl_index: Decl.Index) !v | ... | @@ -2719,14 +2722,9 @@ fn markDeclDependenciesPotentiallyOutdated(zcu: *Zcu, decl_index: Decl.Index) !v |
| 2719 | continue; | 2722 | continue; |
| 2720 | } | 2723 | } |
| 2721 | try zcu.potentially_outdated.putNoClobber(zcu.gpa, po, 1); | 2724 | try zcu.potentially_outdated.putNoClobber(zcu.gpa, po, 1); |
| 2722 | // If this ia a Decl, we must recursively mark dependencies | 2725 | // This Depender was not already PO, so we must recursively mark its dependers as also PO. |
| 2723 | // on its tyval as PO. | 2726 | try zcu.markTransitiveDependersPotentiallyOutdated(po); |
| 2724 | switch (po.unwrap()) { | | |
| 2725 | .decl => |po_decl| try zcu.markDeclDependenciesPotentiallyOutdated(po_decl), | | |
| 2726 | .func => {}, | | |
| 2727 | } | | |
| 2728 | } | 2727 | } |
| 2729 | // TODO: repeat the above for `decl_ty` dependencies when they are introduced | | |
| 2730 | } | 2728 | } |
| 2731 | | 2729 | |
| 2732 | pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?InternPool.Depender { | 2730 | pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?InternPool.Depender { |
| ... | @@ -2852,10 +2850,7 @@ pub fn flushRetryableFailures(zcu: *Zcu) !void { | ... | @@ -2852,10 +2850,7 @@ pub fn flushRetryableFailures(zcu: *Zcu) !void { |
| 2852 | // This Depender was not marked PO, but is now outdated. Mark it as | 2850 | // This Depender was not marked PO, but is now outdated. Mark it as |
| 2853 | // such, then recursively mark transitive dependencies as PO. | 2851 | // such, then recursively mark transitive dependencies as PO. |
| 2854 | try zcu.outdated.put(gpa, depender, 0); | 2852 | try zcu.outdated.put(gpa, depender, 0); |
| 2855 | switch (depender.unwrap()) { | 2853 | try zcu.markTransitiveDependersPotentiallyOutdated(depender); |
| 2856 | .decl => |decl| try zcu.markDeclDependenciesPotentiallyOutdated(decl), | | |
| 2857 | .func => {}, | | |
| 2858 | } | | |
| 2859 | } | 2854 | } |
| 2860 | zcu.retryable_failures.clearRetainingCapacity(); | 2855 | zcu.retryable_failures.clearRetainingCapacity(); |
| 2861 | } | 2856 | } |
| ... | @@ -3142,11 +3137,19 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError | ... | @@ -3142,11 +3137,19 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError |
| 3142 | // decl now refers to a different function, making this one orphaned. If | 3137 | // decl now refers to a different function, making this one orphaned. If |
| 3143 | // that's the case, we should remove this function from the binary. | 3138 | // that's the case, we should remove this function from the binary. |
| 3144 | if (decl.val.ip_index != func_index) { | 3139 | if (decl.val.ip_index != func_index) { |
| | 3140 | try zcu.markDependeeOutdated(.{ .func_ies = func_index }); |
| 3145 | ip.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index })); | 3141 | ip.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index })); |
| 3146 | ip.remove(func_index); | 3142 | ip.remove(func_index); |
| 3147 | @panic("TODO: remove orphaned function from binary"); | 3143 | @panic("TODO: remove orphaned function from binary"); |
| 3148 | } | 3144 | } |
| 3149 | | 3145 | |
| | 3146 | // We'll want to remember what the IES used to be before the update for |
| | 3147 | // dependency invalidation purposes. |
| | 3148 | const old_resolved_ies = if (func.analysis(ip).inferred_error_set) |
| | 3149 | func.resolvedErrorSet(ip).* |
| | 3150 | else |
| | 3151 | .none; |
| | 3152 | |
| 3150 | switch (decl.analysis) { | 3153 | switch (decl.analysis) { |
| 3151 | .unreferenced => unreachable, | 3154 | .unreferenced => unreachable, |
| 3152 | .in_progress => unreachable, | 3155 | .in_progress => unreachable, |
| ... | @@ -3203,6 +3206,20 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError | ... | @@ -3203,6 +3206,20 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError |
| 3203 | }; | 3206 | }; |
| 3204 | defer air.deinit(gpa); | 3207 | defer air.deinit(gpa); |
| 3205 | | 3208 | |
| | 3209 | const invalidate_ies_deps = i: { |
| | 3210 | if (!was_outdated) break :i false; |
| | 3211 | if (!func.analysis(ip).inferred_error_set) break :i true; |
| | 3212 | const new_resolved_ies = func.resolvedErrorSet(ip).*; |
| | 3213 | break :i new_resolved_ies != old_resolved_ies; |
| | 3214 | }; |
| | 3215 | if (invalidate_ies_deps) { |
| | 3216 | log.debug("func IES invalidated ('{d}')", .{@intFromEnum(func_index)}); |
| | 3217 | try zcu.markDependeeOutdated(.{ .func_ies = func_index }); |
| | 3218 | } else if (was_outdated) { |
| | 3219 | log.debug("func IES up-to-date ('{d}')", .{@intFromEnum(func_index)}); |
| | 3220 | try zcu.markPoDependeeUpToDate(.{ .func_ies = func_index }); |
| | 3221 | } |
| | 3222 | |
| 3206 | const comp = zcu.comp; | 3223 | const comp = zcu.comp; |
| 3207 | | 3224 | |
| 3208 | const dump_air = build_options.enable_debug_extensions and comp.verbose_air; | 3225 | const dump_air = build_options.enable_debug_extensions and comp.verbose_air; |