Mercurial > hg > CbC > CbC_llvm
diff llvm/lib/Passes/PassBuilder.cpp @ 224:292f64a68d8a
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 19 Jul 2021 03:29:25 +0900 |
parents | dd44ba33042e 5f17cb93ff66 |
children | 5f20bc1ed4ff |
line wrap: on
line diff
--- a/llvm/lib/Passes/PassBuilder.cpp Sat Jul 17 15:20:00 2021 +0900 +++ b/llvm/lib/Passes/PassBuilder.cpp Mon Jul 19 03:29:25 2021 +0900 @@ -203,7 +203,6 @@ #include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h" #include "llvm/Transforms/Scalar/SimplifyCFG.h" #include "llvm/Transforms/Scalar/Sink.h" -#include "llvm/Transforms/Scalar/SpeculateAroundPHIs.h" #include "llvm/Transforms/Scalar/SpeculativeExecution.h" #include "llvm/Transforms/Scalar/StraightLineStrengthReduce.h" #include "llvm/Transforms/Scalar/StructurizeCFG.h" @@ -284,7 +283,6 @@ SLPVectorization = false; LoopUnrolling = true; ForgetAllSCEVInLoopUnroll = ForgetSCEVInLoopUnroll; - Coroutines = false; LicmMssaOptCap = SetLicmMssaOptCap; LicmMssaNoAccForPromotionCap = SetLicmMssaNoAccForPromotionCap; CallGraphProfile = true; @@ -294,6 +292,7 @@ namespace llvm { extern cl::opt<unsigned> MaxDevirtIterations; extern cl::opt<bool> EnableConstraintElimination; +extern cl::opt<bool> EnableFunctionSpecialization; extern cl::opt<bool> EnableGVNHoist; extern cl::opt<bool> EnableGVNSink; extern cl::opt<bool> EnableHotColdSplit; @@ -456,10 +455,14 @@ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); #define FUNCTION_PASS(NAME, CREATE_PASS) \ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ + PIC->addClassToPassName(CLASS, NAME); #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); #define LOOP_PASS(NAME, CREATE_PASS) \ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ + PIC->addClassToPassName(CLASS, NAME); #define LOOP_ANALYSIS(NAME, CREATE_PASS) \ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME); #define CGSCC_PASS(NAME, CREATE_PASS) \ @@ -552,6 +555,7 @@ FPM.addPass(LibCallsShrinkWrapPass()); invokePeepholeEPCallbacks(FPM, Level); + FPM.addPass(SimplifyCFGPass()); // Form canonically associated expression trees, and simplify the trees using @@ -650,8 +654,7 @@ FPM.addPass(InstCombinePass()); invokePeepholeEPCallbacks(FPM, Level); - if (PTO.Coroutines) - FPM.addPass(CoroElidePass()); + FPM.addPass(CoroElidePass()); for (auto &C : ScalarOptimizerLateEPCallbacks) C(FPM, Level); @@ -848,8 +851,7 @@ LICMPass(PTO.LicmMssaOptCap, PTO.LicmMssaNoAccForPromotionCap), EnableMSSALoopDependency, /*UseBlockFrequencyInfo=*/true)); - if (PTO.Coroutines) - FPM.addPass(CoroElidePass()); + FPM.addPass(CoroElidePass()); for (auto &C : ScalarOptimizerLateEPCallbacks) C(FPM, Level); @@ -1010,9 +1012,6 @@ if (AttributorRun & AttributorRunOption::CGSCC) MainCGPipeline.addPass(AttributorCGSCCPass()); - if (PTO.Coroutines) - MainCGPipeline.addPass(CoroSplitPass(Level != OptimizationLevel::O0)); - // Now deduce any function attributes based in the current code. MainCGPipeline.addPass(PostOrderFunctionAttrsPass()); @@ -1034,6 +1033,8 @@ MainCGPipeline.addPass(createCGSCCToFunctionPassAdaptor( buildFunctionSimplificationPipeline(Level, Phase))); + MainCGPipeline.addPass(CoroSplitPass(Level != OptimizationLevel::O0)); + return MIWP; } @@ -1087,8 +1088,7 @@ EarlyFPM.addPass(SimplifyCFGPass()); EarlyFPM.addPass(SROA()); EarlyFPM.addPass(EarlyCSEPass()); - if (PTO.Coroutines) - EarlyFPM.addPass(CoroEarlyPass()); + EarlyFPM.addPass(CoroEarlyPass()); if (Level == OptimizationLevel::O3) EarlyFPM.addPass(CallSiteSplittingPass()); @@ -1124,7 +1124,7 @@ // Try to perform OpenMP specific optimizations on the module. This is a // (quick!) no-op if there are no OpenMP runtime calls present in the module. - if (Level == OptimizationLevel::O2 || Level == OptimizationLevel::O3) + if (Level != OptimizationLevel::O0) MPM.addPass(OpenMPOptPass()); if (AttributorRun & AttributorRunOption::MODULE) @@ -1139,6 +1139,10 @@ for (auto &C : PipelineEarlySimplificationEPCallbacks) C(MPM, Level); + // Specialize functions with IPSCCP. + if (EnableFunctionSpecialization) + MPM.addPass(FunctionSpecializationPass()); + // Interprocedural constant propagation now that basic cleanup has occurred // and prior to optimizing globals. // FIXME: This position in the pipeline hasn't been carefully considered in @@ -1154,7 +1158,7 @@ // Promote any localized globals to SSA registers. // FIXME: Should this instead by a run of SROA? - // FIXME: We should probably run instcombine and simplify-cfg afterward to + // FIXME: We should probably run instcombine and simplifycfg afterward to // delete control flows that are dead once globals have been folded to // constants. MPM.addPass(createModuleToFunctionPassAdaptor(PromotePass())); @@ -1202,11 +1206,11 @@ /// TODO: Should LTO cause any differences to this set of passes? void PassBuilder::addVectorPasses(OptimizationLevel Level, - FunctionPassManager &FPM, bool IsLTO) { + FunctionPassManager &FPM, bool IsFullLTO) { FPM.addPass(LoopVectorizePass( LoopVectorizeOptions(!PTO.LoopInterleaving, !PTO.LoopVectorization))); - if (IsLTO) { + if (IsFullLTO) { // The vectorizer may have significantly shortened a loop body; unroll // again. Unroll small loops to hide loop backedge latency and saturate any // parallel execution resources of an out-of-order processor. We also then @@ -1216,14 +1220,15 @@ // across the loop nests. // We do UnrollAndJam in a separate LPM to ensure it happens before unroll if (EnableUnrollAndJam && PTO.LoopUnrolling) - FPM.addPass(LoopUnrollAndJamPass(Level.getSpeedupLevel())); + FPM.addPass(createFunctionToLoopPassAdaptor( + LoopUnrollAndJamPass(Level.getSpeedupLevel()))); FPM.addPass(LoopUnrollPass(LoopUnrollOptions( Level.getSpeedupLevel(), /*OnlyWhenForced=*/!PTO.LoopUnrolling, PTO.ForgetAllSCEVInLoopUnroll))); FPM.addPass(WarnMissedTransformationsPass()); } - if (!IsLTO) { + if (!IsFullLTO) { // Eliminate loads by forwarding stores from the previous iteration to loads // of the current iteration. FPM.addPass(LoopLoadEliminationPass()); @@ -1270,7 +1275,7 @@ .hoistCommonInsts(true) .sinkCommonInsts(true))); - if (IsLTO) { + if (IsFullLTO) { FPM.addPass(SCCPPass()); FPM.addPass(InstCombinePass()); FPM.addPass(BDCEPass()); @@ -1286,7 +1291,7 @@ // Enhance/cleanup vector code. FPM.addPass(VectorCombinePass()); - if (!IsLTO) { + if (!IsFullLTO) { FPM.addPass(InstCombinePass()); // Unroll small loops to hide loop backedge latency and saturate any // parallel execution resources of an out-of-order processor. We also then @@ -1296,7 +1301,8 @@ // across the loop nests. // We do UnrollAndJam in a separate LPM to ensure it happens before unroll if (EnableUnrollAndJam && PTO.LoopUnrolling) { - FPM.addPass(LoopUnrollAndJamPass(Level.getSpeedupLevel())); + FPM.addPass(createFunctionToLoopPassAdaptor( + LoopUnrollAndJamPass(Level.getSpeedupLevel()))); } FPM.addPass(LoopUnrollPass(LoopUnrollOptions( Level.getSpeedupLevel(), /*OnlyWhenForced=*/!PTO.LoopUnrolling, @@ -1314,7 +1320,7 @@ // alignment information, try to re-derive it here. FPM.addPass(AlignmentFromAssumptionsPass()); - if (IsLTO) + if (IsFullLTO) FPM.addPass(InstCombinePass()); } @@ -1386,7 +1392,7 @@ } // FIXME: We need to run some loop optimizations to re-rotate loops after - // simplify-cfg and others undo their rotation. + // simplifycfg and others undo their rotation. // Optimize the loop execution. These passes operate on entire loop nests // rather than on each loop in an inside-out manner, and so they are actually @@ -1412,7 +1418,7 @@ // from the TargetLibraryInfo. OptimizePM.addPass(InjectTLIMappings()); - addVectorPasses(Level, OptimizePM, /* IsLTO */ false); + addVectorPasses(Level, OptimizePM, /* IsFullLTO */ false); // Split out cold code. Splitting is done late to avoid hiding context from // other optimizations and inadvertently regressing performance. The tradeoff @@ -1449,13 +1455,7 @@ // resulted in single-entry-single-exit or empty blocks. Clean up the CFG. OptimizePM.addPass(SimplifyCFGPass()); - // Optimize PHIs by speculating around them when profitable. Note that this - // pass needs to be run after any PRE or similar pass as it is essentially - // inserting redundancies into the program. This even includes SimplifyCFG. - OptimizePM.addPass(SpeculateAroundPHIsPass()); - - if (PTO.Coroutines) - OptimizePM.addPass(CoroCleanupPass()); + OptimizePM.addPass(CoroCleanupPass()); // Add the core optimizing pipeline. MPM.addPass(createModuleToFunctionPassAdaptor(std::move(OptimizePM))); @@ -1565,8 +1565,21 @@ // Module simplification splits coroutines, but does not fully clean up // coroutine intrinsics. To ensure ThinLTO optimization passes don't trip up // on these, we schedule the cleanup here. - if (PTO.Coroutines) - MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); + MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); + + if (PGOOpt && PGOOpt->PseudoProbeForProfiling) + MPM.addPass(PseudoProbeUpdatePass()); + + // Handle OptimizerLastEPCallbacks added by clang on PreLink. Actual + // optimization is going to be done in PostLink stage, but clang can't + // add callbacks there in case of in-process ThinLTO called by linker. + for (auto &C : OptimizerLastEPCallbacks) + C(MPM, Level); + + // Emit annotation remarks. + addAnnotationRemarksPass(MPM); + + addRequiredLTOPreLinkPasses(MPM); if (PGOOpt && PGOOpt->PseudoProbeForProfiling) MPM.addPass(PseudoProbeUpdatePass()); @@ -1704,6 +1717,9 @@ // produce the same result as if we only do promotion here. MPM.addPass(PGOIndirectCallPromotion( true /* InLTO */, PGOOpt && PGOOpt->Action == PGOOptions::SampleUse)); + + if (EnableFunctionSpecialization) + MPM.addPass(FunctionSpecializationPass()); // Propagate constants at call sites into the functions they call. This // opens opportunities for globalopt (and inlining) by substituting function // pointers passed as arguments to direct uses of functions. @@ -1866,7 +1882,7 @@ MainFPM.addPass(LoopDistributePass()); - addVectorPasses(Level, MainFPM, /* IsLTO */ true); + addVectorPasses(Level, MainFPM, /* IsFullLTO */ true); invokePeepholeEPCallbacks(MainFPM, Level); MainFPM.addPass(JumpThreadingPass(/*InsertFreezeWhenUnfoldingSelect*/ true)); @@ -1926,6 +1942,10 @@ for (auto &C : PipelineStartEPCallbacks) C(MPM, Level); + + if (PGOOpt && PGOOpt->DebugInfoForProfiling) + MPM.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass())); + for (auto &C : PipelineEarlySimplificationEPCallbacks) C(MPM, Level); @@ -1933,10 +1953,8 @@ // which is just that always inlining occurs. Further, disable generating // lifetime intrinsics to avoid enabling further optimizations during // code generation. - // However, we need to insert lifetime intrinsics to avoid invalid access - // caused by multithreaded coroutines. MPM.addPass(AlwaysInlinerPass( - /*InsertLifetimeIntrinsics=*/PTO.Coroutines)); + /*InsertLifetimeIntrinsics=*/false)); if (PTO.MergeFunctions) MPM.addPass(MergeFunctionsPass()); @@ -1985,16 +2003,11 @@ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); } - if (PTO.Coroutines) { - MPM.addPass(createModuleToFunctionPassAdaptor(CoroEarlyPass())); - - CGSCCPassManager CGPM; - CGPM.addPass(CoroSplitPass()); - CGPM.addPass(createCGSCCToFunctionPassAdaptor(CoroElidePass())); - MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); - - MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); - } + MPM.addPass(createModuleToFunctionPassAdaptor(CoroEarlyPass())); + CGSCCPassManager CGPM; + CGPM.addPass(CoroSplitPass()); + MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); + MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass())); for (auto &C : OptimizerLastEPCallbacks) C(MPM, Level); @@ -2088,9 +2101,8 @@ assert(false && "unable to strip pass name from parametrized pass specification"); } - if (Params.empty()) - return ParametersT{}; - if (!Params.consume_front("<") || !Params.consume_back(">")) { + if (!Params.empty() && + (!Params.consume_front("<") || !Params.consume_back(">"))) { assert(false && "invalid format for parametrized pass name"); } @@ -2231,15 +2243,17 @@ return Opts; } -Expected<bool> parseLoopUnswitchOptions(StringRef Params) { - bool Result = false; +Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) { + std::pair<bool, bool> Result = {false, true}; while (!Params.empty()) { StringRef ParamName; std::tie(ParamName, Params) = Params.split(';'); bool Enable = !ParamName.consume_front("no-"); if (ParamName == "nontrivial") { - Result = Enable; + Result.first = Enable; + } else if (ParamName == "trivial") { + Result.second = Enable; } else { return make_error<StringError>( formatv("invalid LoopUnswitch pass parameter '{0}' ", ParamName) @@ -2411,7 +2425,7 @@ #define FUNCTION_PASS(NAME, CREATE_PASS) \ if (Name == NAME) \ return true; -#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \ +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) \ return true; #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \ @@ -2435,7 +2449,7 @@ #define LOOP_PASS(NAME, CREATE_PASS) \ if (Name == NAME) \ return true; -#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \ +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) \ return true; #define LOOP_ANALYSIS(NAME, CREATE_PASS) \ @@ -2625,7 +2639,7 @@ MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \ return Error::success(); \ } -#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \ +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -2639,7 +2653,7 @@ createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \ return Error::success(); \ } -#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \ +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -2732,7 +2746,7 @@ CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \ return Error::success(); \ } -#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \ +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -2746,7 +2760,7 @@ createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \ return Error::success(); \ } -#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \ +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -2817,7 +2831,7 @@ FPM.addPass(CREATE_PASS); \ return Error::success(); \ } -#define FUNCTION_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \ +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -2846,7 +2860,7 @@ FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \ return Error::success(); \ } -#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \ +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -2904,7 +2918,7 @@ LPM.addPass(CREATE_PASS); \ return Error::success(); \ } -#define LOOP_PASS_WITH_PARAMS(NAME, CREATE_PASS, PARSER) \ +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ if (checkParametrizedPassName(Name, NAME)) { \ auto Params = parsePassParameters(PARSER, Name, NAME); \ if (!Params) \ @@ -3164,6 +3178,10 @@ static void printPassName(StringRef PassName, raw_ostream &OS) { OS << " " << PassName << "\n"; } +static void printPassName(StringRef PassName, StringRef Params, + raw_ostream &OS) { + OS << " " << PassName << "<" << Params << ">\n"; +} void PassBuilder::printPassNames(raw_ostream &OS) { // TODO: print pass descriptions when they are available @@ -3192,6 +3210,11 @@ #define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS); #include "PassRegistry.def" + OS << "Function passes with params:\n"; +#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ + printPassName(NAME, PARAMS, OS); +#include "PassRegistry.def" + OS << "Function analyses:\n"; #define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS); #include "PassRegistry.def" @@ -3204,6 +3227,11 @@ #define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS); #include "PassRegistry.def" + OS << "Loop passes with params:\n"; +#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \ + printPassName(NAME, PARAMS, OS); +#include "PassRegistry.def" + OS << "Loop analyses:\n"; #define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS); #include "PassRegistry.def"