| ... | ... | @@ -2661,10 +2661,9 @@ pub fn markDependeeOutdated(zcu: *Zcu, dependee: InternPool.Dependee) !void { |
| 2661 | 2661 | } |
| 2662 | 2662 | // If this is a Decl and was not previously PO, we must recursively |
| 2663 | 2663 | // mark dependencies on its tyval as PO. |
| 2664 | | if (opt_po_entry == null) switch (depender.unwrap()) { |
| 2665 | | .decl => |decl_index| try zcu.markDeclDependenciesPotentiallyOutdated(decl_index), |
| 2666 | | .func => {}, |
| 2667 | | }; |
| 2664 | if (opt_po_entry == null) { |
| 2665 | try zcu.markTransitiveDependersPotentiallyOutdated(depender); |
| 2666 | } |
| 2668 | 2667 | } |
| 2669 | 2668 | } |
| 2670 | 2669 | |
| ... | ... | @@ -2694,15 +2693,19 @@ fn markPoDependeeUpToDate(zcu: *Zcu, dependee: InternPool.Dependee) !void { |
| 2694 | 2693 | // as no longer PO. |
| 2695 | 2694 | switch (depender.unwrap()) { |
| 2696 | 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 |
| 2703 | | /// on its tyval as PO. |
| 2704 | | fn markDeclDependenciesPotentiallyOutdated(zcu: *Zcu, decl_index: Decl.Index) !void { |
| 2705 | | var it = zcu.intern_pool.dependencyIterator(.{ .decl_val = decl_index }); |
| 2701 | /// Given a Depender which is newly outdated or PO, mark all Dependers which may |
| 2702 | /// in turn be PO, due to a dependency on the original Depender's tyval or IES. |
| 2703 | fn markTransitiveDependersPotentiallyOutdated(zcu: *Zcu, maybe_outdated: InternPool.Depender) !void { |
| 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 | 2709 | while (it.next()) |po| { |
| 2707 | 2710 | if (zcu.outdated.getPtr(po)) |po_dep_count| { |
| 2708 | 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 | 2722 | continue; |
| 2720 | 2723 | } |
| 2721 | 2724 | try zcu.potentially_outdated.putNoClobber(zcu.gpa, po, 1); |
| 2722 | | // If this ia a Decl, we must recursively mark dependencies |
| 2723 | | // on its tyval as PO. |
| 2724 | | switch (po.unwrap()) { |
| 2725 | | .decl => |po_decl| try zcu.markDeclDependenciesPotentiallyOutdated(po_decl), |
| 2726 | | .func => {}, |
| 2727 | | } |
| 2725 | // This Depender was not already PO, so we must recursively mark its dependers as also PO. |
| 2726 | try zcu.markTransitiveDependersPotentiallyOutdated(po); |
| 2728 | 2727 | } |
| 2729 | | // TODO: repeat the above for `decl_ty` dependencies when they are introduced |
| 2730 | 2728 | } |
| 2731 | 2729 | |
| 2732 | 2730 | pub fn findOutdatedToAnalyze(zcu: *Zcu) Allocator.Error!?InternPool.Depender { |
| ... | ... | @@ -2852,10 +2850,7 @@ pub fn flushRetryableFailures(zcu: *Zcu) !void { |
| 2852 | 2850 | // This Depender was not marked PO, but is now outdated. Mark it as |
| 2853 | 2851 | // such, then recursively mark transitive dependencies as PO. |
| 2854 | 2852 | try zcu.outdated.put(gpa, depender, 0); |
| 2855 | | switch (depender.unwrap()) { |
| 2856 | | .decl => |decl| try zcu.markDeclDependenciesPotentiallyOutdated(decl), |
| 2857 | | .func => {}, |
| 2858 | | } |
| 2853 | try zcu.markTransitiveDependersPotentiallyOutdated(depender); |
| 2859 | 2854 | } |
| 2860 | 2855 | zcu.retryable_failures.clearRetainingCapacity(); |
| 2861 | 2856 | } |
| ... | ... | @@ -3142,11 +3137,19 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError |
| 3142 | 3137 | // decl now refers to a different function, making this one orphaned. If |
| 3143 | 3138 | // that's the case, we should remove this function from the binary. |
| 3144 | 3139 | if (decl.val.ip_index != func_index) { |
| 3140 | try zcu.markDependeeOutdated(.{ .func_ies = func_index }); |
| 3145 | 3141 | ip.removeDependenciesForDepender(gpa, InternPool.Depender.wrap(.{ .func = func_index })); |
| 3146 | 3142 | ip.remove(func_index); |
| 3147 | 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 | 3153 | switch (decl.analysis) { |
| 3151 | 3154 | .unreferenced => unreachable, |
| 3152 | 3155 | .in_progress => unreachable, |
| ... | ... | @@ -3203,6 +3206,20 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError |
| 3203 | 3206 | }; |
| 3204 | 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 | 3223 | const comp = zcu.comp; |
| 3207 | 3224 | |
| 3208 | 3225 | const dump_air = build_options.enable_debug_extensions and comp.verbose_air; |