Skip to content

Commit 05c83f9

Browse files
committed
Use per-file issue generation for isInsideReportedValue
isInsideReportedValue only checks within same file, so files are independent. Now group dead declarations by file and process each file with: - Sort within file only (not global sort) - Fresh ReportingContext per file Timing improvement: - group: 4-5ms (was sort: 7-8ms for global sort) - report: 10-11ms (files processed independently) All 380/19000 issues still match between reactive and non-reactive modes.
1 parent 97cf8ae commit 05c83f9

File tree

1 file changed

+32
-16
lines changed

1 file changed

+32
-16
lines changed

analysis/reanalyze/src/ReactiveSolver.ml

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,15 @@
66
- dead_decls, live_decls, dead_modules are reactive (zero recomputation on cache hit)
77
- dead_modules = modules with dead decls but no live decls (reactive anti-join)
88
- is_pos_live uses reactive live collection (no resolvedDead mutation needed)
9-
- collect_issues still iterates dead_decls + live_decls for annotations + sorting
10-
- Uses DeadCommon.reportDeclaration for isInsideReportedValue and hasRefBelow
9+
- Per-file issue generation: group by file, sort within file, fresh ReportingContext per file
10+
- isInsideReportedValue is per-file only, so files are independent
1111
1212
TODO for fully reactive issues:
13-
- isInsideReportedValue: needs reactive tracking of reported positions
14-
(currently relies on sequential iteration order via ReportingContext)
13+
- Make dead_decls_by_file a reactive collection (per-file grouping)
14+
- Make per-file issues reactive (only recompute changed files)
1515
- hasRefBelow: uses O(total_refs) linear scan of refs_from per dead decl;
1616
could use reactive refs_to index for O(1) lookup per decl
1717
- report field: still mutated to suppress annotated decls; could check in reportDeclaration
18-
- Sorting: O(n log n) for isInsideReportedValue ordering; fundamentally sequential
1918
2019
All issues now match between reactive and non-reactive modes (380 on deadcode test):
2120
- Dead code issues: 362 (Exception:2, Module:31, Type:87, Value:233, ValueWithSideEffects:8)
@@ -164,11 +163,18 @@ let collect_issues ~(t : t) ~(config : DceConfig.t)
164163
t.live_decls;
165164
let t2 = Unix.gettimeofday () in
166165

167-
(* Sort dead declarations for isInsideReportedValue ordering *)
168-
let sorted_dead = !dead_list |> List.fast_sort Decl.compareForReporting in
166+
(* Group dead declarations by file *)
167+
let by_file : (string, Decl.t list) Hashtbl.t = Hashtbl.create 64 in
168+
List.iter
169+
(fun (decl : Decl.t) ->
170+
let file = decl.pos.pos_fname in
171+
let existing = Hashtbl.find_opt by_file file |> Option.value ~default:[] in
172+
Hashtbl.replace by_file file (decl :: existing))
173+
!dead_list;
169174
let t3 = Unix.gettimeofday () in
170175

171-
(* Generate issues - use reactive dead_modules via callback *)
176+
(* Generate issues per-file with independent ReportingContext.
177+
isInsideReportedValue only checks within same file, so files are independent. *)
172178
let transitive = config.DceConfig.run.transitive in
173179
let hasRefBelow =
174180
match t.value_refs_from with
@@ -182,23 +188,33 @@ let collect_issues ~(t : t) ~(config : DceConfig.t)
182188
check_module_dead ~dead_modules:t.dead_modules ~reported_modules ~fileName
183189
moduleName
184190
in
185-
let reporting_ctx = DeadCommon.ReportingContext.create () in
186191
let dead_issues =
187-
sorted_dead
188-
|> List.concat_map (fun decl ->
189-
DeadCommon.reportDeclaration ~config ~hasRefBelow ~checkModuleDead
190-
reporting_ctx decl)
192+
Hashtbl.fold
193+
(fun _file decls acc ->
194+
(* Sort within file for isInsideReportedValue *)
195+
let sorted = decls |> List.fast_sort Decl.compareForReporting in
196+
(* Fresh ReportingContext per file *)
197+
let reporting_ctx = DeadCommon.ReportingContext.create () in
198+
let file_issues =
199+
sorted
200+
|> List.concat_map (fun decl ->
201+
DeadCommon.reportDeclaration ~config ~hasRefBelow ~checkModuleDead
202+
reporting_ctx decl)
203+
in
204+
file_issues @ acc)
205+
by_file []
191206
in
192207
let t4 = Unix.gettimeofday () in
193208

194209
if !Cli.timing then
195210
Printf.eprintf
196-
" collect_issues: iter_dead=%.2fms iter_live=%.2fms sort=%.2fms \
197-
report=%.2fms\n"
211+
" collect_issues: iter_dead=%.2fms iter_live=%.2fms group=%.2fms \
212+
report=%.2fms (%d files)\n"
198213
((t1 -. t0) *. 1000.0)
199214
((t2 -. t1) *. 1000.0)
200215
((t3 -. t2) *. 1000.0)
201-
((t4 -. t3) *. 1000.0);
216+
((t4 -. t3) *. 1000.0)
217+
(Hashtbl.length by_file);
202218

203219
List.rev !incorrect_dead_issues @ dead_issues
204220

0 commit comments

Comments
 (0)