void PassBuilder::crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM) { MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); }); MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); }); CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); }); FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); }); FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); }); FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); }); LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); }); }
bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M, tool_output_file *Out, StringRef PassPipeline, OutputKind OK, VerifierKind VK) { FunctionAnalysisManager FAM; ModuleAnalysisManager MAM; // FIXME: Lift this registration of analysis passes into a .def file adjacent // to the one used to associate names with passes. MAM.registerPass(LazyCallGraphAnalysis()); // Cross register the analysis managers through their proxies. MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM)); FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM)); ModulePassManager MPM; if (VK > VK_NoVerifier) MPM.addPass(VerifierPass()); if (!parsePassPipeline(MPM, PassPipeline, VK == VK_VerifyEachPass)) { errs() << Arg0 << ": unable to parse pass pipeline description.\n"; return false; } if (VK > VK_NoVerifier) MPM.addPass(VerifierPass()); // Add any relevant output pass at the end of the pipeline. switch (OK) { case OK_NoOutput: break; // No output pass needed. case OK_OutputAssembly: MPM.addPass(PrintModulePass(Out->os())); break; case OK_OutputBitcode: MPM.addPass(BitcodeWriterPass(Out->os())); break; } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); // Now that we have all of the passes ready, run them. MPM.run(&M, &MAM); // Declare success. if (OK != OK_NoOutput) Out->keep(); return true; }
static void runNewCustomLtoPasses(Module &M, TargetMachine &TM) { PassBuilder PB(&TM); AAManager AA; // Parse a custom AA pipeline if asked to. if (!PB.parseAAPipeline(AA, Config->LtoAAPipeline)) { error("Unable to parse AA pipeline description: " + Config->LtoAAPipeline); return; } LoopAnalysisManager LAM; FunctionAnalysisManager FAM; CGSCCAnalysisManager CGAM; ModuleAnalysisManager MAM; // Register the AA manager first so that our version is the one used. FAM.registerPass([&] { return std::move(AA); }); // Register all the basic analyses with the managers. PB.registerModuleAnalyses(MAM); PB.registerCGSCCAnalyses(CGAM); PB.registerFunctionAnalyses(FAM); PB.registerLoopAnalyses(LAM); PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); ModulePassManager MPM; if (!Config->DisableVerify) MPM.addPass(VerifierPass()); // Now, add all the passes we've been requested to. if (!PB.parsePassPipeline(MPM, Config->LtoNewPmPasses)) { error("unable to parse pass pipeline description: " + Config->LtoNewPmPasses); return; } if (!Config->DisableVerify) MPM.addPass(VerifierPass()); MPM.run(M, MAM); }
/// A clean version of `EmitAssembly` that uses the new pass manager. /// /// Not all features are currently supported in this system, but where /// necessary it falls back to the legacy pass manager to at least provide /// basic functionality. /// /// This API is planned to have its functionality finished and then to replace /// `EmitAssembly` at some point in the future when the default switches. void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) { TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr); setCommandLineOpts(CodeGenOpts); // The new pass manager always makes a target machine available to passes // during construction. CreateTargetMachine(/*MustCreateTM*/ true); if (!TM) // This will already be diagnosed, just bail. return; TheModule->setDataLayout(TM->createDataLayout()); Optional<PGOOptions> PGOOpt; if (CodeGenOpts.hasProfileIRInstr()) // -fprofile-generate. PGOOpt = PGOOptions(CodeGenOpts.InstrProfileOutput.empty() ? DefaultProfileGenName : CodeGenOpts.InstrProfileOutput, "", "", true, CodeGenOpts.DebugInfoForProfiling); else if (CodeGenOpts.hasProfileIRUse()) // -fprofile-use. PGOOpt = PGOOptions("", CodeGenOpts.ProfileInstrumentUsePath, "", false, CodeGenOpts.DebugInfoForProfiling); else if (!CodeGenOpts.SampleProfileFile.empty()) // -fprofile-sample-use PGOOpt = PGOOptions("", "", CodeGenOpts.SampleProfileFile, false, CodeGenOpts.DebugInfoForProfiling); else if (CodeGenOpts.DebugInfoForProfiling) // -fdebug-info-for-profiling PGOOpt = PGOOptions("", "", "", false, true); PassBuilder PB(TM.get(), PGOOpt); LoopAnalysisManager LAM; FunctionAnalysisManager FAM; CGSCCAnalysisManager CGAM; ModuleAnalysisManager MAM; // Register the AA manager first so that our version is the one used. FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); }); // Register the target library analysis directly and give it a customized // preset TLI. Triple TargetTriple(TheModule->getTargetTriple()); std::unique_ptr<TargetLibraryInfoImpl> TLII( createTLII(TargetTriple, CodeGenOpts)); FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); MAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); // Register all the basic analyses with the managers. PB.registerModuleAnalyses(MAM); PB.registerCGSCCAnalyses(CGAM); PB.registerFunctionAnalyses(FAM); PB.registerLoopAnalyses(LAM); PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); ModulePassManager MPM(CodeGenOpts.DebugPassManager); if (!CodeGenOpts.DisableLLVMPasses) { bool IsThinLTO = CodeGenOpts.EmitSummaryIndex; bool IsLTO = CodeGenOpts.PrepareForLTO; if (CodeGenOpts.OptimizationLevel == 0) { // Build a minimal pipeline based on the semantics required by Clang, // which is just that always inlining occurs. MPM.addPass(AlwaysInlinerPass()); if (IsThinLTO) MPM.addPass(NameAnonGlobalPass()); } else { // Map our optimization levels into one of the distinct levels used to // configure the pipeline. PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts); if (IsThinLTO) { MPM = PB.buildThinLTOPreLinkDefaultPipeline( Level, CodeGenOpts.DebugPassManager); MPM.addPass(NameAnonGlobalPass()); } else if (IsLTO) { MPM = PB.buildLTOPreLinkDefaultPipeline(Level, CodeGenOpts.DebugPassManager); } else { MPM = PB.buildPerModuleDefaultPipeline(Level, CodeGenOpts.DebugPassManager); } } } // FIXME: We still use the legacy pass manager to do code generation. We // create that pass manager here and use it as needed below. legacy::PassManager CodeGenPasses; bool NeedCodeGen = false; Optional<raw_fd_ostream> ThinLinkOS; // Append any output we need to the pass manager. switch (Action) { case Backend_EmitNothing: break; case Backend_EmitBC: if (CodeGenOpts.EmitSummaryIndex) { if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) { std::error_code EC; ThinLinkOS.emplace(CodeGenOpts.ThinLinkBitcodeFile, EC, llvm::sys::fs::F_None); if (EC) { Diags.Report(diag::err_fe_unable_to_open_output) << CodeGenOpts.ThinLinkBitcodeFile << EC.message(); return; } } MPM.addPass( ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &*ThinLinkOS : nullptr)); } else { MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists, CodeGenOpts.EmitSummaryIndex, CodeGenOpts.EmitSummaryIndex)); } break; case Backend_EmitLL: MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists)); break; case Backend_EmitAssembly: case Backend_EmitMCNull: case Backend_EmitObj: NeedCodeGen = true; CodeGenPasses.add( createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); if (!AddEmitPasses(CodeGenPasses, Action, *OS)) // FIXME: Should we handle this error differently? return; break; } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); // Now that we have all of the passes ready, run them. { PrettyStackTraceString CrashInfo("Optimizer"); MPM.run(*TheModule, MAM); } // Now if needed, run the legacy PM for codegen. if (NeedCodeGen) { PrettyStackTraceString CrashInfo("Code generation"); CodeGenPasses.run(*TheModule); } }
/// A clean version of `EmitAssembly` that uses the new pass manager. /// /// Not all features are currently supported in this system, but where /// necessary it falls back to the legacy pass manager to at least provide /// basic functionality. /// /// This API is planned to have its functionality finished and then to replace /// `EmitAssembly` at some point in the future when the default switches. void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( BackendAction Action, std::unique_ptr<raw_pwrite_stream> OS) { TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr); setCommandLineOpts(); // The new pass manager always makes a target machine available to passes // during construction. CreateTargetMachine(/*MustCreateTM*/ true); if (!TM) // This will already be diagnosed, just bail. return; TheModule->setDataLayout(TM->createDataLayout()); PassBuilder PB(TM.get()); LoopAnalysisManager LAM; FunctionAnalysisManager FAM; CGSCCAnalysisManager CGAM; ModuleAnalysisManager MAM; // Register the AA manager first so that our version is the one used. FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); }); // Register all the basic analyses with the managers. PB.registerModuleAnalyses(MAM); PB.registerCGSCCAnalyses(CGAM); PB.registerFunctionAnalyses(FAM); PB.registerLoopAnalyses(LAM); PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); ModulePassManager MPM; if (!CodeGenOpts.DisableLLVMPasses) { if (CodeGenOpts.OptimizationLevel == 0) { // Build a minimal pipeline based on the semantics required by Clang, // which is just that always inlining occurs. MPM.addPass(AlwaysInlinerPass()); } else { // Otherwise, use the default pass pipeline. We also have to map our // optimization levels into one of the distinct levels used to configure // the pipeline. PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts); MPM = PB.buildPerModuleDefaultPipeline(Level); } } // FIXME: We still use the legacy pass manager to do code generation. We // create that pass manager here and use it as needed below. legacy::PassManager CodeGenPasses; bool NeedCodeGen = false; // Append any output we need to the pass manager. switch (Action) { case Backend_EmitNothing: break; case Backend_EmitBC: MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists, CodeGenOpts.EmitSummaryIndex, CodeGenOpts.EmitSummaryIndex)); break; case Backend_EmitLL: MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists)); break; case Backend_EmitAssembly: case Backend_EmitMCNull: case Backend_EmitObj: NeedCodeGen = true; CodeGenPasses.add( createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); if (!AddEmitPasses(CodeGenPasses, Action, *OS)) // FIXME: Should we handle this error differently? return; break; } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); // Now that we have all of the passes ready, run them. { PrettyStackTraceString CrashInfo("Optimizer"); MPM.run(*TheModule, MAM); } // Now if needed, run the legacy PM for codegen. if (NeedCodeGen) { PrettyStackTraceString CrashInfo("Code generation"); CodeGenPasses.run(*TheModule); } }