diff options
| author | Stefan Stipanovic <sstipanovic@s-energize.com> | 2019-07-22 19:36:27 +0000 | 
|---|---|---|
| committer | Stefan Stipanovic <sstipanovic@s-energize.com> | 2019-07-22 19:36:27 +0000 | 
| commit | 69ebb02001f57a561c072b14f79f7d61a9c68e13 (patch) | |
| tree | d642b6b861c4207b23870f1f79b9fc58033bd8d8 /llvm/lib/Transforms | |
| parent | 942537d9fa5026bb4780edfec695fb5bf497d369 (diff) | |
| download | bcm5719-llvm-69ebb02001f57a561c072b14f79f7d61a9c68e13.tar.gz bcm5719-llvm-69ebb02001f57a561c072b14f79f7d61a9c68e13.zip | |
[Attributor] NoAlias on return values.
Porting function return value attribute noalias to attributor.
This will be followed with a patch for callsite and function argumets.
Reviewers: jdoerfert
Subscribers: lebedev.ri, hiraditya, llvm-commits
Differential Revision: https://reviews.llvm.org/D63067
llvm-svn: 366728
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/IPO/Attributor.cpp | 113 | 
1 files changed, 109 insertions, 4 deletions
| diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 2a52c6b9b4a..fa5dbc23014 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -20,6 +20,7 @@  #include "llvm/ADT/SmallPtrSet.h"  #include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/CaptureTracking.h"  #include "llvm/Analysis/GlobalsModRef.h"  #include "llvm/Analysis/ValueTracking.h"  #include "llvm/IR/Argument.h" @@ -59,6 +60,7 @@ STATISTIC(NumFnReturnedNonNull,  STATISTIC(NumFnArgumentNonNull, "Number of function arguments marked nonnull");  STATISTIC(NumCSArgumentNonNull, "Number of call site arguments marked nonnull");  STATISTIC(NumFnWillReturn, "Number of functions marked willreturn"); +STATISTIC(NumFnArgumentNoAlias, "Number of function arguments marked noalias");  // TODO: Determine a good default value.  // @@ -134,6 +136,9 @@ static void bookkeeping(AbstractAttribute::ManifestPosition MP,    case Attribute::WillReturn:      NumFnWillReturn++;      break; +  case Attribute::NoAlias: +    NumFnArgumentNoAlias++; +    return;    default:      return;    } @@ -1311,6 +1316,101 @@ ChangeStatus AAWillReturnFunction::updateImpl(Attributor &A) {    return ChangeStatus::UNCHANGED;  } +/// ------------------------ NoAlias Argument Attribute ------------------------ + +struct AANoAliasImpl : AANoAlias, BooleanState { + +  AANoAliasImpl(Value &V, InformationCache &InfoCache) +      : AANoAlias(V, InfoCache) {} + +  /// See AbstractAttribute::getState() +  /// { +  AbstractState &getState() override { return *this; } +  const AbstractState &getState() const override { return *this; } +  /// } + +  const std::string getAsStr() const override { +    return getAssumed() ? "noalias" : "may-alias"; +  } + +  /// See AANoAlias::isAssumedNoAlias(). +  bool isAssumedNoAlias() const override { return getAssumed(); } + +  /// See AANoAlias::isKnowndNoAlias(). +  bool isKnownNoAlias() const override { return getKnown(); } +}; + +/// NoAlias attribute for function return value. +struct AANoAliasReturned : AANoAliasImpl { + +  AANoAliasReturned(Function &F, InformationCache &InfoCache) +      : AANoAliasImpl(F, InfoCache) {} + +  /// See AbstractAttribute::getManifestPosition(). +  virtual ManifestPosition getManifestPosition() const override { +    return MP_RETURNED; +  } + +  /// See AbstractAttriubute::initialize(...). +  void initialize(Attributor &A) override { +    Function &F = getAnchorScope(); + +    // Already noalias. +    if (F.returnDoesNotAlias()) { +      indicateOptimisticFixpoint(); +      return; +    } +  } + +  /// See AbstractAttribute::updateImpl(...). +  virtual ChangeStatus updateImpl(Attributor &A) override; +}; + +ChangeStatus AANoAliasReturned::updateImpl(Attributor &A) { +  Function &F = getAnchorScope(); + +  auto *AARetValImpl = A.getAAFor<AAReturnedValuesImpl>(*this, F); +  if (!AARetValImpl) { +    indicatePessimisticFixpoint(); +    return ChangeStatus::CHANGED; +  } + +  std::function<bool(Value &)> Pred = [&](Value &RV) -> bool { +    if (Constant *C = dyn_cast<Constant>(&RV)) +      if (C->isNullValue() || isa<UndefValue>(C)) +        return true; + +    /// For now, we can only deduce noalias if we have call sites. +    /// FIXME: add more support. +    ImmutableCallSite ICS(&RV); +    if (!ICS) +      return false; + +    auto *NoAliasAA = A.getAAFor<AANoAlias>(*this, RV); + +    if (!ICS.returnDoesNotAlias() && (!NoAliasAA || +        !NoAliasAA->isAssumedNoAlias())) +      return false; + +    /// FIXME: We can improve capture check in two ways: +    /// 1. Use the AANoCapture facilities. +    /// 2. Use the location of return insts for escape queries. +    if (PointerMayBeCaptured(&RV, /* ReturnCaptures */ false, +                             /* StoreCaptures */ true)) +      return false; + + +    return true; +  }; + +  if (!AARetValImpl->checkForallReturnedValues(Pred)) { +    indicatePessimisticFixpoint(); +    return ChangeStatus::CHANGED; +  } + +  return ChangeStatus::UNCHANGED; +} +  /// ----------------------------------------------------------------------------  ///                               Attributor  /// ---------------------------------------------------------------------------- @@ -1507,10 +1607,15 @@ void Attributor::identifyDefaultAbstractAttributes(      if (!Whitelist || Whitelist->count(AAReturnedValues::ID))        registerAA(*new AAReturnedValuesImpl(F, InfoCache)); -    // Every function with pointer return type might be marked nonnull. -    if (ReturnType->isPointerTy() && -        (!Whitelist || Whitelist->count(AANonNullReturned::ID))) -      registerAA(*new AANonNullReturned(F, InfoCache)); +    if (ReturnType->isPointerTy()) { +      // Every function with pointer return type might be marked nonnull. +      if (!Whitelist || Whitelist->count(AANonNullReturned::ID)) +        registerAA(*new AANonNullReturned(F, InfoCache)); + +      // Every function with pointer return type might be marked noalias. +      if (!Whitelist || Whitelist->count(AANoAliasReturned::ID)) +        registerAA(*new AANoAliasReturned(F, InfoCache)); +    }    }    // Every argument with pointer type might be marked nonnull. | 

