From 241bf2456f548b7a0f2003586180dfa6aaf401dd Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Wed, 3 Aug 2016 07:44:48 +0000 Subject: [PM] Add a generic 'repeat N times' pass wrapper to the new pass manager. While this has some utility for debugging and testing on its own, it is primarily intended to demonstrate the technique for adding custom wrappers that can provide more interesting interation behavior in a nice, orthogonal, and composable layer. Being able to write these kinds of very dynamic and customized controls for running passes was one of the motivating use cases of the new pass manager design, and this gives a hint at how they might look. The actual logic is tiny here, and most of this is just wiring in the pipeline parsing so that this can be widely used. I'm adding this now to show the wiring without a lot of business logic. This is a precursor patch for showing how a "iterate up to N times as long as we devirtualize a call" utility can be added as a separable and composable component along side the CGSCC pass management. Differential Revision: https://reviews.llvm.org/D22405 llvm-svn: 277581 --- llvm/lib/Passes/PassBuilder.cpp | 59 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'llvm/lib') diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 4dae8748ffd..6369b55e4b6 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -274,6 +274,15 @@ void PassBuilder::addLTODefaultPipeline(ModulePassManager &MPM, MPM.addPass(createModuleToFunctionPassAdaptor(std::move(LateFPM))); } +static Optional parseRepeatPassName(StringRef Name) { + if (!Name.consume_front("repeat<") || !Name.consume_back(">")) + return None; + int Count; + if (Name.getAsInteger(0, Count) || Count <= 0) + return None; + return Count; +} + static bool isModulePassName(StringRef Name) { // Manually handle aliases for pre-configured pipeline fragments. if (Name.startswith("default") || Name.startswith("lto")) @@ -287,6 +296,10 @@ static bool isModulePassName(StringRef Name) { if (Name == "function") return true; + // Explicitly handle custom-parsed pass names. + if (parseRepeatPassName(Name)) + return true; + #define MODULE_PASS(NAME, CREATE_PASS) \ if (Name == NAME) \ return true; @@ -305,6 +318,10 @@ static bool isCGSCCPassName(StringRef Name) { if (Name == "function") return true; + // Explicitly handle custom-parsed pass names. + if (parseRepeatPassName(Name)) + return true; + #define CGSCC_PASS(NAME, CREATE_PASS) \ if (Name == NAME) \ return true; @@ -323,6 +340,10 @@ static bool isFunctionPassName(StringRef Name) { if (Name == "loop") return true; + // Explicitly handle custom-parsed pass names. + if (parseRepeatPassName(Name)) + return true; + #define FUNCTION_PASS(NAME, CREATE_PASS) \ if (Name == NAME) \ return true; @@ -339,6 +360,10 @@ static bool isLoopPassName(StringRef Name) { if (Name == "loop") return true; + // Explicitly handle custom-parsed pass names. + if (parseRepeatPassName(Name)) + return true; + #define LOOP_PASS(NAME, CREATE_PASS) \ if (Name == NAME) \ return true; @@ -440,6 +465,14 @@ bool PassBuilder::parseModulePass(ModulePassManager &MPM, MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); return true; } + if (auto Count = parseRepeatPassName(Name)) { + ModulePassManager NestedMPM(DebugLogging); + if (!parseModulePassPipeline(NestedMPM, InnerPipeline, VerifyEachPass, + DebugLogging)) + return false; + MPM.addPass(createRepeatingPassWrapper(*Count, std::move(NestedMPM))); + return true; + } // Normal passes can't have pipelines. return false; } @@ -519,6 +552,14 @@ bool PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM, createCGSCCToFunctionPassAdaptor(std::move(FPM), DebugLogging)); return true; } + if (auto Count = parseRepeatPassName(Name)) { + CGSCCPassManager NestedCGPM(DebugLogging); + if (!parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, VerifyEachPass, + DebugLogging)) + return false; + CGPM.addPass(createRepeatingPassWrapper(*Count, std::move(NestedCGPM))); + return true; + } // Normal passes can't have pipelines. return false; } @@ -571,6 +612,14 @@ bool PassBuilder::parseFunctionPass(FunctionPassManager &FPM, FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM))); return true; } + if (auto Count = parseRepeatPassName(Name)) { + FunctionPassManager NestedFPM(DebugLogging); + if (!parseFunctionPassPipeline(NestedFPM, InnerPipeline, VerifyEachPass, + DebugLogging)) + return false; + FPM.addPass(createRepeatingPassWrapper(*Count, std::move(NestedFPM))); + return true; + } // Normal passes can't have pipelines. return false; } @@ -599,7 +648,7 @@ bool PassBuilder::parseFunctionPass(FunctionPassManager &FPM, bool PassBuilder::parseLoopPass(LoopPassManager &FPM, const PipelineElement &E, bool VerifyEachPass, bool DebugLogging) { - auto &Name = E.Name; + StringRef Name = E.Name; auto &InnerPipeline = E.InnerPipeline; // First handle complex passes like the pass managers which carry pipelines. @@ -613,6 +662,14 @@ bool PassBuilder::parseLoopPass(LoopPassManager &FPM, const PipelineElement &E, FPM.addPass(std::move(NestedLPM)); return true; } + if (auto Count = parseRepeatPassName(Name)) { + LoopPassManager NestedLPM(DebugLogging); + if (!parseLoopPassPipeline(NestedLPM, InnerPipeline, VerifyEachPass, + DebugLogging)) + return false; + FPM.addPass(createRepeatingPassWrapper(*Count, std::move(NestedLPM))); + return true; + } // Normal passes can't have pipelines. return false; } -- cgit v1.2.3