diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
commit | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch) | |
tree | 012bb94d777798f1f56ac1cec429509766d05181 /contrib/libs/llvm12/include/llvm/Passes | |
parent | 6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff) | |
download | ydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/llvm12/include/llvm/Passes')
-rw-r--r-- | contrib/libs/llvm12/include/llvm/Passes/PassBuilder.h | 198 | ||||
-rw-r--r-- | contrib/libs/llvm12/include/llvm/Passes/StandardInstrumentations.h | 458 |
2 files changed, 328 insertions, 328 deletions
diff --git a/contrib/libs/llvm12/include/llvm/Passes/PassBuilder.h b/contrib/libs/llvm12/include/llvm/Passes/PassBuilder.h index a32a4f7cb9..5a72257513 100644 --- a/contrib/libs/llvm12/include/llvm/Passes/PassBuilder.h +++ b/contrib/libs/llvm12/include/llvm/Passes/PassBuilder.h @@ -43,15 +43,15 @@ struct PGOOptions { enum CSPGOAction { NoCSAction, CSIRInstr, CSIRUse }; PGOOptions(std::string ProfileFile = "", std::string CSProfileGenFile = "", std::string ProfileRemappingFile = "", PGOAction Action = NoAction, - CSPGOAction CSAction = NoCSAction, - bool DebugInfoForProfiling = false, - bool PseudoProbeForProfiling = false) + CSPGOAction CSAction = NoCSAction, + bool DebugInfoForProfiling = false, + bool PseudoProbeForProfiling = false) : ProfileFile(ProfileFile), CSProfileGenFile(CSProfileGenFile), ProfileRemappingFile(ProfileRemappingFile), Action(Action), - CSAction(CSAction), DebugInfoForProfiling(DebugInfoForProfiling || - (Action == SampleUse && - !PseudoProbeForProfiling)), - PseudoProbeForProfiling(PseudoProbeForProfiling) { + CSAction(CSAction), DebugInfoForProfiling(DebugInfoForProfiling || + (Action == SampleUse && + !PseudoProbeForProfiling)), + PseudoProbeForProfiling(PseudoProbeForProfiling) { // Note, we do allow ProfileFile.empty() for Action=IRUse LTO can // callback with IRUse action without ProfileFile. @@ -66,26 +66,26 @@ struct PGOOptions { // a profile. assert(this->CSAction != CSIRUse || this->Action == IRUse); - // If neither Action nor CSAction, DebugInfoForProfiling or - // PseudoProbeForProfiling needs to be true. + // If neither Action nor CSAction, DebugInfoForProfiling or + // PseudoProbeForProfiling needs to be true. assert(this->Action != NoAction || this->CSAction != NoCSAction || - this->DebugInfoForProfiling || this->PseudoProbeForProfiling); - - // Pseudo probe emission does not work with -fdebug-info-for-profiling since - // they both use the discriminator field of debug lines but for different - // purposes. - if (this->DebugInfoForProfiling && this->PseudoProbeForProfiling) { - report_fatal_error( - "Pseudo probes cannot be used with -debug-info-for-profiling", false); - } + this->DebugInfoForProfiling || this->PseudoProbeForProfiling); + + // Pseudo probe emission does not work with -fdebug-info-for-profiling since + // they both use the discriminator field of debug lines but for different + // purposes. + if (this->DebugInfoForProfiling && this->PseudoProbeForProfiling) { + report_fatal_error( + "Pseudo probes cannot be used with -debug-info-for-profiling", false); + } } std::string ProfileFile; std::string CSProfileGenFile; std::string ProfileRemappingFile; PGOAction Action; CSPGOAction CSAction; - bool DebugInfoForProfiling; - bool PseudoProbeForProfiling; + bool DebugInfoForProfiling; + bool PseudoProbeForProfiling; }; /// Tunable parameters for passes in the default pipelines. @@ -130,13 +130,13 @@ public: /// Tuning option to enable/disable call graph profile. Its default value is /// that of the flag: `-enable-npm-call-graph-profile`. bool CallGraphProfile; - - /// Tuning option to enable/disable function merging. Its default value is - /// false. - bool MergeFunctions; - - /// Uniquefy function linkage name. Its default value is false. - bool UniqueLinkageNames; + + /// Tuning option to enable/disable function merging. Its default value is + /// false. + bool MergeFunctions; + + /// Uniquefy function linkage name. Its default value is false. + bool UniqueLinkageNames; }; /// This class provides access to building LLVM's passes. @@ -146,7 +146,7 @@ public: /// of the built-in passes, and those may reference these members during /// construction. class PassBuilder { - bool DebugLogging; + bool DebugLogging; TargetMachine *TM; PipelineTuningOptions PTO; Optional<PGOOptions> PGOOpt; @@ -276,10 +276,10 @@ public: unsigned getSizeLevel() const { return SizeLevel; } }; - explicit PassBuilder(bool DebugLogging = false, TargetMachine *TM = nullptr, + explicit PassBuilder(bool DebugLogging = false, TargetMachine *TM = nullptr, PipelineTuningOptions PTO = PipelineTuningOptions(), Optional<PGOOptions> PGOOpt = None, - PassInstrumentationCallbacks *PIC = nullptr); + PassInstrumentationCallbacks *PIC = nullptr); /// Cross register the analysis managers through their proxies. /// @@ -337,7 +337,7 @@ public: /// \p Phase indicates the current ThinLTO phase. FunctionPassManager buildFunctionSimplificationPipeline(OptimizationLevel Level, - ThinOrFullLTOPhase Phase); + ThinOrFullLTOPhase Phase); /// Construct the core LLVM module canonicalization and simplification /// pipeline. @@ -354,13 +354,13 @@ public: /// build them. /// /// \p Phase indicates the current ThinLTO phase. - ModulePassManager buildModuleSimplificationPipeline(OptimizationLevel Level, - ThinOrFullLTOPhase Phase); + ModulePassManager buildModuleSimplificationPipeline(OptimizationLevel Level, + ThinOrFullLTOPhase Phase); /// Construct the module pipeline that performs inlining as well as /// the inlining-driven cleanups. ModuleInlinerWrapperPass buildInlinerPipeline(OptimizationLevel Level, - ThinOrFullLTOPhase Phase); + ThinOrFullLTOPhase Phase); /// Construct the core LLVM module optimization pipeline. /// @@ -404,7 +404,7 @@ public: /// only intended for use when attempting to optimize code. If frontends /// require some transformations for semantic reasons, they should explicitly /// build them. - ModulePassManager buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level); + ModulePassManager buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level); /// Build an ThinLTO default optimization pipeline to a pass manager. /// @@ -418,7 +418,7 @@ public: /// require some transformations for semantic reasons, they should explicitly /// build them. ModulePassManager - buildThinLTODefaultPipeline(OptimizationLevel Level, + buildThinLTODefaultPipeline(OptimizationLevel Level, const ModuleSummaryIndex *ImportSummary); /// Build a pre-link, LTO-targeting default optimization pipeline to a pass @@ -433,7 +433,7 @@ public: /// only intended for use when attempting to optimize code. If frontends /// require some transformations for semantic reasons, they should explicitly /// build them. - ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level); + ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level); /// Build an LTO default optimization pipeline to a pass manager. /// @@ -449,17 +449,17 @@ public: ModulePassManager buildLTODefaultPipeline(OptimizationLevel Level, ModuleSummaryIndex *ExportSummary); - /// Build an O0 pipeline with the minimal semantically required passes. - /// - /// This should only be used for non-LTO and LTO pre-link pipelines. - ModulePassManager buildO0DefaultPipeline(OptimizationLevel Level, - bool LTOPreLink = false); - + /// Build an O0 pipeline with the minimal semantically required passes. + /// + /// This should only be used for non-LTO and LTO pre-link pipelines. + ModulePassManager buildO0DefaultPipeline(OptimizationLevel Level, + bool LTOPreLink = false); + /// Build the default `AAManager` with the default alias analysis pipeline /// registered. - /// - /// This also adds target-specific alias analyses registered via - /// TargetMachine::registerDefaultAliasAnalyses(). + /// + /// This also adds target-specific alias analyses registered via + /// TargetMachine::registerDefaultAliasAnalyses(). AAManager buildDefaultAAPipeline(); /// Parse a textual pass pipeline description into a \c @@ -487,22 +487,22 @@ public: /// module(function(loop(lpass1,lpass2,lpass3))) /// /// This shortcut is especially useful for debugging and testing small pass - /// combinations. - /// - /// The sequence of passes aren't necessarily the exact same kind of pass. - /// You can mix different levels implicitly if adaptor passes are defined to - /// make them work. For example, - /// - /// mpass1,fpass1,fpass2,mpass2,lpass1 - /// - /// This pipeline uses only one pass manager: the top-level module manager. - /// fpass1,fpass2 and lpass1 are added into the the top-level module manager - /// using only adaptor passes. No nested function/loop pass managers are - /// added. The purpose is to allow easy pass testing when the user - /// specifically want the pass to run under a adaptor directly. This is - /// preferred when a pipeline is largely of one type, but one or just a few - /// passes are of different types(See PassBuilder.cpp for examples). - Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText); + /// combinations. + /// + /// The sequence of passes aren't necessarily the exact same kind of pass. + /// You can mix different levels implicitly if adaptor passes are defined to + /// make them work. For example, + /// + /// mpass1,fpass1,fpass2,mpass2,lpass1 + /// + /// This pipeline uses only one pass manager: the top-level module manager. + /// fpass1,fpass2 and lpass1 are added into the the top-level module manager + /// using only adaptor passes. No nested function/loop pass managers are + /// added. The purpose is to allow easy pass testing when the user + /// specifically want the pass to run under a adaptor directly. This is + /// preferred when a pipeline is largely of one type, but one or just a few + /// passes are of different types(See PassBuilder.cpp for examples). + Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText); /// {{@ Parse a textual pass pipeline description into a specific PassManager /// @@ -511,9 +511,9 @@ public: /// this is the valid pipeline text: /// /// function(lpass) - Error parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText); - Error parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText); - Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText); + Error parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText); + Error parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText); + Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText); /// @}} /// Parse a textual alias analysis pipeline into the provided AA manager. @@ -612,23 +612,23 @@ public: /// pipeline. This does not apply to 'backend' compiles (LTO and ThinLTO /// link-time pipelines). void registerPipelineStartEPCallback( - const std::function<void(ModulePassManager &, OptimizationLevel)> &C) { + const std::function<void(ModulePassManager &, OptimizationLevel)> &C) { PipelineStartEPCallbacks.push_back(C); } - /// Register a callback for a default optimizer pipeline extension point. - /// - /// This extension point allows adding optimization right after passes that do - /// basic simplification of the input IR. - void registerPipelineEarlySimplificationEPCallback( - const std::function<void(ModulePassManager &, OptimizationLevel)> &C) { - PipelineEarlySimplificationEPCallbacks.push_back(C); - } - + /// Register a callback for a default optimizer pipeline extension point. + /// + /// This extension point allows adding optimization right after passes that do + /// basic simplification of the input IR. + void registerPipelineEarlySimplificationEPCallback( + const std::function<void(ModulePassManager &, OptimizationLevel)> &C) { + PipelineEarlySimplificationEPCallbacks.push_back(C); + } + /// Register a callback for a default optimizer pipeline extension point /// /// This extension point allows adding optimizations at the very end of the - /// function optimization pipeline. + /// function optimization pipeline. void registerOptimizerLastEPCallback( const std::function<void(ModulePassManager &, OptimizationLevel)> &C) { OptimizerLastEPCallbacks.push_back(C); @@ -695,11 +695,11 @@ public: /// PassManagers and populate the passed ModulePassManager. void registerParseTopLevelPipelineCallback( const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>, - bool DebugLogging)> &C); + bool DebugLogging)> &C); /// Add PGOInstrumenation passes for O0 only. - void addPGOInstrPassesForO0(ModulePassManager &MPM, bool RunProfileGen, - bool IsCS, std::string ProfileFile, + void addPGOInstrPassesForO0(ModulePassManager &MPM, bool RunProfileGen, + bool IsCS, std::string ProfileFile, std::string ProfileRemappingFile); /// Returns PIC. External libraries can use this to register pass @@ -710,32 +710,32 @@ public: private: // O1 pass pipeline - FunctionPassManager - buildO1FunctionSimplificationPipeline(OptimizationLevel Level, - ThinOrFullLTOPhase Phase); - - void addRequiredLTOPreLinkPasses(ModulePassManager &MPM); + FunctionPassManager + buildO1FunctionSimplificationPipeline(OptimizationLevel Level, + ThinOrFullLTOPhase Phase); + void addRequiredLTOPreLinkPasses(ModulePassManager &MPM); + static Optional<std::vector<PipelineElement>> parsePipelineText(StringRef Text); - Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E); - Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E); - Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E); - Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E); + Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E); + Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E); + Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E); + Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E); bool parseAAPassName(AAManager &AA, StringRef Name); Error parseLoopPassPipeline(LoopPassManager &LPM, - ArrayRef<PipelineElement> Pipeline); + ArrayRef<PipelineElement> Pipeline); Error parseFunctionPassPipeline(FunctionPassManager &FPM, - ArrayRef<PipelineElement> Pipeline); + ArrayRef<PipelineElement> Pipeline); Error parseCGSCCPassPipeline(CGSCCPassManager &CGPM, - ArrayRef<PipelineElement> Pipeline); + ArrayRef<PipelineElement> Pipeline); Error parseModulePassPipeline(ModulePassManager &MPM, - ArrayRef<PipelineElement> Pipeline); + ArrayRef<PipelineElement> Pipeline); - void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level, - bool RunProfileGen, bool IsCS, std::string ProfileFile, + void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level, + bool RunProfileGen, bool IsCS, std::string ProfileFile, std::string ProfileRemappingFile); void invokePeepholeEPCallbacks(FunctionPassManager &, OptimizationLevel); @@ -755,11 +755,11 @@ private: SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2> OptimizerLastEPCallbacks; // Module callbacks - SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2> + SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2> PipelineStartEPCallbacks; - SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2> - PipelineEarlySimplificationEPCallbacks; - + SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2> + PipelineEarlySimplificationEPCallbacks; + SmallVector<std::function<void(ModuleAnalysisManager &)>, 2> ModuleAnalysisRegistrationCallbacks; SmallVector<std::function<bool(StringRef, ModulePassManager &, @@ -767,7 +767,7 @@ private: 2> ModulePipelineParsingCallbacks; SmallVector<std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>, - bool DebugLogging)>, + bool DebugLogging)>, 2> TopLevelPipelineParsingCallbacks; // CGSCC callbacks diff --git a/contrib/libs/llvm12/include/llvm/Passes/StandardInstrumentations.h b/contrib/libs/llvm12/include/llvm/Passes/StandardInstrumentations.h index d66a0ec466..93df62b562 100644 --- a/contrib/libs/llvm12/include/llvm/Passes/StandardInstrumentations.h +++ b/contrib/libs/llvm12/include/llvm/Passes/StandardInstrumentations.h @@ -23,13 +23,13 @@ #define LLVM_PASSES_STANDARDINSTRUMENTATIONS_H #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/IR/BasicBlock.h" -#include "llvm/IR/OptBisect.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/OptBisect.h" #include "llvm/IR/PassTimingInfo.h" -#include "llvm/IR/ValueHandle.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Transforms/IPO/SampleProfileProbe.h" +#include "llvm/IR/ValueHandle.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Transforms/IPO/SampleProfileProbe.h" #include <string> #include <utility> @@ -37,8 +37,8 @@ namespace llvm { class Module; -class Function; -class PassInstrumentationCallbacks; +class Function; +class PassInstrumentationCallbacks; /// Instrumentation to print IR before/after passes. /// @@ -51,252 +51,252 @@ public: void registerCallbacks(PassInstrumentationCallbacks &PIC); private: - void printBeforePass(StringRef PassID, Any IR); + void printBeforePass(StringRef PassID, Any IR); void printAfterPass(StringRef PassID, Any IR); void printAfterPassInvalidated(StringRef PassID); - bool shouldPrintBeforePass(StringRef PassID); - bool shouldPrintAfterPass(StringRef PassID); - + bool shouldPrintBeforePass(StringRef PassID); + bool shouldPrintAfterPass(StringRef PassID); + using PrintModuleDesc = std::tuple<const Module *, std::string, StringRef>; void pushModuleDesc(StringRef PassID, Any IR); PrintModuleDesc popModuleDesc(StringRef PassID); - PassInstrumentationCallbacks *PIC; + PassInstrumentationCallbacks *PIC; /// Stack of Module description, enough to print the module after a given /// pass. SmallVector<PrintModuleDesc, 2> ModuleDescStack; bool StoreModuleDesc = false; }; -class OptNoneInstrumentation { -public: - OptNoneInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {} - void registerCallbacks(PassInstrumentationCallbacks &PIC); - -private: - bool DebugLogging; - bool shouldRun(StringRef PassID, Any IR); -}; - -class OptBisectInstrumentation { -public: - OptBisectInstrumentation() {} - void registerCallbacks(PassInstrumentationCallbacks &PIC); -}; - -// Debug logging for transformation and analysis passes. -class PrintPassInstrumentation { -public: - PrintPassInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {} - void registerCallbacks(PassInstrumentationCallbacks &PIC); - -private: - bool DebugLogging; -}; - -class PreservedCFGCheckerInstrumentation { -private: - // CFG is a map BB -> {(Succ, Multiplicity)}, where BB is a non-leaf basic - // block, {(Succ, Multiplicity)} set of all pairs of the block's successors - // and the multiplicity of the edge (BB->Succ). As the mapped sets are - // unordered the order of successors is not tracked by the CFG. In other words - // this allows basic block successors to be swapped by a pass without - // reporting a CFG change. CFG can be guarded by basic block tracking pointers - // in the Graph (BBGuard). That is if any of the block is deleted or RAUWed - // then the CFG is treated poisoned and no block pointer of the Graph is used. - struct CFG { - struct BBGuard final : public CallbackVH { - BBGuard(const BasicBlock *BB) : CallbackVH(BB) {} - void deleted() override { CallbackVH::deleted(); } - void allUsesReplacedWith(Value *) override { CallbackVH::deleted(); } - bool isPoisoned() const { return !getValPtr(); } - }; - - Optional<DenseMap<intptr_t, BBGuard>> BBGuards; - DenseMap<const BasicBlock *, DenseMap<const BasicBlock *, unsigned>> Graph; - - CFG(const Function *F, bool TrackBBLifetime = false); - - bool operator==(const CFG &G) const { - return !isPoisoned() && !G.isPoisoned() && Graph == G.Graph; - } - - bool isPoisoned() const { - if (BBGuards) - for (auto &BB : *BBGuards) { - if (BB.second.isPoisoned()) - return true; - } - return false; - } - - static void printDiff(raw_ostream &out, const CFG &Before, - const CFG &After); - }; - - SmallVector<std::pair<StringRef, Optional<CFG>>, 8> GraphStackBefore; - -public: - static cl::opt<bool> VerifyPreservedCFG; - void registerCallbacks(PassInstrumentationCallbacks &PIC); -}; - -// Base class for classes that report changes to the IR. -// It presents an interface for such classes and provides calls -// on various events as the new pass manager transforms the IR. -// It also provides filtering of information based on hidden options -// specifying which functions are interesting. -// Calls are made for the following events/queries: -// 1. The initial IR processed. -// 2. To get the representation of the IR (of type \p T). -// 3. When a pass does not change the IR. -// 4. When a pass changes the IR (given both before and after representations -// of type \p T). -// 5. When an IR is invalidated. -// 6. When a pass is run on an IR that is not interesting (based on options). -// 7. When a pass is ignored (pass manager or adapter pass). -// 8. To compare two IR representations (of type \p T). -template <typename IRUnitT> class ChangeReporter { -protected: - ChangeReporter(bool RunInVerboseMode) : VerboseMode(RunInVerboseMode) {} - -public: - virtual ~ChangeReporter(); - - // Determine if this pass/IR is interesting and if so, save the IR - // otherwise it is left on the stack without data. - void saveIRBeforePass(Any IR, StringRef PassID); - // Compare the IR from before the pass after the pass. - void handleIRAfterPass(Any IR, StringRef PassID); - // Handle the situation where a pass is invalidated. - void handleInvalidatedPass(StringRef PassID); - -protected: - // Register required callbacks. - void registerRequiredCallbacks(PassInstrumentationCallbacks &PIC); - - // Return true when this is a defined function for which printing - // of changes is desired. - bool isInterestingFunction(const Function &F); - - // Return true when this is a pass for which printing of changes is desired. - bool isInterestingPass(StringRef PassID); - - // Return true when this is a pass on IR for which printing - // of changes is desired. - bool isInteresting(Any IR, StringRef PassID); - - // Called on the first IR processed. - virtual void handleInitialIR(Any IR) = 0; - // Called before and after a pass to get the representation of the IR. - virtual void generateIRRepresentation(Any IR, StringRef PassID, - IRUnitT &Output) = 0; - // Called when the pass is not iteresting. - virtual void omitAfter(StringRef PassID, std::string &Name) = 0; - // Called when an interesting IR has changed. - virtual void handleAfter(StringRef PassID, std::string &Name, - const IRUnitT &Before, const IRUnitT &After, - Any) = 0; - // Called when an interesting pass is invalidated. - virtual void handleInvalidated(StringRef PassID) = 0; - // Called when the IR or pass is not interesting. - virtual void handleFiltered(StringRef PassID, std::string &Name) = 0; - // Called when an ignored pass is encountered. - virtual void handleIgnored(StringRef PassID, std::string &Name) = 0; - // Called to compare the before and after representations of the IR. - virtual bool same(const IRUnitT &Before, const IRUnitT &After) = 0; - - // Stack of IRs before passes. - std::vector<IRUnitT> BeforeStack; - // Is this the first IR seen? - bool InitialIR = true; - - // Run in verbose mode, printing everything? - const bool VerboseMode; -}; - -// An abstract template base class that handles printing banners and -// reporting when things have not changed or are filtered out. -template <typename IRUnitT> -class TextChangeReporter : public ChangeReporter<IRUnitT> { -protected: - TextChangeReporter(bool Verbose); - - // Print a module dump of the first IR that is changed. - void handleInitialIR(Any IR) override; - // Report that the IR was omitted because it did not change. - void omitAfter(StringRef PassID, std::string &Name) override; - // Report that the pass was invalidated. - void handleInvalidated(StringRef PassID) override; - // Report that the IR was filtered out. - void handleFiltered(StringRef PassID, std::string &Name) override; - // Report that the pass was ignored. - void handleIgnored(StringRef PassID, std::string &Name) override; - // Make substitutions in \p S suitable for reporting changes - // after the pass and then print it. - - raw_ostream &Out; -}; - -// A change printer based on the string representation of the IR as created -// by unwrapAndPrint. The string representation is stored in a std::string -// to preserve it as the IR changes in each pass. Note that the banner is -// included in this representation but it is massaged before reporting. -class IRChangedPrinter : public TextChangeReporter<std::string> { -public: - IRChangedPrinter(bool VerboseMode) - : TextChangeReporter<std::string>(VerboseMode) {} - ~IRChangedPrinter() override; - void registerCallbacks(PassInstrumentationCallbacks &PIC); - -protected: - // Called before and after a pass to get the representation of the IR. - void generateIRRepresentation(Any IR, StringRef PassID, - std::string &Output) override; - // Called when an interesting IR has changed. - void handleAfter(StringRef PassID, std::string &Name, - const std::string &Before, const std::string &After, - Any) override; - // Called to compare the before and after representations of the IR. - bool same(const std::string &Before, const std::string &After) override; -}; - -class VerifyInstrumentation { - bool DebugLogging; - -public: - VerifyInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {} - void registerCallbacks(PassInstrumentationCallbacks &PIC); -}; - +class OptNoneInstrumentation { +public: + OptNoneInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {} + void registerCallbacks(PassInstrumentationCallbacks &PIC); + +private: + bool DebugLogging; + bool shouldRun(StringRef PassID, Any IR); +}; + +class OptBisectInstrumentation { +public: + OptBisectInstrumentation() {} + void registerCallbacks(PassInstrumentationCallbacks &PIC); +}; + +// Debug logging for transformation and analysis passes. +class PrintPassInstrumentation { +public: + PrintPassInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {} + void registerCallbacks(PassInstrumentationCallbacks &PIC); + +private: + bool DebugLogging; +}; + +class PreservedCFGCheckerInstrumentation { +private: + // CFG is a map BB -> {(Succ, Multiplicity)}, where BB is a non-leaf basic + // block, {(Succ, Multiplicity)} set of all pairs of the block's successors + // and the multiplicity of the edge (BB->Succ). As the mapped sets are + // unordered the order of successors is not tracked by the CFG. In other words + // this allows basic block successors to be swapped by a pass without + // reporting a CFG change. CFG can be guarded by basic block tracking pointers + // in the Graph (BBGuard). That is if any of the block is deleted or RAUWed + // then the CFG is treated poisoned and no block pointer of the Graph is used. + struct CFG { + struct BBGuard final : public CallbackVH { + BBGuard(const BasicBlock *BB) : CallbackVH(BB) {} + void deleted() override { CallbackVH::deleted(); } + void allUsesReplacedWith(Value *) override { CallbackVH::deleted(); } + bool isPoisoned() const { return !getValPtr(); } + }; + + Optional<DenseMap<intptr_t, BBGuard>> BBGuards; + DenseMap<const BasicBlock *, DenseMap<const BasicBlock *, unsigned>> Graph; + + CFG(const Function *F, bool TrackBBLifetime = false); + + bool operator==(const CFG &G) const { + return !isPoisoned() && !G.isPoisoned() && Graph == G.Graph; + } + + bool isPoisoned() const { + if (BBGuards) + for (auto &BB : *BBGuards) { + if (BB.second.isPoisoned()) + return true; + } + return false; + } + + static void printDiff(raw_ostream &out, const CFG &Before, + const CFG &After); + }; + + SmallVector<std::pair<StringRef, Optional<CFG>>, 8> GraphStackBefore; + +public: + static cl::opt<bool> VerifyPreservedCFG; + void registerCallbacks(PassInstrumentationCallbacks &PIC); +}; + +// Base class for classes that report changes to the IR. +// It presents an interface for such classes and provides calls +// on various events as the new pass manager transforms the IR. +// It also provides filtering of information based on hidden options +// specifying which functions are interesting. +// Calls are made for the following events/queries: +// 1. The initial IR processed. +// 2. To get the representation of the IR (of type \p T). +// 3. When a pass does not change the IR. +// 4. When a pass changes the IR (given both before and after representations +// of type \p T). +// 5. When an IR is invalidated. +// 6. When a pass is run on an IR that is not interesting (based on options). +// 7. When a pass is ignored (pass manager or adapter pass). +// 8. To compare two IR representations (of type \p T). +template <typename IRUnitT> class ChangeReporter { +protected: + ChangeReporter(bool RunInVerboseMode) : VerboseMode(RunInVerboseMode) {} + +public: + virtual ~ChangeReporter(); + + // Determine if this pass/IR is interesting and if so, save the IR + // otherwise it is left on the stack without data. + void saveIRBeforePass(Any IR, StringRef PassID); + // Compare the IR from before the pass after the pass. + void handleIRAfterPass(Any IR, StringRef PassID); + // Handle the situation where a pass is invalidated. + void handleInvalidatedPass(StringRef PassID); + +protected: + // Register required callbacks. + void registerRequiredCallbacks(PassInstrumentationCallbacks &PIC); + + // Return true when this is a defined function for which printing + // of changes is desired. + bool isInterestingFunction(const Function &F); + + // Return true when this is a pass for which printing of changes is desired. + bool isInterestingPass(StringRef PassID); + + // Return true when this is a pass on IR for which printing + // of changes is desired. + bool isInteresting(Any IR, StringRef PassID); + + // Called on the first IR processed. + virtual void handleInitialIR(Any IR) = 0; + // Called before and after a pass to get the representation of the IR. + virtual void generateIRRepresentation(Any IR, StringRef PassID, + IRUnitT &Output) = 0; + // Called when the pass is not iteresting. + virtual void omitAfter(StringRef PassID, std::string &Name) = 0; + // Called when an interesting IR has changed. + virtual void handleAfter(StringRef PassID, std::string &Name, + const IRUnitT &Before, const IRUnitT &After, + Any) = 0; + // Called when an interesting pass is invalidated. + virtual void handleInvalidated(StringRef PassID) = 0; + // Called when the IR or pass is not interesting. + virtual void handleFiltered(StringRef PassID, std::string &Name) = 0; + // Called when an ignored pass is encountered. + virtual void handleIgnored(StringRef PassID, std::string &Name) = 0; + // Called to compare the before and after representations of the IR. + virtual bool same(const IRUnitT &Before, const IRUnitT &After) = 0; + + // Stack of IRs before passes. + std::vector<IRUnitT> BeforeStack; + // Is this the first IR seen? + bool InitialIR = true; + + // Run in verbose mode, printing everything? + const bool VerboseMode; +}; + +// An abstract template base class that handles printing banners and +// reporting when things have not changed or are filtered out. +template <typename IRUnitT> +class TextChangeReporter : public ChangeReporter<IRUnitT> { +protected: + TextChangeReporter(bool Verbose); + + // Print a module dump of the first IR that is changed. + void handleInitialIR(Any IR) override; + // Report that the IR was omitted because it did not change. + void omitAfter(StringRef PassID, std::string &Name) override; + // Report that the pass was invalidated. + void handleInvalidated(StringRef PassID) override; + // Report that the IR was filtered out. + void handleFiltered(StringRef PassID, std::string &Name) override; + // Report that the pass was ignored. + void handleIgnored(StringRef PassID, std::string &Name) override; + // Make substitutions in \p S suitable for reporting changes + // after the pass and then print it. + + raw_ostream &Out; +}; + +// A change printer based on the string representation of the IR as created +// by unwrapAndPrint. The string representation is stored in a std::string +// to preserve it as the IR changes in each pass. Note that the banner is +// included in this representation but it is massaged before reporting. +class IRChangedPrinter : public TextChangeReporter<std::string> { +public: + IRChangedPrinter(bool VerboseMode) + : TextChangeReporter<std::string>(VerboseMode) {} + ~IRChangedPrinter() override; + void registerCallbacks(PassInstrumentationCallbacks &PIC); + +protected: + // Called before and after a pass to get the representation of the IR. + void generateIRRepresentation(Any IR, StringRef PassID, + std::string &Output) override; + // Called when an interesting IR has changed. + void handleAfter(StringRef PassID, std::string &Name, + const std::string &Before, const std::string &After, + Any) override; + // Called to compare the before and after representations of the IR. + bool same(const std::string &Before, const std::string &After) override; +}; + +class VerifyInstrumentation { + bool DebugLogging; + +public: + VerifyInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {} + void registerCallbacks(PassInstrumentationCallbacks &PIC); +}; + /// This class provides an interface to register all the standard pass /// instrumentations and manages their state (if any). class StandardInstrumentations { PrintIRInstrumentation PrintIR; - PrintPassInstrumentation PrintPass; + PrintPassInstrumentation PrintPass; TimePassesHandler TimePasses; - OptNoneInstrumentation OptNone; - OptBisectInstrumentation OptBisect; - PreservedCFGCheckerInstrumentation PreservedCFGChecker; - IRChangedPrinter PrintChangedIR; - PseudoProbeVerifier PseudoProbeVerification; - VerifyInstrumentation Verify; - - bool VerifyEach; - + OptNoneInstrumentation OptNone; + OptBisectInstrumentation OptBisect; + PreservedCFGCheckerInstrumentation PreservedCFGChecker; + IRChangedPrinter PrintChangedIR; + PseudoProbeVerifier PseudoProbeVerification; + VerifyInstrumentation Verify; + + bool VerifyEach; + public: - StandardInstrumentations(bool DebugLogging, bool VerifyEach = false); + StandardInstrumentations(bool DebugLogging, bool VerifyEach = false); void registerCallbacks(PassInstrumentationCallbacks &PIC); TimePassesHandler &getTimePasses() { return TimePasses; } }; - -extern template class ChangeReporter<std::string>; -extern template class TextChangeReporter<std::string>; - + +extern template class ChangeReporter<std::string>; +extern template class TextChangeReporter<std::string>; + } // namespace llvm #endif |