LLVM 19.0.0git
PassBuilder.cpp
Go to the documentation of this file.
1//===- Parsing and selection of pass pipelines ----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9///
10/// This file provides the implementation of the PassBuilder based on our
11/// static pass registry as well as related functionality. It also provides
12/// helpers to aid in analyzing, debugging, and testing passes and pass
13/// pipelines.
14///
15//===----------------------------------------------------------------------===//
16
32#include "llvm/Analysis/DDG.h"
48#include "llvm/Analysis/Lint.h"
107#include "llvm/IR/DebugInfo.h"
108#include "llvm/IR/Dominators.h"
109#include "llvm/IR/PassManager.h"
110#include "llvm/IR/PrintPasses.h"
112#include "llvm/IR/Verifier.h"
116#include "llvm/Support/Debug.h"
119#include "llvm/Support/Regex.h"
300#include <optional>
301
302using namespace llvm;
303
305 "^(default|thinlto-pre-link|thinlto|lto-pre-link|lto)<(O[0123sz])>$");
306
307namespace llvm {
309 "print-pipeline-passes",
310 cl::desc("Print a '-passes' compatible string describing the pipeline "
311 "(best-effort only)."));
312} // namespace llvm
313
314AnalysisKey NoOpModuleAnalysis::Key;
315AnalysisKey NoOpCGSCCAnalysis::Key;
316AnalysisKey NoOpFunctionAnalysis::Key;
317AnalysisKey NoOpLoopAnalysis::Key;
318
319namespace {
320
321/// Whether or not we should populate a PassInstrumentationCallbacks's class to
322/// pass name map.
323///
324/// This is for optimization purposes so we don't populate it if we never use
325/// it. This should be updated if new pass instrumentation wants to use the map.
326/// We currently only use this for --print-before/after.
327bool shouldPopulateClassToPassNames() {
328 return PrintPipelinePasses || !printBeforePasses().empty() ||
329 !printAfterPasses().empty() || !isFilterPassesEmpty() ||
331}
332
333// A pass for testing -print-on-crash.
334// DO NOT USE THIS EXCEPT FOR TESTING!
335class TriggerCrashPass : public PassInfoMixin<TriggerCrashPass> {
336public:
338 abort();
339 return PreservedAnalyses::all();
340 }
341 static StringRef name() { return "TriggerCrashPass"; }
342};
343
344// A pass for testing message reporting of -verify-each failures.
345// DO NOT USE THIS EXCEPT FOR TESTING!
346class TriggerVerifierErrorPass
347 : public PassInfoMixin<TriggerVerifierErrorPass> {
348public:
350 // Intentionally break the Module by creating an alias without setting the
351 // aliasee.
352 auto *PtrTy = llvm::PointerType::getUnqual(M.getContext());
353 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
354 GlobalValue::LinkageTypes::InternalLinkage,
355 "__bad_alias", nullptr, &M);
357 }
358
360 // Intentionally break the Function by inserting a terminator
361 // instruction in the middle of a basic block.
362 BasicBlock &BB = F.getEntryBlock();
363 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
365 }
366
368 // Intentionally create a virtual register and set NoVRegs property.
369 auto &MRI = MF.getRegInfo();
370 MRI.createGenericVirtualRegister(LLT::scalar(8));
371 MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
372 return PreservedAnalyses::all();
373 }
374
375 static StringRef name() { return "TriggerVerifierErrorPass"; }
376};
377
378// A pass requires all MachineFunctionProperties.
379// DO NOT USE THIS EXCEPT FOR TESTING!
380class RequireAllMachineFunctionPropertiesPass
381 : public PassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
382public:
385 }
386
387 static MachineFunctionProperties getRequiredProperties() {
389 MFProps.set(MachineFunctionProperties::Property::FailedISel);
390 MFProps.set(MachineFunctionProperties::Property::FailsVerification);
391 MFProps.set(MachineFunctionProperties::Property::IsSSA);
392 MFProps.set(MachineFunctionProperties::Property::Legalized);
393 MFProps.set(MachineFunctionProperties::Property::NoPHIs);
394 MFProps.set(MachineFunctionProperties::Property::NoVRegs);
395 MFProps.set(MachineFunctionProperties::Property::RegBankSelected);
396 MFProps.set(MachineFunctionProperties::Property::Selected);
397 MFProps.set(MachineFunctionProperties::Property::TiedOpsRewritten);
398 MFProps.set(MachineFunctionProperties::Property::TracksDebugUserValues);
399 MFProps.set(MachineFunctionProperties::Property::TracksLiveness);
400 return MFProps;
401 }
402 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
403};
404
405} // namespace
406
408 std::optional<PGOOptions> PGOOpt,
410 : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) {
411 bool ShouldPopulateClassToPassNames = PIC && shouldPopulateClassToPassNames();
412 if (TM)
413 TM->registerPassBuilderCallbacks(*this, ShouldPopulateClassToPassNames);
414 if (ShouldPopulateClassToPassNames) {
415#define MODULE_PASS(NAME, CREATE_PASS) \
416 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
417#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
418 PIC->addClassToPassName(CLASS, NAME);
419#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
420 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
421#define FUNCTION_PASS(NAME, CREATE_PASS) \
422 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
423#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
424 PIC->addClassToPassName(CLASS, NAME);
425#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
426 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
427#define LOOPNEST_PASS(NAME, CREATE_PASS) \
428 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
429#define LOOP_PASS(NAME, CREATE_PASS) \
430 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
431#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
432 PIC->addClassToPassName(CLASS, NAME);
433#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
434 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
435#define CGSCC_PASS(NAME, CREATE_PASS) \
436 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
437#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
438 PIC->addClassToPassName(CLASS, NAME);
439#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
440 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
441#include "PassRegistry.def"
442
443#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
444 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
445#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
446 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
447#include "llvm/Passes/MachinePassRegistry.def"
448 }
449}
450
452#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
453 MAM.registerPass([&] { return CREATE_PASS; });
454#include "PassRegistry.def"
455
456 for (auto &C : ModuleAnalysisRegistrationCallbacks)
457 C(MAM);
458}
459
461#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
462 CGAM.registerPass([&] { return CREATE_PASS; });
463#include "PassRegistry.def"
464
465 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
466 C(CGAM);
467}
468
470 // We almost always want the default alias analysis pipeline.
471 // If a user wants a different one, they can register their own before calling
472 // registerFunctionAnalyses().
473 FAM.registerPass([&] { return buildDefaultAAPipeline(); });
474
475#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
476 FAM.registerPass([&] { return CREATE_PASS; });
477#include "PassRegistry.def"
478
479 for (auto &C : FunctionAnalysisRegistrationCallbacks)
480 C(FAM);
481}
482
485
486#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
487 MFAM.registerPass([&] { return CREATE_PASS; });
488#include "llvm/Passes/MachinePassRegistry.def"
489
490 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
491 C(MFAM);
492}
493
495#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
496 LAM.registerPass([&] { return CREATE_PASS; });
497#include "PassRegistry.def"
498
499 for (auto &C : LoopAnalysisRegistrationCallbacks)
500 C(LAM);
501}
502
503static std::optional<int> parseRepeatPassName(StringRef Name) {
504 if (!Name.consume_front("repeat<") || !Name.consume_back(">"))
505 return std::nullopt;
506 int Count;
507 if (Name.getAsInteger(0, Count) || Count <= 0)
508 return std::nullopt;
509 return Count;
510}
511
512static std::optional<std::pair<bool, bool>>
514 std::pair<bool, bool> Params;
515 if (!Name.consume_front("function"))
516 return std::nullopt;
517 if (Name.empty())
518 return Params;
519 if (!Name.consume_front("<") || !Name.consume_back(">"))
520 return std::nullopt;
521 while (!Name.empty()) {
522 auto [Front, Back] = Name.split(';');
523 Name = Back;
524 if (Front == "eager-inv")
525 Params.first = true;
526 else if (Front == "no-rerun")
527 Params.second = true;
528 else
529 return std::nullopt;
530 }
531 return Params;
532}
533
534static std::optional<int> parseDevirtPassName(StringRef Name) {
535 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
536 return std::nullopt;
537 int Count;
538 if (Name.getAsInteger(0, Count) || Count < 0)
539 return std::nullopt;
540 return Count;
541}
542
543static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
545 .Case("O0", OptimizationLevel::O0)
551 .Default(std::nullopt);
552}
553
555 StringRef OptionName,
557 bool Result = false;
558 while (!Params.empty()) {
559 StringRef ParamName;
560 std::tie(ParamName, Params) = Params.split(';');
561
562 if (ParamName == OptionName) {
563 Result = true;
564 } else {
565 return make_error<StringError>(
566 formatv("invalid {1} pass parameter '{0}' ", ParamName, PassName)
567 .str(),
569 }
570 }
571 return Result;
572}
573
574namespace {
575
576/// Parser of parameters for HardwareLoops pass.
577Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
578 HardwareLoopOptions HardwareLoopOpts;
579
580 while (!Params.empty()) {
581 StringRef ParamName;
582 std::tie(ParamName, Params) = Params.split(';');
583 if (ParamName.consume_front("hardware-loop-decrement=")) {
584 int Count;
585 if (ParamName.getAsInteger(0, Count))
586 return make_error<StringError>(
587 formatv("invalid HardwareLoopPass parameter '{0}' ", ParamName).str(),
589 HardwareLoopOpts.setDecrement(Count);
590 continue;
591 }
592 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
593 int Count;
594 if (ParamName.getAsInteger(0, Count))
595 return make_error<StringError>(
596 formatv("invalid HardwareLoopPass parameter '{0}' ", ParamName).str(),
598 HardwareLoopOpts.setCounterBitwidth(Count);
599 continue;
600 }
601 if (ParamName == "force-hardware-loops") {
602 HardwareLoopOpts.setForce(true);
603 } else if (ParamName == "force-hardware-loop-phi") {
604 HardwareLoopOpts.setForcePhi(true);
605 } else if (ParamName == "force-nested-hardware-loop") {
606 HardwareLoopOpts.setForceNested(true);
607 } else if (ParamName == "force-hardware-loop-guard") {
608 HardwareLoopOpts.setForceGuard(true);
609 } else {
610 return make_error<StringError>(
611 formatv("invalid HardwarePass parameter '{0}' ", ParamName).str(),
613 }
614 }
615 return HardwareLoopOpts;
616}
617
618/// Parser of parameters for LoopUnroll pass.
619Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
620 LoopUnrollOptions UnrollOpts;
621 while (!Params.empty()) {
622 StringRef ParamName;
623 std::tie(ParamName, Params) = Params.split(';');
624 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
625 // Don't accept -Os/-Oz.
626 if (OptLevel && !OptLevel->isOptimizingForSize()) {
627 UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel());
628 continue;
629 }
630 if (ParamName.consume_front("full-unroll-max=")) {
631 int Count;
632 if (ParamName.getAsInteger(0, Count))
633 return make_error<StringError>(
634 formatv("invalid LoopUnrollPass parameter '{0}' ", ParamName).str(),
636 UnrollOpts.setFullUnrollMaxCount(Count);
637 continue;
638 }
639
640 bool Enable = !ParamName.consume_front("no-");
641 if (ParamName == "partial") {
642 UnrollOpts.setPartial(Enable);
643 } else if (ParamName == "peeling") {
644 UnrollOpts.setPeeling(Enable);
645 } else if (ParamName == "profile-peeling") {
646 UnrollOpts.setProfileBasedPeeling(Enable);
647 } else if (ParamName == "runtime") {
648 UnrollOpts.setRuntime(Enable);
649 } else if (ParamName == "upperbound") {
650 UnrollOpts.setUpperBound(Enable);
651 } else {
652 return make_error<StringError>(
653 formatv("invalid LoopUnrollPass parameter '{0}' ", ParamName).str(),
655 }
656 }
657 return UnrollOpts;
658}
659
660Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
662 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
663}
664
665Expected<bool> parseCGProfilePassOptions(StringRef Params) {
666 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
667 "CGProfile");
668}
669
670Expected<bool> parseInlinerPassOptions(StringRef Params) {
671 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
672 "InlinerPass");
673}
674
675Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
676 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
677 "CoroSplitPass");
678}
679
680Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
682 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
683}
684
685Expected<CFGuardPass::Mechanism> parseCFGuardPassOptions(StringRef Params) {
686 if (Params.empty())
688
689 auto [Param, RHS] = Params.split(';');
690 if (!RHS.empty())
691 return make_error<StringError>(
692 formatv("too many CFGuardPass parameters '{0}' ", Params).str(),
694
695 if (Param == "check")
697 if (Param == "dispatch")
699
700 return make_error<StringError>(
701 formatv("invalid CFGuardPass mechanism: '{0}' ", Param).str(),
703}
704
705Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
706 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
707}
708
709Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
710 return PassBuilder::parseSinglePassOption(Params, "post-inline",
711 "EntryExitInstrumenter");
712}
713
714Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
715 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor");
716}
717
718Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
719 return PassBuilder::parseSinglePassOption(Params, "minimal",
720 "LowerMatrixIntrinsics");
721}
722
723Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
725 while (!Params.empty()) {
726 StringRef ParamName;
727 std::tie(ParamName, Params) = Params.split(';');
728
729 if (ParamName == "kernel") {
730 Result.CompileKernel = true;
731 } else {
732 return make_error<StringError>(
733 formatv("invalid AddressSanitizer pass parameter '{0}' ", ParamName)
734 .str(),
736 }
737 }
738 return Result;
739}
740
741Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
743 while (!Params.empty()) {
744 StringRef ParamName;
745 std::tie(ParamName, Params) = Params.split(';');
746
747 if (ParamName == "recover") {
748 Result.Recover = true;
749 } else if (ParamName == "kernel") {
750 Result.CompileKernel = true;
751 } else {
752 return make_error<StringError>(
753 formatv("invalid HWAddressSanitizer pass parameter '{0}' ", ParamName)
754 .str(),
756 }
757 }
758 return Result;
759}
760
761Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
763 while (!Params.empty()) {
764 StringRef ParamName;
765 std::tie(ParamName, Params) = Params.split(';');
766
767 if (ParamName == "thinlto") {
768 Result.IsThinLTO = true;
769 } else if (ParamName == "emit-summary") {
770 Result.EmitLTOSummary = true;
771 } else {
772 return make_error<StringError>(
773 formatv("invalid EmbedBitcode pass parameter '{0}' ", ParamName)
774 .str(),
776 }
777 }
778 return Result;
779}
780
781Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
783 while (!Params.empty()) {
784 StringRef ParamName;
785 std::tie(ParamName, Params) = Params.split(';');
786
787 if (ParamName == "recover") {
788 Result.Recover = true;
789 } else if (ParamName == "kernel") {
790 Result.Kernel = true;
791 } else if (ParamName.consume_front("track-origins=")) {
792 if (ParamName.getAsInteger(0, Result.TrackOrigins))
793 return make_error<StringError>(
794 formatv("invalid argument to MemorySanitizer pass track-origins "
795 "parameter: '{0}' ",
796 ParamName)
797 .str(),
799 } else if (ParamName == "eager-checks") {
800 Result.EagerChecks = true;
801 } else {
802 return make_error<StringError>(
803 formatv("invalid MemorySanitizer pass parameter '{0}' ", ParamName)
804 .str(),
806 }
807 }
808 return Result;
809}
810
811/// Parser of parameters for SimplifyCFG pass.
812Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
814 while (!Params.empty()) {
815 StringRef ParamName;
816 std::tie(ParamName, Params) = Params.split(';');
817
818 bool Enable = !ParamName.consume_front("no-");
819 if (ParamName == "speculate-blocks") {
820 Result.speculateBlocks(Enable);
821 } else if (ParamName == "simplify-cond-branch") {
822 Result.setSimplifyCondBranch(Enable);
823 } else if (ParamName == "forward-switch-cond") {
824 Result.forwardSwitchCondToPhi(Enable);
825 } else if (ParamName == "switch-range-to-icmp") {
826 Result.convertSwitchRangeToICmp(Enable);
827 } else if (ParamName == "switch-to-lookup") {
828 Result.convertSwitchToLookupTable(Enable);
829 } else if (ParamName == "keep-loops") {
830 Result.needCanonicalLoops(Enable);
831 } else if (ParamName == "hoist-common-insts") {
832 Result.hoistCommonInsts(Enable);
833 } else if (ParamName == "sink-common-insts") {
834 Result.sinkCommonInsts(Enable);
835 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
836 APInt BonusInstThreshold;
837 if (ParamName.getAsInteger(0, BonusInstThreshold))
838 return make_error<StringError>(
839 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
840 "parameter: '{0}' ",
841 ParamName).str(),
843 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
844 } else {
845 return make_error<StringError>(
846 formatv("invalid SimplifyCFG pass parameter '{0}' ", ParamName).str(),
848 }
849 }
850 return Result;
851}
852
853Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
855 // When specifying "instcombine" in -passes enable fix-point verification by
856 // default, as this is what most tests should use.
857 Result.setVerifyFixpoint(true);
858 while (!Params.empty()) {
859 StringRef ParamName;
860 std::tie(ParamName, Params) = Params.split(';');
861
862 bool Enable = !ParamName.consume_front("no-");
863 if (ParamName == "use-loop-info") {
864 Result.setUseLoopInfo(Enable);
865 } else if (ParamName == "verify-fixpoint") {
866 Result.setVerifyFixpoint(Enable);
867 } else if (Enable && ParamName.consume_front("max-iterations=")) {
868 APInt MaxIterations;
869 if (ParamName.getAsInteger(0, MaxIterations))
870 return make_error<StringError>(
871 formatv("invalid argument to InstCombine pass max-iterations "
872 "parameter: '{0}' ",
873 ParamName).str(),
875 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
876 } else {
877 return make_error<StringError>(
878 formatv("invalid InstCombine pass parameter '{0}' ", ParamName).str(),
880 }
881 }
882 return Result;
883}
884
885/// Parser of parameters for LoopVectorize pass.
886Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
888 while (!Params.empty()) {
889 StringRef ParamName;
890 std::tie(ParamName, Params) = Params.split(';');
891
892 bool Enable = !ParamName.consume_front("no-");
893 if (ParamName == "interleave-forced-only") {
895 } else if (ParamName == "vectorize-forced-only") {
897 } else {
898 return make_error<StringError>(
899 formatv("invalid LoopVectorize parameter '{0}' ", ParamName).str(),
901 }
902 }
903 return Opts;
904}
905
906Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
907 std::pair<bool, bool> Result = {false, true};
908 while (!Params.empty()) {
909 StringRef ParamName;
910 std::tie(ParamName, Params) = Params.split(';');
911
912 bool Enable = !ParamName.consume_front("no-");
913 if (ParamName == "nontrivial") {
914 Result.first = Enable;
915 } else if (ParamName == "trivial") {
916 Result.second = Enable;
917 } else {
918 return make_error<StringError>(
919 formatv("invalid LoopUnswitch pass parameter '{0}' ", ParamName)
920 .str(),
922 }
923 }
924 return Result;
925}
926
927Expected<LICMOptions> parseLICMOptions(StringRef Params) {
929 while (!Params.empty()) {
930 StringRef ParamName;
931 std::tie(ParamName, Params) = Params.split(';');
932
933 bool Enable = !ParamName.consume_front("no-");
934 if (ParamName == "allowspeculation") {
935 Result.AllowSpeculation = Enable;
936 } else {
937 return make_error<StringError>(
938 formatv("invalid LICM pass parameter '{0}' ", ParamName).str(),
940 }
941 }
942 return Result;
943}
944
945Expected<std::pair<bool, bool>> parseLoopRotateOptions(StringRef Params) {
946 std::pair<bool, bool> Result = {true, false};
947 while (!Params.empty()) {
948 StringRef ParamName;
949 std::tie(ParamName, Params) = Params.split(';');
950
951 bool Enable = !ParamName.consume_front("no-");
952 if (ParamName == "header-duplication") {
953 Result.first = Enable;
954 } else if (ParamName == "prepare-for-lto") {
955 Result.second = Enable;
956 } else {
957 return make_error<StringError>(
958 formatv("invalid LoopRotate pass parameter '{0}' ", ParamName).str(),
960 }
961 }
962 return Result;
963}
964
965Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
966 bool Result = false;
967 while (!Params.empty()) {
968 StringRef ParamName;
969 std::tie(ParamName, Params) = Params.split(';');
970
971 bool Enable = !ParamName.consume_front("no-");
972 if (ParamName == "split-footer-bb") {
973 Result = Enable;
974 } else {
975 return make_error<StringError>(
976 formatv("invalid MergedLoadStoreMotion pass parameter '{0}' ",
977 ParamName)
978 .str(),
980 }
981 }
982 return Result;
983}
984
985Expected<GVNOptions> parseGVNOptions(StringRef Params) {
987 while (!Params.empty()) {
988 StringRef ParamName;
989 std::tie(ParamName, Params) = Params.split(';');
990
991 bool Enable = !ParamName.consume_front("no-");
992 if (ParamName == "pre") {
993 Result.setPRE(Enable);
994 } else if (ParamName == "load-pre") {
995 Result.setLoadPRE(Enable);
996 } else if (ParamName == "split-backedge-load-pre") {
997 Result.setLoadPRESplitBackedge(Enable);
998 } else if (ParamName == "memdep") {
999 Result.setMemDep(Enable);
1000 } else {
1001 return make_error<StringError>(
1002 formatv("invalid GVN pass parameter '{0}' ", ParamName).str(),
1004 }
1005 }
1006 return Result;
1007}
1008
1009Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1011 while (!Params.empty()) {
1012 StringRef ParamName;
1013 std::tie(ParamName, Params) = Params.split(';');
1014
1015 bool Enable = !ParamName.consume_front("no-");
1016 if (ParamName == "func-spec")
1017 Result.setFuncSpec(Enable);
1018 else
1019 return make_error<StringError>(
1020 formatv("invalid IPSCCP pass parameter '{0}' ", ParamName).str(),
1022 }
1023 return Result;
1024}
1025
1026Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1027 if (Params.empty() || Params == "modify-cfg")
1029 if (Params == "preserve-cfg")
1031 return make_error<StringError>(
1032 formatv("invalid SROA pass parameter '{0}' (either preserve-cfg or "
1033 "modify-cfg can be specified)",
1034 Params)
1035 .str(),
1037}
1038
1040parseStackLifetimeOptions(StringRef Params) {
1042 while (!Params.empty()) {
1043 StringRef ParamName;
1044 std::tie(ParamName, Params) = Params.split(';');
1045
1046 if (ParamName == "may") {
1048 } else if (ParamName == "must") {
1050 } else {
1051 return make_error<StringError>(
1052 formatv("invalid StackLifetime parameter '{0}' ", ParamName).str(),
1054 }
1055 }
1056 return Result;
1057}
1058
1059Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1060 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1061 "DependenceAnalysisPrinter");
1062}
1063
1064Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1065 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1066 "SeparateConstOffsetFromGEP");
1067}
1068
1070parseFunctionSimplificationPipelineOptions(StringRef Params) {
1071 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1072 if (!L || *L == OptimizationLevel::O0) {
1073 return make_error<StringError>(
1074 formatv("invalid function-simplification parameter '{0}' ", Params)
1075 .str(),
1077 };
1078 return *L;
1079}
1080
1081Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1082 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1083 "MemorySSAPrinterPass");
1084}
1085
1086Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1087 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1088 "SpeculativeExecutionPass");
1089}
1090
1091Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1092 std::string Result;
1093 while (!Params.empty()) {
1094 StringRef ParamName;
1095 std::tie(ParamName, Params) = Params.split(';');
1096
1097 if (ParamName.consume_front("profile-filename=")) {
1098 Result = ParamName.str();
1099 } else {
1100 return make_error<StringError>(
1101 formatv("invalid MemProfUse pass parameter '{0}' ", ParamName).str(),
1103 }
1104 }
1105 return Result;
1106}
1107
1108Expected<bool> parseStructuralHashPrinterPassOptions(StringRef Params) {
1109 return PassBuilder::parseSinglePassOption(Params, "detailed",
1110 "StructuralHashPrinterPass");
1111}
1112
1113Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1114 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1115 "WinEHPreparePass");
1116}
1117
1118Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1120 while (!Params.empty()) {
1121 StringRef ParamName;
1122 std::tie(ParamName, Params) = Params.split(';');
1123
1124 bool Enable = !ParamName.consume_front("no-");
1125 if (ParamName == "group-by-use")
1126 Result.GroupByUse = Enable;
1127 else if (ParamName == "ignore-single-use")
1128 Result.IgnoreSingleUse = Enable;
1129 else if (ParamName == "merge-const")
1130 Result.MergeConst = Enable;
1131 else if (ParamName == "merge-external")
1132 Result.MergeExternal = Enable;
1133 else if (ParamName.consume_front("max-offset=")) {
1134 if (ParamName.getAsInteger(0, Result.MaxOffset))
1135 return make_error<StringError>(
1136 formatv("invalid GlobalMergePass parameter '{0}' ", ParamName)
1137 .str(),
1139 }
1140 }
1141 return Result;
1142}
1143
1144} // namespace
1145
1146/// Tests whether a pass name starts with a valid prefix for a default pipeline
1147/// alias.
1149 return Name.starts_with("default") || Name.starts_with("thinlto") ||
1150 Name.starts_with("lto");
1151}
1152
1153/// Tests whether registered callbacks will accept a given pass name.
1154///
1155/// When parsing a pipeline text, the type of the outermost pipeline may be
1156/// omitted, in which case the type is automatically determined from the first
1157/// pass name in the text. This may be a name that is handled through one of the
1158/// callbacks. We check this through the oridinary parsing callbacks by setting
1159/// up a dummy PassManager in order to not force the client to also handle this
1160/// type of query.
1161template <typename PassManagerT, typename CallbacksT>
1162static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1163 if (!Callbacks.empty()) {
1164 PassManagerT DummyPM;
1165 for (auto &CB : Callbacks)
1166 if (CB(Name, DummyPM, {}))
1167 return true;
1168 }
1169 return false;
1170}
1171
1172template <typename CallbacksT>
1173static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1174 // Manually handle aliases for pre-configured pipeline fragments.
1177
1178 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1179
1180 // Explicitly handle pass manager names.
1181 if (Name == "module")
1182 return true;
1183 if (Name == "cgscc")
1184 return true;
1185 if (NameNoBracket == "function")
1186 return true;
1187 if (Name == "coro-cond")
1188 return true;
1189
1190 // Explicitly handle custom-parsed pass names.
1192 return true;
1193
1194#define MODULE_PASS(NAME, CREATE_PASS) \
1195 if (Name == NAME) \
1196 return true;
1197#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1198 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1199 return true;
1200#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1201 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1202 return true;
1203#include "PassRegistry.def"
1204
1205 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1206}
1207
1208template <typename CallbacksT>
1209static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1210 // Explicitly handle pass manager names.
1211 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1212 if (Name == "cgscc")
1213 return true;
1214 if (NameNoBracket == "function")
1215 return true;
1216
1217 // Explicitly handle custom-parsed pass names.
1219 return true;
1221 return true;
1222
1223#define CGSCC_PASS(NAME, CREATE_PASS) \
1224 if (Name == NAME) \
1225 return true;
1226#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1227 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1228 return true;
1229#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1230 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1231 return true;
1232#include "PassRegistry.def"
1233
1234 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1235}
1236
1237template <typename CallbacksT>
1238static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1239 // Explicitly handle pass manager names.
1240 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1241 if (NameNoBracket == "function")
1242 return true;
1243 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1244 return true;
1245
1246 // Explicitly handle custom-parsed pass names.
1248 return true;
1249
1250#define FUNCTION_PASS(NAME, CREATE_PASS) \
1251 if (Name == NAME) \
1252 return true;
1253#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1254 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1255 return true;
1256#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1257 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1258 return true;
1259#include "PassRegistry.def"
1260
1261 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1262}
1263
1264template <typename CallbacksT>
1265static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1266 // Explicitly handle pass manager names.
1267 if (Name == "machine-function")
1268 return true;
1269
1270 // Explicitly handle custom-parsed pass names.
1272 return true;
1273
1274#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1275 if (Name == NAME) \
1276 return true;
1277#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1278 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1279 return true;
1280
1281#include "llvm/Passes/MachinePassRegistry.def"
1282
1283 return callbacksAcceptPassName<MachineFunctionPassManager>(Name, Callbacks);
1284}
1285
1286template <typename CallbacksT>
1287static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1288 bool &UseMemorySSA) {
1289 UseMemorySSA = false;
1290
1291 // Explicitly handle custom-parsed pass names.
1293 return true;
1294
1296 UseMemorySSA = true;
1297 return true;
1298 }
1299
1300#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1301 if (Name == NAME) \
1302 return true;
1303#include "PassRegistry.def"
1304
1305 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1306}
1307
1308template <typename CallbacksT>
1309static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1310 bool &UseMemorySSA) {
1311 UseMemorySSA = false;
1312
1313 // Explicitly handle custom-parsed pass names.
1315 return true;
1316
1318 UseMemorySSA = true;
1319 return true;
1320 }
1321
1322#define LOOP_PASS(NAME, CREATE_PASS) \
1323 if (Name == NAME) \
1324 return true;
1325#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1326 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1327 return true;
1328#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1329 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1330 return true;
1331#include "PassRegistry.def"
1332
1333 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1334}
1335
1336std::optional<std::vector<PassBuilder::PipelineElement>>
1337PassBuilder::parsePipelineText(StringRef Text) {
1338 std::vector<PipelineElement> ResultPipeline;
1339
1340 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1341 &ResultPipeline};
1342 for (;;) {
1343 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1344 size_t Pos = Text.find_first_of(",()");
1345 Pipeline.push_back({Text.substr(0, Pos), {}});
1346
1347 // If we have a single terminating name, we're done.
1348 if (Pos == Text.npos)
1349 break;
1350
1351 char Sep = Text[Pos];
1352 Text = Text.substr(Pos + 1);
1353 if (Sep == ',')
1354 // Just a name ending in a comma, continue.
1355 continue;
1356
1357 if (Sep == '(') {
1358 // Push the inner pipeline onto the stack to continue processing.
1359 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1360 continue;
1361 }
1362
1363 assert(Sep == ')' && "Bogus separator!");
1364 // When handling the close parenthesis, we greedily consume them to avoid
1365 // empty strings in the pipeline.
1366 do {
1367 // If we try to pop the outer pipeline we have unbalanced parentheses.
1368 if (PipelineStack.size() == 1)
1369 return std::nullopt;
1370
1371 PipelineStack.pop_back();
1372 } while (Text.consume_front(")"));
1373
1374 // Check if we've finished parsing.
1375 if (Text.empty())
1376 break;
1377
1378 // Otherwise, the end of an inner pipeline always has to be followed by
1379 // a comma, and then we can continue.
1380 if (!Text.consume_front(","))
1381 return std::nullopt;
1382 }
1383
1384 if (PipelineStack.size() > 1)
1385 // Unbalanced paretheses.
1386 return std::nullopt;
1387
1388 assert(PipelineStack.back() == &ResultPipeline &&
1389 "Wrong pipeline at the bottom of the stack!");
1390 return {std::move(ResultPipeline)};
1391}
1392
1393Error PassBuilder::parseModulePass(ModulePassManager &MPM,
1394 const PipelineElement &E) {
1395 auto &Name = E.Name;
1396 auto &InnerPipeline = E.InnerPipeline;
1397
1398 // First handle complex passes like the pass managers which carry pipelines.
1399 if (!InnerPipeline.empty()) {
1400 if (Name == "module") {
1401 ModulePassManager NestedMPM;
1402 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1403 return Err;
1404 MPM.addPass(std::move(NestedMPM));
1405 return Error::success();
1406 }
1407 if (Name == "coro-cond") {
1408 ModulePassManager NestedMPM;
1409 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1410 return Err;
1411 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
1412 return Error::success();
1413 }
1414 if (Name == "cgscc") {
1415 CGSCCPassManager CGPM;
1416 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
1417 return Err;
1419 return Error::success();
1420 }
1421 if (auto Params = parseFunctionPipelineName(Name)) {
1422 if (Params->second)
1423 return make_error<StringError>(
1424 "cannot have a no-rerun module to function adaptor",
1427 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
1428 return Err;
1429 MPM.addPass(
1430 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
1431 return Error::success();
1432 }
1433 if (auto Count = parseRepeatPassName(Name)) {
1434 ModulePassManager NestedMPM;
1435 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1436 return Err;
1437 MPM.addPass(createRepeatedPass(*Count, std::move(NestedMPM)));
1438 return Error::success();
1439 }
1440
1441 for (auto &C : ModulePipelineParsingCallbacks)
1442 if (C(Name, MPM, InnerPipeline))
1443 return Error::success();
1444
1445 // Normal passes can't have pipelines.
1446 return make_error<StringError>(
1447 formatv("invalid use of '{0}' pass as module pipeline", Name).str(),
1449 ;
1450 }
1451
1452 // Manually handle aliases for pre-configured pipeline fragments.
1455 if (!DefaultAliasRegex.match(Name, &Matches))
1456 return make_error<StringError>(
1457 formatv("unknown default pipeline alias '{0}'", Name).str(),
1459
1460 assert(Matches.size() == 3 && "Must capture two matched strings!");
1461
1462 OptimizationLevel L = *parseOptLevel(Matches[2]);
1463
1464 // This is consistent with old pass manager invoked via opt, but
1465 // inconsistent with clang. Clang doesn't enable loop vectorization
1466 // but does enable slp vectorization at Oz.
1467 PTO.LoopVectorization =
1468 L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1469 PTO.SLPVectorization =
1470 L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1471
1472 if (Matches[1] == "default") {
1474 } else if (Matches[1] == "thinlto-pre-link") {
1476 } else if (Matches[1] == "thinlto") {
1478 } else if (Matches[1] == "lto-pre-link") {
1479 if (PTO.UnifiedLTO)
1480 // When UnifiedLTO is enabled, use the ThinLTO pre-link pipeline. This
1481 // avoids compile-time performance regressions and keeps the pre-link
1482 // LTO pipeline "unified" for both LTO modes.
1484 else
1486 } else {
1487 assert(Matches[1] == "lto" && "Not one of the matched options!");
1488 MPM.addPass(buildLTODefaultPipeline(L, nullptr));
1489 }
1490 return Error::success();
1491 }
1492
1493 // Finally expand the basic registered passes from the .inc file.
1494#define MODULE_PASS(NAME, CREATE_PASS) \
1495 if (Name == NAME) { \
1496 MPM.addPass(CREATE_PASS); \
1497 return Error::success(); \
1498 }
1499#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1500 if (checkParametrizedPassName(Name, NAME)) { \
1501 auto Params = parsePassParameters(PARSER, Name, NAME); \
1502 if (!Params) \
1503 return Params.takeError(); \
1504 MPM.addPass(CREATE_PASS(Params.get())); \
1505 return Error::success(); \
1506 }
1507#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1508 if (Name == "require<" NAME ">") { \
1509 MPM.addPass( \
1510 RequireAnalysisPass< \
1511 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
1512 return Error::success(); \
1513 } \
1514 if (Name == "invalidate<" NAME ">") { \
1515 MPM.addPass(InvalidateAnalysisPass< \
1516 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1517 return Error::success(); \
1518 }
1519#define CGSCC_PASS(NAME, CREATE_PASS) \
1520 if (Name == NAME) { \
1521 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
1522 return Error::success(); \
1523 }
1524#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1525 if (checkParametrizedPassName(Name, NAME)) { \
1526 auto Params = parsePassParameters(PARSER, Name, NAME); \
1527 if (!Params) \
1528 return Params.takeError(); \
1529 MPM.addPass( \
1530 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
1531 return Error::success(); \
1532 }
1533#define FUNCTION_PASS(NAME, CREATE_PASS) \
1534 if (Name == NAME) { \
1535 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
1536 return Error::success(); \
1537 }
1538#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1539 if (checkParametrizedPassName(Name, NAME)) { \
1540 auto Params = parsePassParameters(PARSER, Name, NAME); \
1541 if (!Params) \
1542 return Params.takeError(); \
1543 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
1544 return Error::success(); \
1545 }
1546#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1547 if (Name == NAME) { \
1548 MPM.addPass(createModuleToFunctionPassAdaptor( \
1549 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1550 return Error::success(); \
1551 }
1552#define LOOP_PASS(NAME, CREATE_PASS) \
1553 if (Name == NAME) { \
1554 MPM.addPass(createModuleToFunctionPassAdaptor( \
1555 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1556 return Error::success(); \
1557 }
1558#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1559 if (checkParametrizedPassName(Name, NAME)) { \
1560 auto Params = parsePassParameters(PARSER, Name, NAME); \
1561 if (!Params) \
1562 return Params.takeError(); \
1563 MPM.addPass( \
1564 createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
1565 CREATE_PASS(Params.get()), false, false))); \
1566 return Error::success(); \
1567 }
1568#include "PassRegistry.def"
1569
1570 for (auto &C : ModulePipelineParsingCallbacks)
1571 if (C(Name, MPM, InnerPipeline))
1572 return Error::success();
1573 return make_error<StringError>(
1574 formatv("unknown module pass '{0}'", Name).str(),
1576}
1577
1578Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
1579 const PipelineElement &E) {
1580 auto &Name = E.Name;
1581 auto &InnerPipeline = E.InnerPipeline;
1582
1583 // First handle complex passes like the pass managers which carry pipelines.
1584 if (!InnerPipeline.empty()) {
1585 if (Name == "cgscc") {
1586 CGSCCPassManager NestedCGPM;
1587 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1588 return Err;
1589 // Add the nested pass manager with the appropriate adaptor.
1590 CGPM.addPass(std::move(NestedCGPM));
1591 return Error::success();
1592 }
1593 if (auto Params = parseFunctionPipelineName(Name)) {
1595 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
1596 return Err;
1597 // Add the nested pass manager with the appropriate adaptor.
1599 std::move(FPM), Params->first, Params->second));
1600 return Error::success();
1601 }
1602 if (auto Count = parseRepeatPassName(Name)) {
1603 CGSCCPassManager NestedCGPM;
1604 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1605 return Err;
1606 CGPM.addPass(createRepeatedPass(*Count, std::move(NestedCGPM)));
1607 return Error::success();
1608 }
1609 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
1610 CGSCCPassManager NestedCGPM;
1611 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1612 return Err;
1613 CGPM.addPass(
1614 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
1615 return Error::success();
1616 }
1617
1618 for (auto &C : CGSCCPipelineParsingCallbacks)
1619 if (C(Name, CGPM, InnerPipeline))
1620 return Error::success();
1621
1622 // Normal passes can't have pipelines.
1623 return make_error<StringError>(
1624 formatv("invalid use of '{0}' pass as cgscc pipeline", Name).str(),
1626 }
1627
1628// Now expand the basic registered passes from the .inc file.
1629#define CGSCC_PASS(NAME, CREATE_PASS) \
1630 if (Name == NAME) { \
1631 CGPM.addPass(CREATE_PASS); \
1632 return Error::success(); \
1633 }
1634#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1635 if (checkParametrizedPassName(Name, NAME)) { \
1636 auto Params = parsePassParameters(PARSER, Name, NAME); \
1637 if (!Params) \
1638 return Params.takeError(); \
1639 CGPM.addPass(CREATE_PASS(Params.get())); \
1640 return Error::success(); \
1641 }
1642#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1643 if (Name == "require<" NAME ">") { \
1644 CGPM.addPass(RequireAnalysisPass< \
1645 std::remove_reference_t<decltype(CREATE_PASS)>, \
1646 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
1647 CGSCCUpdateResult &>()); \
1648 return Error::success(); \
1649 } \
1650 if (Name == "invalidate<" NAME ">") { \
1651 CGPM.addPass(InvalidateAnalysisPass< \
1652 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1653 return Error::success(); \
1654 }
1655#define FUNCTION_PASS(NAME, CREATE_PASS) \
1656 if (Name == NAME) { \
1657 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
1658 return Error::success(); \
1659 }
1660#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1661 if (checkParametrizedPassName(Name, NAME)) { \
1662 auto Params = parsePassParameters(PARSER, Name, NAME); \
1663 if (!Params) \
1664 return Params.takeError(); \
1665 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
1666 return Error::success(); \
1667 }
1668#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1669 if (Name == NAME) { \
1670 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
1671 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1672 return Error::success(); \
1673 }
1674#define LOOP_PASS(NAME, CREATE_PASS) \
1675 if (Name == NAME) { \
1676 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
1677 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1678 return Error::success(); \
1679 }
1680#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1681 if (checkParametrizedPassName(Name, NAME)) { \
1682 auto Params = parsePassParameters(PARSER, Name, NAME); \
1683 if (!Params) \
1684 return Params.takeError(); \
1685 CGPM.addPass( \
1686 createCGSCCToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
1687 CREATE_PASS(Params.get()), false, false))); \
1688 return Error::success(); \
1689 }
1690#include "PassRegistry.def"
1691
1692 for (auto &C : CGSCCPipelineParsingCallbacks)
1693 if (C(Name, CGPM, InnerPipeline))
1694 return Error::success();
1695 return make_error<StringError>(
1696 formatv("unknown cgscc pass '{0}'", Name).str(),
1698}
1699
1700Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
1701 const PipelineElement &E) {
1702 auto &Name = E.Name;
1703 auto &InnerPipeline = E.InnerPipeline;
1704
1705 // First handle complex passes like the pass managers which carry pipelines.
1706 if (!InnerPipeline.empty()) {
1707 if (Name == "function") {
1708 FunctionPassManager NestedFPM;
1709 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
1710 return Err;
1711 // Add the nested pass manager with the appropriate adaptor.
1712 FPM.addPass(std::move(NestedFPM));
1713 return Error::success();
1714 }
1715 if (Name == "loop" || Name == "loop-mssa") {
1716 LoopPassManager LPM;
1717 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
1718 return Err;
1719 // Add the nested pass manager with the appropriate adaptor.
1720 bool UseMemorySSA = (Name == "loop-mssa");
1721 bool UseBFI = llvm::any_of(InnerPipeline, [](auto Pipeline) {
1722 return Pipeline.Name.contains("simple-loop-unswitch");
1723 });
1724 bool UseBPI = llvm::any_of(InnerPipeline, [](auto Pipeline) {
1725 return Pipeline.Name == "loop-predication";
1726 });
1727 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA,
1728 UseBFI, UseBPI));
1729 return Error::success();
1730 }
1731 if (auto Count = parseRepeatPassName(Name)) {
1732 FunctionPassManager NestedFPM;
1733 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
1734 return Err;
1735 FPM.addPass(createRepeatedPass(*Count, std::move(NestedFPM)));
1736 return Error::success();
1737 }
1738 if (Name == "machine-function") {
1740 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
1741 return Err;
1743 return Error::success();
1744 }
1745
1746 for (auto &C : FunctionPipelineParsingCallbacks)
1747 if (C(Name, FPM, InnerPipeline))
1748 return Error::success();
1749
1750 // Normal passes can't have pipelines.
1751 return make_error<StringError>(
1752 formatv("invalid use of '{0}' pass as function pipeline", Name).str(),
1754 }
1755
1756// Now expand the basic registered passes from the .inc file.
1757#define FUNCTION_PASS(NAME, CREATE_PASS) \
1758 if (Name == NAME) { \
1759 FPM.addPass(CREATE_PASS); \
1760 return Error::success(); \
1761 }
1762#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1763 if (checkParametrizedPassName(Name, NAME)) { \
1764 auto Params = parsePassParameters(PARSER, Name, NAME); \
1765 if (!Params) \
1766 return Params.takeError(); \
1767 FPM.addPass(CREATE_PASS(Params.get())); \
1768 return Error::success(); \
1769 }
1770#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1771 if (Name == "require<" NAME ">") { \
1772 FPM.addPass( \
1773 RequireAnalysisPass< \
1774 std::remove_reference_t<decltype(CREATE_PASS)>, Function>()); \
1775 return Error::success(); \
1776 } \
1777 if (Name == "invalidate<" NAME ">") { \
1778 FPM.addPass(InvalidateAnalysisPass< \
1779 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1780 return Error::success(); \
1781 }
1782// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
1783// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
1784// "guard-widening");
1785// The risk is that it may become obsolete if we're not careful.
1786#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1787 if (Name == NAME) { \
1788 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
1789 return Error::success(); \
1790 }
1791#define LOOP_PASS(NAME, CREATE_PASS) \
1792 if (Name == NAME) { \
1793 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
1794 return Error::success(); \
1795 }
1796#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1797 if (checkParametrizedPassName(Name, NAME)) { \
1798 auto Params = parsePassParameters(PARSER, Name, NAME); \
1799 if (!Params) \
1800 return Params.takeError(); \
1801 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), \
1802 false, false)); \
1803 return Error::success(); \
1804 }
1805#include "PassRegistry.def"
1806
1807 for (auto &C : FunctionPipelineParsingCallbacks)
1808 if (C(Name, FPM, InnerPipeline))
1809 return Error::success();
1810 return make_error<StringError>(
1811 formatv("unknown function pass '{0}'", Name).str(),
1813}
1814
1815Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
1816 const PipelineElement &E) {
1817 StringRef Name = E.Name;
1818 auto &InnerPipeline = E.InnerPipeline;
1819
1820 // First handle complex passes like the pass managers which carry pipelines.
1821 if (!InnerPipeline.empty()) {
1822 if (Name == "loop") {
1823 LoopPassManager NestedLPM;
1824 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
1825 return Err;
1826 // Add the nested pass manager with the appropriate adaptor.
1827 LPM.addPass(std::move(NestedLPM));
1828 return Error::success();
1829 }
1830 if (auto Count = parseRepeatPassName(Name)) {
1831 LoopPassManager NestedLPM;
1832 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
1833 return Err;
1834 LPM.addPass(createRepeatedPass(*Count, std::move(NestedLPM)));
1835 return Error::success();
1836 }
1837
1838 for (auto &C : LoopPipelineParsingCallbacks)
1839 if (C(Name, LPM, InnerPipeline))
1840 return Error::success();
1841
1842 // Normal passes can't have pipelines.
1843 return make_error<StringError>(
1844 formatv("invalid use of '{0}' pass as loop pipeline", Name).str(),
1846 }
1847
1848// Now expand the basic registered passes from the .inc file.
1849#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1850 if (Name == NAME) { \
1851 LPM.addPass(CREATE_PASS); \
1852 return Error::success(); \
1853 }
1854#define LOOP_PASS(NAME, CREATE_PASS) \
1855 if (Name == NAME) { \
1856 LPM.addPass(CREATE_PASS); \
1857 return Error::success(); \
1858 }
1859#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1860 if (checkParametrizedPassName(Name, NAME)) { \
1861 auto Params = parsePassParameters(PARSER, Name, NAME); \
1862 if (!Params) \
1863 return Params.takeError(); \
1864 LPM.addPass(CREATE_PASS(Params.get())); \
1865 return Error::success(); \
1866 }
1867#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1868 if (Name == "require<" NAME ">") { \
1869 LPM.addPass(RequireAnalysisPass< \
1870 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
1871 LoopAnalysisManager, LoopStandardAnalysisResults &, \
1872 LPMUpdater &>()); \
1873 return Error::success(); \
1874 } \
1875 if (Name == "invalidate<" NAME ">") { \
1876 LPM.addPass(InvalidateAnalysisPass< \
1877 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1878 return Error::success(); \
1879 }
1880#include "PassRegistry.def"
1881
1882 for (auto &C : LoopPipelineParsingCallbacks)
1883 if (C(Name, LPM, InnerPipeline))
1884 return Error::success();
1885 return make_error<StringError>(formatv("unknown loop pass '{0}'", Name).str(),
1887}
1888
1889Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
1890 const PipelineElement &E) {
1891 StringRef Name = E.Name;
1892 if (!E.InnerPipeline.empty())
1893 return make_error<StringError>("invalid pipeline",
1895
1896#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
1897 if (Name == NAME) { \
1898 MFPM.addPass(CREATE_PASS); \
1899 return Error::success(); \
1900 }
1901#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1902 if (Name == NAME) { \
1903 MFPM.addPass(CREATE_PASS); \
1904 return Error::success(); \
1905 }
1906#include "llvm/Passes/MachinePassRegistry.def"
1907
1908 for (auto &C : MachineFunctionPipelineParsingCallbacks)
1909 if (C(Name, MFPM, E.InnerPipeline))
1910 return Error::success();
1911 return make_error<StringError>(
1912 formatv("unknown machine pass '{0}'", Name).str(),
1914}
1915
1916bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
1917#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1918 if (Name == NAME) { \
1919 AA.registerModuleAnalysis< \
1920 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
1921 return true; \
1922 }
1923#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1924 if (Name == NAME) { \
1925 AA.registerFunctionAnalysis< \
1926 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
1927 return true; \
1928 }
1929#include "PassRegistry.def"
1930
1931 for (auto &C : AAParsingCallbacks)
1932 if (C(Name, AA))
1933 return true;
1934 return false;
1935}
1936
1937Error PassBuilder::parseMachinePassPipeline(
1939 for (const auto &Element : Pipeline) {
1940 if (auto Err = parseMachinePass(MFPM, Element))
1941 return Err;
1942 }
1943 return Error::success();
1944}
1945
1946Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
1947 ArrayRef<PipelineElement> Pipeline) {
1948 for (const auto &Element : Pipeline) {
1949 if (auto Err = parseLoopPass(LPM, Element))
1950 return Err;
1951 }
1952 return Error::success();
1953}
1954
1955Error PassBuilder::parseFunctionPassPipeline(
1957 for (const auto &Element : Pipeline) {
1958 if (auto Err = parseFunctionPass(FPM, Element))
1959 return Err;
1960 }
1961 return Error::success();
1962}
1963
1964Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
1965 ArrayRef<PipelineElement> Pipeline) {
1966 for (const auto &Element : Pipeline) {
1967 if (auto Err = parseCGSCCPass(CGPM, Element))
1968 return Err;
1969 }
1970 return Error::success();
1971}
1972
1985 if (MFAM) {
1987 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
1989 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
1990 MFAM->registerPass(
1992 MFAM->registerPass(
1994 }
1995}
1996
1997Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
1998 ArrayRef<PipelineElement> Pipeline) {
1999 for (const auto &Element : Pipeline) {
2000 if (auto Err = parseModulePass(MPM, Element))
2001 return Err;
2002 }
2003 return Error::success();
2004}
2005
2006// Primary pass pipeline description parsing routine for a \c ModulePassManager
2007// FIXME: Should this routine accept a TargetMachine or require the caller to
2008// pre-populate the analysis managers with target-specific stuff?
2010 StringRef PipelineText) {
2011 auto Pipeline = parsePipelineText(PipelineText);
2012 if (!Pipeline || Pipeline->empty())
2013 return make_error<StringError>(
2014 formatv("invalid pipeline '{0}'", PipelineText).str(),
2016
2017 // If the first name isn't at the module layer, wrap the pipeline up
2018 // automatically.
2019 StringRef FirstName = Pipeline->front().Name;
2020
2021 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2022 bool UseMemorySSA;
2023 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2024 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2025 } else if (isFunctionPassName(FirstName,
2026 FunctionPipelineParsingCallbacks)) {
2027 Pipeline = {{"function", std::move(*Pipeline)}};
2028 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2029 UseMemorySSA)) {
2030 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2031 std::move(*Pipeline)}}}};
2032 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2033 UseMemorySSA)) {
2034 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2035 std::move(*Pipeline)}}}};
2036 } else if (isMachineFunctionPassName(
2037 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2038 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2039 } else {
2040 for (auto &C : TopLevelPipelineParsingCallbacks)
2041 if (C(MPM, *Pipeline))
2042 return Error::success();
2043
2044 // Unknown pass or pipeline name!
2045 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2046 return make_error<StringError>(
2047 formatv("unknown {0} name '{1}'",
2048 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2049 .str(),
2051 }
2052 }
2053
2054 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2055 return Err;
2056 return Error::success();
2057}
2058
2059// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2061 StringRef PipelineText) {
2062 auto Pipeline = parsePipelineText(PipelineText);
2063 if (!Pipeline || Pipeline->empty())
2064 return make_error<StringError>(
2065 formatv("invalid pipeline '{0}'", PipelineText).str(),
2067
2068 StringRef FirstName = Pipeline->front().Name;
2069 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2070 return make_error<StringError>(
2071 formatv("unknown cgscc pass '{0}' in pipeline '{1}'", FirstName,
2072 PipelineText)
2073 .str(),
2075
2076 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2077 return Err;
2078 return Error::success();
2079}
2080
2081// Primary pass pipeline description parsing routine for a \c
2082// FunctionPassManager
2084 StringRef PipelineText) {
2085 auto Pipeline = parsePipelineText(PipelineText);
2086 if (!Pipeline || Pipeline->empty())
2087 return make_error<StringError>(
2088 formatv("invalid pipeline '{0}'", PipelineText).str(),
2090
2091 StringRef FirstName = Pipeline->front().Name;
2092 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2093 return make_error<StringError>(
2094 formatv("unknown function pass '{0}' in pipeline '{1}'", FirstName,
2095 PipelineText)
2096 .str(),
2098
2099 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2100 return Err;
2101 return Error::success();
2102}
2103
2104// Primary pass pipeline description parsing routine for a \c LoopPassManager
2106 StringRef PipelineText) {
2107 auto Pipeline = parsePipelineText(PipelineText);
2108 if (!Pipeline || Pipeline->empty())
2109 return make_error<StringError>(
2110 formatv("invalid pipeline '{0}'", PipelineText).str(),
2112
2113 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2114 return Err;
2115
2116 return Error::success();
2117}
2118
2120 StringRef PipelineText) {
2121 auto Pipeline = parsePipelineText(PipelineText);
2122 if (!Pipeline || Pipeline->empty())
2123 return make_error<StringError>(
2124 formatv("invalid machine pass pipeline '{0}'", PipelineText).str(),
2126
2127 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2128 return Err;
2129
2130 return Error::success();
2131}
2132
2134 // If the pipeline just consists of the word 'default' just replace the AA
2135 // manager with our default one.
2136 if (PipelineText == "default") {
2138 return Error::success();
2139 }
2140
2141 while (!PipelineText.empty()) {
2143 std::tie(Name, PipelineText) = PipelineText.split(',');
2144 if (!parseAAPassName(AA, Name))
2145 return make_error<StringError>(
2146 formatv("unknown alias analysis name '{0}'", Name).str(),
2148 }
2149
2150 return Error::success();
2151}
2152
2154 OS << " " << PassName << "\n";
2155}
2157 raw_ostream &OS) {
2158 OS << " " << PassName << "<" << Params << ">\n";
2159}
2160
2162 // TODO: print pass descriptions when they are available
2163
2164 OS << "Module passes:\n";
2165#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2166#include "PassRegistry.def"
2167
2168 OS << "Module passes with params:\n";
2169#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2170 printPassName(NAME, PARAMS, OS);
2171#include "PassRegistry.def"
2172
2173 OS << "Module analyses:\n";
2174#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2175#include "PassRegistry.def"
2176
2177 OS << "Module alias analyses:\n";
2178#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2179#include "PassRegistry.def"
2180
2181 OS << "CGSCC passes:\n";
2182#define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2183#include "PassRegistry.def"
2184
2185 OS << "CGSCC passes with params:\n";
2186#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2187 printPassName(NAME, PARAMS, OS);
2188#include "PassRegistry.def"
2189
2190 OS << "CGSCC analyses:\n";
2191#define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2192#include "PassRegistry.def"
2193
2194 OS << "Function passes:\n";
2195#define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2196#include "PassRegistry.def"
2197
2198 OS << "Function passes with params:\n";
2199#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2200 printPassName(NAME, PARAMS, OS);
2201#include "PassRegistry.def"
2202
2203 OS << "Function analyses:\n";
2204#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2205#include "PassRegistry.def"
2206
2207 OS << "Function alias analyses:\n";
2208#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2209#include "PassRegistry.def"
2210
2211 OS << "LoopNest passes:\n";
2212#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2213#include "PassRegistry.def"
2214
2215 OS << "Loop passes:\n";
2216#define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2217#include "PassRegistry.def"
2218
2219 OS << "Loop passes with params:\n";
2220#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2221 printPassName(NAME, PARAMS, OS);
2222#include "PassRegistry.def"
2223
2224 OS << "Loop analyses:\n";
2225#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2226#include "PassRegistry.def"
2227
2228 OS << "Machine module passes (WIP):\n";
2229#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2230#include "llvm/Passes/MachinePassRegistry.def"
2231
2232 OS << "Machine function passes (WIP):\n";
2233#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2234#include "llvm/Passes/MachinePassRegistry.def"
2235
2236 OS << "Machine function analyses (WIP):\n";
2237#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2238#include "llvm/Passes/MachinePassRegistry.def"
2239}
2240
2242 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
2243 &C) {
2244 TopLevelPipelineParsingCallbacks.push_back(C);
2245}
unsigned const MachineRegisterInfo * MRI
AggressiveInstCombiner - Combine expression patterns to form expressions with fewer,...
This file implements a simple N^2 alias analysis accuracy evaluator.
Provides passes to inlining "always_inline" functions.
This is the interface for LLVM's primary stateless and local alias analysis.
This file provides the interface for LLVM's Call Graph Profile pass.
This header provides classes for managing passes over SCCs of the call graph.
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
Defines an IR pass for CodeGen Prepare.
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
std::string Name
This file provides the interface for a simple, fast CSE pass.
This file provides a pass which clones the current module and runs the provided pass pipeline on the ...
Super simple passes to force specific function attrs from the commandline into the IR for debugging p...
Provides passes for computing function attributes based on interprocedural analyses.
This file provides the interface for the GCOV style profiler pass.
This file provides the interface for LLVM's Global Value Numbering pass which eliminates fully redund...
This is the interface for a simple mod/ref and alias analysis over globals.
Defines an IR pass for the creation of hardware loops.
AcceleratorCodeSelection - Identify all functions reachable from a kernel, removing those that are un...
This file defines passes to print out IR in various granularities.
Interfaces for passes which infer implicit function attributes from the name and signature of functio...
This file provides the primary interface to the instcombine pass.
Defines passes for running instruction simplification across chunks of IR.
This file provides the interface for LLVM's PGO Instrumentation lowering pass.
This file contains the declaration of the InterleavedAccessPass class, its corresponding pass name is...
See the comments on JumpThreadingPass.
Implements a lazy call graph analysis and related passes for the new pass manager.
This file defines the interface for the loop cache analysis.
This file provides the interface for LLVM's Loop Data Prefetching Pass.
This file implements the Loop Fusion pass.
This header defines the LoopLoadEliminationPass object.
This file defines the interface for the loop nest analysis.
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
This file provides the interface for the pass responsible for removing expensive ubsan checks.
The header file for the LowerConstantIntrinsics pass as used by the new pass manager.
The header file for the LowerExpectIntrinsic pass as used by the new pass manager.
#define F(x, y, z)
Definition: MD5.cpp:55
UseBFI
Definition: MachineLICM.cpp:88
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
This pass performs merges of loads and stores on both sides of a.
This is the interface to build a ModuleSummaryIndex for a module.
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
This file provides the interface for LLVM's Global Value Numbering pass.
This file declares a simple ARC-aware AliasAnalysis using special knowledge of Objective C to enhance...
This header enumerates the LLVM-provided high-level optimization levels.
This file provides the interface for IR based instrumentation passes ( (profile-gen,...
CGSCCAnalysisManager CGAM
ModulePassManager MPM
LoopAnalysisManager LAM
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const char LLVMTargetMachineRef TM
PassInstrumentationCallbacks PIC
static bool isModulePassName(StringRef Name, CallbacksT &Callbacks)
static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks)
Tests whether registered callbacks will accept a given pass name.
static std::optional< int > parseDevirtPassName(StringRef Name)
static std::optional< int > parseRepeatPassName(StringRef Name)
static bool startsWithDefaultPipelineAliasPrefix(StringRef Name)
Tests whether a pass name starts with a valid prefix for a default pipeline alias.
static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static std::optional< OptimizationLevel > parseOptLevel(StringRef S)
static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static std::optional< std::pair< bool, bool > > parseFunctionPipelineName(StringRef Name)
static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks)
static void printPassName(StringRef PassName, raw_ostream &OS)
static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static const Regex DefaultAliasRegex("^(default|thinlto-pre-link|thinlto|lto-pre-link|lto)<(O[0123sz])>$")
This header defines various interfaces for pass management in LLVM.
This file implements the PredicateInfo analysis, which creates an Extended SSA form for operations us...
This file implements relative lookup table converter that converts lookup tables to relative lookup t...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file provides the interface for LLVM's Scalar Replacement of Aggregates pass.
raw_pwrite_stream & OS
This file provides the interface for the pseudo probe implementation for AutoFDO.
This file provides the interface for the sampled PGO loader pass.
This is the interface for a SCEV-based alias analysis.
This pass converts vector operations into scalar operations (or, optionally, operations on smaller ve...
This is the interface for a metadata-based scoped no-alias analysis.
This file contains the declaration of the SelectOptimizePass class, its corresponding pass name is se...
This file provides the interface for the pass responsible for both simplifying and canonicalizing the...
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
This is the interface for a metadata-based TBAA.
Defines an IR pass for type promotion.
LLVM IR instance of the generic uniformity analysis.
static const char PassName[]
Value * RHS
A manager for alias analyses.
Class for arbitrary precision integers.
Definition: APInt.h:76
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1491
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1513
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:321
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
Definition: PassManager.h:535
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.h:221
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:334
Tagged union holding either a T or a Error.
Definition: Error.h:474
static GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition: Globals.cpp:525
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:631
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:42
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineFunctionProperties & getProperties() const
Get the function properties.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
static const OptimizationLevel O3
Optimize for fast execution as much as possible.
static const OptimizationLevel Oz
A very specialized mode that will optimize for code size at any and all costs.
static const OptimizationLevel O0
Disable as many optimizations as possible.
static const OptimizationLevel Os
Similar to O2 but tries to optimize for small code size instead of fast execution without triggering ...
static const OptimizationLevel O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
static const OptimizationLevel O1
Optimize quickly without destroying debuggability.
void printPassNames(raw_ostream &OS)
Print pass names.
static bool checkParametrizedPassName(StringRef Name, StringRef PassName)
Definition: PassBuilder.h:629
AAManager buildDefaultAAPipeline()
Build the default AAManager with the default alias analysis pipeline registered.
Error parseAAPipeline(AAManager &AA, StringRef PipelineText)
Parse a textual alias analysis pipeline into the provided AA manager.
ModulePassManager buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level)
Build a pre-link, ThinLTO-targeting default optimization pipeline to a pass manager.
PassBuilder(TargetMachine *TM=nullptr, PipelineTuningOptions PTO=PipelineTuningOptions(), std::optional< PGOOptions > PGOOpt=std::nullopt, PassInstrumentationCallbacks *PIC=nullptr)
void registerLoopAnalyses(LoopAnalysisManager &LAM)
Registers all available loop analysis passes.
void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM, MachineFunctionAnalysisManager *MFAM=nullptr)
Cross register the analysis managers through their proxies.
ModulePassManager buildPerModuleDefaultPipeline(OptimizationLevel Level, bool LTOPreLink=false)
Build a per-module default optimization pipeline.
Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText)
Parse a textual pass pipeline description into a ModulePassManager.
ModulePassManager buildLTODefaultPipeline(OptimizationLevel Level, ModuleSummaryIndex *ExportSummary)
Build an LTO default optimization pipeline to a pass manager.
ModulePassManager buildThinLTODefaultPipeline(OptimizationLevel Level, const ModuleSummaryIndex *ImportSummary)
Build a ThinLTO default optimization pipeline to a pass manager.
void registerModuleAnalyses(ModuleAnalysisManager &MAM)
Registers all available module analysis passes.
void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM)
Registers all available CGSCC analysis passes.
static Expected< bool > parseSinglePassOption(StringRef Params, StringRef OptionName, StringRef PassName)
Handle passes only accept one bool-valued parameter.
void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM)
Registers all available machine function analysis passes.
void registerParseTopLevelPipelineCallback(const std::function< bool(ModulePassManager &, ArrayRef< PipelineElement >)> &C)
Register a callback for a top-level pipeline entry.
ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level)
Build a pre-link, LTO-targeting default optimization pipeline to a pass manager.
void registerFunctionAnalyses(FunctionAnalysisManager &FAM)
Registers all available function analysis passes.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t< is_detected< HasRunOnLoopT, PassT >::value > addPass(PassT &&Pass)
LLVM_ATTRIBUTE_MINSIZE void addPass(PassT &&Pass)
Definition: PassManager.h:249
Tunable parameters for passes in the default pipelines.
Definition: PassBuilder.h:42
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition: PassBuilder.h:57
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition: PassBuilder.h:53
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Definition: DerivedTypes.h:662
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:109
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:115
bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr, std::string *Error=nullptr) const
matches - Match the regex against a given String.
Definition: Regex.cpp:83
size_t size() const
Definition: SmallVector.h:91
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:692
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:462
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:222
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
char front() const
front - Get the first character in the string.
Definition: StringRef.h:140
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition: StringRef.h:627
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
static bool hasLimitedCodeGenPipeline()
Returns true if one of the -start-after, -start-before, -stop-after or -stop-before options is set.
This function has undefined behavior.
self_iterator getIterator()
Definition: ilist_node.h:109
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
Interfaces for registering analysis passes, producing common pass manager configurations,...
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::vector< std::string > printAfterPasses()
ModuleToFunctionPassAdaptor createModuleToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
Definition: PassManager.h:916
RepeatedPass< PassT > createRepeatedPass(int Count, PassT &&P)
Definition: PassManager.h:1050
DevirtSCCRepeatedPass createDevirtSCCRepeatedPass(CGSCCPassT &&Pass, int MaxIterations)
A function to deduce a function pass type and wrap it in the templated adaptor.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:90
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
Definition: PassManager.h:866
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Module > MachineFunctionAnalysisManagerModuleProxy
OuterAnalysisManagerProxy< ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph & > ModuleAnalysisManagerCGSCCProxy
A proxy from a ModuleAnalysisManager to an SCC.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1729
std::vector< std::string > printBeforePasses()
ModuleToPostOrderCGSCCPassAdaptor createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT &&Pass)
A function to deduce a function pass type and wrap it in the templated adaptor.
CGSCCToFunctionPassAdaptor createCGSCCToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false, bool NoRerun=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
Definition: PassManager.h:712
FunctionToMachineFunctionPassAdaptor createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass)
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Function > MachineFunctionAnalysisManagerFunctionProxy
cl::opt< bool > PrintPipelinePasses("print-pipeline-passes", cl::desc("Print a '-passes' compatible string describing the pipeline " "(best-effort only)."))
OuterAnalysisManagerProxy< FunctionAnalysisManager, Loop, LoopStandardAnalysisResults & > FunctionAnalysisManagerLoopProxy
A proxy from a FunctionAnalysisManager to a Loop.
OuterAnalysisManagerProxy< CGSCCAnalysisManager, Function > CGSCCAnalysisManagerFunctionProxy
A proxy from a CGSCCAnalysisManager to a Function.
std::enable_if_t< is_detected< HasRunOnLoopT, LoopPassT >::value, FunctionToLoopPassAdaptor > createFunctionToLoopPassAdaptor(LoopPassT &&Pass, bool UseMemorySSA=false, bool UseBlockFrequencyInfo=false, bool UseBranchProbabilityInfo=false)
A function to deduce a loop pass type and wrap it in the templated adaptor.
bool isFilterPassesEmpty()
@ Enable
Enable colors.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: Analysis.h:26
A set of parameters to control various transforms performed by GVN pass.
Definition: GVN.h:74
HardwareLoopOptions & setForceNested(bool Force)
Definition: HardwareLoops.h:45
HardwareLoopOptions & setDecrement(unsigned Count)
Definition: HardwareLoops.h:29
HardwareLoopOptions & setForceGuard(bool Force)
Definition: HardwareLoops.h:49
HardwareLoopOptions & setForce(bool Force)
Definition: HardwareLoops.h:37
HardwareLoopOptions & setCounterBitwidth(unsigned Width)
Definition: HardwareLoops.h:33
HardwareLoopOptions & setForcePhi(bool Force)
Definition: HardwareLoops.h:41
A set of parameters to control various transforms performed by IPSCCP pass.
Definition: SCCP.h:35
A set of parameters used to control various transforms performed by the LoopUnroll pass.
LoopUnrollOptions & setPeeling(bool Peeling)
Enables or disables loop peeling.
LoopUnrollOptions & setOptLevel(int O)
LoopUnrollOptions & setPartial(bool Partial)
Enables or disables partial unrolling.
LoopUnrollOptions & setFullUnrollMaxCount(unsigned O)
LoopUnrollOptions & setUpperBound(bool UpperBound)
Enables or disables the use of trip count upper bound in loop unrolling.
LoopUnrollOptions & setRuntime(bool Runtime)
Enables or disables unrolling of loops with runtime trip count.
LoopUnrollOptions & setProfileBasedPeeling(int O)
LoopVectorizeOptions & setVectorizeOnlyWhenForced(bool Value)
LoopVectorizeOptions & setInterleaveOnlyWhenForced(bool Value)
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:74
static StringRef name()
Gets the name of the pass we are mixed into.
Definition: PassManager.h:76