summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/IPO/Attributor.cpp113
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.
OpenPOWER on IntegriCloud