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