|
|
|||
File indexing completed on 2026-05-10 08:44:07
0001 //===- LegacyPassManagers.h - Legacy Pass Infrastructure --------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This file declares the LLVM Pass Manager infrastructure. 0010 // 0011 //===----------------------------------------------------------------------===// 0012 0013 #ifndef LLVM_IR_LEGACYPASSMANAGERS_H 0014 #define LLVM_IR_LEGACYPASSMANAGERS_H 0015 0016 #include "llvm/ADT/DenseMap.h" 0017 #include "llvm/ADT/FoldingSet.h" 0018 #include "llvm/ADT/SmallPtrSet.h" 0019 #include "llvm/ADT/SmallVector.h" 0020 #include "llvm/Pass.h" 0021 #include <vector> 0022 0023 //===----------------------------------------------------------------------===// 0024 // Overview: 0025 // The Pass Manager Infrastructure manages passes. It's responsibilities are: 0026 // 0027 // o Manage optimization pass execution order 0028 // o Make required Analysis information available before pass P is run 0029 // o Release memory occupied by dead passes 0030 // o If Analysis information is dirtied by a pass then regenerate Analysis 0031 // information before it is consumed by another pass. 0032 // 0033 // Pass Manager Infrastructure uses multiple pass managers. They are 0034 // PassManager, FunctionPassManager, MPPassManager, FPPassManager, BBPassManager. 0035 // This class hierarchy uses multiple inheritance but pass managers do not 0036 // derive from another pass manager. 0037 // 0038 // PassManager and FunctionPassManager are two top-level pass manager that 0039 // represents the external interface of this entire pass manager infrastucture. 0040 // 0041 // Important classes : 0042 // 0043 // [o] class PMTopLevelManager; 0044 // 0045 // Two top level managers, PassManager and FunctionPassManager, derive from 0046 // PMTopLevelManager. PMTopLevelManager manages information used by top level 0047 // managers such as last user info. 0048 // 0049 // [o] class PMDataManager; 0050 // 0051 // PMDataManager manages information, e.g. list of available analysis info, 0052 // used by a pass manager to manage execution order of passes. It also provides 0053 // a place to implement common pass manager APIs. All pass managers derive from 0054 // PMDataManager. 0055 // 0056 // [o] class FunctionPassManager; 0057 // 0058 // This is a external interface used to manage FunctionPasses. This 0059 // interface relies on FunctionPassManagerImpl to do all the tasks. 0060 // 0061 // [o] class FunctionPassManagerImpl : public ModulePass, PMDataManager, 0062 // public PMTopLevelManager; 0063 // 0064 // FunctionPassManagerImpl is a top level manager. It manages FPPassManagers 0065 // 0066 // [o] class FPPassManager : public ModulePass, public PMDataManager; 0067 // 0068 // FPPassManager manages FunctionPasses and BBPassManagers 0069 // 0070 // [o] class MPPassManager : public Pass, public PMDataManager; 0071 // 0072 // MPPassManager manages ModulePasses and FPPassManagers 0073 // 0074 // [o] class PassManager; 0075 // 0076 // This is a external interface used by various tools to manages passes. It 0077 // relies on PassManagerImpl to do all the tasks. 0078 // 0079 // [o] class PassManagerImpl : public Pass, public PMDataManager, 0080 // public PMTopLevelManager 0081 // 0082 // PassManagerImpl is a top level pass manager responsible for managing 0083 // MPPassManagers. 0084 //===----------------------------------------------------------------------===// 0085 0086 #include "llvm/Support/PrettyStackTrace.h" 0087 0088 namespace llvm { 0089 template <typename T> class ArrayRef; 0090 class Module; 0091 class StringRef; 0092 class Value; 0093 class PMDataManager; 0094 0095 // enums for debugging strings 0096 enum PassDebuggingString { 0097 EXECUTION_MSG, // "Executing Pass '" + PassName 0098 MODIFICATION_MSG, // "Made Modification '" + PassName 0099 FREEING_MSG, // " Freeing Pass '" + PassName 0100 ON_FUNCTION_MSG, // "' on Function '" + FunctionName + "'...\n" 0101 ON_MODULE_MSG, // "' on Module '" + ModuleName + "'...\n" 0102 ON_REGION_MSG, // "' on Region '" + Msg + "'...\n'" 0103 ON_LOOP_MSG, // "' on Loop '" + Msg + "'...\n'" 0104 ON_CG_MSG // "' on Call Graph Nodes '" + Msg + "'...\n'" 0105 }; 0106 0107 /// PassManagerPrettyStackEntry - This is used to print informative information 0108 /// about what pass is running when/if a stack trace is generated. 0109 class PassManagerPrettyStackEntry : public PrettyStackTraceEntry { 0110 Pass *P; 0111 Value *V; 0112 Module *M; 0113 0114 public: 0115 explicit PassManagerPrettyStackEntry(Pass *p) 0116 : P(p), V(nullptr), M(nullptr) {} // When P is releaseMemory'd. 0117 PassManagerPrettyStackEntry(Pass *p, Value &v) 0118 : P(p), V(&v), M(nullptr) {} // When P is run on V 0119 PassManagerPrettyStackEntry(Pass *p, Module &m) 0120 : P(p), V(nullptr), M(&m) {} // When P is run on M 0121 0122 /// print - Emit information about this stack frame to OS. 0123 void print(raw_ostream &OS) const override; 0124 }; 0125 0126 //===----------------------------------------------------------------------===// 0127 // PMStack 0128 // 0129 /// PMStack - This class implements a stack data structure of PMDataManager 0130 /// pointers. 0131 /// 0132 /// Top level pass managers (see PassManager.cpp) maintain active Pass Managers 0133 /// using PMStack. Each Pass implements assignPassManager() to connect itself 0134 /// with appropriate manager. assignPassManager() walks PMStack to find 0135 /// suitable manager. 0136 class PMStack { 0137 public: 0138 typedef std::vector<PMDataManager *>::const_reverse_iterator iterator; 0139 iterator begin() const { return S.rbegin(); } 0140 iterator end() const { return S.rend(); } 0141 0142 void pop(); 0143 PMDataManager *top() const { return S.back(); } 0144 void push(PMDataManager *PM); 0145 bool empty() const { return S.empty(); } 0146 0147 void dump() const; 0148 0149 private: 0150 std::vector<PMDataManager *> S; 0151 }; 0152 0153 //===----------------------------------------------------------------------===// 0154 // PMTopLevelManager 0155 // 0156 /// PMTopLevelManager manages LastUser info and collects common APIs used by 0157 /// top level pass managers. 0158 class PMTopLevelManager { 0159 protected: 0160 explicit PMTopLevelManager(PMDataManager *PMDM); 0161 0162 unsigned getNumContainedManagers() const { 0163 return (unsigned)PassManagers.size(); 0164 } 0165 0166 void initializeAllAnalysisInfo(); 0167 0168 private: 0169 virtual PMDataManager *getAsPMDataManager() = 0; 0170 virtual PassManagerType getTopLevelPassManagerType() = 0; 0171 0172 public: 0173 /// Schedule pass P for execution. Make sure that passes required by 0174 /// P are run before P is run. Update analysis info maintained by 0175 /// the manager. Remove dead passes. This is a recursive function. 0176 void schedulePass(Pass *P); 0177 0178 /// Set pass P as the last user of the given analysis passes. 0179 void setLastUser(ArrayRef<Pass*> AnalysisPasses, Pass *P); 0180 0181 /// Collect passes whose last user is P 0182 void collectLastUses(SmallVectorImpl<Pass *> &LastUses, Pass *P); 0183 0184 /// Find the pass that implements Analysis AID. Search immutable 0185 /// passes and all pass managers. If desired pass is not found 0186 /// then return NULL. 0187 Pass *findAnalysisPass(AnalysisID AID); 0188 0189 /// Retrieve the PassInfo for an analysis. 0190 const PassInfo *findAnalysisPassInfo(AnalysisID AID) const; 0191 0192 /// Find analysis usage information for the pass P. 0193 AnalysisUsage *findAnalysisUsage(Pass *P); 0194 0195 virtual ~PMTopLevelManager(); 0196 0197 /// Add immutable pass and initialize it. 0198 void addImmutablePass(ImmutablePass *P); 0199 0200 inline SmallVectorImpl<ImmutablePass *>& getImmutablePasses() { 0201 return ImmutablePasses; 0202 } 0203 0204 void addPassManager(PMDataManager *Manager) { 0205 PassManagers.push_back(Manager); 0206 } 0207 0208 // Add Manager into the list of managers that are not directly 0209 // maintained by this top level pass manager 0210 inline void addIndirectPassManager(PMDataManager *Manager) { 0211 IndirectPassManagers.push_back(Manager); 0212 } 0213 0214 // Print passes managed by this top level manager. 0215 void dumpPasses() const; 0216 void dumpArguments() const; 0217 0218 // Active Pass Managers 0219 PMStack activeStack; 0220 0221 protected: 0222 /// Collection of pass managers 0223 SmallVector<PMDataManager *, 8> PassManagers; 0224 0225 private: 0226 /// Collection of pass managers that are not directly maintained 0227 /// by this pass manager 0228 SmallVector<PMDataManager *, 8> IndirectPassManagers; 0229 0230 // Map to keep track of last user of the analysis pass. 0231 // LastUser->second is the last user of Lastuser->first. 0232 // This is kept in sync with InversedLastUser. 0233 DenseMap<Pass *, Pass *> LastUser; 0234 0235 // Map to keep track of passes that are last used by a pass. 0236 // This is kept in sync with LastUser. 0237 DenseMap<Pass *, SmallPtrSet<Pass *, 8> > InversedLastUser; 0238 0239 /// Immutable passes are managed by top level manager. 0240 SmallVector<ImmutablePass *, 16> ImmutablePasses; 0241 0242 /// Map from ID to immutable passes. 0243 SmallDenseMap<AnalysisID, ImmutablePass *, 8> ImmutablePassMap; 0244 0245 0246 /// A wrapper around AnalysisUsage for the purpose of uniqueing. The wrapper 0247 /// is used to avoid needing to make AnalysisUsage itself a folding set node. 0248 struct AUFoldingSetNode : public FoldingSetNode { 0249 AnalysisUsage AU; 0250 AUFoldingSetNode(const AnalysisUsage &AU) : AU(AU) {} 0251 void Profile(FoldingSetNodeID &ID) const { 0252 Profile(ID, AU); 0253 } 0254 static void Profile(FoldingSetNodeID &ID, const AnalysisUsage &AU) { 0255 // TODO: We could consider sorting the dependency arrays within the 0256 // AnalysisUsage (since they are conceptually unordered). 0257 ID.AddBoolean(AU.getPreservesAll()); 0258 auto ProfileVec = [&](const SmallVectorImpl<AnalysisID>& Vec) { 0259 ID.AddInteger(Vec.size()); 0260 for(AnalysisID AID : Vec) 0261 ID.AddPointer(AID); 0262 }; 0263 ProfileVec(AU.getRequiredSet()); 0264 ProfileVec(AU.getRequiredTransitiveSet()); 0265 ProfileVec(AU.getPreservedSet()); 0266 ProfileVec(AU.getUsedSet()); 0267 } 0268 }; 0269 0270 // Contains all of the unique combinations of AnalysisUsage. This is helpful 0271 // when we have multiple instances of the same pass since they'll usually 0272 // have the same analysis usage and can share storage. 0273 FoldingSet<AUFoldingSetNode> UniqueAnalysisUsages; 0274 0275 // Allocator used for allocating UAFoldingSetNodes. This handles deletion of 0276 // all allocated nodes in one fell swoop. 0277 SpecificBumpPtrAllocator<AUFoldingSetNode> AUFoldingSetNodeAllocator; 0278 0279 // Maps from a pass to it's associated entry in UniqueAnalysisUsages. Does 0280 // not own the storage associated with either key or value.. 0281 DenseMap<Pass *, AnalysisUsage*> AnUsageMap; 0282 0283 /// Collection of PassInfo objects found via analysis IDs and in this top 0284 /// level manager. This is used to memoize queries to the pass registry. 0285 /// FIXME: This is an egregious hack because querying the pass registry is 0286 /// either slow or racy. 0287 mutable DenseMap<AnalysisID, const PassInfo *> AnalysisPassInfos; 0288 }; 0289 0290 //===----------------------------------------------------------------------===// 0291 // PMDataManager 0292 0293 /// PMDataManager provides the common place to manage the analysis data 0294 /// used by pass managers. 0295 class PMDataManager { 0296 public: 0297 explicit PMDataManager() { initializeAnalysisInfo(); } 0298 0299 virtual ~PMDataManager(); 0300 0301 virtual Pass *getAsPass() = 0; 0302 0303 /// Augment AvailableAnalysis by adding analysis made available by pass P. 0304 void recordAvailableAnalysis(Pass *P); 0305 0306 /// verifyPreservedAnalysis -- Verify analysis presreved by pass P. 0307 void verifyPreservedAnalysis(Pass *P); 0308 0309 /// Remove Analysis that is not preserved by the pass 0310 void removeNotPreservedAnalysis(Pass *P); 0311 0312 /// Remove dead passes used by P. 0313 void removeDeadPasses(Pass *P, StringRef Msg, 0314 enum PassDebuggingString); 0315 0316 /// Remove P. 0317 void freePass(Pass *P, StringRef Msg, 0318 enum PassDebuggingString); 0319 0320 /// Add pass P into the PassVector. Update 0321 /// AvailableAnalysis appropriately if ProcessAnalysis is true. 0322 void add(Pass *P, bool ProcessAnalysis = true); 0323 0324 /// Add RequiredPass into list of lower level passes required by pass P. 0325 /// RequiredPass is run on the fly by Pass Manager when P requests it 0326 /// through getAnalysis interface. 0327 virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass); 0328 0329 virtual std::tuple<Pass *, bool> getOnTheFlyPass(Pass *P, AnalysisID PI, 0330 Function &F); 0331 0332 /// Initialize available analysis information. 0333 void initializeAnalysisInfo() { 0334 AvailableAnalysis.clear(); 0335 for (auto &IA : InheritedAnalysis) 0336 IA = nullptr; 0337 } 0338 0339 // Return true if P preserves high level analysis used by other 0340 // passes that are managed by this manager. 0341 bool preserveHigherLevelAnalysis(Pass *P); 0342 0343 /// Populate UsedPasses with analysis pass that are used or required by pass 0344 /// P and are available. Populate ReqPassNotAvailable with analysis pass that 0345 /// are required by pass P but are not available. 0346 void collectRequiredAndUsedAnalyses( 0347 SmallVectorImpl<Pass *> &UsedPasses, 0348 SmallVectorImpl<AnalysisID> &ReqPassNotAvailable, Pass *P); 0349 0350 /// All Required analyses should be available to the pass as it runs! Here 0351 /// we fill in the AnalysisImpls member of the pass so that it can 0352 /// successfully use the getAnalysis() method to retrieve the 0353 /// implementations it needs. 0354 void initializeAnalysisImpl(Pass *P); 0355 0356 /// Find the pass that implements Analysis AID. If desired pass is not found 0357 /// then return NULL. 0358 Pass *findAnalysisPass(AnalysisID AID, bool Direction); 0359 0360 // Access toplevel manager 0361 PMTopLevelManager *getTopLevelManager() { return TPM; } 0362 void setTopLevelManager(PMTopLevelManager *T) { TPM = T; } 0363 0364 unsigned getDepth() const { return Depth; } 0365 void setDepth(unsigned newDepth) { Depth = newDepth; } 0366 0367 // Print routines used by debug-pass 0368 void dumpLastUses(Pass *P, unsigned Offset) const; 0369 void dumpPassArguments() const; 0370 void dumpPassInfo(Pass *P, enum PassDebuggingString S1, 0371 enum PassDebuggingString S2, StringRef Msg); 0372 void dumpRequiredSet(const Pass *P) const; 0373 void dumpPreservedSet(const Pass *P) const; 0374 void dumpUsedSet(const Pass *P) const; 0375 0376 unsigned getNumContainedPasses() const { 0377 return (unsigned)PassVector.size(); 0378 } 0379 0380 virtual PassManagerType getPassManagerType() const { 0381 assert ( 0 && "Invalid use of getPassManagerType"); 0382 return PMT_Unknown; 0383 } 0384 0385 DenseMap<AnalysisID, Pass*> *getAvailableAnalysis() { 0386 return &AvailableAnalysis; 0387 } 0388 0389 // Collect AvailableAnalysis from all the active Pass Managers. 0390 void populateInheritedAnalysis(PMStack &PMS) { 0391 unsigned Index = 0; 0392 for (PMDataManager *PMDM : PMS) 0393 InheritedAnalysis[Index++] = PMDM->getAvailableAnalysis(); 0394 } 0395 0396 /// Set the initial size of the module if the user has specified that they 0397 /// want remarks for size. 0398 /// Returns 0 if the remark was not requested. 0399 unsigned initSizeRemarkInfo( 0400 Module &M, 0401 StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount); 0402 0403 /// Emit a remark signifying that the number of IR instructions in the module 0404 /// changed. 0405 /// \p F is optionally passed by passes which run on Functions, and thus 0406 /// always know whether or not a non-empty function is available. 0407 /// 0408 /// \p FunctionToInstrCount maps the name of a \p Function to a pair. The 0409 /// first member of the pair is the IR count of the \p Function before running 0410 /// \p P, and the second member is the IR count of the \p Function after 0411 /// running \p P. 0412 void emitInstrCountChangedRemark( 0413 Pass *P, Module &M, int64_t Delta, unsigned CountBefore, 0414 StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount, 0415 Function *F = nullptr); 0416 0417 protected: 0418 // Top level manager. 0419 PMTopLevelManager *TPM = nullptr; 0420 0421 // Collection of pass that are managed by this manager 0422 SmallVector<Pass *, 16> PassVector; 0423 0424 // Collection of Analysis provided by Parent pass manager and 0425 // used by current pass manager. At any time there can not be more 0426 // then PMT_Last active pass managers. 0427 DenseMap<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last]; 0428 0429 /// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions 0430 /// or higher is specified. 0431 bool isPassDebuggingExecutionsOrMore() const; 0432 0433 private: 0434 void dumpAnalysisUsage(StringRef Msg, const Pass *P, 0435 const AnalysisUsage::VectorType &Set) const; 0436 0437 // Set of available Analysis. This information is used while scheduling 0438 // pass. If a pass requires an analysis which is not available then 0439 // the required analysis pass is scheduled to run before the pass itself is 0440 // scheduled to run. 0441 DenseMap<AnalysisID, Pass*> AvailableAnalysis; 0442 0443 // Collection of higher level analysis used by the pass managed by 0444 // this manager. 0445 SmallVector<Pass *, 16> HigherLevelAnalysis; 0446 0447 unsigned Depth = 0; 0448 }; 0449 0450 //===----------------------------------------------------------------------===// 0451 // FPPassManager 0452 // 0453 /// FPPassManager manages BBPassManagers and FunctionPasses. 0454 /// It batches all function passes and basic block pass managers together and 0455 /// sequence them to process one function at a time before processing next 0456 /// function. 0457 class FPPassManager : public ModulePass, public PMDataManager { 0458 public: 0459 static char ID; 0460 explicit FPPassManager() : ModulePass(ID) {} 0461 0462 /// run - Execute all of the passes scheduled for execution. Keep track of 0463 /// whether any of the passes modifies the module, and if so, return true. 0464 bool runOnFunction(Function &F); 0465 bool runOnModule(Module &M) override; 0466 0467 /// cleanup - After running all passes, clean up pass manager cache. 0468 void cleanup(); 0469 0470 /// doInitialization - Overrides ModulePass doInitialization for global 0471 /// initialization tasks 0472 /// 0473 using ModulePass::doInitialization; 0474 0475 /// doInitialization - Run all of the initializers for the function passes. 0476 /// 0477 bool doInitialization(Module &M) override; 0478 0479 /// doFinalization - Overrides ModulePass doFinalization for global 0480 /// finalization tasks 0481 /// 0482 using ModulePass::doFinalization; 0483 0484 /// doFinalization - Run all of the finalizers for the function passes. 0485 /// 0486 bool doFinalization(Module &M) override; 0487 0488 PMDataManager *getAsPMDataManager() override { return this; } 0489 Pass *getAsPass() override { return this; } 0490 0491 /// Pass Manager itself does not invalidate any analysis info. 0492 void getAnalysisUsage(AnalysisUsage &Info) const override { 0493 Info.setPreservesAll(); 0494 } 0495 0496 // Print passes managed by this manager 0497 void dumpPassStructure(unsigned Offset) override; 0498 0499 StringRef getPassName() const override { return "Function Pass Manager"; } 0500 0501 FunctionPass *getContainedPass(unsigned N) { 0502 assert ( N < PassVector.size() && "Pass number out of range!"); 0503 FunctionPass *FP = static_cast<FunctionPass *>(PassVector[N]); 0504 return FP; 0505 } 0506 0507 PassManagerType getPassManagerType() const override { 0508 return PMT_FunctionPassManager; 0509 } 0510 }; 0511 0512 } 0513 0514 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|