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 @@ -171,9 +171,16 @@ /// most optimistic information for other abstract attributes in-flight, e.g. /// the one reasoning about the "captured" state for the argument or the one /// reasoning on the memory access behavior of the function as a whole. + /// + /// If the flag \p TrackDependence is set to false the dependence from + /// \p QueryingAA to the return abstract attribute is not automatically + /// recorded. This should only be used if the caller will record the + /// dependence explicitly if necessary, thus if it the returned abstract + /// attribute is used for reasoning. To record the dependences explicitly use + /// the `Attributor::recordDependence` method. template const AAType *getAAFor(AbstractAttribute &QueryingAA, const Value &V, - int ArgNo = -1) { + int ArgNo = -1, bool TrackDependence = true) { static_assert(std::is_base_of::value, "Cannot query an attribute with a type not derived from " "'AbstractAttribute'!"); @@ -189,15 +196,17 @@ // arguments. if (ArgNo >= 0 && isa(&V) && cast(&V)->arg_size() > (size_t)ArgNo) - return getAAFor( - QueryingAA, *(cast(&V)->arg_begin() + ArgNo), ArgNo); + return getAAFor(QueryingAA, + *(cast(&V)->arg_begin() + ArgNo), ArgNo, + TrackDependence); // Lookup the abstract attribute of type AAType. If found, return it after // registering a dependence of QueryingAA on the one returned attribute. const auto &KindToAbstractAttributeMap = AAMap.lookup({&V, ArgNo}); if (AAType *AA = static_cast( KindToAbstractAttributeMap.lookup(AAType::ID))) { - QueryMap[AA].insert(&QueryingAA); + if (TrackDependence) + QueryMap[AA].insert(&QueryingAA); return AA; } @@ -205,12 +214,24 @@ // defer to the actual argument instead. ImmutableCallSite ICS(&V); if (ICS && ICS.getCalledValue()) - return getAAFor(QueryingAA, *ICS.getCalledValue(), ArgNo); + return getAAFor(QueryingAA, *ICS.getCalledValue(), ArgNo, + TrackDependence); // No matching attribute found return nullptr; } + /// Explicitly record a dependence from \p FromAA to \p ToAA, that is if + /// \p FromAA changes \p ToAA should be updated as well. + /// + /// This method should be used in conjunction with the `getAAFor` method and + /// with the TrackDependence flag passed to the method set to false. This can + /// be beneficial to avoid false dependences but it requires the users of + /// `getAAFor` to explicitly record true dependences through this method. + void recordDependence(AbstractAttribute *FromAA, AbstractAttribute *ToAA) { + QueryMap[FromAA].insert(ToAA); + } + /// Introduce a new abstract attribute into the fixpoint analysis. /// /// Note that ownership of the attribute is given to the Attributor. It will