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 @@ -683,13 +683,18 @@ /// return instructions that might return them. DenseMap> ReturnedValues; + /// Mapping to remember the number of returned values for a call site such + /// that we can avoid updates if nothing changed. + DenseMap NumReturnedValuesPerKnownAA; + + /// Set of unresolved calls returned by the associated function. SmallPtrSet UnresolvedCalls; /// State flags /// ///{ - bool IsFixed; - bool IsValidState; + bool IsFixed = false; + bool IsValidState = true; ///} public: @@ -775,7 +780,6 @@ /// See AbstractState::indicateOptimisticFixpoint(...). ChangeStatus indicateOptimisticFixpoint() override { IsFixed = true; - IsValidState &= true; return ChangeStatus::UNCHANGED; } @@ -1000,6 +1004,15 @@ if (Unresolved) continue; + // Now track transitively returned values. + unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB]; + if (NumRetAA == RetValAA.getNumReturnValues()) { + LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not " + "changed since it was seen last\n"); + continue; + } + NumRetAA = RetValAA.getNumReturnValues(); + for (auto &RetValAAIt : RetValAA.returned_values()) { Value *RetVal = RetValAAIt.first; if (Argument *Arg = dyn_cast(RetVal)) {