1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

[Attributor] Use the AANoNull attribute directly in AADereferenceable

Summary:
Instead of constantly keeping track of the nonnull status with the
dereferenceable information we can simply query the nonnull attribute
whenever we need the information (debug + manifest).

Reviewers: sstefan1, uenoku

Subscribers: hiraditya, bollu, jfb, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D66113

llvm-svn: 368924
This commit is contained in:
Johannes Doerfert 2019-08-14 21:31:32 +00:00
parent c97843653b
commit 1b61fbc6f8
2 changed files with 34 additions and 81 deletions

View File

@ -1297,9 +1297,6 @@ struct AADereferenceable
/// Return true if we assume that the underlying value is nonnull. /// Return true if we assume that the underlying value is nonnull.
virtual bool isAssumedNonNull() const = 0; virtual bool isAssumedNonNull() const = 0;
/// Return true if we know that underlying value is nonnull.
virtual bool isKnownNonNull() const = 0;
/// Return true if we assume that underlying value is /// Return true if we assume that underlying value is
/// dereferenceable(_or_null) globally. /// dereferenceable(_or_null) globally.
virtual bool isAssumedGlobal() const = 0; virtual bool isAssumedGlobal() const = 0;

View File

@ -1609,35 +1609,29 @@ struct DerefState : AbstractState {
/// State representing for dereferenceable bytes. /// State representing for dereferenceable bytes.
IntegerState DerefBytesState; IntegerState DerefBytesState;
/// State representing that whether the value is nonnull or global. /// State representing that whether the value is globaly dereferenceable.
IntegerState NonNullGlobalState; BooleanState GlobalState;
/// Bits encoding for NonNullGlobalState.
enum {
DEREF_NONNULL = 1 << 0,
DEREF_GLOBAL = 1 << 1,
};
/// See AbstractState::isValidState() /// See AbstractState::isValidState()
bool isValidState() const override { return DerefBytesState.isValidState(); } bool isValidState() const override { return DerefBytesState.isValidState(); }
/// See AbstractState::isAtFixpoint() /// See AbstractState::isAtFixpoint()
bool isAtFixpoint() const override { bool isAtFixpoint() const override {
return !isValidState() || (DerefBytesState.isAtFixpoint() && return !isValidState() ||
NonNullGlobalState.isAtFixpoint()); (DerefBytesState.isAtFixpoint() && GlobalState.isAtFixpoint());
} }
/// See AbstractState::indicateOptimisticFixpoint(...) /// See AbstractState::indicateOptimisticFixpoint(...)
ChangeStatus indicateOptimisticFixpoint() override { ChangeStatus indicateOptimisticFixpoint() override {
DerefBytesState.indicateOptimisticFixpoint(); DerefBytesState.indicateOptimisticFixpoint();
NonNullGlobalState.indicateOptimisticFixpoint(); GlobalState.indicateOptimisticFixpoint();
return ChangeStatus::UNCHANGED; return ChangeStatus::UNCHANGED;
} }
/// See AbstractState::indicatePessimisticFixpoint(...) /// See AbstractState::indicatePessimisticFixpoint(...)
ChangeStatus indicatePessimisticFixpoint() override { ChangeStatus indicatePessimisticFixpoint() override {
DerefBytesState.indicatePessimisticFixpoint(); DerefBytesState.indicatePessimisticFixpoint();
NonNullGlobalState.indicatePessimisticFixpoint(); GlobalState.indicatePessimisticFixpoint();
return ChangeStatus::CHANGED; return ChangeStatus::CHANGED;
} }
@ -1651,18 +1645,10 @@ struct DerefState : AbstractState {
DerefBytesState.takeAssumedMinimum(Bytes); DerefBytesState.takeAssumedMinimum(Bytes);
} }
/// Update assumed NonNullGlobalState
void updateAssumedNonNullGlobalState(bool IsNonNull, bool IsGlobal) {
if (!IsNonNull)
NonNullGlobalState.removeAssumedBits(DEREF_NONNULL);
if (!IsGlobal)
NonNullGlobalState.removeAssumedBits(DEREF_GLOBAL);
}
/// Equality for DerefState. /// Equality for DerefState.
bool operator==(const DerefState &R) { bool operator==(const DerefState &R) {
return this->DerefBytesState == R.DerefBytesState && return this->DerefBytesState == R.DerefBytesState &&
this->NonNullGlobalState == R.NonNullGlobalState; this->GlobalState == R.GlobalState;
} }
}; };
@ -1670,6 +1656,16 @@ struct AADereferenceableImpl : AADereferenceable, DerefState {
AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {} AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
using StateType = DerefState; using StateType = DerefState;
void initialize(Attributor &A) override {
SmallVector<Attribute, 4> Attrs;
getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
Attrs);
for (const Attribute &Attr : Attrs)
takeKnownDerefBytesMaximum(Attr.getValueAsInt());
NonNullAA = A.getAAFor<AANonNull>(*this, getIRPosition());
}
/// See AbstractAttribute::getState() /// See AbstractAttribute::getState()
/// { /// {
StateType &getState() override { return *this; } StateType &getState() override { return *this; }
@ -1686,38 +1682,14 @@ struct AADereferenceableImpl : AADereferenceable, DerefState {
return DerefBytesState.getKnown(); return DerefBytesState.getKnown();
} }
// Helper function for syncing nonnull state.
void syncNonNull(const AANonNull *NonNullAA) {
if (!NonNullAA) {
NonNullGlobalState.removeAssumedBits(DEREF_NONNULL);
return;
}
if (NonNullAA->isKnownNonNull())
NonNullGlobalState.addKnownBits(DEREF_NONNULL);
if (!NonNullAA->isAssumedNonNull())
NonNullGlobalState.removeAssumedBits(DEREF_NONNULL);
}
/// See AADereferenceable::isAssumedGlobal(). /// See AADereferenceable::isAssumedGlobal().
bool isAssumedGlobal() const override { bool isAssumedGlobal() const override { return GlobalState.getAssumed(); }
return NonNullGlobalState.isAssumed(DEREF_GLOBAL);
}
/// See AADereferenceable::isKnownGlobal(). /// See AADereferenceable::isKnownGlobal().
bool isKnownGlobal() const override { bool isKnownGlobal() const override { return GlobalState.getKnown(); }
return NonNullGlobalState.isKnown(DEREF_GLOBAL);
}
/// See AADereferenceable::isAssumedNonNull().
bool isAssumedNonNull() const override { bool isAssumedNonNull() const override {
return NonNullGlobalState.isAssumed(DEREF_NONNULL); return NonNullAA && NonNullAA->isAssumedNonNull();
}
/// See AADereferenceable::isKnownNonNull().
bool isKnownNonNull() const override {
return NonNullGlobalState.isKnown(DEREF_NONNULL);
} }
void getDeducedAttributes(LLVMContext &Ctx, void getDeducedAttributes(LLVMContext &Ctx,
@ -1731,15 +1703,7 @@ struct AADereferenceableImpl : AADereferenceable, DerefState {
Ctx, getAssumedDereferenceableBytes())); Ctx, getAssumedDereferenceableBytes()));
} }
uint64_t computeAssumedDerefenceableBytes(Attributor &A, Value &V, uint64_t computeAssumedDerefenceableBytes(Attributor &A, Value &V,
bool &IsNonNull, bool &IsGlobal); bool &IsGlobal);
void initialize(Attributor &A) override {
SmallVector<Attribute, 4> Attrs;
getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
Attrs);
for (const Attribute &Attr : Attrs)
takeKnownDerefBytesMaximum(Attr.getValueAsInt());
}
/// See AbstractAttribute::getAsStr(). /// See AbstractAttribute::getAsStr().
const std::string getAsStr() const override { const std::string getAsStr() const override {
@ -1751,6 +1715,9 @@ struct AADereferenceableImpl : AADereferenceable, DerefState {
std::to_string(getKnownDereferenceableBytes()) + "-" + std::to_string(getKnownDereferenceableBytes()) + "-" +
std::to_string(getAssumedDereferenceableBytes()) + ">"; std::to_string(getAssumedDereferenceableBytes()) + ">";
} }
private:
const AANonNull *NonNullAA = nullptr;
}; };
struct AADereferenceableReturned final : AADereferenceableImpl { struct AADereferenceableReturned final : AADereferenceableImpl {
@ -1774,15 +1741,15 @@ static uint64_t calcDifferenceIfBaseIsNonNull(int64_t DerefBytes,
return std::max((int64_t)0, DerefBytes - Offset); return std::max((int64_t)0, DerefBytes - Offset);
} }
uint64_t AADereferenceableImpl::computeAssumedDerefenceableBytes( uint64_t
Attributor &A, Value &V, bool &IsNonNull, bool &IsGlobal) { AADereferenceableImpl::computeAssumedDerefenceableBytes(Attributor &A, Value &V,
bool &IsGlobal) {
// TODO: Tracking the globally flag. // TODO: Tracking the globally flag.
IsGlobal = false; IsGlobal = false;
// First, we try to get information about V from Attributor. // First, we try to get information about V from Attributor.
if (auto *DerefAA = if (auto *DerefAA =
A.getAAFor<AADereferenceable>(*this, IRPosition::value(V))) { A.getAAFor<AADereferenceable>(*this, IRPosition::value(V))) {
IsNonNull &= DerefAA->isAssumedNonNull();
return DerefAA->getAssumedDereferenceableBytes(); return DerefAA->getAssumedDereferenceableBytes();
} }
@ -1795,7 +1762,6 @@ uint64_t AADereferenceableImpl::computeAssumedDerefenceableBytes(
if (auto *BaseDerefAA = if (auto *BaseDerefAA =
A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base))) { A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base))) {
IsNonNull &= Offset != 0;
return calcDifferenceIfBaseIsNonNull( return calcDifferenceIfBaseIsNonNull(
BaseDerefAA->getAssumedDereferenceableBytes(), Offset.getSExtValue(), BaseDerefAA->getAssumedDereferenceableBytes(), Offset.getSExtValue(),
Offset != 0 || BaseDerefAA->isAssumedNonNull()); Offset != 0 || BaseDerefAA->isAssumedNonNull());
@ -1810,26 +1776,22 @@ uint64_t AADereferenceableImpl::computeAssumedDerefenceableBytes(
!NullPointerIsDefined(getAnchorScope(), !NullPointerIsDefined(getAnchorScope(),
V.getType()->getPointerAddressSpace())); V.getType()->getPointerAddressSpace()));
IsNonNull = false;
return 0; return 0;
} }
ChangeStatus AADereferenceableReturned::updateImpl(Attributor &A) { ChangeStatus AADereferenceableReturned::updateImpl(Attributor &A) {
auto BeforeState = static_cast<DerefState>(*this); auto BeforeState = static_cast<DerefState>(*this);
syncNonNull(A.getAAFor<AANonNull>(*this, getIRPosition()));
bool IsNonNull = isAssumedNonNull();
bool IsGlobal = isAssumedGlobal(); bool IsGlobal = isAssumedGlobal();
auto CheckReturnValue = [&](Value &RV) -> bool { auto CheckReturnValue = [&](Value &RV) -> bool {
takeAssumedDerefBytesMinimum( takeAssumedDerefBytesMinimum(
computeAssumedDerefenceableBytes(A, RV, IsNonNull, IsGlobal)); computeAssumedDerefenceableBytes(A, RV, IsGlobal));
return isValidState(); return isValidState();
}; };
if (A.checkForAllReturnedValues(CheckReturnValue, *this)) { if (A.checkForAllReturnedValues(CheckReturnValue, *this)) {
updateAssumedNonNullGlobalState(IsNonNull, IsGlobal); GlobalState.intersectAssumedBits(IsGlobal);
return BeforeState == static_cast<DerefState>(*this) return BeforeState == static_cast<DerefState>(*this)
? ChangeStatus::UNCHANGED ? ChangeStatus::UNCHANGED
: ChangeStatus::CHANGED; : ChangeStatus::CHANGED;
@ -1857,9 +1819,6 @@ ChangeStatus AADereferenceableArgument::updateImpl(Attributor &A) {
unsigned ArgNo = Arg.getArgNo(); unsigned ArgNo = Arg.getArgNo();
syncNonNull(A.getAAFor<AANonNull>(*this, getIRPosition()));
bool IsNonNull = isAssumedNonNull();
bool IsGlobal = isAssumedGlobal(); bool IsGlobal = isAssumedGlobal();
// Callback function // Callback function
@ -1874,14 +1833,13 @@ ChangeStatus AADereferenceableArgument::updateImpl(Attributor &A) {
if (ICS && CS.getInstruction() == ICS.getInstruction()) { if (ICS && CS.getInstruction() == ICS.getInstruction()) {
takeAssumedDerefBytesMinimum( takeAssumedDerefBytesMinimum(
DereferenceableAA->getAssumedDereferenceableBytes()); DereferenceableAA->getAssumedDereferenceableBytes());
IsNonNull &= DereferenceableAA->isAssumedNonNull();
IsGlobal &= DereferenceableAA->isAssumedGlobal(); IsGlobal &= DereferenceableAA->isAssumedGlobal();
return isValidState(); return isValidState();
} }
} }
takeAssumedDerefBytesMinimum(computeAssumedDerefenceableBytes( takeAssumedDerefBytesMinimum(computeAssumedDerefenceableBytes(
A, *CS.getArgOperand(ArgNo), IsNonNull, IsGlobal)); A, *CS.getArgOperand(ArgNo), IsGlobal));
return isValidState(); return isValidState();
}; };
@ -1889,7 +1847,7 @@ ChangeStatus AADereferenceableArgument::updateImpl(Attributor &A) {
if (!A.checkForAllCallSites(CallSiteCheck, *this, true)) if (!A.checkForAllCallSites(CallSiteCheck, *this, true))
return indicatePessimisticFixpoint(); return indicatePessimisticFixpoint();
updateAssumedNonNullGlobalState(IsNonNull, IsGlobal); GlobalState.intersectAssumedBits(IsGlobal);
return BeforeState == static_cast<DerefState>(*this) ? ChangeStatus::UNCHANGED return BeforeState == static_cast<DerefState>(*this) ? ChangeStatus::UNCHANGED
: ChangeStatus::CHANGED; : ChangeStatus::CHANGED;
@ -1918,13 +1876,11 @@ ChangeStatus AADereferenceableCallSiteArgument::updateImpl(Attributor &A) {
auto BeforeState = static_cast<DerefState>(*this); auto BeforeState = static_cast<DerefState>(*this);
syncNonNull(A.getAAFor<AANonNull>(*this, getIRPosition())); bool IsGlobal = isAssumedGlobal();
bool IsNonNull = isAssumedNonNull();
bool IsGlobal = isKnownGlobal();
takeAssumedDerefBytesMinimum( takeAssumedDerefBytesMinimum(
computeAssumedDerefenceableBytes(A, V, IsNonNull, IsGlobal)); computeAssumedDerefenceableBytes(A, V, IsGlobal));
updateAssumedNonNullGlobalState(IsNonNull, IsGlobal); GlobalState.intersectAssumedBits(IsGlobal);
return BeforeState == static_cast<DerefState>(*this) ? ChangeStatus::UNCHANGED return BeforeState == static_cast<DerefState>(*this) ? ChangeStatus::UNCHANGED
: ChangeStatus::CHANGED; : ChangeStatus::CHANGED;