diff options
Diffstat (limited to 'contrib/llvm/lib/IR/LegacyPassManager.cpp')
-rw-r--r-- | contrib/llvm/lib/IR/LegacyPassManager.cpp | 157 |
1 files changed, 88 insertions, 69 deletions
diff --git a/contrib/llvm/lib/IR/LegacyPassManager.cpp b/contrib/llvm/lib/IR/LegacyPassManager.cpp index 27d98a2..f2e0c7d 100644 --- a/contrib/llvm/lib/IR/LegacyPassManager.cpp +++ b/contrib/llvm/lib/IR/LegacyPassManager.cpp @@ -569,13 +569,33 @@ void PMTopLevelManager::collectLastUses(SmallVectorImpl<Pass *> &LastUses, AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) { AnalysisUsage *AnUsage = nullptr; - DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.find(P); + auto DMI = AnUsageMap.find(P); if (DMI != AnUsageMap.end()) AnUsage = DMI->second; else { - AnUsage = new AnalysisUsage(); - P->getAnalysisUsage(*AnUsage); - AnUsageMap[P] = AnUsage; + // Look up the analysis usage from the pass instance (different instances + // of the same pass can produce different results), but unique the + // resulting object to reduce memory usage. This helps to greatly reduce + // memory usage when we have many instances of only a few pass types + // (e.g. instcombine, simplifycfg, etc...) which tend to share a fixed set + // of dependencies. + AnalysisUsage AU; + P->getAnalysisUsage(AU); + + AUFoldingSetNode* Node = nullptr; + FoldingSetNodeID ID; + AUFoldingSetNode::Profile(ID, AU); + void *IP = nullptr; + if (auto *N = UniqueAnalysisUsages.FindNodeOrInsertPos(ID, IP)) + Node = N; + else { + Node = new (AUFoldingSetNodeAllocator.Allocate()) AUFoldingSetNode(AU); + UniqueAnalysisUsages.InsertNode(Node, IP); + } + assert(Node && "cached analysis usage must be non null"); + + AnUsageMap[P] = &Node->AU; + AnUsage = &Node->AU;; } return AnUsage; } @@ -686,6 +706,10 @@ void PMTopLevelManager::schedulePass(Pass *P) { /// passes and all pass managers. If desired pass is not found /// then return NULL. Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { + // For immutable passes we have a direct mapping from ID to pass, so check + // that first. + if (Pass *P = ImmutablePassMap.lookup(AID)) + return P; // Check pass managers for (PMDataManager *PassManager : PassManagers) @@ -697,24 +721,6 @@ Pass *PMTopLevelManager::findAnalysisPass(AnalysisID AID) { if (Pass *P = IndirectPassManager->findAnalysisPass(AID, false)) return P; - // Check the immutable passes. Iterate in reverse order so that we find - // the most recently registered passes first. - for (auto I = ImmutablePasses.rbegin(), E = ImmutablePasses.rend(); I != E; - ++I) { - AnalysisID PI = (*I)->getPassID(); - if (PI == AID) - return *I; - - // If Pass not found then check the interfaces implemented by Immutable Pass - const PassInfo *PassInf = findAnalysisPassInfo(PI); - assert(PassInf && "Expected all immutable passes to be initialized"); - const std::vector<const PassInfo*> &ImmPI = - PassInf->getInterfacesImplemented(); - for (const PassInfo *PI : ImmPI) - if (PI->getTypeInfo() == AID) - return *I; - } - return nullptr; } @@ -729,6 +735,24 @@ const PassInfo *PMTopLevelManager::findAnalysisPassInfo(AnalysisID AID) const { return PI; } +void PMTopLevelManager::addImmutablePass(ImmutablePass *P) { + P->initializePass(); + ImmutablePasses.push_back(P); + + // Add this pass to the map from its analysis ID. We clobber any prior runs + // of the pass in the map so that the last one added is the one found when + // doing lookups. + AnalysisID AID = P->getPassID(); + ImmutablePassMap[AID] = P; + + // Also add any interfaces implemented by the immutable pass to the map for + // fast lookup. + const PassInfo *PassInf = findAnalysisPassInfo(AID); + assert(PassInf && "Expected all immutable passes to be initialized"); + for (const PassInfo *ImmPI : PassInf->getInterfacesImplemented()) + ImmutablePassMap[ImmPI->getTypeInfo()] = P; +} + // Print passes managed by this top level manager. void PMTopLevelManager::dumpPasses() const { @@ -780,15 +804,8 @@ void PMTopLevelManager::initializeAllAnalysisInfo() { for (DenseMap<Pass *, Pass *>::iterator DMI = LastUser.begin(), DME = LastUser.end(); DMI != DME; ++DMI) { - DenseMap<Pass *, SmallPtrSet<Pass *, 8> >::iterator InvDMI = - InversedLastUser.find(DMI->second); - if (InvDMI != InversedLastUser.end()) { - SmallPtrSet<Pass *, 8> &L = InvDMI->second; - L.insert(DMI->first); - } else { - SmallPtrSet<Pass *, 8> L; L.insert(DMI->first); - InversedLastUser[DMI->second] = L; - } + SmallPtrSet<Pass *, 8> &L = InversedLastUser[DMI->second]; + L.insert(DMI->first); } } @@ -801,10 +818,6 @@ PMTopLevelManager::~PMTopLevelManager() { for (SmallVectorImpl<ImmutablePass *>::iterator I = ImmutablePasses.begin(), E = ImmutablePasses.end(); I != E; ++I) delete *I; - - for (DenseMap<Pass *, AnalysisUsage *>::iterator DMI = AnUsageMap.begin(), - DME = AnUsageMap.end(); DMI != DME; ++DMI) - delete DMI->second; } //===----------------------------------------------------------------------===// @@ -989,31 +1002,28 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) { // At the moment, this pass is the last user of all required passes. SmallVector<Pass *, 12> LastUses; - SmallVector<Pass *, 8> RequiredPasses; + SmallVector<Pass *, 8> UsedPasses; SmallVector<AnalysisID, 8> ReqAnalysisNotAvailable; unsigned PDepth = this->getDepth(); - collectRequiredAnalysis(RequiredPasses, - ReqAnalysisNotAvailable, P); - for (SmallVectorImpl<Pass *>::iterator I = RequiredPasses.begin(), - E = RequiredPasses.end(); I != E; ++I) { - Pass *PRequired = *I; + collectRequiredAndUsedAnalyses(UsedPasses, ReqAnalysisNotAvailable, P); + for (Pass *PUsed : UsedPasses) { unsigned RDepth = 0; - assert(PRequired->getResolver() && "Analysis Resolver is not set"); - PMDataManager &DM = PRequired->getResolver()->getPMDataManager(); + assert(PUsed->getResolver() && "Analysis Resolver is not set"); + PMDataManager &DM = PUsed->getResolver()->getPMDataManager(); RDepth = DM.getDepth(); if (PDepth == RDepth) - LastUses.push_back(PRequired); + LastUses.push_back(PUsed); else if (PDepth > RDepth) { // Let the parent claim responsibility of last use - TransferLastUses.push_back(PRequired); + TransferLastUses.push_back(PUsed); // Keep track of higher level analysis used by this manager. - HigherLevelAnalysis.push_back(PRequired); + HigherLevelAnalysis.push_back(PUsed); } else - llvm_unreachable("Unable to accommodate Required Pass"); + llvm_unreachable("Unable to accommodate Used Pass"); } // Set P as P's last user until someone starts using P. @@ -1030,10 +1040,8 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) { } // Now, take care of required analyses that are not available. - for (SmallVectorImpl<AnalysisID>::iterator - I = ReqAnalysisNotAvailable.begin(), - E = ReqAnalysisNotAvailable.end() ;I != E; ++I) { - const PassInfo *PI = TPM->findAnalysisPassInfo(*I); + for (AnalysisID ID : ReqAnalysisNotAvailable) { + const PassInfo *PI = TPM->findAnalysisPassInfo(ID); Pass *AnalysisPass = PI->createPass(); this->addLowerLevelRequiredPass(P, AnalysisPass); } @@ -1048,30 +1056,29 @@ void PMDataManager::add(Pass *P, bool ProcessAnalysis) { } -/// Populate RP with analysis pass that are required by +/// Populate UP with analysis pass that are used or required by /// pass P and are available. Populate RP_NotAvail with analysis /// pass that are required by pass P but are not available. -void PMDataManager::collectRequiredAnalysis(SmallVectorImpl<Pass *> &RP, - SmallVectorImpl<AnalysisID> &RP_NotAvail, - Pass *P) { +void PMDataManager::collectRequiredAndUsedAnalyses( + SmallVectorImpl<Pass *> &UP, SmallVectorImpl<AnalysisID> &RP_NotAvail, + Pass *P) { AnalysisUsage *AnUsage = TPM->findAnalysisUsage(P); - const AnalysisUsage::VectorType &RequiredSet = AnUsage->getRequiredSet(); - for (AnalysisUsage::VectorType::const_iterator - I = RequiredSet.begin(), E = RequiredSet.end(); I != E; ++I) { - if (Pass *AnalysisPass = findAnalysisPass(*I, true)) - RP.push_back(AnalysisPass); + + for (const auto &UsedID : AnUsage->getUsedSet()) + if (Pass *AnalysisPass = findAnalysisPass(UsedID, true)) + UP.push_back(AnalysisPass); + + for (const auto &RequiredID : AnUsage->getRequiredSet()) + if (Pass *AnalysisPass = findAnalysisPass(RequiredID, true)) + UP.push_back(AnalysisPass); else - RP_NotAvail.push_back(*I); - } + RP_NotAvail.push_back(RequiredID); - const AnalysisUsage::VectorType &IDs = AnUsage->getRequiredTransitiveSet(); - for (AnalysisUsage::VectorType::const_iterator I = IDs.begin(), - E = IDs.end(); I != E; ++I) { - if (Pass *AnalysisPass = findAnalysisPass(*I, true)) - RP.push_back(AnalysisPass); + for (const auto &RequiredID : AnUsage->getRequiredTransitiveSet()) + if (Pass *AnalysisPass = findAnalysisPass(RequiredID, true)) + UP.push_back(AnalysisPass); else - RP_NotAvail.push_back(*I); - } + RP_NotAvail.push_back(RequiredID); } // All Required analyses should be available to the pass as it runs! Here @@ -1206,6 +1213,15 @@ void PMDataManager::dumpPreservedSet(const Pass *P) const { dumpAnalysisUsage("Preserved", P, analysisUsage.getPreservedSet()); } +void PMDataManager::dumpUsedSet(const Pass *P) const { + if (PassDebugging < Details) + return; + + AnalysisUsage analysisUsage; + P->getAnalysisUsage(analysisUsage); + dumpAnalysisUsage("Used", P, analysisUsage.getUsedSet()); +} + void PMDataManager::dumpAnalysisUsage(StringRef Msg, const Pass *P, const AnalysisUsage::VectorType &Set) const { assert(PassDebugging >= Details); @@ -1310,6 +1326,7 @@ bool BBPassManager::runOnFunction(Function &F) { dumpPassInfo(BP, MODIFICATION_MSG, ON_BASICBLOCK_MSG, I->getName()); dumpPreservedSet(BP); + dumpUsedSet(BP); verifyPreservedAnalysis(BP); removeNotPreservedAnalysis(BP); @@ -1524,6 +1541,7 @@ bool FPPassManager::runOnFunction(Function &F) { if (LocalChanged) dumpPassInfo(FP, MODIFICATION_MSG, ON_FUNCTION_MSG, F.getName()); dumpPreservedSet(FP); + dumpUsedSet(FP); verifyPreservedAnalysis(FP); removeNotPreservedAnalysis(FP); @@ -1601,6 +1619,7 @@ MPPassManager::runOnModule(Module &M) { dumpPassInfo(MP, MODIFICATION_MSG, ON_MODULE_MSG, M.getModuleIdentifier()); dumpPreservedSet(MP); + dumpUsedSet(MP); verifyPreservedAnalysis(MP); removeNotPreservedAnalysis(MP); |