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