@@ -275,15 +275,15 @@ SupplementaryOutputPathsComputer::computeOutputPaths() const {
275
275
276
276
if (InputsAndOutputs.hasPrimaryInputs ())
277
277
assert (OutputFiles.size () == pathsFromUser->size ());
278
- else if (InputsAndOutputs.isSingleThreadedWMO ())
279
- assert (OutputFiles.size () == pathsFromUser->size () &&
280
- pathsFromUser->size () == 1 );
281
278
else {
282
- // Multi-threaded WMO is the exception
283
- assert (OutputFiles.size () == InputsAndOutputs.inputCount () &&
284
- pathsFromUser->size () == (InputsAndOutputs.hasInputs () ? 1 : 0 ));
279
+ if (!InputsAndOutputs.isSingleThreadedWMO ()) {
280
+ assert (OutputFiles.size () == InputsAndOutputs.inputCount ());
281
+ }
282
+ assert (pathsFromUser->size () == 1 ||
283
+ pathsFromUser->size () == InputsAndOutputs.inputCount ());
285
284
}
286
285
286
+ // For other cases, process the paths normally
287
287
std::vector<SupplementaryOutputPaths> outputPaths;
288
288
unsigned i = 0 ;
289
289
bool hadError = InputsAndOutputs.forEachInputProducingSupplementaryOutput (
@@ -380,18 +380,52 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
380
380
options::OPT_emit_module_semantic_info_path);
381
381
auto optRecordOutput = getSupplementaryFilenamesFromArguments (
382
382
options::OPT_save_optimization_record_path);
383
+ auto silOutput =
384
+ getSupplementaryFilenamesFromArguments (options::OPT_sil_output_path);
385
+ auto irOutput =
386
+ getSupplementaryFilenamesFromArguments (options::OPT_ir_output_path);
383
387
if (!clangHeaderOutput || !moduleOutput || !moduleDocOutput ||
384
388
!dependenciesFile || !referenceDependenciesFile ||
385
389
!serializedDiagnostics || !loadedModuleTrace || !TBD ||
386
- !moduleInterfaceOutput || !privateModuleInterfaceOutput || !packageModuleInterfaceOutput ||
387
- !moduleSourceInfoOutput || !moduleSummaryOutput || !abiDescriptorOutput ||
388
- !moduleSemanticInfoOutput || !optRecordOutput) {
390
+ !moduleInterfaceOutput || !privateModuleInterfaceOutput ||
391
+ !packageModuleInterfaceOutput || !moduleSourceInfoOutput ||
392
+ !moduleSummaryOutput || !abiDescriptorOutput ||
393
+ !moduleSemanticInfoOutput || !optRecordOutput || !silOutput ||
394
+ !irOutput) {
389
395
return std::nullopt ;
390
396
}
391
397
std::vector<SupplementaryOutputPaths> result;
392
398
393
- const unsigned N =
394
- InputsAndOutputs.countOfFilesProducingSupplementaryOutput ();
399
+ // In WMO mode with multiple IR output paths, we need to create one
400
+ // SupplementaryOutputPaths per input file, not just one for the module
401
+ unsigned N = InputsAndOutputs.countOfFilesProducingSupplementaryOutput ();
402
+ if (!InputsAndOutputs.hasPrimaryInputs () && irOutput->size () > 1 ) {
403
+ // WMO mode with multiple IR outputs: use input count instead of 1
404
+ N = InputsAndOutputs.inputCount ();
405
+ }
406
+
407
+ // Find the index of SIL output path matching module name
408
+ auto findSILIndexForModuleName = [&]() -> unsigned {
409
+ if (!InputsAndOutputs.hasPrimaryInputs () && silOutput->size () > 1 ) {
410
+ // In WMO mode with multiple SIL output paths, find the one whose matches
411
+ // module name
412
+ for (unsigned i = 0 ; i < silOutput->size (); ++i) {
413
+ StringRef silPath = (*silOutput)[i];
414
+ if (!silPath.empty ()) {
415
+ StringRef basename = llvm::sys::path::stem (silPath);
416
+ if (basename == ModuleName) {
417
+ return i;
418
+ }
419
+ }
420
+ }
421
+ // If no match found, fall back to first
422
+ return 0 ;
423
+ }
424
+ return 0 ;
425
+ };
426
+
427
+ unsigned silOutputIndex = findSILIndexForModuleName ();
428
+
395
429
for (unsigned i = 0 ; i < N; ++i) {
396
430
SupplementaryOutputPaths sop;
397
431
sop.ClangHeaderOutputPath = (*clangHeaderOutput)[i];
@@ -413,6 +447,8 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
413
447
sop.ModuleSemanticInfoOutputPath = (*moduleSemanticInfoOutput)[i];
414
448
sop.YAMLOptRecordPath = (*optRecordOutput)[i];
415
449
sop.BitstreamOptRecordPath = (*optRecordOutput)[i];
450
+ sop.SILOutputPath = (*silOutput)[silOutputIndex];
451
+ sop.LLVMIROutputPath = (*irOutput)[i];
416
452
result.push_back (sop);
417
453
}
418
454
return result;
@@ -439,6 +475,15 @@ SupplementaryOutputPathsComputer::getSupplementaryFilenamesFromArguments(
439
475
paths.emplace_back ();
440
476
return paths;
441
477
}
478
+ // Special handling for SIL and IR output paths: allow multiple paths per file
479
+ // type
480
+ else if ((pathID == options::OPT_sil_output_path ||
481
+ pathID == options::OPT_ir_output_path) &&
482
+ paths.size () > N) {
483
+ // For parallel compilation, we can have multiple SIL/IR output paths
484
+ // so return all the paths.
485
+ return paths;
486
+ }
442
487
443
488
if (paths.empty ())
444
489
return std::vector<std::string>(N, std::string ());
@@ -613,6 +658,9 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput(
613
658
file_types::TY_BitstreamOptRecord, " " ,
614
659
defaultSupplementaryOutputPathExcludingExtension);
615
660
661
+ auto SILOutputPath = pathsFromArguments.SILOutputPath ;
662
+ auto LLVMIROutputPath = pathsFromArguments.LLVMIROutputPath ;
663
+
616
664
SupplementaryOutputPaths sop;
617
665
sop.ClangHeaderOutputPath = clangHeaderOutputPath;
618
666
sop.ModuleOutputPath = moduleOutputPath;
@@ -635,6 +683,8 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput(
635
683
sop.ModuleSemanticInfoOutputPath = ModuleSemanticInfoOutputPath;
636
684
sop.YAMLOptRecordPath = YAMLOptRecordPath;
637
685
sop.BitstreamOptRecordPath = bitstreamOptRecordPath;
686
+ sop.SILOutputPath = SILOutputPath;
687
+ sop.LLVMIROutputPath = LLVMIROutputPath;
638
688
return sop;
639
689
}
640
690
@@ -741,18 +791,18 @@ createFromTypeToPathMap(const TypeToPathMap *map) {
741
791
742
792
std::optional<std::vector<SupplementaryOutputPaths>>
743
793
SupplementaryOutputPathsComputer::readSupplementaryOutputFileMap () const {
744
- if (Arg *A = Args.getLastArg (options::OPT_emit_objc_header_path,
745
- options::OPT_emit_module_path,
746
- options::OPT_emit_module_doc_path,
747
- options::OPT_emit_dependencies_path,
748
- options::OPT_emit_reference_dependencies_path,
749
- options::OPT_serialize_diagnostics_path,
750
- options::OPT_emit_loaded_module_trace_path,
751
- options::OPT_emit_module_interface_path,
752
- options::OPT_emit_private_module_interface_path,
753
- options::OPT_emit_package_module_interface_path,
754
- options::OPT_emit_module_source_info_path,
755
- options::OPT_emit_tbd_path )) {
794
+ if (Arg *A = Args.getLastArg (
795
+ options::OPT_emit_objc_header_path, options::OPT_emit_module_path,
796
+ options::OPT_emit_module_doc_path,
797
+ options::OPT_emit_dependencies_path,
798
+ options::OPT_emit_reference_dependencies_path,
799
+ options::OPT_serialize_diagnostics_path,
800
+ options::OPT_emit_loaded_module_trace_path,
801
+ options::OPT_emit_module_interface_path,
802
+ options::OPT_emit_private_module_interface_path,
803
+ options::OPT_emit_package_module_interface_path,
804
+ options::OPT_emit_module_source_info_path, options::OPT_emit_tbd_path ,
805
+ options::OPT_sil_output_path, options::OPT_ir_output_path )) {
756
806
Diags.diagnose (SourceLoc (),
757
807
diag::error_cannot_have_supplementary_outputs,
758
808
A->getSpelling (), " -supplementary-output-file-map" );
0 commit comments