Skip to content

Commit 702f64a

Browse files
committed
Enable WPD without lto
1 parent 2b1ebef commit 702f64a

File tree

4 files changed

+61
-36
lines changed

4 files changed

+61
-36
lines changed

clang/lib/CodeGen/CGVTables.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,8 @@ void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD,
13591359
// Emit type metadata on vtables with LTO or IR instrumentation.
13601360
// In IR instrumentation, the type metadata is used to find out vtable
13611361
// definitions (for type profiling) among all global variables.
1362-
if (!getCodeGenOpts().LTOUnit && !getCodeGenOpts().hasProfileIRInstr())
1362+
if (!getCodeGenOpts().LTOUnit && !getCodeGenOpts().hasProfileIRInstr() &&
1363+
!getCodeGenOpts().WholeProgramVTables)
13631364
return;
13641365

13651366
CharUnits ComponentWidth = GetTargetTypeStoreSize(getVTableComponentType());

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7970,8 +7970,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
79707970
IsDeviceOffloadAction ? D.getLTOMode() : D.getOffloadLTOMode();
79717971
auto OtherIsUsingLTO = OtherLTOMode != LTOK_None;
79727972

7973-
if ((!IsUsingLTO && !OtherIsUsingLTO) ||
7974-
(IsPS4 && !UnifiedLTO && (D.getLTOMode() != LTOK_Full)))
7973+
if (!IsUsingLTO && !OtherIsUsingLTO && !UnifiedLTO) {
7974+
if (Arg *A = Args.getLastArg(options::OPT_O_Group))
7975+
if (!A->getOption().matches(options::OPT_O0))
7976+
CmdArgs.push_back("-fwhole-program-vtables");
7977+
} else if ((!IsUsingLTO && !OtherIsUsingLTO) ||
7978+
(IsPS4 && !UnifiedLTO && (D.getLTOMode() != LTOK_Full)))
79757979
D.Diag(diag::err_drv_argument_only_allowed_with)
79767980
<< "-fwhole-program-vtables"
79777981
<< ((IsPS4 && !UnifiedLTO) ? "-flto=full" : "-flto");

llvm/lib/Passes/PassBuilderPipelines.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,6 +1295,9 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
12951295
MPM.addPass(GlobalOptPass());
12961296
MPM.addPass(GlobalDCEPass());
12971297

1298+
if (Phase == ThinOrFullLTOPhase::None && Level != OptimizationLevel::O0)
1299+
MPM.addPass(WholeProgramDevirtPass(nullptr, nullptr));
1300+
12981301
return MPM;
12991302
}
13001303

llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@
6060
#include "llvm/ADT/Statistic.h"
6161
#include "llvm/Analysis/AssumptionCache.h"
6262
#include "llvm/Analysis/BasicAliasAnalysis.h"
63+
#include "llvm/Analysis/ModuleSummaryAnalysis.h"
6364
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
65+
#include "llvm/Analysis/ProfileSummaryInfo.h"
6466
#include "llvm/Analysis/TypeMetadataUtils.h"
6567
#include "llvm/Bitcode/BitcodeReader.h"
6668
#include "llvm/Bitcode/BitcodeWriter.h"
@@ -209,7 +211,8 @@ static cl::opt<WPDCheckMode> DevirtCheckMode(
209211
cl::values(clEnumValN(WPDCheckMode::None, "none", "No checking"),
210212
clEnumValN(WPDCheckMode::Trap, "trap", "Trap when incorrect"),
211213
clEnumValN(WPDCheckMode::Fallback, "fallback",
212-
"Fallback to indirect when incorrect")));
214+
"Fallback to indirect when incorrect")),
215+
cl::init(WPDCheckMode::Fallback));
213216

214217
namespace {
215218
struct PatternList {
@@ -804,6 +807,12 @@ PreservedAnalyses WholeProgramDevirtPass::run(Module &M,
804807
return PreservedAnalyses::all();
805808
return PreservedAnalyses::none();
806809
}
810+
if (!ExportSummary) {
811+
ProfileSummaryInfo PSI(M);
812+
std::optional<ModuleSummaryIndex> Index;
813+
Index.emplace(buildModuleSummaryIndex(M, nullptr, &PSI));
814+
ExportSummary = Index.has_value() ? &Index.value() : nullptr;
815+
}
807816
if (!DevirtModule(M, AARGetter, OREGetter, LookupDomTree, ExportSummary,
808817
ImportSummary)
809818
.run())
@@ -814,8 +823,10 @@ PreservedAnalyses WholeProgramDevirtPass::run(Module &M,
814823
// Enable whole program visibility if enabled by client (e.g. linker) or
815824
// internal option, and not force disabled.
816825
bool llvm::hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO) {
817-
return (WholeProgramVisibilityEnabledInLTO || WholeProgramVisibility) &&
818-
!DisableWholeProgramVisibility;
826+
if (WholeProgramVisibilityEnabledInLTO)
827+
return (WholeProgramVisibilityEnabledInLTO || WholeProgramVisibility) &&
828+
!DisableWholeProgramVisibility;
829+
return true;
819830
}
820831

821832
static bool
@@ -1099,9 +1110,9 @@ bool DevirtModule::tryFindVirtualCallTargets(
10991110

11001111
// We cannot perform whole program devirtualization analysis on a vtable
11011112
// with public LTO visibility.
1102-
if (TM.Bits->GV->getVCallVisibility() ==
1103-
GlobalObject::VCallVisibilityPublic)
1104-
return false;
1113+
// if (TM.Bits->GV->getVCallVisibility() ==
1114+
// GlobalObject::VCallVisibilityPublic)
1115+
// return false;
11051116

11061117
Function *Fn = nullptr;
11071118
Constant *C = nullptr;
@@ -1342,26 +1353,28 @@ bool DevirtModule::trySingleImplDevirt(
13421353
// If the only implementation has local linkage, we must promote to external
13431354
// to make it visible to thin LTO objects. We can only get here during the
13441355
// ThinLTO export phase.
1345-
if (TheFn->hasLocalLinkage()) {
1346-
std::string NewName = (TheFn->getName() + ".llvm.merged").str();
1347-
1348-
// Since we are renaming the function, any comdats with the same name must
1349-
// also be renamed. This is required when targeting COFF, as the comdat name
1350-
// must match one of the names of the symbols in the comdat.
1351-
if (Comdat *C = TheFn->getComdat()) {
1352-
if (C->getName() == TheFn->getName()) {
1353-
Comdat *NewC = M.getOrInsertComdat(NewName);
1354-
NewC->setSelectionKind(C->getSelectionKind());
1355-
for (GlobalObject &GO : M.global_objects())
1356-
if (GO.getComdat() == C)
1357-
GO.setComdat(NewC);
1358-
}
1359-
}
1360-
1361-
TheFn->setLinkage(GlobalValue::ExternalLinkage);
1362-
TheFn->setVisibility(GlobalValue::HiddenVisibility);
1363-
TheFn->setName(NewName);
1364-
}
1356+
// if (TheFn->hasLocalLinkage()) {
1357+
// std::string NewName = (TheFn->getName() + ".llvm.merged").str();
1358+
1359+
// // Since we are renaming the function, any comdats with the same name
1360+
// must
1361+
// // also be renamed. This is required when targeting COFF, as the comdat
1362+
// name
1363+
// // must match one of the names of the symbols in the comdat.
1364+
// if (Comdat *C = TheFn->getComdat()) {
1365+
// if (C->getName() == TheFn->getName()) {
1366+
// Comdat *NewC = M.getOrInsertComdat(NewName);
1367+
// NewC->setSelectionKind(C->getSelectionKind());
1368+
// for (GlobalObject &GO : M.global_objects())
1369+
// if (GO.getComdat() == C)
1370+
// GO.setComdat(NewC);
1371+
// }
1372+
// }
1373+
1374+
// TheFn->setLinkage(GlobalValue::ExternalLinkage);
1375+
// TheFn->setVisibility(GlobalValue::HiddenVisibility);
1376+
// TheFn->setName(NewName);
1377+
// }
13651378
if (ValueInfo TheFnVI = ExportSummary->getValueInfo(TheFn->getGUID()))
13661379
// Any needed promotion of 'TheFn' has already been done during
13671380
// LTO unit split, so we can ignore return value of AddCalls.
@@ -2321,6 +2334,9 @@ bool DevirtModule::run() {
23212334

23222335
Function *TypeTestFunc =
23232336
Intrinsic::getDeclarationIfExists(&M, Intrinsic::type_test);
2337+
if (!TypeTestFunc)
2338+
TypeTestFunc =
2339+
Intrinsic::getDeclarationIfExists(&M, Intrinsic::public_type_test);
23242340
Function *TypeCheckedLoadFunc =
23252341
Intrinsic::getDeclarationIfExists(&M, Intrinsic::type_checked_load);
23262342
Function *TypeCheckedLoadRelativeFunc = Intrinsic::getDeclarationIfExists(
@@ -2443,13 +2459,14 @@ bool DevirtModule::run() {
24432459
.WPDRes[S.first.ByteOffset];
24442460
if (tryFindVirtualCallTargets(TargetsForSlot, TypeMemberInfos,
24452461
S.first.ByteOffset, ExportSummary)) {
2446-
2447-
if (!trySingleImplDevirt(ExportSummary, TargetsForSlot, S.second, Res)) {
2448-
DidVirtualConstProp |=
2449-
tryVirtualConstProp(TargetsForSlot, S.second, Res, S.first);
2450-
2451-
tryICallBranchFunnel(TargetsForSlot, S.second, Res, S.first);
2452-
}
2462+
trySingleImplDevirt(ExportSummary, TargetsForSlot, S.second, Res);
2463+
// Following features are not needed for the case of enabling WPD without
2464+
// lto. if (!trySingleImplDevirt(ExportSummary, TargetsForSlot, S.second,
2465+
// Res)) { DidVirtualConstProp |=
2466+
// tryVirtualConstProp(TargetsForSlot, S.second, Res, S.first);
2467+
2468+
// tryICallBranchFunnel(TargetsForSlot, S.second, Res, S.first);
2469+
// }
24532470

24542471
// Collect functions devirtualized at least for one call site for stats.
24552472
if (RemarksEnabled || AreStatisticsEnabled())

0 commit comments

Comments
 (0)