diff options
| author | Teresa Johnson <tejohnson@google.com> | 2018-07-19 14:51:32 +0000 |
|---|---|---|
| committer | Teresa Johnson <tejohnson@google.com> | 2018-07-19 14:51:32 +0000 |
| commit | 28023dbed744a1154f3dbcd76beefb5ebd579237 (patch) | |
| tree | 08f39982bd25bced120999fec92e2ce652767153 /llvm/lib | |
| parent | ed2605d36d673626d18ed945f52b11fa80aa6e32 (diff) | |
| download | bcm5719-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.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/Passes/PassBuilder.cpp | 51 | ||||
| -rw-r--r-- | llvm/lib/Passes/PassRegistry.def | 4 | ||||
| -rw-r--r-- | llvm/lib/Transforms/IPO/LowerTypeTests.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp | 3 |
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(); } |

