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"
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 (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
849 APInt BonusInstThreshold;
850 if (ParamName.getAsInteger(0, BonusInstThreshold))
851 return make_error<StringError>(
852 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
853 "parameter: '{0}' ",
854 ParamName).str(),
856 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
857 } else {
858 return make_error<StringError>(
859 formatv("invalid SimplifyCFG pass parameter '{0}' ", ParamName).str(),
861 }
862 }
863 return Result;
864}
865
866Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
868 // When specifying "instcombine" in -passes enable fix-point verification by
869 // default, as this is what most tests should use.
870 Result.setVerifyFixpoint(true);
871 while (!Params.empty()) {
872 StringRef ParamName;
873 std::tie(ParamName, Params) = Params.split(';');
874
875 bool Enable = !ParamName.consume_front("no-");
876 if (ParamName == "use-loop-info") {
877 Result.setUseLoopInfo(Enable);
878 } else if (ParamName == "verify-fixpoint") {
879 Result.setVerifyFixpoint(Enable);
880 } else if (Enable && ParamName.consume_front("max-iterations=")) {
881 APInt MaxIterations;
882 if (ParamName.getAsInteger(0, MaxIterations))
883 return make_error<StringError>(
884 formatv("invalid argument to InstCombine pass max-iterations "
885 "parameter: '{0}' ",
886 ParamName).str(),
888 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
889 } else {
890 return make_error<StringError>(
891 formatv("invalid InstCombine pass parameter '{0}' ", ParamName).str(),
893 }
894 }
895 return Result;
896}
897
898/// Parser of parameters for LoopVectorize pass.
899Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
901 while (!Params.empty()) {
902 StringRef ParamName;
903 std::tie(ParamName, Params) = Params.split(';');
904
905 bool Enable = !ParamName.consume_front("no-");
906 if (ParamName == "interleave-forced-only") {
908 } else if (ParamName == "vectorize-forced-only") {
910 } else {
911 return make_error<StringError>(
912 formatv("invalid LoopVectorize parameter '{0}' ", ParamName).str(),
914 }
915 }
916 return Opts;
917}
918
919Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
920 std::pair<bool, bool> Result = {false, true};
921 while (!Params.empty()) {
922 StringRef ParamName;
923 std::tie(ParamName, Params) = Params.split(';');
924
925 bool Enable = !ParamName.consume_front("no-");
926 if (ParamName == "nontrivial") {
927 Result.first = Enable;
928 } else if (ParamName == "trivial") {
929 Result.second = Enable;
930 } else {
931 return make_error<StringError>(
932 formatv("invalid LoopUnswitch pass parameter '{0}' ", ParamName)
933 .str(),
935 }
936 }
937 return Result;
938}
939
940Expected<LICMOptions> parseLICMOptions(StringRef Params) {
942 while (!Params.empty()) {
943 StringRef ParamName;
944 std::tie(ParamName, Params) = Params.split(';');
945
946 bool Enable = !ParamName.consume_front("no-");
947 if (ParamName == "allowspeculation") {
948 Result.AllowSpeculation = Enable;
949 } else {
950 return make_error<StringError>(
951 formatv("invalid LICM pass parameter '{0}' ", ParamName).str(),
953 }
954 }
955 return Result;
956}
957
958Expected<std::pair<bool, bool>> parseLoopRotateOptions(StringRef Params) {
959 std::pair<bool, bool> Result = {true, false};
960 while (!Params.empty()) {
961 StringRef ParamName;
962 std::tie(ParamName, Params) = Params.split(';');
963
964 bool Enable = !ParamName.consume_front("no-");
965 if (ParamName == "header-duplication") {
966 Result.first = Enable;
967 } else if (ParamName == "prepare-for-lto") {
968 Result.second = Enable;
969 } else {
970 return make_error<StringError>(
971 formatv("invalid LoopRotate pass parameter '{0}' ", ParamName).str(),
973 }
974 }
975 return Result;
976}
977
978Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
979 bool Result = false;
980 while (!Params.empty()) {
981 StringRef ParamName;
982 std::tie(ParamName, Params) = Params.split(';');
983
984 bool Enable = !ParamName.consume_front("no-");
985 if (ParamName == "split-footer-bb") {
986 Result = Enable;
987 } else {
988 return make_error<StringError>(
989 formatv("invalid MergedLoadStoreMotion pass parameter '{0}' ",
990 ParamName)
991 .str(),
993 }
994 }
995 return Result;
996}
997
998Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1000 while (!Params.empty()) {
1001 StringRef ParamName;
1002 std::tie(ParamName, Params) = Params.split(';');
1003
1004 bool Enable = !ParamName.consume_front("no-");
1005 if (ParamName == "pre") {
1006 Result.setPRE(Enable);
1007 } else if (ParamName == "load-pre") {
1008 Result.setLoadPRE(Enable);
1009 } else if (ParamName == "split-backedge-load-pre") {
1010 Result.setLoadPRESplitBackedge(Enable);
1011 } else if (ParamName == "memdep") {
1012 Result.setMemDep(Enable);
1013 } else {
1014 return make_error<StringError>(
1015 formatv("invalid GVN pass parameter '{0}' ", ParamName).str(),
1017 }
1018 }
1019 return Result;
1020}
1021
1022Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1024 while (!Params.empty()) {
1025 StringRef ParamName;
1026 std::tie(ParamName, Params) = Params.split(';');
1027
1028 bool Enable = !ParamName.consume_front("no-");
1029 if (ParamName == "func-spec")
1030 Result.setFuncSpec(Enable);
1031 else
1032 return make_error<StringError>(
1033 formatv("invalid IPSCCP pass parameter '{0}' ", ParamName).str(),
1035 }
1036 return Result;
1037}
1038
1039Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1040 if (Params.empty() || Params == "modify-cfg")
1042 if (Params == "preserve-cfg")
1044 return make_error<StringError>(
1045 formatv("invalid SROA pass parameter '{0}' (either preserve-cfg or "
1046 "modify-cfg can be specified)",
1047 Params)
1048 .str(),
1050}
1051
1053parseStackLifetimeOptions(StringRef Params) {
1055 while (!Params.empty()) {
1056 StringRef ParamName;
1057 std::tie(ParamName, Params) = Params.split(';');
1058
1059 if (ParamName == "may") {
1061 } else if (ParamName == "must") {
1063 } else {
1064 return make_error<StringError>(
1065 formatv("invalid StackLifetime parameter '{0}' ", ParamName).str(),
1067 }
1068 }
1069 return Result;
1070}
1071
1072Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1073 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1074 "DependenceAnalysisPrinter");
1075}
1076
1077Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1078 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1079 "SeparateConstOffsetFromGEP");
1080}
1081
1083parseFunctionSimplificationPipelineOptions(StringRef Params) {
1084 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1085 if (!L || *L == OptimizationLevel::O0) {
1086 return make_error<StringError>(
1087 formatv("invalid function-simplification parameter '{0}' ", Params)
1088 .str(),
1090 };
1091 return *L;
1092}
1093
1094Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1095 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1096 "MemorySSAPrinterPass");
1097}
1098
1099Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1100 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1101 "SpeculativeExecutionPass");
1102}
1103
1104Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1105 std::string Result;
1106 while (!Params.empty()) {
1107 StringRef ParamName;
1108 std::tie(ParamName, Params) = Params.split(';');
1109
1110 if (ParamName.consume_front("profile-filename=")) {
1111 Result = ParamName.str();
1112 } else {
1113 return make_error<StringError>(
1114 formatv("invalid MemProfUse pass parameter '{0}' ", ParamName).str(),
1116 }
1117 }
1118 return Result;
1119}
1120
1121Expected<bool> parseStructuralHashPrinterPassOptions(StringRef Params) {
1122 return PassBuilder::parseSinglePassOption(Params, "detailed",
1123 "StructuralHashPrinterPass");
1124}
1125
1126Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1127 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1128 "WinEHPreparePass");
1129}
1130
1131Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1133 while (!Params.empty()) {
1134 StringRef ParamName;
1135 std::tie(ParamName, Params) = Params.split(';');
1136
1137 bool Enable = !ParamName.consume_front("no-");
1138 if (ParamName == "group-by-use")
1139 Result.GroupByUse = Enable;
1140 else if (ParamName == "ignore-single-use")
1141 Result.IgnoreSingleUse = Enable;
1142 else if (ParamName == "merge-const")
1143 Result.MergeConst = Enable;
1144 else if (ParamName == "merge-external")
1145 Result.MergeExternal = Enable;
1146 else if (ParamName.consume_front("max-offset=")) {
1147 if (ParamName.getAsInteger(0, Result.MaxOffset))
1148 return make_error<StringError>(
1149 formatv("invalid GlobalMergePass parameter '{0}' ", ParamName)
1150 .str(),
1152 }
1153 }
1154 return Result;
1155}
1156
1157Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1158 SmallVector<std::string, 1> PreservedGVs;
1159 while (!Params.empty()) {
1160 StringRef ParamName;
1161 std::tie(ParamName, Params) = Params.split(';');
1162
1163 if (ParamName.consume_front("preserve-gv=")) {
1164 PreservedGVs.push_back(ParamName.str());
1165 } else {
1166 return make_error<StringError>(
1167 formatv("invalid Internalize pass parameter '{0}' ", ParamName).str(),
1169 }
1170 }
1171
1172 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1173}
1174
1176parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1178 while (!Params.empty()) {
1179 StringRef ParamName;
1180 std::tie(ParamName, Params) = Params.split(';');
1181
1182 if (ParamName.consume_front("filter=")) {
1183 std::optional<RegClassFilterFunc> Filter =
1184 PB.parseRegAllocFilter(ParamName);
1185 if (!Filter) {
1186 return make_error<StringError>(
1187 formatv("invalid regallocfast register filter '{0}' ", ParamName)
1188 .str(),
1190 }
1191 Opts.Filter = *Filter;
1192 Opts.FilterName = ParamName;
1193 continue;
1194 }
1195
1196 if (ParamName == "no-clear-vregs") {
1197 Opts.ClearVRegs = false;
1198 continue;
1199 }
1200
1201 return make_error<StringError>(
1202 formatv("invalid regallocfast pass parameter '{0}' ", ParamName).str(),
1204 }
1205 return Opts;
1206}
1207
1208} // namespace
1209
1210/// Tests whether a pass name starts with a valid prefix for a default pipeline
1211/// alias.
1213 return Name.starts_with("default") || Name.starts_with("thinlto") ||
1214 Name.starts_with("lto");
1215}
1216
1217/// Tests whether registered callbacks will accept a given pass name.
1218///
1219/// When parsing a pipeline text, the type of the outermost pipeline may be
1220/// omitted, in which case the type is automatically determined from the first
1221/// pass name in the text. This may be a name that is handled through one of the
1222/// callbacks. We check this through the oridinary parsing callbacks by setting
1223/// up a dummy PassManager in order to not force the client to also handle this
1224/// type of query.
1225template <typename PassManagerT, typename CallbacksT>
1226static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1227 if (!Callbacks.empty()) {
1228 PassManagerT DummyPM;
1229 for (auto &CB : Callbacks)
1230 if (CB(Name, DummyPM, {}))
1231 return true;
1232 }
1233 return false;
1234}
1235
1236template <typename CallbacksT>
1237static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1238 // Manually handle aliases for pre-configured pipeline fragments.
1241
1242 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1243
1244 // Explicitly handle pass manager names.
1245 if (Name == "module")
1246 return true;
1247 if (Name == "cgscc")
1248 return true;
1249 if (NameNoBracket == "function")
1250 return true;
1251 if (Name == "coro-cond")
1252 return true;
1253
1254#define MODULE_PASS(NAME, CREATE_PASS) \
1255 if (Name == NAME) \
1256 return true;
1257#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1258 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1259 return true;
1260#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1261 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1262 return true;
1263#include "PassRegistry.def"
1264
1265 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1266}
1267
1268template <typename CallbacksT>
1269static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1270 // Explicitly handle pass manager names.
1271 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1272 if (Name == "cgscc")
1273 return true;
1274 if (NameNoBracket == "function")
1275 return true;
1276
1277 // Explicitly handle custom-parsed pass names.
1279 return true;
1280
1281#define CGSCC_PASS(NAME, CREATE_PASS) \
1282 if (Name == NAME) \
1283 return true;
1284#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1285 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1286 return true;
1287#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1288 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1289 return true;
1290#include "PassRegistry.def"
1291
1292 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1293}
1294
1295template <typename CallbacksT>
1296static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1297 // Explicitly handle pass manager names.
1298 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1299 if (NameNoBracket == "function")
1300 return true;
1301 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1302 return true;
1303
1304#define FUNCTION_PASS(NAME, CREATE_PASS) \
1305 if (Name == NAME) \
1306 return true;
1307#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1308 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1309 return true;
1310#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1311 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1312 return true;
1313#include "PassRegistry.def"
1314
1315 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1316}
1317
1318template <typename CallbacksT>
1319static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1320 // Explicitly handle pass manager names.
1321 if (Name == "machine-function")
1322 return true;
1323
1324#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1325 if (Name == NAME) \
1326 return true;
1327#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1328 PARAMS) \
1329 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1330 return true;
1331
1332#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1333 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1334 return true;
1335
1336#include "llvm/Passes/MachinePassRegistry.def"
1337
1338 return callbacksAcceptPassName<MachineFunctionPassManager>(Name, Callbacks);
1339}
1340
1341template <typename CallbacksT>
1342static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1343 bool &UseMemorySSA) {
1344 UseMemorySSA = false;
1345
1347 UseMemorySSA = true;
1348 return true;
1349 }
1350
1351#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1352 if (Name == NAME) \
1353 return true;
1354#include "PassRegistry.def"
1355
1356 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1357}
1358
1359template <typename CallbacksT>
1360static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1361 bool &UseMemorySSA) {
1362 UseMemorySSA = false;
1363
1365 UseMemorySSA = true;
1366 return true;
1367 }
1368
1369#define LOOP_PASS(NAME, CREATE_PASS) \
1370 if (Name == NAME) \
1371 return true;
1372#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1373 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1374 return true;
1375#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1376 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1377 return true;
1378#include "PassRegistry.def"
1379
1380 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1381}
1382
1383std::optional<std::vector<PassBuilder::PipelineElement>>
1384PassBuilder::parsePipelineText(StringRef Text) {
1385 std::vector<PipelineElement> ResultPipeline;
1386
1387 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1388 &ResultPipeline};
1389 for (;;) {
1390 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1391 size_t Pos = Text.find_first_of(",()");
1392 Pipeline.push_back({Text.substr(0, Pos), {}});
1393
1394 // If we have a single terminating name, we're done.
1395 if (Pos == Text.npos)
1396 break;
1397
1398 char Sep = Text[Pos];
1399 Text = Text.substr(Pos + 1);
1400 if (Sep == ',')
1401 // Just a name ending in a comma, continue.
1402 continue;
1403
1404 if (Sep == '(') {
1405 // Push the inner pipeline onto the stack to continue processing.
1406 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1407 continue;
1408 }
1409
1410 assert(Sep == ')' && "Bogus separator!");
1411 // When handling the close parenthesis, we greedily consume them to avoid
1412 // empty strings in the pipeline.
1413 do {
1414 // If we try to pop the outer pipeline we have unbalanced parentheses.
1415 if (PipelineStack.size() == 1)
1416 return std::nullopt;
1417
1418 PipelineStack.pop_back();
1419 } while (Text.consume_front(")"));
1420
1421 // Check if we've finished parsing.
1422 if (Text.empty())
1423 break;
1424
1425 // Otherwise, the end of an inner pipeline always has to be followed by
1426 // a comma, and then we can continue.
1427 if (!Text.consume_front(","))
1428 return std::nullopt;
1429 }
1430
1431 if (PipelineStack.size() > 1)
1432 // Unbalanced paretheses.
1433 return std::nullopt;
1434
1435 assert(PipelineStack.back() == &ResultPipeline &&
1436 "Wrong pipeline at the bottom of the stack!");
1437 return {std::move(ResultPipeline)};
1438}
1439
1440Error PassBuilder::parseModulePass(ModulePassManager &MPM,
1441 const PipelineElement &E) {
1442 auto &Name = E.Name;
1443 auto &InnerPipeline = E.InnerPipeline;
1444
1445 // First handle complex passes like the pass managers which carry pipelines.
1446 if (!InnerPipeline.empty()) {
1447 if (Name == "module") {
1448 ModulePassManager NestedMPM;
1449 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1450 return Err;
1451 MPM.addPass(std::move(NestedMPM));
1452 return Error::success();
1453 }
1454 if (Name == "coro-cond") {
1455 ModulePassManager NestedMPM;
1456 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1457 return Err;
1458 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
1459 return Error::success();
1460 }
1461 if (Name == "cgscc") {
1462 CGSCCPassManager CGPM;
1463 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
1464 return Err;
1466 return Error::success();
1467 }
1468 if (auto Params = parseFunctionPipelineName(Name)) {
1469 if (Params->second)
1470 return make_error<StringError>(
1471 "cannot have a no-rerun module to function adaptor",
1474 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
1475 return Err;
1476 MPM.addPass(
1477 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
1478 return Error::success();
1479 }
1480
1481 for (auto &C : ModulePipelineParsingCallbacks)
1482 if (C(Name, MPM, InnerPipeline))
1483 return Error::success();
1484
1485 // Normal passes can't have pipelines.
1486 return make_error<StringError>(
1487 formatv("invalid use of '{0}' pass as module pipeline", Name).str(),
1489 ;
1490 }
1491
1492 // Manually handle aliases for pre-configured pipeline fragments.
1495 if (!DefaultAliasRegex.match(Name, &Matches))
1496 return make_error<StringError>(
1497 formatv("unknown default pipeline alias '{0}'", Name).str(),
1499
1500 assert(Matches.size() == 3 && "Must capture two matched strings!");
1501
1502 OptimizationLevel L = *parseOptLevel(Matches[2]);
1503
1504 // This is consistent with old pass manager invoked via opt, but
1505 // inconsistent with clang. Clang doesn't enable loop vectorization
1506 // but does enable slp vectorization at Oz.
1507 PTO.LoopVectorization =
1508 L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1509 PTO.SLPVectorization =
1510 L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1511
1512 if (Matches[1] == "default") {
1514 } else if (Matches[1] == "thinlto-pre-link") {
1516 } else if (Matches[1] == "thinlto") {
1518 } else if (Matches[1] == "lto-pre-link") {
1519 if (PTO.UnifiedLTO)
1520 // When UnifiedLTO is enabled, use the ThinLTO pre-link pipeline. This
1521 // avoids compile-time performance regressions and keeps the pre-link
1522 // LTO pipeline "unified" for both LTO modes.
1524 else
1526 } else {
1527 assert(Matches[1] == "lto" && "Not one of the matched options!");
1528 MPM.addPass(buildLTODefaultPipeline(L, nullptr));
1529 }
1530 return Error::success();
1531 }
1532
1533 // Finally expand the basic registered passes from the .inc file.
1534#define MODULE_PASS(NAME, CREATE_PASS) \
1535 if (Name == NAME) { \
1536 MPM.addPass(CREATE_PASS); \
1537 return Error::success(); \
1538 }
1539#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1540 if (checkParametrizedPassName(Name, NAME)) { \
1541 auto Params = parsePassParameters(PARSER, Name, NAME); \
1542 if (!Params) \
1543 return Params.takeError(); \
1544 MPM.addPass(CREATE_PASS(Params.get())); \
1545 return Error::success(); \
1546 }
1547#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1548 if (Name == "require<" NAME ">") { \
1549 MPM.addPass( \
1550 RequireAnalysisPass< \
1551 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
1552 return Error::success(); \
1553 } \
1554 if (Name == "invalidate<" NAME ">") { \
1555 MPM.addPass(InvalidateAnalysisPass< \
1556 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1557 return Error::success(); \
1558 }
1559#define CGSCC_PASS(NAME, CREATE_PASS) \
1560 if (Name == NAME) { \
1561 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
1562 return Error::success(); \
1563 }
1564#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1565 if (checkParametrizedPassName(Name, NAME)) { \
1566 auto Params = parsePassParameters(PARSER, Name, NAME); \
1567 if (!Params) \
1568 return Params.takeError(); \
1569 MPM.addPass( \
1570 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
1571 return Error::success(); \
1572 }
1573#define FUNCTION_PASS(NAME, CREATE_PASS) \
1574 if (Name == NAME) { \
1575 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
1576 return Error::success(); \
1577 }
1578#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1579 if (checkParametrizedPassName(Name, NAME)) { \
1580 auto Params = parsePassParameters(PARSER, Name, NAME); \
1581 if (!Params) \
1582 return Params.takeError(); \
1583 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
1584 return Error::success(); \
1585 }
1586#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1587 if (Name == NAME) { \
1588 MPM.addPass(createModuleToFunctionPassAdaptor( \
1589 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1590 return Error::success(); \
1591 }
1592#define LOOP_PASS(NAME, CREATE_PASS) \
1593 if (Name == NAME) { \
1594 MPM.addPass(createModuleToFunctionPassAdaptor( \
1595 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1596 return Error::success(); \
1597 }
1598#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1599 if (checkParametrizedPassName(Name, NAME)) { \
1600 auto Params = parsePassParameters(PARSER, Name, NAME); \
1601 if (!Params) \
1602 return Params.takeError(); \
1603 MPM.addPass( \
1604 createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
1605 CREATE_PASS(Params.get()), false, false))); \
1606 return Error::success(); \
1607 }
1608#include "PassRegistry.def"
1609
1610 for (auto &C : ModulePipelineParsingCallbacks)
1611 if (C(Name, MPM, InnerPipeline))
1612 return Error::success();
1613 return make_error<StringError>(
1614 formatv("unknown module pass '{0}'", Name).str(),
1616}
1617
1618Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
1619 const PipelineElement &E) {
1620 auto &Name = E.Name;
1621 auto &InnerPipeline = E.InnerPipeline;
1622
1623 // First handle complex passes like the pass managers which carry pipelines.
1624 if (!InnerPipeline.empty()) {
1625 if (Name == "cgscc") {
1626 CGSCCPassManager NestedCGPM;
1627 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1628 return Err;
1629 // Add the nested pass manager with the appropriate adaptor.
1630 CGPM.addPass(std::move(NestedCGPM));
1631 return Error::success();
1632 }
1633 if (auto Params = parseFunctionPipelineName(Name)) {
1635 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
1636 return Err;
1637 // Add the nested pass manager with the appropriate adaptor.
1639 std::move(FPM), Params->first, Params->second));
1640 return Error::success();
1641 }
1642 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
1643 CGSCCPassManager NestedCGPM;
1644 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1645 return Err;
1646 CGPM.addPass(
1647 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
1648 return Error::success();
1649 }
1650
1651 for (auto &C : CGSCCPipelineParsingCallbacks)
1652 if (C(Name, CGPM, InnerPipeline))
1653 return Error::success();
1654
1655 // Normal passes can't have pipelines.
1656 return make_error<StringError>(
1657 formatv("invalid use of '{0}' pass as cgscc pipeline", Name).str(),
1659 }
1660
1661// Now expand the basic registered passes from the .inc file.
1662#define CGSCC_PASS(NAME, CREATE_PASS) \
1663 if (Name == NAME) { \
1664 CGPM.addPass(CREATE_PASS); \
1665 return Error::success(); \
1666 }
1667#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1668 if (checkParametrizedPassName(Name, NAME)) { \
1669 auto Params = parsePassParameters(PARSER, Name, NAME); \
1670 if (!Params) \
1671 return Params.takeError(); \
1672 CGPM.addPass(CREATE_PASS(Params.get())); \
1673 return Error::success(); \
1674 }
1675#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1676 if (Name == "require<" NAME ">") { \
1677 CGPM.addPass(RequireAnalysisPass< \
1678 std::remove_reference_t<decltype(CREATE_PASS)>, \
1679 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
1680 CGSCCUpdateResult &>()); \
1681 return Error::success(); \
1682 } \
1683 if (Name == "invalidate<" NAME ">") { \
1684 CGPM.addPass(InvalidateAnalysisPass< \
1685 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1686 return Error::success(); \
1687 }
1688#define FUNCTION_PASS(NAME, CREATE_PASS) \
1689 if (Name == NAME) { \
1690 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
1691 return Error::success(); \
1692 }
1693#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1694 if (checkParametrizedPassName(Name, NAME)) { \
1695 auto Params = parsePassParameters(PARSER, Name, NAME); \
1696 if (!Params) \
1697 return Params.takeError(); \
1698 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
1699 return Error::success(); \
1700 }
1701#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1702 if (Name == NAME) { \
1703 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
1704 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1705 return Error::success(); \
1706 }
1707#define LOOP_PASS(NAME, CREATE_PASS) \
1708 if (Name == NAME) { \
1709 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
1710 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1711 return Error::success(); \
1712 }
1713#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1714 if (checkParametrizedPassName(Name, NAME)) { \
1715 auto Params = parsePassParameters(PARSER, Name, NAME); \
1716 if (!Params) \
1717 return Params.takeError(); \
1718 CGPM.addPass( \
1719 createCGSCCToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
1720 CREATE_PASS(Params.get()), false, false))); \
1721 return Error::success(); \
1722 }
1723#include "PassRegistry.def"
1724
1725 for (auto &C : CGSCCPipelineParsingCallbacks)
1726 if (C(Name, CGPM, InnerPipeline))
1727 return Error::success();
1728 return make_error<StringError>(
1729 formatv("unknown cgscc pass '{0}'", Name).str(),
1731}
1732
1733Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
1734 const PipelineElement &E) {
1735 auto &Name = E.Name;
1736 auto &InnerPipeline = E.InnerPipeline;
1737
1738 // First handle complex passes like the pass managers which carry pipelines.
1739 if (!InnerPipeline.empty()) {
1740 if (Name == "function") {
1741 FunctionPassManager NestedFPM;
1742 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
1743 return Err;
1744 // Add the nested pass manager with the appropriate adaptor.
1745 FPM.addPass(std::move(NestedFPM));
1746 return Error::success();
1747 }
1748 if (Name == "loop" || Name == "loop-mssa") {
1749 LoopPassManager LPM;
1750 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
1751 return Err;
1752 // Add the nested pass manager with the appropriate adaptor.
1753 bool UseMemorySSA = (Name == "loop-mssa");
1754 bool UseBFI = llvm::any_of(InnerPipeline, [](auto Pipeline) {
1755 return Pipeline.Name.contains("simple-loop-unswitch");
1756 });
1757 bool UseBPI = llvm::any_of(InnerPipeline, [](auto Pipeline) {
1758 return Pipeline.Name == "loop-predication";
1759 });
1760 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA,
1761 UseBFI, UseBPI));
1762 return Error::success();
1763 }
1764 if (Name == "machine-function") {
1766 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
1767 return Err;
1769 return Error::success();
1770 }
1771
1772 for (auto &C : FunctionPipelineParsingCallbacks)
1773 if (C(Name, FPM, InnerPipeline))
1774 return Error::success();
1775
1776 // Normal passes can't have pipelines.
1777 return make_error<StringError>(
1778 formatv("invalid use of '{0}' pass as function pipeline", Name).str(),
1780 }
1781
1782// Now expand the basic registered passes from the .inc file.
1783#define FUNCTION_PASS(NAME, CREATE_PASS) \
1784 if (Name == NAME) { \
1785 FPM.addPass(CREATE_PASS); \
1786 return Error::success(); \
1787 }
1788#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1789 if (checkParametrizedPassName(Name, NAME)) { \
1790 auto Params = parsePassParameters(PARSER, Name, NAME); \
1791 if (!Params) \
1792 return Params.takeError(); \
1793 FPM.addPass(CREATE_PASS(Params.get())); \
1794 return Error::success(); \
1795 }
1796#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1797 if (Name == "require<" NAME ">") { \
1798 FPM.addPass( \
1799 RequireAnalysisPass< \
1800 std::remove_reference_t<decltype(CREATE_PASS)>, Function>()); \
1801 return Error::success(); \
1802 } \
1803 if (Name == "invalidate<" NAME ">") { \
1804 FPM.addPass(InvalidateAnalysisPass< \
1805 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1806 return Error::success(); \
1807 }
1808// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
1809// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
1810// "guard-widening");
1811// The risk is that it may become obsolete if we're not careful.
1812#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1813 if (Name == NAME) { \
1814 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
1815 return Error::success(); \
1816 }
1817#define LOOP_PASS(NAME, CREATE_PASS) \
1818 if (Name == NAME) { \
1819 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
1820 return Error::success(); \
1821 }
1822#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1823 if (checkParametrizedPassName(Name, NAME)) { \
1824 auto Params = parsePassParameters(PARSER, Name, NAME); \
1825 if (!Params) \
1826 return Params.takeError(); \
1827 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), \
1828 false, false)); \
1829 return Error::success(); \
1830 }
1831#include "PassRegistry.def"
1832
1833 for (auto &C : FunctionPipelineParsingCallbacks)
1834 if (C(Name, FPM, InnerPipeline))
1835 return Error::success();
1836 return make_error<StringError>(
1837 formatv("unknown function pass '{0}'", Name).str(),
1839}
1840
1841Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
1842 const PipelineElement &E) {
1843 StringRef Name = E.Name;
1844 auto &InnerPipeline = E.InnerPipeline;
1845
1846 // First handle complex passes like the pass managers which carry pipelines.
1847 if (!InnerPipeline.empty()) {
1848 if (Name == "loop") {
1849 LoopPassManager NestedLPM;
1850 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
1851 return Err;
1852 // Add the nested pass manager with the appropriate adaptor.
1853 LPM.addPass(std::move(NestedLPM));
1854 return Error::success();
1855 }
1856
1857 for (auto &C : LoopPipelineParsingCallbacks)
1858 if (C(Name, LPM, InnerPipeline))
1859 return Error::success();
1860
1861 // Normal passes can't have pipelines.
1862 return make_error<StringError>(
1863 formatv("invalid use of '{0}' pass as loop pipeline", Name).str(),
1865 }
1866
1867// Now expand the basic registered passes from the .inc file.
1868#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1869 if (Name == NAME) { \
1870 LPM.addPass(CREATE_PASS); \
1871 return Error::success(); \
1872 }
1873#define LOOP_PASS(NAME, CREATE_PASS) \
1874 if (Name == NAME) { \
1875 LPM.addPass(CREATE_PASS); \
1876 return Error::success(); \
1877 }
1878#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1879 if (checkParametrizedPassName(Name, NAME)) { \
1880 auto Params = parsePassParameters(PARSER, Name, NAME); \
1881 if (!Params) \
1882 return Params.takeError(); \
1883 LPM.addPass(CREATE_PASS(Params.get())); \
1884 return Error::success(); \
1885 }
1886#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1887 if (Name == "require<" NAME ">") { \
1888 LPM.addPass(RequireAnalysisPass< \
1889 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
1890 LoopAnalysisManager, LoopStandardAnalysisResults &, \
1891 LPMUpdater &>()); \
1892 return Error::success(); \
1893 } \
1894 if (Name == "invalidate<" NAME ">") { \
1895 LPM.addPass(InvalidateAnalysisPass< \
1896 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1897 return Error::success(); \
1898 }
1899#include "PassRegistry.def"
1900
1901 for (auto &C : LoopPipelineParsingCallbacks)
1902 if (C(Name, LPM, InnerPipeline))
1903 return Error::success();
1904 return make_error<StringError>(formatv("unknown loop pass '{0}'", Name).str(),
1906}
1907
1908Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
1909 const PipelineElement &E) {
1910 StringRef Name = E.Name;
1911 if (!E.InnerPipeline.empty())
1912 return make_error<StringError>("invalid pipeline",
1914
1915#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
1916 if (Name == NAME) { \
1917 MFPM.addPass(CREATE_PASS); \
1918 return Error::success(); \
1919 }
1920#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1921 if (Name == NAME) { \
1922 MFPM.addPass(CREATE_PASS); \
1923 return Error::success(); \
1924 }
1925#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1926 PARAMS) \
1927 if (checkParametrizedPassName(Name, NAME)) { \
1928 auto Params = parsePassParameters(PARSER, Name, NAME); \
1929 if (!Params) \
1930 return Params.takeError(); \
1931 MFPM.addPass(CREATE_PASS(Params.get())); \
1932 return Error::success(); \
1933 }
1934#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1935 if (Name == "require<" NAME ">") { \
1936 MFPM.addPass( \
1937 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
1938 MachineFunction>()); \
1939 return Error::success(); \
1940 } \
1941 if (Name == "invalidate<" NAME ">") { \
1942 MFPM.addPass(InvalidateAnalysisPass< \
1943 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1944 return Error::success(); \
1945 }
1946#include "llvm/Passes/MachinePassRegistry.def"
1947
1948 for (auto &C : MachineFunctionPipelineParsingCallbacks)
1949 if (C(Name, MFPM, E.InnerPipeline))
1950 return Error::success();
1951 return make_error<StringError>(
1952 formatv("unknown machine pass '{0}'", Name).str(),
1954}
1955
1956bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
1957#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1958 if (Name == NAME) { \
1959 AA.registerModuleAnalysis< \
1960 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
1961 return true; \
1962 }
1963#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1964 if (Name == NAME) { \
1965 AA.registerFunctionAnalysis< \
1966 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
1967 return true; \
1968 }
1969#include "PassRegistry.def"
1970
1971 for (auto &C : AAParsingCallbacks)
1972 if (C(Name, AA))
1973 return true;
1974 return false;
1975}
1976
1977Error PassBuilder::parseMachinePassPipeline(
1979 for (const auto &Element : Pipeline) {
1980 if (auto Err = parseMachinePass(MFPM, Element))
1981 return Err;
1982 }
1983 return Error::success();
1984}
1985
1986Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
1987 ArrayRef<PipelineElement> Pipeline) {
1988 for (const auto &Element : Pipeline) {
1989 if (auto Err = parseLoopPass(LPM, Element))
1990 return Err;
1991 }
1992 return Error::success();
1993}
1994
1995Error PassBuilder::parseFunctionPassPipeline(
1997 for (const auto &Element : Pipeline) {
1998 if (auto Err = parseFunctionPass(FPM, Element))
1999 return Err;
2000 }
2001 return Error::success();
2002}
2003
2004Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2005 ArrayRef<PipelineElement> Pipeline) {
2006 for (const auto &Element : Pipeline) {
2007 if (auto Err = parseCGSCCPass(CGPM, Element))
2008 return Err;
2009 }
2010 return Error::success();
2011}
2012
2025 if (MFAM) {
2027 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2029 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2030 MFAM->registerPass(
2032 MFAM->registerPass(
2034 }
2035}
2036
2037Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2038 ArrayRef<PipelineElement> Pipeline) {
2039 for (const auto &Element : Pipeline) {
2040 if (auto Err = parseModulePass(MPM, Element))
2041 return Err;
2042 }
2043 return Error::success();
2044}
2045
2046// Primary pass pipeline description parsing routine for a \c ModulePassManager
2047// FIXME: Should this routine accept a TargetMachine or require the caller to
2048// pre-populate the analysis managers with target-specific stuff?
2050 StringRef PipelineText) {
2051 auto Pipeline = parsePipelineText(PipelineText);
2052 if (!Pipeline || Pipeline->empty())
2053 return make_error<StringError>(
2054 formatv("invalid pipeline '{0}'", PipelineText).str(),
2056
2057 // If the first name isn't at the module layer, wrap the pipeline up
2058 // automatically.
2059 StringRef FirstName = Pipeline->front().Name;
2060
2061 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2062 bool UseMemorySSA;
2063 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2064 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2065 } else if (isFunctionPassName(FirstName,
2066 FunctionPipelineParsingCallbacks)) {
2067 Pipeline = {{"function", std::move(*Pipeline)}};
2068 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2069 UseMemorySSA)) {
2070 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2071 std::move(*Pipeline)}}}};
2072 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2073 UseMemorySSA)) {
2074 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2075 std::move(*Pipeline)}}}};
2076 } else if (isMachineFunctionPassName(
2077 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2078 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2079 } else {
2080 for (auto &C : TopLevelPipelineParsingCallbacks)
2081 if (C(MPM, *Pipeline))
2082 return Error::success();
2083
2084 // Unknown pass or pipeline name!
2085 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2086 return make_error<StringError>(
2087 formatv("unknown {0} name '{1}'",
2088 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2089 .str(),
2091 }
2092 }
2093
2094 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2095 return Err;
2096 return Error::success();
2097}
2098
2099// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2101 StringRef PipelineText) {
2102 auto Pipeline = parsePipelineText(PipelineText);
2103 if (!Pipeline || Pipeline->empty())
2104 return make_error<StringError>(
2105 formatv("invalid pipeline '{0}'", PipelineText).str(),
2107
2108 StringRef FirstName = Pipeline->front().Name;
2109 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2110 return make_error<StringError>(
2111 formatv("unknown cgscc pass '{0}' in pipeline '{1}'", FirstName,
2112 PipelineText)
2113 .str(),
2115
2116 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2117 return Err;
2118 return Error::success();
2119}
2120
2121// Primary pass pipeline description parsing routine for a \c
2122// FunctionPassManager
2124 StringRef PipelineText) {
2125 auto Pipeline = parsePipelineText(PipelineText);
2126 if (!Pipeline || Pipeline->empty())
2127 return make_error<StringError>(
2128 formatv("invalid pipeline '{0}'", PipelineText).str(),
2130
2131 StringRef FirstName = Pipeline->front().Name;
2132 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2133 return make_error<StringError>(
2134 formatv("unknown function pass '{0}' in pipeline '{1}'", FirstName,
2135 PipelineText)
2136 .str(),
2138
2139 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2140 return Err;
2141 return Error::success();
2142}
2143
2144// Primary pass pipeline description parsing routine for a \c LoopPassManager
2146 StringRef PipelineText) {
2147 auto Pipeline = parsePipelineText(PipelineText);
2148 if (!Pipeline || Pipeline->empty())
2149 return make_error<StringError>(
2150 formatv("invalid pipeline '{0}'", PipelineText).str(),
2152
2153 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2154 return Err;
2155
2156 return Error::success();
2157}
2158
2160 StringRef PipelineText) {
2161 auto Pipeline = parsePipelineText(PipelineText);
2162 if (!Pipeline || Pipeline->empty())
2163 return make_error<StringError>(
2164 formatv("invalid machine pass pipeline '{0}'", PipelineText).str(),
2166
2167 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2168 return Err;
2169
2170 return Error::success();
2171}
2172
2174 // If the pipeline just consists of the word 'default' just replace the AA
2175 // manager with our default one.
2176 if (PipelineText == "default") {
2178 return Error::success();
2179 }
2180
2181 while (!PipelineText.empty()) {
2183 std::tie(Name, PipelineText) = PipelineText.split(',');
2184 if (!parseAAPassName(AA, Name))
2185 return make_error<StringError>(
2186 formatv("unknown alias analysis name '{0}'", Name).str(),
2188 }
2189
2190 return Error::success();
2191}
2192
2193std::optional<RegClassFilterFunc>
2195 if (FilterName == "all")
2196 return nullptr;
2197 for (auto &C : RegClassFilterParsingCallbacks)
2198 if (auto F = C(FilterName))
2199 return F;
2200 return std::nullopt;
2201}
2202
2204 OS << " " << PassName << "\n";
2205}
2207 raw_ostream &OS) {
2208 OS << " " << PassName << "<" << Params << ">\n";
2209}
2210
2212 // TODO: print pass descriptions when they are available
2213
2214 OS << "Module passes:\n";
2215#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2216#include "PassRegistry.def"
2217
2218 OS << "Module passes with params:\n";
2219#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2220 printPassName(NAME, PARAMS, OS);
2221#include "PassRegistry.def"
2222
2223 OS << "Module analyses:\n";
2224#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2225#include "PassRegistry.def"
2226
2227 OS << "Module alias analyses:\n";
2228#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2229#include "PassRegistry.def"
2230
2231 OS << "CGSCC passes:\n";
2232#define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2233#include "PassRegistry.def"
2234
2235 OS << "CGSCC passes with params:\n";
2236#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2237 printPassName(NAME, PARAMS, OS);
2238#include "PassRegistry.def"
2239
2240 OS << "CGSCC analyses:\n";
2241#define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2242#include "PassRegistry.def"
2243
2244 OS << "Function passes:\n";
2245#define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2246#include "PassRegistry.def"
2247
2248 OS << "Function passes with params:\n";
2249#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2250 printPassName(NAME, PARAMS, OS);
2251#include "PassRegistry.def"
2252
2253 OS << "Function analyses:\n";
2254#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2255#include "PassRegistry.def"
2256
2257 OS << "Function alias analyses:\n";
2258#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2259#include "PassRegistry.def"
2260
2261 OS << "LoopNest passes:\n";
2262#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2263#include "PassRegistry.def"
2264
2265 OS << "Loop passes:\n";
2266#define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2267#include "PassRegistry.def"
2268
2269 OS << "Loop passes with params:\n";
2270#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2271 printPassName(NAME, PARAMS, OS);
2272#include "PassRegistry.def"
2273
2274 OS << "Loop analyses:\n";
2275#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2276#include "PassRegistry.def"
2277
2278 OS << "Machine module passes (WIP):\n";
2279#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2280#include "llvm/Passes/MachinePassRegistry.def"
2281
2282 OS << "Machine function passes (WIP):\n";
2283#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2284#include "llvm/Passes/MachinePassRegistry.def"
2285
2286 OS << "Machine function analyses (WIP):\n";
2287#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2288#include "llvm/Passes/MachinePassRegistry.def"
2289}
2290
2292 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
2293 &C) {
2294 TopLevelPipelineParsingCallbacks.push_back(C);
2295}
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.
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.
std::optional< RegClassFilterFunc > parseRegAllocFilter(StringRef RegClassFilterName)
Parse RegClassFilterName to get RegClassFilterFunc.
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
RegClassFilterFunc Filter
Definition: RegAllocFast.h:18