LLVM 20.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"
122#include "llvm/IR/DebugInfo.h"
123#include "llvm/IR/Dominators.h"
124#include "llvm/IR/PassManager.h"
125#include "llvm/IR/PrintPasses.h"
127#include "llvm/IR/Verifier.h"
131#include "llvm/Support/Debug.h"
134#include "llvm/Support/Regex.h"
319#include <optional>
320
321using namespace llvm;
322
324 "^(default|thinlto-pre-link|thinlto|lto-pre-link|lto)<(O[0123sz])>$");
325
326namespace llvm {
328 "print-pipeline-passes",
329 cl::desc("Print a '-passes' compatible string describing the pipeline "
330 "(best-effort only)."));
331} // namespace llvm
332
333AnalysisKey NoOpModuleAnalysis::Key;
334AnalysisKey NoOpCGSCCAnalysis::Key;
335AnalysisKey NoOpFunctionAnalysis::Key;
336AnalysisKey NoOpLoopAnalysis::Key;
337
338namespace {
339
340// Passes for testing crashes.
341// DO NOT USE THIS EXCEPT FOR TESTING!
342class TriggerCrashModulePass : public PassInfoMixin<TriggerCrashModulePass> {
343public:
345 abort();
346 return PreservedAnalyses::all();
347 }
348 static StringRef name() { return "TriggerCrashModulePass"; }
349};
350
351class TriggerCrashFunctionPass
352 : public PassInfoMixin<TriggerCrashFunctionPass> {
353public:
355 abort();
356 return PreservedAnalyses::all();
357 }
358 static StringRef name() { return "TriggerCrashFunctionPass"; }
359};
360
361// A pass for testing message reporting of -verify-each failures.
362// DO NOT USE THIS EXCEPT FOR TESTING!
363class TriggerVerifierErrorPass
364 : public PassInfoMixin<TriggerVerifierErrorPass> {
365public:
367 // Intentionally break the Module by creating an alias without setting the
368 // aliasee.
369 auto *PtrTy = llvm::PointerType::getUnqual(M.getContext());
370 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
371 GlobalValue::LinkageTypes::InternalLinkage,
372 "__bad_alias", nullptr, &M);
374 }
375
377 // Intentionally break the Function by inserting a terminator
378 // instruction in the middle of a basic block.
379 BasicBlock &BB = F.getEntryBlock();
380 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
382 }
383
385 // Intentionally create a virtual register and set NoVRegs property.
386 auto &MRI = MF.getRegInfo();
387 MRI.createGenericVirtualRegister(LLT::scalar(8));
388 MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
389 return PreservedAnalyses::all();
390 }
391
392 static StringRef name() { return "TriggerVerifierErrorPass"; }
393};
394
395// A pass requires all MachineFunctionProperties.
396// DO NOT USE THIS EXCEPT FOR TESTING!
397class RequireAllMachineFunctionPropertiesPass
398 : public PassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
399public:
401 MFPropsModifier _(*this, MF);
403 }
404
405 static MachineFunctionProperties getRequiredProperties() {
407 MFProps.set(MachineFunctionProperties::Property::FailedISel);
408 MFProps.set(MachineFunctionProperties::Property::FailsVerification);
409 MFProps.set(MachineFunctionProperties::Property::IsSSA);
410 MFProps.set(MachineFunctionProperties::Property::Legalized);
411 MFProps.set(MachineFunctionProperties::Property::NoPHIs);
412 MFProps.set(MachineFunctionProperties::Property::NoVRegs);
413 MFProps.set(MachineFunctionProperties::Property::RegBankSelected);
414 MFProps.set(MachineFunctionProperties::Property::Selected);
415 MFProps.set(MachineFunctionProperties::Property::TiedOpsRewritten);
416 MFProps.set(MachineFunctionProperties::Property::TracksDebugUserValues);
417 MFProps.set(MachineFunctionProperties::Property::TracksLiveness);
418 return MFProps;
419 }
420 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
421};
422
423} // namespace
424
426 std::optional<PGOOptions> PGOOpt,
428 : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) {
429 if (TM)
430 TM->registerPassBuilderCallbacks(*this);
431 if (PIC) {
433 // MSVC requires this to be captured if it's used inside decltype.
434 // Other compilers consider it an unused lambda capture.
435 (void)this;
436#define MODULE_PASS(NAME, CREATE_PASS) \
437 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
438#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
439 PIC->addClassToPassName(CLASS, NAME);
440#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
441 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
442#define FUNCTION_PASS(NAME, CREATE_PASS) \
443 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
444#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
445 PIC->addClassToPassName(CLASS, NAME);
446#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
447 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
448#define LOOPNEST_PASS(NAME, CREATE_PASS) \
449 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
450#define LOOP_PASS(NAME, CREATE_PASS) \
451 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
452#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
453 PIC->addClassToPassName(CLASS, NAME);
454#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
455 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
456#define CGSCC_PASS(NAME, CREATE_PASS) \
457 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
458#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
459 PIC->addClassToPassName(CLASS, NAME);
460#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
461 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
462#include "PassRegistry.def"
463
464#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
465 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
466#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
467 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
468#include "llvm/Passes/MachinePassRegistry.def"
469 });
470 }
471}
472
474#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
475 MAM.registerPass([&] { return CREATE_PASS; });
476#include "PassRegistry.def"
477
478 for (auto &C : ModuleAnalysisRegistrationCallbacks)
479 C(MAM);
480}
481
483#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
484 CGAM.registerPass([&] { return CREATE_PASS; });
485#include "PassRegistry.def"
486
487 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
488 C(CGAM);
489}
490
492 // We almost always want the default alias analysis pipeline.
493 // If a user wants a different one, they can register their own before calling
494 // registerFunctionAnalyses().
495 FAM.registerPass([&] { return buildDefaultAAPipeline(); });
496
497#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
498 FAM.registerPass([&] { return CREATE_PASS; });
499#include "PassRegistry.def"
500
501 for (auto &C : FunctionAnalysisRegistrationCallbacks)
502 C(FAM);
503}
504
507
508#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
509 MFAM.registerPass([&] { return CREATE_PASS; });
510#include "llvm/Passes/MachinePassRegistry.def"
511
512 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
513 C(MFAM);
514}
515
517#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
518 LAM.registerPass([&] { return CREATE_PASS; });
519#include "PassRegistry.def"
520
521 for (auto &C : LoopAnalysisRegistrationCallbacks)
522 C(LAM);
523}
524
525static std::optional<std::pair<bool, bool>>
527 std::pair<bool, bool> Params;
528 if (!Name.consume_front("function"))
529 return std::nullopt;
530 if (Name.empty())
531 return Params;
532 if (!Name.consume_front("<") || !Name.consume_back(">"))
533 return std::nullopt;
534 while (!Name.empty()) {
535 auto [Front, Back] = Name.split(';');
536 Name = Back;
537 if (Front == "eager-inv")
538 Params.first = true;
539 else if (Front == "no-rerun")
540 Params.second = true;
541 else
542 return std::nullopt;
543 }
544 return Params;
545}
546
547static std::optional<int> parseDevirtPassName(StringRef Name) {
548 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
549 return std::nullopt;
550 int Count;
551 if (Name.getAsInteger(0, Count) || Count < 0)
552 return std::nullopt;
553 return Count;
554}
555
556static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
558 .Case("O0", OptimizationLevel::O0)
564 .Default(std::nullopt);
565}
566
568 StringRef OptionName,
570 bool Result = false;
571 while (!Params.empty()) {
572 StringRef ParamName;
573 std::tie(ParamName, Params) = Params.split(';');
574
575 if (ParamName == OptionName) {
576 Result = true;
577 } else {
578 return make_error<StringError>(
579 formatv("invalid {1} pass parameter '{0}' ", ParamName, PassName)
580 .str(),
582 }
583 }
584 return Result;
585}
586
587namespace {
588
589/// Parser of parameters for HardwareLoops pass.
590Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
591 HardwareLoopOptions HardwareLoopOpts;
592
593 while (!Params.empty()) {
594 StringRef ParamName;
595 std::tie(ParamName, Params) = Params.split(';');
596 if (ParamName.consume_front("hardware-loop-decrement=")) {
597 int Count;
598 if (ParamName.getAsInteger(0, Count))
599 return make_error<StringError>(
600 formatv("invalid HardwareLoopPass parameter '{0}' ", ParamName).str(),
602 HardwareLoopOpts.setDecrement(Count);
603 continue;
604 }
605 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
606 int Count;
607 if (ParamName.getAsInteger(0, Count))
608 return make_error<StringError>(
609 formatv("invalid HardwareLoopPass parameter '{0}' ", ParamName).str(),
611 HardwareLoopOpts.setCounterBitwidth(Count);
612 continue;
613 }
614 if (ParamName == "force-hardware-loops") {
615 HardwareLoopOpts.setForce(true);
616 } else if (ParamName == "force-hardware-loop-phi") {
617 HardwareLoopOpts.setForcePhi(true);
618 } else if (ParamName == "force-nested-hardware-loop") {
619 HardwareLoopOpts.setForceNested(true);
620 } else if (ParamName == "force-hardware-loop-guard") {
621 HardwareLoopOpts.setForceGuard(true);
622 } else {
623 return make_error<StringError>(
624 formatv("invalid HardwarePass parameter '{0}' ", ParamName).str(),
626 }
627 }
628 return HardwareLoopOpts;
629}
630
631/// Parser of parameters for LoopUnroll pass.
632Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
633 LoopUnrollOptions UnrollOpts;
634 while (!Params.empty()) {
635 StringRef ParamName;
636 std::tie(ParamName, Params) = Params.split(';');
637 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
638 // Don't accept -Os/-Oz.
639 if (OptLevel && !OptLevel->isOptimizingForSize()) {
640 UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel());
641 continue;
642 }
643 if (ParamName.consume_front("full-unroll-max=")) {
644 int Count;
645 if (ParamName.getAsInteger(0, Count))
646 return make_error<StringError>(
647 formatv("invalid LoopUnrollPass parameter '{0}' ", ParamName).str(),
649 UnrollOpts.setFullUnrollMaxCount(Count);
650 continue;
651 }
652
653 bool Enable = !ParamName.consume_front("no-");
654 if (ParamName == "partial") {
655 UnrollOpts.setPartial(Enable);
656 } else if (ParamName == "peeling") {
657 UnrollOpts.setPeeling(Enable);
658 } else if (ParamName == "profile-peeling") {
659 UnrollOpts.setProfileBasedPeeling(Enable);
660 } else if (ParamName == "runtime") {
661 UnrollOpts.setRuntime(Enable);
662 } else if (ParamName == "upperbound") {
663 UnrollOpts.setUpperBound(Enable);
664 } else {
665 return make_error<StringError>(
666 formatv("invalid LoopUnrollPass parameter '{0}' ", ParamName).str(),
668 }
669 }
670 return UnrollOpts;
671}
672
673Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
675 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
676}
677
678Expected<bool> parseCGProfilePassOptions(StringRef Params) {
679 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
680 "CGProfile");
681}
682
683Expected<bool> parseInlinerPassOptions(StringRef Params) {
684 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
685 "InlinerPass");
686}
687
688Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
689 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
690 "CoroSplitPass");
691}
692
693Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
695 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
696}
697
698Expected<CFGuardPass::Mechanism> parseCFGuardPassOptions(StringRef Params) {
699 if (Params.empty())
701
702 auto [Param, RHS] = Params.split(';');
703 if (!RHS.empty())
704 return make_error<StringError>(
705 formatv("too many CFGuardPass parameters '{0}' ", Params).str(),
707
708 if (Param == "check")
710 if (Param == "dispatch")
712
713 return make_error<StringError>(
714 formatv("invalid CFGuardPass mechanism: '{0}' ", Param).str(),
716}
717
718Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
719 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
720}
721
722Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
723 return PassBuilder::parseSinglePassOption(Params, "post-inline",
724 "EntryExitInstrumenter");
725}
726
727Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
728 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor");
729}
730
731Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
732 return PassBuilder::parseSinglePassOption(Params, "minimal",
733 "LowerMatrixIntrinsics");
734}
735
736Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
738 while (!Params.empty()) {
739 StringRef ParamName;
740 std::tie(ParamName, Params) = Params.split(';');
741
742 if (ParamName == "kernel") {
743 Result.CompileKernel = true;
744 } else {
745 return make_error<StringError>(
746 formatv("invalid AddressSanitizer pass parameter '{0}' ", ParamName)
747 .str(),
749 }
750 }
751 return Result;
752}
753
754Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
756 while (!Params.empty()) {
757 StringRef ParamName;
758 std::tie(ParamName, Params) = Params.split(';');
759
760 if (ParamName == "recover") {
761 Result.Recover = true;
762 } else if (ParamName == "kernel") {
763 Result.CompileKernel = true;
764 } else {
765 return make_error<StringError>(
766 formatv("invalid HWAddressSanitizer pass parameter '{0}' ", ParamName)
767 .str(),
769 }
770 }
771 return Result;
772}
773
774Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
776 while (!Params.empty()) {
777 StringRef ParamName;
778 std::tie(ParamName, Params) = Params.split(';');
779
780 if (ParamName == "thinlto") {
781 Result.IsThinLTO = true;
782 } else if (ParamName == "emit-summary") {
783 Result.EmitLTOSummary = true;
784 } else {
785 return make_error<StringError>(
786 formatv("invalid EmbedBitcode pass parameter '{0}' ", ParamName)
787 .str(),
789 }
790 }
791 return Result;
792}
793
794Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
796 while (!Params.empty()) {
797 StringRef ParamName;
798 std::tie(ParamName, Params) = Params.split(';');
799
800 if (ParamName == "recover") {
801 Result.Recover = true;
802 } else if (ParamName == "kernel") {
803 Result.Kernel = true;
804 } else if (ParamName.consume_front("track-origins=")) {
805 if (ParamName.getAsInteger(0, Result.TrackOrigins))
806 return make_error<StringError>(
807 formatv("invalid argument to MemorySanitizer pass track-origins "
808 "parameter: '{0}' ",
809 ParamName)
810 .str(),
812 } else if (ParamName == "eager-checks") {
813 Result.EagerChecks = true;
814 } else {
815 return make_error<StringError>(
816 formatv("invalid MemorySanitizer pass parameter '{0}' ", ParamName)
817 .str(),
819 }
820 }
821 return Result;
822}
823
824/// Parser of parameters for SimplifyCFG pass.
825Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
827 while (!Params.empty()) {
828 StringRef ParamName;
829 std::tie(ParamName, Params) = Params.split(';');
830
831 bool Enable = !ParamName.consume_front("no-");
832 if (ParamName == "speculate-blocks") {
833 Result.speculateBlocks(Enable);
834 } else if (ParamName == "simplify-cond-branch") {
835 Result.setSimplifyCondBranch(Enable);
836 } else if (ParamName == "forward-switch-cond") {
837 Result.forwardSwitchCondToPhi(Enable);
838 } else if (ParamName == "switch-range-to-icmp") {
839 Result.convertSwitchRangeToICmp(Enable);
840 } else if (ParamName == "switch-to-lookup") {
841 Result.convertSwitchToLookupTable(Enable);
842 } else if (ParamName == "keep-loops") {
843 Result.needCanonicalLoops(Enable);
844 } else if (ParamName == "hoist-common-insts") {
845 Result.hoistCommonInsts(Enable);
846 } else if (ParamName == "sink-common-insts") {
847 Result.sinkCommonInsts(Enable);
848 } else if (ParamName == "speculate-unpredictables") {
849 Result.speculateUnpredictables(Enable);
850 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
851 APInt BonusInstThreshold;
852 if (ParamName.getAsInteger(0, BonusInstThreshold))
853 return make_error<StringError>(
854 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
855 "parameter: '{0}' ",
856 ParamName).str(),
858 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
859 } else {
860 return make_error<StringError>(
861 formatv("invalid SimplifyCFG pass parameter '{0}' ", ParamName).str(),
863 }
864 }
865 return Result;
866}
867
868Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
870 // When specifying "instcombine" in -passes enable fix-point verification by
871 // default, as this is what most tests should use.
872 Result.setVerifyFixpoint(true);
873 while (!Params.empty()) {
874 StringRef ParamName;
875 std::tie(ParamName, Params) = Params.split(';');
876
877 bool Enable = !ParamName.consume_front("no-");
878 if (ParamName == "use-loop-info") {
879 Result.setUseLoopInfo(Enable);
880 } else if (ParamName == "verify-fixpoint") {
881 Result.setVerifyFixpoint(Enable);
882 } else if (Enable && ParamName.consume_front("max-iterations=")) {
883 APInt MaxIterations;
884 if (ParamName.getAsInteger(0, MaxIterations))
885 return make_error<StringError>(
886 formatv("invalid argument to InstCombine pass max-iterations "
887 "parameter: '{0}' ",
888 ParamName).str(),
890 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
891 } else {
892 return make_error<StringError>(
893 formatv("invalid InstCombine pass parameter '{0}' ", ParamName).str(),
895 }
896 }
897 return Result;
898}
899
900/// Parser of parameters for LoopVectorize pass.
901Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
903 while (!Params.empty()) {
904 StringRef ParamName;
905 std::tie(ParamName, Params) = Params.split(';');
906
907 bool Enable = !ParamName.consume_front("no-");
908 if (ParamName == "interleave-forced-only") {
910 } else if (ParamName == "vectorize-forced-only") {
912 } else {
913 return make_error<StringError>(
914 formatv("invalid LoopVectorize parameter '{0}' ", ParamName).str(),
916 }
917 }
918 return Opts;
919}
920
921Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
922 std::pair<bool, bool> Result = {false, true};
923 while (!Params.empty()) {
924 StringRef ParamName;
925 std::tie(ParamName, Params) = Params.split(';');
926
927 bool Enable = !ParamName.consume_front("no-");
928 if (ParamName == "nontrivial") {
929 Result.first = Enable;
930 } else if (ParamName == "trivial") {
931 Result.second = Enable;
932 } else {
933 return make_error<StringError>(
934 formatv("invalid LoopUnswitch pass parameter '{0}' ", ParamName)
935 .str(),
937 }
938 }
939 return Result;
940}
941
942Expected<LICMOptions> parseLICMOptions(StringRef Params) {
944 while (!Params.empty()) {
945 StringRef ParamName;
946 std::tie(ParamName, Params) = Params.split(';');
947
948 bool Enable = !ParamName.consume_front("no-");
949 if (ParamName == "allowspeculation") {
950 Result.AllowSpeculation = Enable;
951 } else {
952 return make_error<StringError>(
953 formatv("invalid LICM pass parameter '{0}' ", ParamName).str(),
955 }
956 }
957 return Result;
958}
959
960Expected<std::pair<bool, bool>> parseLoopRotateOptions(StringRef Params) {
961 std::pair<bool, bool> Result = {true, false};
962 while (!Params.empty()) {
963 StringRef ParamName;
964 std::tie(ParamName, Params) = Params.split(';');
965
966 bool Enable = !ParamName.consume_front("no-");
967 if (ParamName == "header-duplication") {
968 Result.first = Enable;
969 } else if (ParamName == "prepare-for-lto") {
970 Result.second = Enable;
971 } else {
972 return make_error<StringError>(
973 formatv("invalid LoopRotate pass parameter '{0}' ", ParamName).str(),
975 }
976 }
977 return Result;
978}
979
980Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
981 bool Result = false;
982 while (!Params.empty()) {
983 StringRef ParamName;
984 std::tie(ParamName, Params) = Params.split(';');
985
986 bool Enable = !ParamName.consume_front("no-");
987 if (ParamName == "split-footer-bb") {
988 Result = Enable;
989 } else {
990 return make_error<StringError>(
991 formatv("invalid MergedLoadStoreMotion pass parameter '{0}' ",
992 ParamName)
993 .str(),
995 }
996 }
997 return Result;
998}
999
1000Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1002 while (!Params.empty()) {
1003 StringRef ParamName;
1004 std::tie(ParamName, Params) = Params.split(';');
1005
1006 bool Enable = !ParamName.consume_front("no-");
1007 if (ParamName == "pre") {
1008 Result.setPRE(Enable);
1009 } else if (ParamName == "load-pre") {
1010 Result.setLoadPRE(Enable);
1011 } else if (ParamName == "split-backedge-load-pre") {
1012 Result.setLoadPRESplitBackedge(Enable);
1013 } else if (ParamName == "memdep") {
1014 Result.setMemDep(Enable);
1015 } else {
1016 return make_error<StringError>(
1017 formatv("invalid GVN pass parameter '{0}' ", ParamName).str(),
1019 }
1020 }
1021 return Result;
1022}
1023
1024Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1026 while (!Params.empty()) {
1027 StringRef ParamName;
1028 std::tie(ParamName, Params) = Params.split(';');
1029
1030 bool Enable = !ParamName.consume_front("no-");
1031 if (ParamName == "func-spec")
1032 Result.setFuncSpec(Enable);
1033 else
1034 return make_error<StringError>(
1035 formatv("invalid IPSCCP pass parameter '{0}' ", ParamName).str(),
1037 }
1038 return Result;
1039}
1040
1041Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1042 if (Params.empty() || Params == "modify-cfg")
1044 if (Params == "preserve-cfg")
1046 return make_error<StringError>(
1047 formatv("invalid SROA pass parameter '{0}' (either preserve-cfg or "
1048 "modify-cfg can be specified)",
1049 Params)
1050 .str(),
1052}
1053
1055parseStackLifetimeOptions(StringRef Params) {
1057 while (!Params.empty()) {
1058 StringRef ParamName;
1059 std::tie(ParamName, Params) = Params.split(';');
1060
1061 if (ParamName == "may") {
1063 } else if (ParamName == "must") {
1065 } else {
1066 return make_error<StringError>(
1067 formatv("invalid StackLifetime parameter '{0}' ", ParamName).str(),
1069 }
1070 }
1071 return Result;
1072}
1073
1074Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1075 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1076 "DependenceAnalysisPrinter");
1077}
1078
1079Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1080 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1081 "SeparateConstOffsetFromGEP");
1082}
1083
1085parseFunctionSimplificationPipelineOptions(StringRef Params) {
1086 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1087 if (!L || *L == OptimizationLevel::O0) {
1088 return make_error<StringError>(
1089 formatv("invalid function-simplification parameter '{0}' ", Params)
1090 .str(),
1092 };
1093 return *L;
1094}
1095
1096Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1097 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1098 "MemorySSAPrinterPass");
1099}
1100
1101Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1102 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1103 "SpeculativeExecutionPass");
1104}
1105
1106Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1107 std::string Result;
1108 while (!Params.empty()) {
1109 StringRef ParamName;
1110 std::tie(ParamName, Params) = Params.split(';');
1111
1112 if (ParamName.consume_front("profile-filename=")) {
1113 Result = ParamName.str();
1114 } else {
1115 return make_error<StringError>(
1116 formatv("invalid MemProfUse pass parameter '{0}' ", ParamName).str(),
1118 }
1119 }
1120 return Result;
1121}
1122
1123Expected<bool> parseStructuralHashPrinterPassOptions(StringRef Params) {
1124 return PassBuilder::parseSinglePassOption(Params, "detailed",
1125 "StructuralHashPrinterPass");
1126}
1127
1128Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1129 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1130 "WinEHPreparePass");
1131}
1132
1133Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1135 while (!Params.empty()) {
1136 StringRef ParamName;
1137 std::tie(ParamName, Params) = Params.split(';');
1138
1139 bool Enable = !ParamName.consume_front("no-");
1140 if (ParamName == "group-by-use")
1141 Result.GroupByUse = Enable;
1142 else if (ParamName == "ignore-single-use")
1143 Result.IgnoreSingleUse = Enable;
1144 else if (ParamName == "merge-const")
1145 Result.MergeConst = Enable;
1146 else if (ParamName == "merge-external")
1147 Result.MergeExternal = Enable;
1148 else if (ParamName.consume_front("max-offset=")) {
1149 if (ParamName.getAsInteger(0, Result.MaxOffset))
1150 return make_error<StringError>(
1151 formatv("invalid GlobalMergePass parameter '{0}' ", ParamName)
1152 .str(),
1154 }
1155 }
1156 return Result;
1157}
1158
1159Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1160 SmallVector<std::string, 1> PreservedGVs;
1161 while (!Params.empty()) {
1162 StringRef ParamName;
1163 std::tie(ParamName, Params) = Params.split(';');
1164
1165 if (ParamName.consume_front("preserve-gv=")) {
1166 PreservedGVs.push_back(ParamName.str());
1167 } else {
1168 return make_error<StringError>(
1169 formatv("invalid Internalize pass parameter '{0}' ", ParamName).str(),
1171 }
1172 }
1173
1174 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1175}
1176
1178parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1180 while (!Params.empty()) {
1181 StringRef ParamName;
1182 std::tie(ParamName, Params) = Params.split(';');
1183
1184 if (ParamName.consume_front("filter=")) {
1185 std::optional<RegAllocFilterFunc> Filter =
1186 PB.parseRegAllocFilter(ParamName);
1187 if (!Filter) {
1188 return make_error<StringError>(
1189 formatv("invalid regallocfast register filter '{0}' ", ParamName)
1190 .str(),
1192 }
1193 Opts.Filter = *Filter;
1194 Opts.FilterName = ParamName;
1195 continue;
1196 }
1197
1198 if (ParamName == "no-clear-vregs") {
1199 Opts.ClearVRegs = false;
1200 continue;
1201 }
1202
1203 return make_error<StringError>(
1204 formatv("invalid regallocfast pass parameter '{0}' ", ParamName).str(),
1206 }
1207 return Opts;
1208}
1209
1210} // namespace
1211
1212/// Tests whether a pass name starts with a valid prefix for a default pipeline
1213/// alias.
1215 return Name.starts_with("default") || Name.starts_with("thinlto") ||
1216 Name.starts_with("lto");
1217}
1218
1219/// Tests whether registered callbacks will accept a given pass name.
1220///
1221/// When parsing a pipeline text, the type of the outermost pipeline may be
1222/// omitted, in which case the type is automatically determined from the first
1223/// pass name in the text. This may be a name that is handled through one of the
1224/// callbacks. We check this through the oridinary parsing callbacks by setting
1225/// up a dummy PassManager in order to not force the client to also handle this
1226/// type of query.
1227template <typename PassManagerT, typename CallbacksT>
1228static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1229 if (!Callbacks.empty()) {
1230 PassManagerT DummyPM;
1231 for (auto &CB : Callbacks)
1232 if (CB(Name, DummyPM, {}))
1233 return true;
1234 }
1235 return false;
1236}
1237
1238template <typename CallbacksT>
1239static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1240 // Manually handle aliases for pre-configured pipeline fragments.
1243
1244 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1245
1246 // Explicitly handle pass manager names.
1247 if (Name == "module")
1248 return true;
1249 if (Name == "cgscc")
1250 return true;
1251 if (NameNoBracket == "function")
1252 return true;
1253 if (Name == "coro-cond")
1254 return true;
1255
1256#define MODULE_PASS(NAME, CREATE_PASS) \
1257 if (Name == NAME) \
1258 return true;
1259#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1260 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1261 return true;
1262#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1263 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1264 return true;
1265#include "PassRegistry.def"
1266
1267 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1268}
1269
1270template <typename CallbacksT>
1271static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1272 // Explicitly handle pass manager names.
1273 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1274 if (Name == "cgscc")
1275 return true;
1276 if (NameNoBracket == "function")
1277 return true;
1278
1279 // Explicitly handle custom-parsed pass names.
1281 return true;
1282
1283#define CGSCC_PASS(NAME, CREATE_PASS) \
1284 if (Name == NAME) \
1285 return true;
1286#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1287 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1288 return true;
1289#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1290 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1291 return true;
1292#include "PassRegistry.def"
1293
1294 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1295}
1296
1297template <typename CallbacksT>
1298static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1299 // Explicitly handle pass manager names.
1300 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1301 if (NameNoBracket == "function")
1302 return true;
1303 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1304 return true;
1305
1306#define FUNCTION_PASS(NAME, CREATE_PASS) \
1307 if (Name == NAME) \
1308 return true;
1309#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1310 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1311 return true;
1312#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1313 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1314 return true;
1315#include "PassRegistry.def"
1316
1317 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1318}
1319
1320template <typename CallbacksT>
1321static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1322 // Explicitly handle pass manager names.
1323 if (Name == "machine-function")
1324 return true;
1325
1326#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1327 if (Name == NAME) \
1328 return true;
1329#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1330 PARAMS) \
1331 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1332 return true;
1333
1334#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1335 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1336 return true;
1337
1338#include "llvm/Passes/MachinePassRegistry.def"
1339
1340 return callbacksAcceptPassName<MachineFunctionPassManager>(Name, Callbacks);
1341}
1342
1343template <typename CallbacksT>
1344static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1345 bool &UseMemorySSA) {
1346 UseMemorySSA = false;
1347
1349 UseMemorySSA = true;
1350 return true;
1351 }
1352
1353#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1354 if (Name == NAME) \
1355 return true;
1356#include "PassRegistry.def"
1357
1358 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1359}
1360
1361template <typename CallbacksT>
1362static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1363 bool &UseMemorySSA) {
1364 UseMemorySSA = false;
1365
1367 UseMemorySSA = true;
1368 return true;
1369 }
1370
1371#define LOOP_PASS(NAME, CREATE_PASS) \
1372 if (Name == NAME) \
1373 return true;
1374#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1375 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1376 return true;
1377#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1378 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1379 return true;
1380#include "PassRegistry.def"
1381
1382 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1383}
1384
1385std::optional<std::vector<PassBuilder::PipelineElement>>
1386PassBuilder::parsePipelineText(StringRef Text) {
1387 std::vector<PipelineElement> ResultPipeline;
1388
1389 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1390 &ResultPipeline};
1391 for (;;) {
1392 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1393 size_t Pos = Text.find_first_of(",()");
1394 Pipeline.push_back({Text.substr(0, Pos), {}});
1395
1396 // If we have a single terminating name, we're done.
1397 if (Pos == Text.npos)
1398 break;
1399
1400 char Sep = Text[Pos];
1401 Text = Text.substr(Pos + 1);
1402 if (Sep == ',')
1403 // Just a name ending in a comma, continue.
1404 continue;
1405
1406 if (Sep == '(') {
1407 // Push the inner pipeline onto the stack to continue processing.
1408 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1409 continue;
1410 }
1411
1412 assert(Sep == ')' && "Bogus separator!");
1413 // When handling the close parenthesis, we greedily consume them to avoid
1414 // empty strings in the pipeline.
1415 do {
1416 // If we try to pop the outer pipeline we have unbalanced parentheses.
1417 if (PipelineStack.size() == 1)
1418 return std::nullopt;
1419
1420 PipelineStack.pop_back();
1421 } while (Text.consume_front(")"));
1422
1423 // Check if we've finished parsing.
1424 if (Text.empty())
1425 break;
1426
1427 // Otherwise, the end of an inner pipeline always has to be followed by
1428 // a comma, and then we can continue.
1429 if (!Text.consume_front(","))
1430 return std::nullopt;
1431 }
1432
1433 if (PipelineStack.size() > 1)
1434 // Unbalanced paretheses.
1435 return std::nullopt;
1436
1437 assert(PipelineStack.back() == &ResultPipeline &&
1438 "Wrong pipeline at the bottom of the stack!");
1439 return {std::move(ResultPipeline)};
1440}
1441
1442Error PassBuilder::parseModulePass(ModulePassManager &MPM,
1443 const PipelineElement &E) {
1444 auto &Name = E.Name;
1445 auto &InnerPipeline = E.InnerPipeline;
1446
1447 // First handle complex passes like the pass managers which carry pipelines.
1448 if (!InnerPipeline.empty()) {
1449 if (Name == "module") {
1450 ModulePassManager NestedMPM;
1451 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1452 return Err;
1453 MPM.addPass(std::move(NestedMPM));
1454 return Error::success();
1455 }
1456 if (Name == "coro-cond") {
1457 ModulePassManager NestedMPM;
1458 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1459 return Err;
1460 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
1461 return Error::success();
1462 }
1463 if (Name == "cgscc") {
1464 CGSCCPassManager CGPM;
1465 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
1466 return Err;
1468 return Error::success();
1469 }
1470 if (auto Params = parseFunctionPipelineName(Name)) {
1471 if (Params->second)
1472 return make_error<StringError>(
1473 "cannot have a no-rerun module to function adaptor",
1476 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
1477 return Err;
1478 MPM.addPass(
1479 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
1480 return Error::success();
1481 }
1482
1483 for (auto &C : ModulePipelineParsingCallbacks)
1484 if (C(Name, MPM, InnerPipeline))
1485 return Error::success();
1486
1487 // Normal passes can't have pipelines.
1488 return make_error<StringError>(
1489 formatv("invalid use of '{0}' pass as module pipeline", Name).str(),
1491 ;
1492 }
1493
1494 // Manually handle aliases for pre-configured pipeline fragments.
1497 if (!DefaultAliasRegex.match(Name, &Matches))
1498 return make_error<StringError>(
1499 formatv("unknown default pipeline alias '{0}'", Name).str(),
1501
1502 assert(Matches.size() == 3 && "Must capture two matched strings!");
1503
1504 OptimizationLevel L = *parseOptLevel(Matches[2]);
1505
1506 // This is consistent with old pass manager invoked via opt, but
1507 // inconsistent with clang. Clang doesn't enable loop vectorization
1508 // but does enable slp vectorization at Oz.
1509 PTO.LoopVectorization =
1510 L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1511 PTO.SLPVectorization =
1512 L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1513
1514 if (Matches[1] == "default") {
1516 } else if (Matches[1] == "thinlto-pre-link") {
1518 } else if (Matches[1] == "thinlto") {
1520 } else if (Matches[1] == "lto-pre-link") {
1521 if (PTO.UnifiedLTO)
1522 // When UnifiedLTO is enabled, use the ThinLTO pre-link pipeline. This
1523 // avoids compile-time performance regressions and keeps the pre-link
1524 // LTO pipeline "unified" for both LTO modes.
1526 else
1528 } else {
1529 assert(Matches[1] == "lto" && "Not one of the matched options!");
1530 MPM.addPass(buildLTODefaultPipeline(L, nullptr));
1531 }
1532 return Error::success();
1533 }
1534
1535 // Finally expand the basic registered passes from the .inc file.
1536#define MODULE_PASS(NAME, CREATE_PASS) \
1537 if (Name == NAME) { \
1538 MPM.addPass(CREATE_PASS); \
1539 return Error::success(); \
1540 }
1541#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1542 if (checkParametrizedPassName(Name, NAME)) { \
1543 auto Params = parsePassParameters(PARSER, Name, NAME); \
1544 if (!Params) \
1545 return Params.takeError(); \
1546 MPM.addPass(CREATE_PASS(Params.get())); \
1547 return Error::success(); \
1548 }
1549#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1550 if (Name == "require<" NAME ">") { \
1551 MPM.addPass( \
1552 RequireAnalysisPass< \
1553 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
1554 return Error::success(); \
1555 } \
1556 if (Name == "invalidate<" NAME ">") { \
1557 MPM.addPass(InvalidateAnalysisPass< \
1558 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1559 return Error::success(); \
1560 }
1561#define CGSCC_PASS(NAME, CREATE_PASS) \
1562 if (Name == NAME) { \
1563 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
1564 return Error::success(); \
1565 }
1566#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1567 if (checkParametrizedPassName(Name, NAME)) { \
1568 auto Params = parsePassParameters(PARSER, Name, NAME); \
1569 if (!Params) \
1570 return Params.takeError(); \
1571 MPM.addPass( \
1572 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
1573 return Error::success(); \
1574 }
1575#define FUNCTION_PASS(NAME, CREATE_PASS) \
1576 if (Name == NAME) { \
1577 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
1578 return Error::success(); \
1579 }
1580#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1581 if (checkParametrizedPassName(Name, NAME)) { \
1582 auto Params = parsePassParameters(PARSER, Name, NAME); \
1583 if (!Params) \
1584 return Params.takeError(); \
1585 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
1586 return Error::success(); \
1587 }
1588#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1589 if (Name == NAME) { \
1590 MPM.addPass(createModuleToFunctionPassAdaptor( \
1591 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1592 return Error::success(); \
1593 }
1594#define LOOP_PASS(NAME, CREATE_PASS) \
1595 if (Name == NAME) { \
1596 MPM.addPass(createModuleToFunctionPassAdaptor( \
1597 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1598 return Error::success(); \
1599 }
1600#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1601 if (checkParametrizedPassName(Name, NAME)) { \
1602 auto Params = parsePassParameters(PARSER, Name, NAME); \
1603 if (!Params) \
1604 return Params.takeError(); \
1605 MPM.addPass( \
1606 createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
1607 CREATE_PASS(Params.get()), false, false))); \
1608 return Error::success(); \
1609 }
1610#include "PassRegistry.def"
1611
1612 for (auto &C : ModulePipelineParsingCallbacks)
1613 if (C(Name, MPM, InnerPipeline))
1614 return Error::success();
1615 return make_error<StringError>(
1616 formatv("unknown module pass '{0}'", Name).str(),
1618}
1619
1620Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
1621 const PipelineElement &E) {
1622 auto &Name = E.Name;
1623 auto &InnerPipeline = E.InnerPipeline;
1624
1625 // First handle complex passes like the pass managers which carry pipelines.
1626 if (!InnerPipeline.empty()) {
1627 if (Name == "cgscc") {
1628 CGSCCPassManager NestedCGPM;
1629 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1630 return Err;
1631 // Add the nested pass manager with the appropriate adaptor.
1632 CGPM.addPass(std::move(NestedCGPM));
1633 return Error::success();
1634 }
1635 if (auto Params = parseFunctionPipelineName(Name)) {
1637 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
1638 return Err;
1639 // Add the nested pass manager with the appropriate adaptor.
1641 std::move(FPM), Params->first, Params->second));
1642 return Error::success();
1643 }
1644 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
1645 CGSCCPassManager NestedCGPM;
1646 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1647 return Err;
1648 CGPM.addPass(
1649 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
1650 return Error::success();
1651 }
1652
1653 for (auto &C : CGSCCPipelineParsingCallbacks)
1654 if (C(Name, CGPM, InnerPipeline))
1655 return Error::success();
1656
1657 // Normal passes can't have pipelines.
1658 return make_error<StringError>(
1659 formatv("invalid use of '{0}' pass as cgscc pipeline", Name).str(),
1661 }
1662
1663// Now expand the basic registered passes from the .inc file.
1664#define CGSCC_PASS(NAME, CREATE_PASS) \
1665 if (Name == NAME) { \
1666 CGPM.addPass(CREATE_PASS); \
1667 return Error::success(); \
1668 }
1669#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1670 if (checkParametrizedPassName(Name, NAME)) { \
1671 auto Params = parsePassParameters(PARSER, Name, NAME); \
1672 if (!Params) \
1673 return Params.takeError(); \
1674 CGPM.addPass(CREATE_PASS(Params.get())); \
1675 return Error::success(); \
1676 }
1677#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1678 if (Name == "require<" NAME ">") { \
1679 CGPM.addPass(RequireAnalysisPass< \
1680 std::remove_reference_t<decltype(CREATE_PASS)>, \
1681 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
1682 CGSCCUpdateResult &>()); \
1683 return Error::success(); \
1684 } \
1685 if (Name == "invalidate<" NAME ">") { \
1686 CGPM.addPass(InvalidateAnalysisPass< \
1687 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1688 return Error::success(); \
1689 }
1690#define FUNCTION_PASS(NAME, CREATE_PASS) \
1691 if (Name == NAME) { \
1692 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
1693 return Error::success(); \
1694 }
1695#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1696 if (checkParametrizedPassName(Name, NAME)) { \
1697 auto Params = parsePassParameters(PARSER, Name, NAME); \
1698 if (!Params) \
1699 return Params.takeError(); \
1700 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
1701 return Error::success(); \
1702 }
1703#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1704 if (Name == NAME) { \
1705 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
1706 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1707 return Error::success(); \
1708 }
1709#define LOOP_PASS(NAME, CREATE_PASS) \
1710 if (Name == NAME) { \
1711 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
1712 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1713 return Error::success(); \
1714 }
1715#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1716 if (checkParametrizedPassName(Name, NAME)) { \
1717 auto Params = parsePassParameters(PARSER, Name, NAME); \
1718 if (!Params) \
1719 return Params.takeError(); \
1720 CGPM.addPass( \
1721 createCGSCCToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
1722 CREATE_PASS(Params.get()), false, false))); \
1723 return Error::success(); \
1724 }
1725#include "PassRegistry.def"
1726
1727 for (auto &C : CGSCCPipelineParsingCallbacks)
1728 if (C(Name, CGPM, InnerPipeline))
1729 return Error::success();
1730 return make_error<StringError>(
1731 formatv("unknown cgscc pass '{0}'", Name).str(),
1733}
1734
1735Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
1736 const PipelineElement &E) {
1737 auto &Name = E.Name;
1738 auto &InnerPipeline = E.InnerPipeline;
1739
1740 // First handle complex passes like the pass managers which carry pipelines.
1741 if (!InnerPipeline.empty()) {
1742 if (Name == "function") {
1743 FunctionPassManager NestedFPM;
1744 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
1745 return Err;
1746 // Add the nested pass manager with the appropriate adaptor.
1747 FPM.addPass(std::move(NestedFPM));
1748 return Error::success();
1749 }
1750 if (Name == "loop" || Name == "loop-mssa") {
1751 LoopPassManager LPM;
1752 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
1753 return Err;
1754 // Add the nested pass manager with the appropriate adaptor.
1755 bool UseMemorySSA = (Name == "loop-mssa");
1756 bool UseBFI = llvm::any_of(InnerPipeline, [](auto Pipeline) {
1757 return Pipeline.Name.contains("simple-loop-unswitch");
1758 });
1759 bool UseBPI = llvm::any_of(InnerPipeline, [](auto Pipeline) {
1760 return Pipeline.Name == "loop-predication";
1761 });
1762 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA,
1763 UseBFI, UseBPI));
1764 return Error::success();
1765 }
1766 if (Name == "machine-function") {
1768 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
1769 return Err;
1771 return Error::success();
1772 }
1773
1774 for (auto &C : FunctionPipelineParsingCallbacks)
1775 if (C(Name, FPM, InnerPipeline))
1776 return Error::success();
1777
1778 // Normal passes can't have pipelines.
1779 return make_error<StringError>(
1780 formatv("invalid use of '{0}' pass as function pipeline", Name).str(),
1782 }
1783
1784// Now expand the basic registered passes from the .inc file.
1785#define FUNCTION_PASS(NAME, CREATE_PASS) \
1786 if (Name == NAME) { \
1787 FPM.addPass(CREATE_PASS); \
1788 return Error::success(); \
1789 }
1790#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1791 if (checkParametrizedPassName(Name, NAME)) { \
1792 auto Params = parsePassParameters(PARSER, Name, NAME); \
1793 if (!Params) \
1794 return Params.takeError(); \
1795 FPM.addPass(CREATE_PASS(Params.get())); \
1796 return Error::success(); \
1797 }
1798#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1799 if (Name == "require<" NAME ">") { \
1800 FPM.addPass( \
1801 RequireAnalysisPass< \
1802 std::remove_reference_t<decltype(CREATE_PASS)>, Function>()); \
1803 return Error::success(); \
1804 } \
1805 if (Name == "invalidate<" NAME ">") { \
1806 FPM.addPass(InvalidateAnalysisPass< \
1807 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1808 return Error::success(); \
1809 }
1810// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
1811// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
1812// "guard-widening");
1813// The risk is that it may become obsolete if we're not careful.
1814#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1815 if (Name == NAME) { \
1816 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
1817 return Error::success(); \
1818 }
1819#define LOOP_PASS(NAME, CREATE_PASS) \
1820 if (Name == NAME) { \
1821 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
1822 return Error::success(); \
1823 }
1824#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1825 if (checkParametrizedPassName(Name, NAME)) { \
1826 auto Params = parsePassParameters(PARSER, Name, NAME); \
1827 if (!Params) \
1828 return Params.takeError(); \
1829 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), \
1830 false, false)); \
1831 return Error::success(); \
1832 }
1833#include "PassRegistry.def"
1834
1835 for (auto &C : FunctionPipelineParsingCallbacks)
1836 if (C(Name, FPM, InnerPipeline))
1837 return Error::success();
1838 return make_error<StringError>(
1839 formatv("unknown function pass '{0}'", Name).str(),
1841}
1842
1843Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
1844 const PipelineElement &E) {
1845 StringRef Name = E.Name;
1846 auto &InnerPipeline = E.InnerPipeline;
1847
1848 // First handle complex passes like the pass managers which carry pipelines.
1849 if (!InnerPipeline.empty()) {
1850 if (Name == "loop") {
1851 LoopPassManager NestedLPM;
1852 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
1853 return Err;
1854 // Add the nested pass manager with the appropriate adaptor.
1855 LPM.addPass(std::move(NestedLPM));
1856 return Error::success();
1857 }
1858
1859 for (auto &C : LoopPipelineParsingCallbacks)
1860 if (C(Name, LPM, InnerPipeline))
1861 return Error::success();
1862
1863 // Normal passes can't have pipelines.
1864 return make_error<StringError>(
1865 formatv("invalid use of '{0}' pass as loop pipeline", Name).str(),
1867 }
1868
1869// Now expand the basic registered passes from the .inc file.
1870#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1871 if (Name == NAME) { \
1872 LPM.addPass(CREATE_PASS); \
1873 return Error::success(); \
1874 }
1875#define LOOP_PASS(NAME, CREATE_PASS) \
1876 if (Name == NAME) { \
1877 LPM.addPass(CREATE_PASS); \
1878 return Error::success(); \
1879 }
1880#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1881 if (checkParametrizedPassName(Name, NAME)) { \
1882 auto Params = parsePassParameters(PARSER, Name, NAME); \
1883 if (!Params) \
1884 return Params.takeError(); \
1885 LPM.addPass(CREATE_PASS(Params.get())); \
1886 return Error::success(); \
1887 }
1888#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1889 if (Name == "require<" NAME ">") { \
1890 LPM.addPass(RequireAnalysisPass< \
1891 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
1892 LoopAnalysisManager, LoopStandardAnalysisResults &, \
1893 LPMUpdater &>()); \
1894 return Error::success(); \
1895 } \
1896 if (Name == "invalidate<" NAME ">") { \
1897 LPM.addPass(InvalidateAnalysisPass< \
1898 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1899 return Error::success(); \
1900 }
1901#include "PassRegistry.def"
1902
1903 for (auto &C : LoopPipelineParsingCallbacks)
1904 if (C(Name, LPM, InnerPipeline))
1905 return Error::success();
1906 return make_error<StringError>(formatv("unknown loop pass '{0}'", Name).str(),
1908}
1909
1910Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
1911 const PipelineElement &E) {
1912 StringRef Name = E.Name;
1913 if (!E.InnerPipeline.empty())
1914 return make_error<StringError>("invalid pipeline",
1916
1917#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
1918 if (Name == NAME) { \
1919 MFPM.addPass(CREATE_PASS); \
1920 return Error::success(); \
1921 }
1922#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1923 if (Name == NAME) { \
1924 MFPM.addPass(CREATE_PASS); \
1925 return Error::success(); \
1926 }
1927#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1928 PARAMS) \
1929 if (checkParametrizedPassName(Name, NAME)) { \
1930 auto Params = parsePassParameters(PARSER, Name, NAME); \
1931 if (!Params) \
1932 return Params.takeError(); \
1933 MFPM.addPass(CREATE_PASS(Params.get())); \
1934 return Error::success(); \
1935 }
1936#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1937 if (Name == "require<" NAME ">") { \
1938 MFPM.addPass( \
1939 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
1940 MachineFunction>()); \
1941 return Error::success(); \
1942 } \
1943 if (Name == "invalidate<" NAME ">") { \
1944 MFPM.addPass(InvalidateAnalysisPass< \
1945 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1946 return Error::success(); \
1947 }
1948#include "llvm/Passes/MachinePassRegistry.def"
1949
1950 for (auto &C : MachineFunctionPipelineParsingCallbacks)
1951 if (C(Name, MFPM, E.InnerPipeline))
1952 return Error::success();
1953 return make_error<StringError>(
1954 formatv("unknown machine pass '{0}'", Name).str(),
1956}
1957
1958bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
1959#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1960 if (Name == NAME) { \
1961 AA.registerModuleAnalysis< \
1962 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
1963 return true; \
1964 }
1965#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1966 if (Name == NAME) { \
1967 AA.registerFunctionAnalysis< \
1968 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
1969 return true; \
1970 }
1971#include "PassRegistry.def"
1972
1973 for (auto &C : AAParsingCallbacks)
1974 if (C(Name, AA))
1975 return true;
1976 return false;
1977}
1978
1979Error PassBuilder::parseMachinePassPipeline(
1981 for (const auto &Element : Pipeline) {
1982 if (auto Err = parseMachinePass(MFPM, Element))
1983 return Err;
1984 }
1985 return Error::success();
1986}
1987
1988Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
1989 ArrayRef<PipelineElement> Pipeline) {
1990 for (const auto &Element : Pipeline) {
1991 if (auto Err = parseLoopPass(LPM, Element))
1992 return Err;
1993 }
1994 return Error::success();
1995}
1996
1997Error PassBuilder::parseFunctionPassPipeline(
1999 for (const auto &Element : Pipeline) {
2000 if (auto Err = parseFunctionPass(FPM, Element))
2001 return Err;
2002 }
2003 return Error::success();
2004}
2005
2006Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2007 ArrayRef<PipelineElement> Pipeline) {
2008 for (const auto &Element : Pipeline) {
2009 if (auto Err = parseCGSCCPass(CGPM, Element))
2010 return Err;
2011 }
2012 return Error::success();
2013}
2014
2027 if (MFAM) {
2029 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2031 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2032 MFAM->registerPass(
2034 MFAM->registerPass(
2036 }
2037}
2038
2039Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2040 ArrayRef<PipelineElement> Pipeline) {
2041 for (const auto &Element : Pipeline) {
2042 if (auto Err = parseModulePass(MPM, Element))
2043 return Err;
2044 }
2045 return Error::success();
2046}
2047
2048// Primary pass pipeline description parsing routine for a \c ModulePassManager
2049// FIXME: Should this routine accept a TargetMachine or require the caller to
2050// pre-populate the analysis managers with target-specific stuff?
2052 StringRef PipelineText) {
2053 auto Pipeline = parsePipelineText(PipelineText);
2054 if (!Pipeline || Pipeline->empty())
2055 return make_error<StringError>(
2056 formatv("invalid pipeline '{0}'", PipelineText).str(),
2058
2059 // If the first name isn't at the module layer, wrap the pipeline up
2060 // automatically.
2061 StringRef FirstName = Pipeline->front().Name;
2062
2063 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2064 bool UseMemorySSA;
2065 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2066 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2067 } else if (isFunctionPassName(FirstName,
2068 FunctionPipelineParsingCallbacks)) {
2069 Pipeline = {{"function", std::move(*Pipeline)}};
2070 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2071 UseMemorySSA)) {
2072 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2073 std::move(*Pipeline)}}}};
2074 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2075 UseMemorySSA)) {
2076 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2077 std::move(*Pipeline)}}}};
2078 } else if (isMachineFunctionPassName(
2079 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2080 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2081 } else {
2082 for (auto &C : TopLevelPipelineParsingCallbacks)
2083 if (C(MPM, *Pipeline))
2084 return Error::success();
2085
2086 // Unknown pass or pipeline name!
2087 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2088 return make_error<StringError>(
2089 formatv("unknown {0} name '{1}'",
2090 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2091 .str(),
2093 }
2094 }
2095
2096 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2097 return Err;
2098 return Error::success();
2099}
2100
2101// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2103 StringRef PipelineText) {
2104 auto Pipeline = parsePipelineText(PipelineText);
2105 if (!Pipeline || Pipeline->empty())
2106 return make_error<StringError>(
2107 formatv("invalid pipeline '{0}'", PipelineText).str(),
2109
2110 StringRef FirstName = Pipeline->front().Name;
2111 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2112 return make_error<StringError>(
2113 formatv("unknown cgscc pass '{0}' in pipeline '{1}'", FirstName,
2114 PipelineText)
2115 .str(),
2117
2118 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2119 return Err;
2120 return Error::success();
2121}
2122
2123// Primary pass pipeline description parsing routine for a \c
2124// FunctionPassManager
2126 StringRef PipelineText) {
2127 auto Pipeline = parsePipelineText(PipelineText);
2128 if (!Pipeline || Pipeline->empty())
2129 return make_error<StringError>(
2130 formatv("invalid pipeline '{0}'", PipelineText).str(),
2132
2133 StringRef FirstName = Pipeline->front().Name;
2134 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2135 return make_error<StringError>(
2136 formatv("unknown function pass '{0}' in pipeline '{1}'", FirstName,
2137 PipelineText)
2138 .str(),
2140
2141 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2142 return Err;
2143 return Error::success();
2144}
2145
2146// Primary pass pipeline description parsing routine for a \c LoopPassManager
2148 StringRef PipelineText) {
2149 auto Pipeline = parsePipelineText(PipelineText);
2150 if (!Pipeline || Pipeline->empty())
2151 return make_error<StringError>(
2152 formatv("invalid pipeline '{0}'", PipelineText).str(),
2154
2155 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2156 return Err;
2157
2158 return Error::success();
2159}
2160
2162 StringRef PipelineText) {
2163 auto Pipeline = parsePipelineText(PipelineText);
2164 if (!Pipeline || Pipeline->empty())
2165 return make_error<StringError>(
2166 formatv("invalid machine pass pipeline '{0}'", PipelineText).str(),
2168
2169 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2170 return Err;
2171
2172 return Error::success();
2173}
2174
2176 // If the pipeline just consists of the word 'default' just replace the AA
2177 // manager with our default one.
2178 if (PipelineText == "default") {
2180 return Error::success();
2181 }
2182
2183 while (!PipelineText.empty()) {
2185 std::tie(Name, PipelineText) = PipelineText.split(',');
2186 if (!parseAAPassName(AA, Name))
2187 return make_error<StringError>(
2188 formatv("unknown alias analysis name '{0}'", Name).str(),
2190 }
2191
2192 return Error::success();
2193}
2194
2195std::optional<RegAllocFilterFunc>
2197 if (FilterName == "all")
2198 return nullptr;
2199 for (auto &C : RegClassFilterParsingCallbacks)
2200 if (auto F = C(FilterName))
2201 return F;
2202 return std::nullopt;
2203}
2204
2206 OS << " " << PassName << "\n";
2207}
2209 raw_ostream &OS) {
2210 OS << " " << PassName << "<" << Params << ">\n";
2211}
2212
2214 // TODO: print pass descriptions when they are available
2215
2216 OS << "Module passes:\n";
2217#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2218#include "PassRegistry.def"
2219
2220 OS << "Module passes with params:\n";
2221#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2222 printPassName(NAME, PARAMS, OS);
2223#include "PassRegistry.def"
2224
2225 OS << "Module analyses:\n";
2226#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2227#include "PassRegistry.def"
2228
2229 OS << "Module alias analyses:\n";
2230#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2231#include "PassRegistry.def"
2232
2233 OS << "CGSCC passes:\n";
2234#define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2235#include "PassRegistry.def"
2236
2237 OS << "CGSCC passes with params:\n";
2238#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2239 printPassName(NAME, PARAMS, OS);
2240#include "PassRegistry.def"
2241
2242 OS << "CGSCC analyses:\n";
2243#define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2244#include "PassRegistry.def"
2245
2246 OS << "Function passes:\n";
2247#define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2248#include "PassRegistry.def"
2249
2250 OS << "Function passes with params:\n";
2251#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2252 printPassName(NAME, PARAMS, OS);
2253#include "PassRegistry.def"
2254
2255 OS << "Function analyses:\n";
2256#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2257#include "PassRegistry.def"
2258
2259 OS << "Function alias analyses:\n";
2260#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2261#include "PassRegistry.def"
2262
2263 OS << "LoopNest passes:\n";
2264#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2265#include "PassRegistry.def"
2266
2267 OS << "Loop passes:\n";
2268#define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2269#include "PassRegistry.def"
2270
2271 OS << "Loop passes with params:\n";
2272#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2273 printPassName(NAME, PARAMS, OS);
2274#include "PassRegistry.def"
2275
2276 OS << "Loop analyses:\n";
2277#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2278#include "PassRegistry.def"
2279
2280 OS << "Machine module passes (WIP):\n";
2281#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2282#include "llvm/Passes/MachinePassRegistry.def"
2283
2284 OS << "Machine function passes (WIP):\n";
2285#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2286#include "llvm/Passes/MachinePassRegistry.def"
2287
2288 OS << "Machine function analyses (WIP):\n";
2289#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2290#include "llvm/Passes/MachinePassRegistry.def"
2291}
2292
2294 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
2295 &C) {
2296 TopLevelPipelineParsingCallbacks.push_back(C);
2297}
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.
#define _
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
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
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
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &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 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:78
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1500
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1522
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
Definition: PassManager.h:467
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:61
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:229
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
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:544
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:563
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:42
An RAII based helper class to modify MachineFunctionProperties when running pass.
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.
This class provides access to building LLVM's passes.
Definition: PassBuilder.h:106
void printPassNames(raw_ostream &OS)
Print pass names.
static bool checkParametrizedPassName(StringRef Name, StringRef PassName)
Definition: PassBuilder.h:643
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.
std::optional< RegAllocFilterFunc > parseRegAllocFilter(StringRef RegAllocFilterName)
Parse RegAllocFilterName to get RegAllocFilterFunc.
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 std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
Definition: PassManager.h:195
Tunable parameters for passes in the default pipelines.
Definition: PassBuilder.h:44
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition: PassBuilder.h:59
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition: PassBuilder.h:55
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:111
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: Analysis.h:114
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
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:685
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:455
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:215
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:620
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:77
This function has undefined behavior.
self_iterator getIterator()
Definition: ilist_node.h:132
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
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:848
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:98
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:798
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
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:644
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.
@ Enable
Enable colors.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: Analysis.h:28
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:69
static StringRef name()
Gets the name of the pass we are mixed into.
Definition: PassManager.h:71
RegAllocFilterFunc Filter
Definition: RegAllocFast.h:18