summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorTeresa Johnson <tejohnson@google.com>2018-07-19 14:51:32 +0000
committerTeresa Johnson <tejohnson@google.com>2018-07-19 14:51:32 +0000
commit28023dbed744a1154f3dbcd76beefb5ebd579237 (patch)
tree08f39982bd25bced120999fec92e2ce652767153 /llvm/lib
parented2605d36d673626d18ed945f52b11fa80aa6e32 (diff)
downloadbcm5719-llvm-28023dbed744a1154f3dbcd76beefb5ebd579237.tar.gz
bcm5719-llvm-28023dbed744a1154f3dbcd76beefb5ebd579237.zip
[ThinLTO] Enable ThinLTO WholeProgramDevirt and LowerTypeTests in new PM
Summary: Enable these passes for CFI and WPD in ThinLTO and LTO with the new pass manager. Add a couple of tests for both PMs based on the clang tests tools/clang/test/CodeGen/thinlto-distributed-cfi*.ll, but just test through llvm-lto2 and not with distributed ThinLTO. Reviewers: pcc Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, llvm-commits Differential Revision: https://reviews.llvm.org/D49429 llvm-svn: 337461
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/LTO/LTOBackend.cpp12
-rw-r--r--llvm/lib/Passes/PassBuilder.cpp51
-rw-r--r--llvm/lib/Passes/PassRegistry.def4
-rw-r--r--llvm/lib/Transforms/IPO/LowerTypeTests.cpp4
-rw-r--r--llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp3
5 files changed, 45 insertions, 29 deletions
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 0ead3989941..eadbb410bd5 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -144,7 +144,9 @@ createTargetMachine(Config &Conf, const Target *TheTarget, Module &M) {
}
static void runNewPMPasses(Config &Conf, Module &Mod, TargetMachine *TM,
- unsigned OptLevel, bool IsThinLTO) {
+ unsigned OptLevel, bool IsThinLTO,
+ ModuleSummaryIndex *ExportSummary,
+ const ModuleSummaryIndex *ImportSummary) {
Optional<PGOOptions> PGOOpt;
if (!Conf.SampleProfile.empty())
PGOOpt = PGOOptions("", "", Conf.SampleProfile, false, true);
@@ -194,9 +196,10 @@ static void runNewPMPasses(Config &Conf, Module &Mod, TargetMachine *TM,
}
if (IsThinLTO)
- MPM = PB.buildThinLTODefaultPipeline(OL, Conf.DebugPassManager);
+ MPM = PB.buildThinLTODefaultPipeline(OL, Conf.DebugPassManager,
+ ImportSummary);
else
- MPM = PB.buildLTODefaultPipeline(OL, Conf.DebugPassManager);
+ MPM = PB.buildLTODefaultPipeline(OL, Conf.DebugPassManager, ExportSummary);
MPM.run(Mod, MAM);
// FIXME (davide): verify the output.
@@ -279,7 +282,8 @@ bool opt(Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod,
runNewPMCustomPasses(Mod, TM, Conf.OptPipeline, Conf.AAPipeline,
Conf.DisableVerify);
else if (Conf.UseNewPM)
- runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO);
+ runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO, ExportSummary,
+ ImportSummary);
else
runOldPMPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary);
return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod);
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index d4d66e06a02..eb04dcc8b6e 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -922,15 +922,28 @@ PassBuilder::buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level,
return MPM;
}
-ModulePassManager
-PassBuilder::buildThinLTODefaultPipeline(OptimizationLevel Level,
- bool DebugLogging) {
- // FIXME: The summary index is not hooked in the new pass manager yet.
- // When it's going to be hooked, enable WholeProgramDevirt and LowerTypeTest
- // here.
-
+ModulePassManager PassBuilder::buildThinLTODefaultPipeline(
+ OptimizationLevel Level, bool DebugLogging,
+ const ModuleSummaryIndex *ImportSummary) {
ModulePassManager MPM(DebugLogging);
+ if (ImportSummary) {
+ // These passes import type identifier resolutions for whole-program
+ // devirtualization and CFI. They must run early because other passes may
+ // disturb the specific instruction patterns that these passes look for,
+ // creating dependencies on resolutions that may not appear in the summary.
+ //
+ // For example, GVN may transform the pattern assume(type.test) appearing in
+ // two basic blocks into assume(phi(type.test, type.test)), which would
+ // transform a dependency on a WPD resolution into a dependency on a type
+ // identifier resolution for CFI.
+ //
+ // Also, WPD has access to more precise information than ICP and can
+ // devirtualize more effectively, so it should operate on the IR first.
+ MPM.addPass(WholeProgramDevirtPass(nullptr, ImportSummary));
+ MPM.addPass(LowerTypeTestsPass(nullptr, ImportSummary));
+ }
+
// Force any function attributes we want the rest of the pipeline to observe.
MPM.addPass(ForceFunctionAttrsPass());
@@ -961,8 +974,9 @@ PassBuilder::buildLTOPreLinkDefaultPipeline(OptimizationLevel Level,
return buildPerModuleDefaultPipeline(Level, DebugLogging);
}
-ModulePassManager PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
- bool DebugLogging) {
+ModulePassManager
+PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level, bool DebugLogging,
+ ModuleSummaryIndex *ExportSummary) {
assert(Level != O0 && "Must request optimizations for the default pipeline!");
ModulePassManager MPM(DebugLogging);
@@ -1012,11 +1026,15 @@ ModulePassManager PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
// Run whole program optimization of virtual call when the list of callees
// is fixed.
- MPM.addPass(WholeProgramDevirtPass());
+ MPM.addPass(WholeProgramDevirtPass(ExportSummary, nullptr));
// Stop here at -O1.
- if (Level == 1)
+ if (Level == 1) {
+ // The LowerTypeTestsPass needs to run to lower type metadata and the
+ // type.test intrinsics. The pass does nothing if CFI is disabled.
+ MPM.addPass(LowerTypeTestsPass(ExportSummary, nullptr));
return MPM;
+ }
// Optimize globals to try and fold them into constants.
MPM.addPass(GlobalOptPass());
@@ -1125,12 +1143,7 @@ ModulePassManager PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
// clang's control flow integrity mechanisms (-fsanitize=cfi*) and needs
// to be run at link time if CFI is enabled. This pass does nothing if
// CFI is disabled.
- // Enable once we add support for the summary in the new PM.
-#if 0
- MPM.addPass(LowerTypeTestsPass(Summary ? PassSummaryAction::Export :
- PassSummaryAction::None,
- Summary));
-#endif
+ MPM.addPass(LowerTypeTestsPass(ExportSummary, nullptr));
// Add late LTO optimization passes.
// Delete basic blocks, which optimization passes may have killed.
@@ -1442,12 +1455,12 @@ bool PassBuilder::parseModulePass(ModulePassManager &MPM,
} else if (Matches[1] == "thinlto-pre-link") {
MPM.addPass(buildThinLTOPreLinkDefaultPipeline(L, DebugLogging));
} else if (Matches[1] == "thinlto") {
- MPM.addPass(buildThinLTODefaultPipeline(L, DebugLogging));
+ MPM.addPass(buildThinLTODefaultPipeline(L, DebugLogging, nullptr));
} else if (Matches[1] == "lto-pre-link") {
MPM.addPass(buildLTOPreLinkDefaultPipeline(L, DebugLogging));
} else {
assert(Matches[1] == "lto" && "Not one of the matched options!");
- MPM.addPass(buildLTODefaultPipeline(L, DebugLogging));
+ MPM.addPass(buildLTODefaultPipeline(L, DebugLogging, nullptr));
}
return true;
}
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 367f8ee3fb0..6ae93a47696 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -56,7 +56,7 @@ MODULE_PASS("instrprof", InstrProfiling())
MODULE_PASS("internalize", InternalizePass())
MODULE_PASS("invalidate<all>", InvalidateAllAnalysesPass())
MODULE_PASS("ipsccp", IPSCCPPass())
-MODULE_PASS("lowertypetests", LowerTypeTestsPass())
+MODULE_PASS("lowertypetests", LowerTypeTestsPass(nullptr, nullptr))
MODULE_PASS("name-anon-globals", NameAnonGlobalPass())
MODULE_PASS("no-op-module", NoOpModulePass())
MODULE_PASS("partial-inliner", PartialInlinerPass())
@@ -75,7 +75,7 @@ MODULE_PASS("rpo-functionattrs", ReversePostOrderFunctionAttrsPass())
MODULE_PASS("sample-profile", SampleProfileLoaderPass())
MODULE_PASS("strip-dead-prototypes", StripDeadPrototypesPass())
MODULE_PASS("synthetic-counts-propagation", SyntheticCountsPropagation())
-MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass())
+MODULE_PASS("wholeprogramdevirt", WholeProgramDevirtPass(nullptr, nullptr))
MODULE_PASS("verify", VerifierPass())
#undef MODULE_PASS
diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index 9d6442b51ee..367b6282e24 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -2102,9 +2102,7 @@ bool LowerTypeTestsModule::lower() {
PreservedAnalyses LowerTypeTestsPass::run(Module &M,
ModuleAnalysisManager &AM) {
- bool Changed = LowerTypeTestsModule(M, /*ExportSummary=*/nullptr,
- /*ImportSummary=*/nullptr)
- .lower();
+ bool Changed = LowerTypeTestsModule(M, ExportSummary, ImportSummary).lower();
if (!Changed)
return PreservedAnalyses::all();
return PreservedAnalyses::none();
diff --git a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
index 6a99ca17dfd..d65da2504db 100644
--- a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
+++ b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
@@ -611,7 +611,8 @@ PreservedAnalyses WholeProgramDevirtPass::run(Module &M,
auto OREGetter = [&](Function *F) -> OptimizationRemarkEmitter & {
return FAM.getResult<OptimizationRemarkEmitterAnalysis>(*F);
};
- if (!DevirtModule(M, AARGetter, OREGetter, nullptr, nullptr).run())
+ if (!DevirtModule(M, AARGetter, OREGetter, ExportSummary, ImportSummary)
+ .run())
return PreservedAnalyses::all();
return PreservedAnalyses::none();
}
OpenPOWER on IntegriCloud