bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM, StringRef &PipelineText, bool VerifyEachPass, bool DebugLogging) { for (;;) { // Parse nested pass managers by recursing. if (PipelineText.startswith("cgscc(")) { CGSCCPassManager NestedCGPM(DebugLogging); // Parse the inner pipeline into the nested manager. PipelineText = PipelineText.substr(strlen("cgscc(")); if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass, DebugLogging) || PipelineText.empty()) return false; assert(PipelineText[0] == ')'); PipelineText = PipelineText.substr(1); // Add the nested pass manager with the appropriate adaptor. CGPM.addPass(std::move(NestedCGPM)); } else if (PipelineText.startswith("function(")) { FunctionPassManager NestedFPM(DebugLogging); // Parse the inner pipeline inte the nested manager. PipelineText = PipelineText.substr(strlen("function(")); if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass, DebugLogging) || PipelineText.empty()) return false; assert(PipelineText[0] == ')'); PipelineText = PipelineText.substr(1); // Add the nested pass manager with the appropriate adaptor. CGPM.addPass( createCGSCCToFunctionPassAdaptor(std::move(NestedFPM), DebugLogging)); } else { // Otherwise try to parse a pass name. size_t End = PipelineText.find_first_of(",)"); if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End))) return false; // FIXME: No verifier support for CGSCC passes! PipelineText = PipelineText.substr(End); } if (PipelineText.empty() || PipelineText[0] == ')') return true; assert(PipelineText[0] == ','); PipelineText = PipelineText.substr(1); } }
bool PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E, bool VerifyEachPass, bool DebugLogging) { auto &Name = E.Name; auto &InnerPipeline = E.InnerPipeline; // First handle complex passes like the pass managers which carry pipelines. if (!InnerPipeline.empty()) { if (Name == "cgscc") { CGSCCPassManager NestedCGPM(DebugLogging); if (!parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, VerifyEachPass, DebugLogging)) return false; // Add the nested pass manager with the appropriate adaptor. CGPM.addPass(std::move(NestedCGPM)); return true; } if (Name == "function") { FunctionPassManager FPM(DebugLogging); if (!parseFunctionPassPipeline(FPM, InnerPipeline, VerifyEachPass, DebugLogging)) return false; // Add the nested pass manager with the appropriate adaptor. CGPM.addPass( 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(createRepeatedPass(*Count, std::move(NestedCGPM))); return true; } if (auto MaxRepetitions = parseDevirtPassName(Name)) { CGSCCPassManager NestedCGPM(DebugLogging); if (!parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, VerifyEachPass, DebugLogging)) return false; CGPM.addPass(createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions, DebugLogging)); return true; } // Normal passes can't have pipelines. return false; } // Now expand the basic registered passes from the .inc file. #define CGSCC_PASS(NAME, CREATE_PASS) \ if (Name == NAME) { \ CGPM.addPass(CREATE_PASS); \ return true; \ } #define CGSCC_ANALYSIS(NAME, CREATE_PASS) \ if (Name == "require<" NAME ">") { \ CGPM.addPass(RequireAnalysisPass< \ std::remove_reference<decltype(CREATE_PASS)>::type, \ LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \ CGSCCUpdateResult &>()); \ return true; \ } \ if (Name == "invalidate<" NAME ">") { \ CGPM.addPass(InvalidateAnalysisPass< \ std::remove_reference<decltype(CREATE_PASS)>::type>()); \ return true; \ } #include "PassRegistry.def" return false; }