@@ -636,9 +636,11 @@ struct DevirtModule {
636636 std::map<CallInst *, unsigned > NumUnsafeUsesForTypeTest;
637637 PatternList FunctionsToSkip;
638638
639+ const bool DevirtSpeculatively;
639640 DevirtModule (Module &M, ModuleAnalysisManager &MAM,
640641 ModuleSummaryIndex *ExportSummary,
641- const ModuleSummaryIndex *ImportSummary)
642+ const ModuleSummaryIndex *ImportSummary,
643+ bool DevirtSpeculatively)
642644 : M(M), MAM(MAM),
643645 FAM (MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager()),
644646 ExportSummary(ExportSummary), ImportSummary(ImportSummary),
@@ -651,7 +653,8 @@ struct DevirtModule {
651653 RemarksEnabled(areRemarksEnabled()),
652654 OREGetter([&](Function &F) -> OptimizationRemarkEmitter & {
653655 return FAM.getResult <OptimizationRemarkEmitterAnalysis>(F);
654- }) {
656+ }),
657+ DevirtSpeculatively (DevirtSpeculatively) {
655658 assert (!(ExportSummary && ImportSummary));
656659 FunctionsToSkip.init (SkipFunctionNames);
657660 }
@@ -765,7 +768,8 @@ struct DevirtModule {
765768
766769 // Lower the module using the action and summary passed as command line
767770 // arguments. For testing purposes only.
768- static bool runForTesting (Module &M, ModuleAnalysisManager &MAM);
771+ static bool runForTesting (Module &M, ModuleAnalysisManager &MAM,
772+ bool DevirtSpeculatively);
769773};
770774
771775struct DevirtIndex {
@@ -808,11 +812,22 @@ struct DevirtIndex {
808812PreservedAnalyses WholeProgramDevirtPass::run (Module &M,
809813 ModuleAnalysisManager &MAM) {
810814 if (UseCommandLine) {
811- if (!DevirtModule::runForTesting (M, MAM))
815+ if (!DevirtModule::runForTesting (M, MAM, ClDevirtualizeSpeculatively ))
812816 return PreservedAnalyses::all ();
813817 return PreservedAnalyses::none ();
814818 }
815- if (!DevirtModule (M, MAM, ExportSummary, ImportSummary).run ())
819+
820+ std::optional<ModuleSummaryIndex> Index;
821+ if (!ExportSummary && !ImportSummary && DevirtSpeculatively) {
822+ // Build the ExportSummary from the module.
823+ assert (!ExportSummary &&
824+ " ExportSummary is expected to be empty in non-LTO mode" );
825+ ProfileSummaryInfo PSI (M);
826+ Index.emplace (buildModuleSummaryIndex (M, nullptr , &PSI));
827+ ExportSummary = Index.has_value () ? &Index.value () : nullptr ;
828+ }
829+ if (!DevirtModule (M, MAM, ExportSummary, ImportSummary, DevirtSpeculatively)
830+ .run ())
816831 return PreservedAnalyses::all ();
817832 return PreservedAnalyses::none ();
818833}
@@ -1008,7 +1023,8 @@ static Error checkCombinedSummaryForTesting(ModuleSummaryIndex *Summary) {
10081023 return ErrorSuccess ();
10091024}
10101025
1011- bool DevirtModule::runForTesting (Module &M, ModuleAnalysisManager &MAM) {
1026+ bool DevirtModule::runForTesting (Module &M, ModuleAnalysisManager &MAM,
1027+ bool DevirtSpeculatively) {
10121028 std::unique_ptr<ModuleSummaryIndex> Summary =
10131029 std::make_unique<ModuleSummaryIndex>(/* HaveGVs=*/ false );
10141030
@@ -1037,7 +1053,8 @@ bool DevirtModule::runForTesting(Module &M, ModuleAnalysisManager &MAM) {
10371053 ClSummaryAction == PassSummaryAction::Export ? Summary.get ()
10381054 : nullptr ,
10391055 ClSummaryAction == PassSummaryAction::Import ? Summary.get ()
1040- : nullptr )
1056+ : nullptr ,
1057+ DevirtSpeculatively)
10411058 .run ();
10421059
10431060 if (!ClWriteSummary.empty ()) {
@@ -1101,10 +1118,10 @@ bool DevirtModule::tryFindVirtualCallTargets(
11011118 if (!TM.Bits ->GV ->isConstant ())
11021119 return false ;
11031120
1104- // Without ClDevirtualizeSpeculatively , we cannot perform whole program
1121+ // Without DevirtSpeculatively , we cannot perform whole program
11051122 // devirtualization analysis on a vtable with public LTO visibility.
1106- if (!ClDevirtualizeSpeculatively && TM.Bits ->GV ->getVCallVisibility () ==
1107- GlobalObject::VCallVisibilityPublic)
1123+ if (!DevirtSpeculatively && TM.Bits ->GV ->getVCallVisibility () ==
1124+ GlobalObject::VCallVisibilityPublic)
11081125 return false ;
11091126
11101127 Function *Fn = nullptr ;
@@ -1125,7 +1142,7 @@ bool DevirtModule::tryFindVirtualCallTargets(
11251142
11261143 // In most cases empty functions will be overridden by the
11271144 // implementation of the derived class, so we can skip them.
1128- if (ClDevirtualizeSpeculatively && Fn->getReturnType ()->isVoidTy () &&
1145+ if (DevirtSpeculatively && Fn->getReturnType ()->isVoidTy () &&
11291146 Fn->getInstructionCount () <= 1 )
11301147 continue ;
11311148
@@ -1251,8 +1268,7 @@ void DevirtModule::applySingleImplDevirt(VTableSlotInfo &SlotInfo,
12511268 // add support to compare the virtual function pointer to the
12521269 // devirtualized target. In case of a mismatch, fall back to indirect
12531270 // call.
1254- if (DevirtCheckMode == WPDCheckMode::Fallback ||
1255- ClDevirtualizeSpeculatively) {
1271+ if (DevirtCheckMode == WPDCheckMode::Fallback || DevirtSpeculatively) {
12561272 MDNode *Weights = MDBuilder (M.getContext ()).createLikelyBranchWeights ();
12571273 // Version the indirect call site. If the called value is equal to the
12581274 // given callee, 'NewInst' will be executed, otherwise the original call
@@ -1354,7 +1370,7 @@ bool DevirtModule::trySingleImplDevirt(
13541370 // Out of speculative devirtualization mode, if the only implementation has
13551371 // local linkage, we must promote to external to make it visible to thin LTO
13561372 // objects.
1357- if (!ClDevirtualizeSpeculatively && TheFn->hasLocalLinkage ()) {
1373+ if (!DevirtSpeculatively && TheFn->hasLocalLinkage ()) {
13581374 std::string NewName = (TheFn->getName () + " .llvm.merged" ).str ();
13591375
13601376 // Since we are renaming the function, any comdats with the same name must
@@ -2378,7 +2394,7 @@ bool DevirtModule::run() {
23782394 Intrinsic::getDeclarationIfExists (&M, Intrinsic::type_test);
23792395 // If we are in speculative devirtualization mode, we can work on the public
23802396 // type test intrinsics.
2381- if (!TypeTestFunc && ClDevirtualizeSpeculatively )
2397+ if (!TypeTestFunc && DevirtSpeculatively )
23822398 TypeTestFunc =
23832399 Intrinsic::getDeclarationIfExists (&M, Intrinsic::public_type_test);
23842400 Function *TypeCheckedLoadFunc =
@@ -2507,7 +2523,7 @@ bool DevirtModule::run() {
25072523 trySingleImplDevirt (ExportSummary, TargetsForSlot, S.second , Res);
25082524 // Out of speculative devirtualization mode, Try to apply virtual constant
25092525 // propagation or branch funneling.
2510- if (!SingleImplDevirt && !ClDevirtualizeSpeculatively ) {
2526+ if (!SingleImplDevirt && !DevirtSpeculatively ) {
25112527 DidVirtualConstProp |=
25122528 tryVirtualConstProp (TargetsForSlot, S.second , Res, S.first );
25132529
0 commit comments