@@ -129,20 +129,21 @@ let collectCmtFilePaths ~cmtRoot : string list =
129129(* * Process files sequentially *)
130130let processFilesSequential ~config (cmtFilePaths : string list ) :
131131 all_files_result =
132- let dce_data_list = ref [] in
133- let exception_results = ref [] in
134- cmtFilePaths
135- |> List. iter (fun cmtFilePath ->
136- match loadCmtFile ~config cmtFilePath with
137- | Some {dce_data; exception_data} -> (
138- (match dce_data with
139- | Some data -> dce_data_list := data :: ! dce_data_list
140- | None -> () );
141- match exception_data with
142- | Some data -> exception_results := data :: ! exception_results
143- | None -> () )
144- | None -> () );
145- {dce_data_list = ! dce_data_list; exception_results = ! exception_results}
132+ Timing. time_phase `FileLoading (fun () ->
133+ let dce_data_list = ref [] in
134+ let exception_results = ref [] in
135+ cmtFilePaths
136+ |> List. iter (fun cmtFilePath ->
137+ match loadCmtFile ~config cmtFilePath with
138+ | Some {dce_data; exception_data} -> (
139+ (match dce_data with
140+ | Some data -> dce_data_list := data :: ! dce_data_list
141+ | None -> () );
142+ match exception_data with
143+ | Some data -> exception_results := data :: ! exception_results
144+ | None -> () )
145+ | None -> () );
146+ {dce_data_list = ! dce_data_list; exception_results = ! exception_results})
146147
147148(* * Process files in parallel using OCaml 5 Domains *)
148149let processFilesParallel ~config ~numDomains (cmtFilePaths : string list ) :
@@ -178,42 +179,43 @@ let processFilesParallel ~config ~numDomains (cmtFilePaths : string list) :
178179 allExceptionData := ! localExn @ ! allExceptionData;
179180 Mutex. unlock resultsMutex
180181 in
181- (* Spawn domains for parallel processing *)
182- let domains =
183- Array. init numDomains (fun i ->
184- let startIdx = i * chunkSize in
185- let endIdx = min ((i + 1 ) * chunkSize) numFiles in
186- if startIdx < numFiles then
187- Some (Domain. spawn (fun () -> processChunk startIdx endIdx))
188- else None )
189- in
190- (* Wait for all domains to complete *)
191- Array. iter
192- (function
193- | Some d -> Domain. join d
194- | None -> () )
195- domains;
182+ (* Time the overall parallel processing *)
183+ Timing. time_phase `FileLoading (fun () ->
184+ (* Spawn domains for parallel processing *)
185+ let domains =
186+ Array. init numDomains (fun i ->
187+ let startIdx = i * chunkSize in
188+ let endIdx = min ((i + 1 ) * chunkSize) numFiles in
189+ if startIdx < numFiles then
190+ Some (Domain. spawn (fun () -> processChunk startIdx endIdx))
191+ else None )
192+ in
193+ (* Wait for all domains to complete *)
194+ Array. iter
195+ (function
196+ | Some d -> Domain. join d
197+ | None -> () )
198+ domains);
196199 {dce_data_list = ! allDceData; exception_results = ! allExceptionData}
197200
198201(* * Process all cmt files and return results for DCE and Exception analysis.
199202 Conceptually: map process_cmt_file over all files. *)
200203let processCmtFiles ~config ~cmtRoot : all_files_result =
201- Timing. time_phase `CmtProcessing (fun () ->
202- let cmtFilePaths = collectCmtFilePaths ~cmt Root in
203- let numDomains =
204- match ! Cli. parallel with
205- | n when n > 0 -> n
206- | n when n < 0 ->
207- (* Auto-detect: use recommended domain count (number of cores) *)
208- Domain. recommended_domain_count ()
209- | _ -> 0
210- in
211- if numDomains > 0 then (
212- if ! Cli. timing then
213- Printf. eprintf " Using %d parallel domains for %d files\n %!" numDomains
214- (List. length cmtFilePaths);
215- processFilesParallel ~config ~num Domains cmtFilePaths)
216- else processFilesSequential ~config cmtFilePaths)
204+ let cmtFilePaths = collectCmtFilePaths ~cmt Root in
205+ let numDomains =
206+ match ! Cli. parallel with
207+ | n when n > 0 -> n
208+ | n when n < 0 ->
209+ (* Auto-detect: use recommended domain count (number of cores) *)
210+ Domain. recommended_domain_count ()
211+ | _ -> 0
212+ in
213+ if numDomains > 0 then (
214+ if ! Cli. timing then
215+ Printf. eprintf " Using %d parallel domains for %d files\n %!" numDomains
216+ (List. length cmtFilePaths);
217+ processFilesParallel ~config ~num Domains cmtFilePaths)
218+ else processFilesSequential ~config cmtFilePaths
217219
218220(* Shuffle a list using Fisher-Yates algorithm *)
219221let shuffle_list lst =
@@ -243,44 +245,47 @@ let runAnalysis ~dce_config ~cmtRoot =
243245 in
244246 (* Analysis phase: merge data and solve *)
245247 let analysis_result =
246- Timing. time_phase `Analysis (fun () ->
247- if dce_config.DceConfig. run.dce then (
248- (* Merge: combine all builders -> immutable data *)
249- let annotations =
250- FileAnnotations. merge_all
251- (dce_data_list
252- |> List. map (fun fd -> fd.DceFileProcessing. annotations))
253- in
254- let decls =
255- Declarations. merge_all
256- (dce_data_list |> List. map (fun fd -> fd.DceFileProcessing. decls))
257- in
258- let cross_file =
259- CrossFileItems. merge_all
260- (dce_data_list
261- |> List. map (fun fd -> fd.DceFileProcessing. cross_file))
262- in
263- (* Merge refs and file_deps into builders for cross-file items processing *)
264- let refs_builder = References. create_builder () in
265- let file_deps_builder = FileDeps. create_builder () in
266- dce_data_list
267- |> List. iter (fun fd ->
268- References. merge_into_builder ~from: fd.DceFileProcessing. refs
269- ~into: refs_builder;
270- FileDeps. merge_into_builder
271- ~from: fd.DceFileProcessing. file_deps ~into: file_deps_builder);
272- (* Compute type-label dependencies after merge (no global TypeLabels table during traversal) *)
273- DeadType. process_type_label_dependencies ~config: dce_config ~decls
274- ~refs: refs_builder;
275- let find_exception = DeadException. find_exception_from_decls decls in
276- (* Process cross-file exception refs - they write to refs_builder and file_deps_builder *)
277- CrossFileItems. process_exception_refs cross_file ~refs: refs_builder
278- ~file_deps: file_deps_builder ~find_exception ~config: dce_config;
279- (* Now freeze refs and file_deps for solver *)
280- let refs = References. freeze_builder refs_builder in
281- let file_deps = FileDeps. freeze_builder file_deps_builder in
282- (* Run the solver - returns immutable AnalysisResult.t.
283- Optional-args checks are done in a separate pass after liveness is known. *)
248+ if dce_config.DceConfig. run.dce then (
249+ (* Merging phase: combine all builders -> immutable data *)
250+ let annotations, decls, cross_file, refs, file_deps =
251+ Timing. time_phase `Merging (fun () ->
252+ let annotations =
253+ FileAnnotations. merge_all
254+ (dce_data_list
255+ |> List. map (fun fd -> fd.DceFileProcessing. annotations))
256+ in
257+ let decls =
258+ Declarations. merge_all
259+ (dce_data_list |> List. map (fun fd -> fd.DceFileProcessing. decls))
260+ in
261+ let cross_file =
262+ CrossFileItems. merge_all
263+ (dce_data_list
264+ |> List. map (fun fd -> fd.DceFileProcessing. cross_file))
265+ in
266+ (* Merge refs and file_deps into builders for cross-file items processing *)
267+ let refs_builder = References. create_builder () in
268+ let file_deps_builder = FileDeps. create_builder () in
269+ dce_data_list
270+ |> List. iter (fun fd ->
271+ References. merge_into_builder ~from: fd.DceFileProcessing. refs
272+ ~into: refs_builder;
273+ FileDeps. merge_into_builder
274+ ~from: fd.DceFileProcessing. file_deps ~into: file_deps_builder);
275+ (* Compute type-label dependencies after merge *)
276+ DeadType. process_type_label_dependencies ~config: dce_config ~decls
277+ ~refs: refs_builder;
278+ let find_exception = DeadException. find_exception_from_decls decls in
279+ (* Process cross-file exception refs *)
280+ CrossFileItems. process_exception_refs cross_file ~refs: refs_builder
281+ ~file_deps: file_deps_builder ~find_exception ~config: dce_config;
282+ (* Freeze refs and file_deps for solver *)
283+ let refs = References. freeze_builder refs_builder in
284+ let file_deps = FileDeps. freeze_builder file_deps_builder in
285+ (annotations, decls, cross_file, refs, file_deps))
286+ in
287+ (* Solving phase: run the solver and collect issues *)
288+ Timing. time_phase `Solving (fun () ->
284289 let empty_optional_args_state = OptionalArgsState. create () in
285290 let analysis_result_core =
286291 DeadCommon. solveDead ~annotations ~decls ~refs ~file_deps
@@ -295,8 +300,7 @@ let runAnalysis ~dce_config ~cmtRoot =
295300 | None -> true
296301 in
297302 let optional_args_state =
298- CrossFileItems. compute_optional_args_state cross_file ~decls
299- ~is_live
303+ CrossFileItems. compute_optional_args_state cross_file ~decls ~is_live
300304 in
301305 (* Collect optional args issues only for live declarations *)
302306 let optional_args_issues =
@@ -312,9 +316,8 @@ let runAnalysis ~dce_config ~cmtRoot =
312316 decls []
313317 |> List. rev
314318 in
315- Some
316- (AnalysisResult. add_issues analysis_result_core optional_args_issues))
317- else None )
319+ Some (AnalysisResult. add_issues analysis_result_core optional_args_issues)))
320+ else None
318321 in
319322 (* Reporting phase *)
320323 Timing. time_phase `Reporting (fun () ->
0 commit comments