@@ -614,6 +614,91 @@ static string_vector saveResultSymbolsLists(string_vector &ResSymbolsLists) {
614614 } \
615615 }
616616
617+ static int processOneModule (std::unique_ptr<Module> M,
618+ util::SimpleTable &Table) {
619+ std::map<StringRef, std::vector<Function *>> GlobalsSet;
620+
621+ bool DoSplit = SplitMode.getNumOccurrences () > 0 ;
622+ bool DoSpecConst = SpecConstLower.getNumOccurrences () > 0 ;
623+
624+ if (DoSplit || DoSymGen) {
625+ KernelMapEntryScope Scope = Scope_Global;
626+ if (DoSplit) {
627+ if (SplitMode == SPLIT_AUTO)
628+ Scope = selectDeviceCodeSplitScopeAutomatically (*M);
629+ else
630+ Scope =
631+ SplitMode == SPLIT_PER_KERNEL ? Scope_PerKernel : Scope_PerModule;
632+ }
633+ collectKernelModuleMap (*M, GlobalsSet, Scope);
634+ }
635+
636+ std::vector<std::unique_ptr<Module>> ResultModules;
637+ string_vector ResultSymbolsLists;
638+
639+ bool SpecConstsMet = false ;
640+ bool SetSpecConstAtRT = DoSpecConst && (SpecConstLower == SC_USE_RT_VAL);
641+
642+ if (DoSpecConst) {
643+ // perform the spec constant intrinsics transformation and enumeration on
644+ // the whole module
645+ ModulePassManager RunSpecConst;
646+ ModuleAnalysisManager MAM;
647+ SpecConstantsPass SCP (SetSpecConstAtRT);
648+ // Register required analysis
649+ MAM.registerPass ([&] { return PassInstrumentationAnalysis (); });
650+ RunSpecConst.addPass (SCP);
651+ if (!DoSplit)
652+ // This pass deletes unreachable globals. Code splitter runs it later.
653+ RunSpecConst.addPass (GlobalDCEPass ());
654+ PreservedAnalyses Res = RunSpecConst.run (*M, MAM);
655+ SpecConstsMet = !Res.areAllPreserved ();
656+ }
657+ if (IROutputOnly) {
658+ // the result is the transformed input LLVMIR file rather than a file table
659+ saveModule (*M, OutputFilename);
660+ return 0 ;
661+ }
662+ if (DoSplit) {
663+ splitModule (*M, GlobalsSet, ResultModules);
664+ // post-link always produces a code result, even if it is unmodified input
665+ if (ResultModules.size () == 0 )
666+ ResultModules.push_back (std::move (M));
667+ } else
668+ ResultModules.push_back (std::move (M));
669+
670+ {
671+ // reuse input module if there were no spec constants and no splitting
672+ string_vector Files = SpecConstsMet || (ResultModules.size () > 1 )
673+ ? saveResultModules (ResultModules)
674+ : string_vector{InputFilename};
675+ // "Code" column is always output
676+ Error Err = Table.addColumn (COL_CODE, Files);
677+ CHECK_AND_EXIT (Err);
678+ }
679+
680+ {
681+ ImagePropSaveInfo ImgPSInfo = {true , DoSpecConst, SetSpecConstAtRT,
682+ SpecConstsMet, EmitKernelParamInfo};
683+ string_vector Files = saveDeviceImageProperty (ResultModules, ImgPSInfo);
684+ Error Err = Table.addColumn (COL_PROPS, Files);
685+ CHECK_AND_EXIT (Err);
686+ }
687+ if (DoSymGen) {
688+ // extract symbols per each module
689+ collectSymbolsLists (GlobalsSet, ResultSymbolsLists);
690+ if (ResultSymbolsLists.empty ()) {
691+ // push empty symbols list for consistency
692+ assert (ResultModules.size () == 1 );
693+ ResultSymbolsLists.push_back (" " );
694+ }
695+ string_vector Files = saveResultSymbolsLists (ResultSymbolsLists);
696+ Error Err = Table.addColumn (COL_SYM, Files);
697+ CHECK_AND_EXIT (Err);
698+ }
699+ return 0 ;
700+ }
701+
617702int main (int argc, char **argv) {
618703 InitLLVM X{argc, argv};
619704
@@ -704,84 +789,14 @@ int main(int argc, char **argv) {
704789 if (OutputFilename.getNumOccurrences () == 0 )
705790 OutputFilename = (Twine (sys::path::stem (InputFilename)) + " .files" ).str ();
706791
707- std::map<StringRef, std::vector<Function *>> GlobalsSet;
708-
709- if (DoSplit || DoSymGen) {
710- KernelMapEntryScope Scope = Scope_Global;
711- if (DoSplit) {
712- if (SplitMode == SPLIT_AUTO)
713- Scope = selectDeviceCodeSplitScopeAutomatically (*MPtr);
714- else
715- Scope =
716- SplitMode == SPLIT_PER_KERNEL ? Scope_PerKernel : Scope_PerModule;
717- }
718- collectKernelModuleMap (*MPtr, GlobalsSet, Scope);
719- }
720-
721- std::vector<std::unique_ptr<Module>> ResultModules;
722- string_vector ResultSymbolsLists;
723-
724792 util::SimpleTable Table;
725- bool SpecConstsMet = false ;
726- bool SetSpecConstAtRT = DoSpecConst && (SpecConstLower == SC_USE_RT_VAL);
793+ int Res = processOneModule (std::move (M), Table);
794+ if (Res)
795+ return Res;
727796
728- if (DoSpecConst) {
729- // perform the spec constant intrinsics transformation and enumeration on
730- // the whole module
731- ModulePassManager RunSpecConst;
732- ModuleAnalysisManager MAM;
733- SpecConstantsPass SCP (SetSpecConstAtRT);
734- // Register required analysis
735- MAM.registerPass ([&] { return PassInstrumentationAnalysis (); });
736- RunSpecConst.addPass (SCP);
737- if (!DoSplit)
738- // This pass deletes unreachable globals. Code splitter runs it later.
739- RunSpecConst.addPass (GlobalDCEPass ());
740- PreservedAnalyses Res = RunSpecConst.run (*MPtr, MAM);
741- SpecConstsMet = !Res.areAllPreserved ();
742- }
743- if (IROutputOnly) {
744- // the result is the transformed input LLVMIR file rather than a file table
745- saveModule (*MPtr, OutputFilename);
797+ if (IROutputOnly)
746798 return 0 ;
747- }
748- if (DoSplit) {
749- splitModule (*MPtr, GlobalsSet, ResultModules);
750- // post-link always produces a code result, even if it is unmodified input
751- if (ResultModules.size () == 0 )
752- ResultModules.push_back (std::move (M));
753- } else
754- ResultModules.push_back (std::move (M));
755-
756- {
757- // reuse input module if there were no spec constants and no splitting
758- string_vector Files = SpecConstsMet || (ResultModules.size () > 1 )
759- ? saveResultModules (ResultModules)
760- : string_vector{InputFilename};
761- // "Code" column is always output
762- Error Err = Table.addColumn (COL_CODE, Files);
763- CHECK_AND_EXIT (Err);
764- }
765799
766- {
767- ImagePropSaveInfo ImgPSInfo = {true , DoSpecConst, SetSpecConstAtRT,
768- SpecConstsMet, EmitKernelParamInfo};
769- string_vector Files = saveDeviceImageProperty (ResultModules, ImgPSInfo);
770- Error Err = Table.addColumn (COL_PROPS, Files);
771- CHECK_AND_EXIT (Err);
772- }
773- if (DoSymGen) {
774- // extract symbols per each module
775- collectSymbolsLists (GlobalsSet, ResultSymbolsLists);
776- if (ResultSymbolsLists.empty ()) {
777- // push empty symbols list for consistency
778- assert (ResultModules.size () == 1 );
779- ResultSymbolsLists.push_back (" " );
780- }
781- string_vector Files = saveResultSymbolsLists (ResultSymbolsLists);
782- Error Err = Table.addColumn (COL_SYM, Files);
783- CHECK_AND_EXIT (Err);
784- }
785800 {
786801 std::error_code EC;
787802 raw_fd_ostream Out{OutputFilename, EC, sys::fs::OF_None};
0 commit comments