diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -1424,6 +1424,21 @@ BumpPtrAllocator &Allocator; private: + /// For invalid AAs we can fix dependent AAs that have a required dependence, + /// thereby folding long dependence chains in a single step without the need + /// to run updates. \see runTillFixpoint. + void invalidateTransative(SetVector &InvalidAAs, + SmallVector &ChangedAAs, + SetVector &Worklist); + + /// Reset abstract arguments not settled in a sound fixpoint by the end of + /// the fixpoint iteration. This happens when we stopped the fixpoint + /// iteration early. Note that only the ones marked as "changed" *and* the + /// ones transitively depending on them need to be reverted to a pessimistic + /// state. Others might not be in a fixpoint state but we can use the + /// optimistic results for them anyway. \see runTillFixpoint. + void enforceFixpoint(SmallVector &ChangedAAs); + /// This method will do fixpoint iteration until fixpoint or the /// maximum iteration count is reached. /// diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -948,6 +948,65 @@ return true; } +void Attributor::invalidateTransative( + SetVector &InvalidAAs, + SmallVector &ChangedAAs, + SetVector &Worklist) { + for (unsigned u = 0; u < InvalidAAs.size(); ++u) { + AbstractAttribute *InvalidAA = InvalidAAs[u]; + + // Check the dependences to fast track invalidation. + LLVM_DEBUG(dbgs() << "[Attributor] InvalidAA: " << *InvalidAA << " has " + << InvalidAA->Deps.size() + << " required & optional dependences\n"); + while (!InvalidAA->Deps.empty()) { + const auto &Dep = InvalidAA->Deps.back(); + InvalidAA->Deps.pop_back(); + AbstractAttribute *DepAA = cast(Dep.getPointer()); + if (Dep.getInt() == unsigned(DepClassTy::OPTIONAL)) { + Worklist.insert(DepAA); + continue; + } + DepAA->getState().indicatePessimisticFixpoint(); + assert(DepAA->getState().isAtFixpoint() && "Expected fixpoint state!"); + if (!DepAA->getState().isValidState()) + InvalidAAs.insert(DepAA); + else + ChangedAAs.push_back(DepAA); + } + } + InvalidAAs.clear(); +} + +void Attributor::enforceFixpoint( + SmallVector &ChangedAAs) { + SmallPtrSet Visited; + for (unsigned u = 0; u < ChangedAAs.size(); u++) { + AbstractAttribute *ChangedAA = ChangedAAs[u]; + if (!Visited.insert(ChangedAA).second) + continue; + + AbstractState &State = ChangedAA->getState(); + if (!State.isAtFixpoint()) { + State.indicatePessimisticFixpoint(); + + NumAttributesTimedOut++; + } + + while (!ChangedAA->Deps.empty()) { + ChangedAAs.push_back( + cast(ChangedAA->Deps.back().getPointer())); + ChangedAA->Deps.pop_back(); + } + } + + LLVM_DEBUG({ + if (!Visited.empty()) + dbgs() << "\n[Attributor] Finalized " << Visited.size() + << " abstract attributes.\n"; + }); +} + void Attributor::runTillFixpoint() { TimeTraceScope TimeScope("Attributor::runTillFixpoint"); LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized " @@ -969,32 +1028,8 @@ LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter << ", Worklist size: " << Worklist.size() << "\n"); - // For invalid AAs we can fix dependent AAs that have a required dependence, - // thereby folding long dependence chains in a single step without the need - // to run updates. - for (unsigned u = 0; u < InvalidAAs.size(); ++u) { - AbstractAttribute *InvalidAA = InvalidAAs[u]; - - // Check the dependences to fast track invalidation. - LLVM_DEBUG(dbgs() << "[Attributor] InvalidAA: " << *InvalidAA << " has " - << InvalidAA->Deps.size() - << " required & optional dependences\n"); - while (!InvalidAA->Deps.empty()) { - const auto &Dep = InvalidAA->Deps.back(); - InvalidAA->Deps.pop_back(); - AbstractAttribute *DepAA = cast(Dep.getPointer()); - if (Dep.getInt() == unsigned(DepClassTy::OPTIONAL)) { - Worklist.insert(DepAA); - continue; - } - DepAA->getState().indicatePessimisticFixpoint(); - assert(DepAA->getState().isAtFixpoint() && "Expected fixpoint state!"); - if (!DepAA->getState().isValidState()) - InvalidAAs.insert(DepAA); - else - ChangedAAs.push_back(DepAA); - } - } + // For invalid AAs we can fix dependent AAs that have a required dependence. + invalidateTransative(InvalidAAs, ChangedAAs, Worklist); // Add all abstract attributes that are potentially dependent on one that // changed to the work list. @@ -1011,7 +1046,6 @@ // Reset the changed and invalid set. ChangedAAs.clear(); - InvalidAAs.clear(); // Update all abstract attribute in the work list and record the ones that // changed. @@ -1045,35 +1079,8 @@ << " iterations\n"); // Reset abstract arguments not settled in a sound fixpoint by now. This - // happens when we stopped the fixpoint iteration early. Note that only the - // ones marked as "changed" *and* the ones transitively depending on them - // need to be reverted to a pessimistic state. Others might not be in a - // fixpoint state but we can use the optimistic results for them anyway. - SmallPtrSet Visited; - for (unsigned u = 0; u < ChangedAAs.size(); u++) { - AbstractAttribute *ChangedAA = ChangedAAs[u]; - if (!Visited.insert(ChangedAA).second) - continue; - - AbstractState &State = ChangedAA->getState(); - if (!State.isAtFixpoint()) { - State.indicatePessimisticFixpoint(); - - NumAttributesTimedOut++; - } - - while (!ChangedAA->Deps.empty()) { - ChangedAAs.push_back( - cast(ChangedAA->Deps.back().getPointer())); - ChangedAA->Deps.pop_back(); - } - } - - LLVM_DEBUG({ - if (!Visited.empty()) - dbgs() << "\n[Attributor] Finalized " << Visited.size() - << " abstract attributes.\n"; - }); + // happens when we stopped the fixpoint iteration early. + enforceFixpoint(ChangedAAs); if (VerifyMaxFixpointIterations && IterationCounter != MaxFixpointIterations) {