[llvm] r368224 - [Attributor] Introduce a state wrapper class
Johannes Doerfert via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 7 15:34:26 PDT 2019
Author: jdoerfert
Date: Wed Aug 7 15:34:26 2019
New Revision: 368224
URL: http://llvm.org/viewvc/llvm-project?rev=368224&view=rev
Log:
[Attributor] Introduce a state wrapper class
Summary:
The wrapper reduces boilerplate code and also provide a nice way to
determine the state type used by an abstract attributes statically via
AAType::StateType.
This was already discussed as part of the review of D65711.
Reviewers: sstefan1, uenoku
Subscribers: hiraditya, bollu, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D65786
Modified:
llvm/trunk/include/llvm/Transforms/IPO/Attributor.h
llvm/trunk/lib/Transforms/IPO/Attributor.cpp
Modified: llvm/trunk/include/llvm/Transforms/IPO/Attributor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/Attributor.h?rev=368224&r1=368223&r2=368224&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/IPO/Attributor.h (original)
+++ llvm/trunk/include/llvm/Transforms/IPO/Attributor.h Wed Aug 7 15:34:26 2019
@@ -690,6 +690,19 @@ struct IRAttributeManifest {
const ArrayRef<Attribute> &DeducedAttrs);
};
+/// Helper to tie a abstract state implementation to an abstract attribute.
+template <typename StateTy, typename Base>
+struct StateWrapper : public StateTy, public Base {
+ /// Provide static access to the type of the state.
+ using StateType = StateTy;
+
+ /// See AbstractAttribute::getState(...).
+ StateType &getState() override { return *this; }
+
+ /// See AbstractAttribute::getState(...).
+ const AbstractState &getState() const override { return *this; }
+};
+
/// Helper class that provides common functionality to manifest IR attributes.
template <Attribute::AttrKind AK, typename Base>
struct IRAttribute : public IRPosition, public Base, public IRAttributeManifest {
@@ -769,6 +782,7 @@ struct IRAttribute : public IRPosition,
/// NOTE: The mechanics of adding a new "concrete" abstract attribute are
/// described in the file comment.
struct AbstractAttribute {
+ using StateType = AbstractState;
/// Virtual destructor.
virtual ~AbstractAttribute() {}
@@ -784,7 +798,8 @@ struct AbstractAttribute {
virtual void initialize(Attributor &A, InformationCache &InfoCache) {}
/// Return the internal abstract state for inspection.
- virtual const AbstractState &getState() const = 0;
+ virtual StateType &getState() = 0;
+ virtual const StateType &getState() const = 0;
/// Return an IR position, see struct IRPosition.
virtual const IRPosition &getIRPosition() const = 0;
@@ -820,9 +835,6 @@ protected:
/// Return an IR position, see struct IRPosition.
virtual IRPosition &getIRPosition() = 0;
- /// Return the internal abstract state for careful modification.
- virtual AbstractState &getState() = 0;
-
/// The actual update/transfer function which has to be implemented by the
/// derived classes.
///
@@ -875,41 +887,47 @@ struct AAReturnedValues
static const char ID;
};
-struct AANoUnwind : public IRAttribute<Attribute::NoUnwind, AbstractAttribute> {
+struct AANoUnwind
+ : public IRAttribute<Attribute::NoUnwind,
+ StateWrapper<BooleanState, AbstractAttribute>> {
IRPositionConstructorForward(AANoUnwind, IRAttribute);
/// Returns true if nounwind is assumed.
- virtual bool isAssumedNoUnwind() const = 0;
+ bool isAssumedNoUnwind() const { return getAssumed(); }
/// Returns true if nounwind is known.
- virtual bool isKnownNoUnwind() const = 0;
+ bool isKnownNoUnwind() const { return getKnown(); }
/// Unique ID (due to the unique address)
static const char ID;
};
-struct AANoSync : public IRAttribute<Attribute::NoSync, AbstractAttribute> {
+struct AANoSync
+ : public IRAttribute<Attribute::NoSync,
+ StateWrapper<BooleanState, AbstractAttribute>> {
IRPositionConstructorForward(AANoSync, IRAttribute);
/// Returns true if "nosync" is assumed.
- virtual bool isAssumedNoSync() const = 0;
+ bool isAssumedNoSync() const { return getAssumed(); }
/// Returns true if "nosync" is known.
- virtual bool isKnownNoSync() const = 0;
+ bool isKnownNoSync() const { return getKnown(); }
/// Unique ID (due to the unique address)
static const char ID;
};
/// An abstract interface for all nonnull attributes.
-struct AANonNull : public IRAttribute<Attribute::NonNull, AbstractAttribute> {
+struct AANonNull
+ : public IRAttribute<Attribute::NonNull,
+ StateWrapper<BooleanState, AbstractAttribute>> {
IRPositionConstructorForward(AANonNull, IRAttribute);
/// Return true if we assume that the underlying value is nonnull.
- virtual bool isAssumedNonNull() const = 0;
+ bool isAssumedNonNull() const { return getAssumed(); }
/// Return true if we know that underlying value is nonnull.
- virtual bool isKnownNonNull() const = 0;
+ bool isKnownNonNull() const { return getKnown(); }
/// Unique ID (due to the unique address)
static const char ID;
@@ -917,14 +935,15 @@ struct AANonNull : public IRAttribute<At
/// An abstract attribute for norecurse.
struct AANoRecurse
- : public IRAttribute<Attribute::NoRecurse, AbstractAttribute> {
+ : public IRAttribute<Attribute::NoRecurse,
+ StateWrapper<BooleanState, AbstractAttribute>> {
IRPositionConstructorForward(AANoRecurse, IRAttribute);
- /// Return true if "norecurse" is known.
- virtual bool isKnownNoRecurse() const = 0;
-
/// Return true if "norecurse" is assumed.
- virtual bool isAssumedNoRecurse() const = 0;
+ bool isAssumedNoRecurse() const { return getAssumed(); }
+
+ /// Return true if "norecurse" is known.
+ bool isKnownNoRecurse() const { return getKnown(); }
/// Unique ID (due to the unique address)
static const char ID;
@@ -932,63 +951,71 @@ struct AANoRecurse
/// An abstract attribute for willreturn.
struct AAWillReturn
- : public IRAttribute<Attribute::WillReturn, AbstractAttribute> {
+ : public IRAttribute<Attribute::WillReturn,
+ StateWrapper<BooleanState, AbstractAttribute>> {
IRPositionConstructorForward(AAWillReturn, IRAttribute);
- /// Return true if "willreturn" is known.
- virtual bool isKnownWillReturn() const = 0;
-
/// Return true if "willreturn" is assumed.
- virtual bool isAssumedWillReturn() const = 0;
+ bool isAssumedWillReturn() const { return getAssumed(); }
+
+ /// Return true if "willreturn" is known.
+ bool isKnownWillReturn() const { return getKnown(); }
/// Unique ID (due to the unique address)
static const char ID;
};
/// An abstract interface for all noalias attributes.
-struct AANoAlias : public IRAttribute<Attribute::NoAlias, AbstractAttribute> {
+struct AANoAlias
+ : public IRAttribute<Attribute::NoAlias,
+ StateWrapper<BooleanState, AbstractAttribute>> {
IRPositionConstructorForward(AANoAlias, IRAttribute);
/// Return true if we assume that the underlying value is alias.
- virtual bool isAssumedNoAlias() const = 0;
+ bool isAssumedNoAlias() const { return getAssumed(); }
/// Return true if we know that underlying value is noalias.
- virtual bool isKnownNoAlias() const = 0;
+ bool isKnownNoAlias() const { return getKnown(); }
/// Unique ID (due to the unique address)
static const char ID;
};
/// An AbstractAttribute for nofree.
-struct AANoFree : public IRAttribute<Attribute::NoFree, AbstractAttribute> {
+struct AANoFree
+ : public IRAttribute<Attribute::NoFree,
+ StateWrapper<BooleanState, AbstractAttribute>> {
IRPositionConstructorForward(AANoFree, IRAttribute);
- /// Return true if "nofree" is known.
- virtual bool isKnownNoFree() const = 0;
-
/// Return true if "nofree" is assumed.
- virtual bool isAssumedNoFree() const = 0;
+ bool isAssumedNoFree() const { return getAssumed(); }
+
+ /// Return true if "nofree" is known.
+ bool isKnownNoFree() const { return getKnown(); }
/// Unique ID (due to the unique address)
static const char ID;
};
/// An AbstractAttribute for noreturn.
-struct AANoReturn : public IRAttribute<Attribute::NoReturn, AbstractAttribute> {
+struct AANoReturn
+ : public IRAttribute<Attribute::NoReturn,
+ StateWrapper<BooleanState, AbstractAttribute>> {
IRPositionConstructorForward(AANoReturn, IRAttribute);
- /// Return true if the underlying object is known to never return.
- virtual bool isKnownNoReturn() const = 0;
-
/// Return true if the underlying object is assumed to never return.
- virtual bool isAssumedNoReturn() const = 0;
+ bool isAssumedNoReturn() const { return getAssumed(); }
+
+ /// Return true if the underlying object is known to never return.
+ bool isKnownNoReturn() const { return getKnown(); }
/// Unique ID (due to the unique address)
static const char ID;
};
/// An abstract interface for liveness abstract attribute.
-struct AAIsDead : public AbstractAttribute, public IRPosition {
+struct AAIsDead : public StateWrapper<BooleanState, AbstractAttribute>,
+ public IRPosition {
IRPositionConstructorForward(AAIsDead, IRPosition);
/// Returns true if \p BB is assumed dead.
@@ -1058,14 +1085,16 @@ struct AADereferenceable
};
/// An abstract interface for all align attributes.
-struct AAAlign : public IRAttribute<Attribute::Alignment, AbstractAttribute> {
+struct AAAlign
+ : public IRAttribute<Attribute::Alignment,
+ StateWrapper<IntegerState, AbstractAttribute>> {
IRPositionConstructorForward(AAAlign, IRAttribute);
/// Return assumed alignment.
- virtual unsigned getAssumedAlign() const = 0;
+ unsigned getAssumedAlign() const { return getAssumed(); }
/// Return known alignemnt.
- virtual unsigned getKnownAlign() const = 0;
+ unsigned getKnownAlign() const { return getKnown(); }
/// Unique ID (due to the unique address)
static const char ID;
Modified: llvm/trunk/lib/Transforms/IPO/Attributor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Attributor.cpp?rev=368224&r1=368223&r2=368224&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Attributor.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Attributor.cpp Wed Aug 7 15:34:26 2019
@@ -385,27 +385,15 @@ ChangeStatus AbstractAttribute::update(A
/// -----------------------NoUnwind Function Attribute--------------------------
-struct AANoUnwindImpl : AANoUnwind, BooleanState {
+struct AANoUnwindImpl : AANoUnwind {
IRPositionConstructorForward(AANoUnwindImpl, AANoUnwind);
- /// See AbstractAttribute::getState()
- /// {
- AbstractState &getState() override { return *this; }
- const AbstractState &getState() const override { return *this; }
- /// }
-
const std::string getAsStr() const override {
return getAssumed() ? "nounwind" : "may-unwind";
}
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
-
- /// See AANoUnwind::isAssumedNoUnwind().
- bool isAssumedNoUnwind() const override { return getAssumed(); }
-
- /// See AANoUnwind::isKnownNoUnwind().
- bool isKnownNoUnwind() const override { return getKnown(); }
};
struct AANoUnwindFunction final : public AANoUnwindImpl {
@@ -787,15 +775,9 @@ ChangeStatus AAReturnedValuesImpl::updat
/// ------------------------ NoSync Function Attribute -------------------------
-struct AANoSyncImpl : AANoSync, BooleanState {
+struct AANoSyncImpl : AANoSync {
IRPositionConstructorForward(AANoSyncImpl, AANoSync);
- /// See AbstractAttribute::getState()
- /// {
- AbstractState &getState() override { return *this; }
- const AbstractState &getState() const override { return *this; }
- /// }
-
const std::string getAsStr() const override {
return getAssumed() ? "nosync" : "may-sync";
}
@@ -803,12 +785,6 @@ struct AANoSyncImpl : AANoSync, BooleanS
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
- /// See AANoSync::isAssumedNoSync()
- bool isAssumedNoSync() const override { return getAssumed(); }
-
- /// See AANoSync::isKnownNoSync()
- bool isKnownNoSync() const override { return getKnown(); }
-
/// Helper function used to determine whether an instruction is non-relaxed
/// atomic. In other words, if an atomic instruction does not have unordered
/// or monotonic ordering
@@ -962,15 +938,9 @@ ChangeStatus AANoSyncImpl::updateImpl(At
/// ------------------------ No-Free Attributes ----------------------------
-struct AANoFreeImpl : public AANoFree, BooleanState {
+struct AANoFreeImpl : public AANoFree {
IRPositionConstructorForward(AANoFreeImpl, AANoFree);
- /// See AbstractAttribute::getState()
- ///{
- AbstractState &getState() override { return *this; }
- const AbstractState &getState() const override { return *this; }
- ///}
-
/// See AbstractAttribute::getAsStr().
const std::string getAsStr() const override {
return getAssumed() ? "nofree" : "may-free";
@@ -978,12 +948,6 @@ struct AANoFreeImpl : public AANoFree, B
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
-
- /// Return true if "nofree" is assumed.
- bool isAssumedNoFree() const override { return getAssumed(); }
-
- /// Return true if "nofree" is known.
- bool isKnownNoFree() const override { return getKnown(); }
};
struct AANoFreeFunction final : public AANoFreeImpl {
@@ -1008,26 +972,15 @@ ChangeStatus AANoFreeImpl::updateImpl(At
}
/// ------------------------ NonNull Argument Attribute ------------------------
-struct AANonNullImpl : AANonNull, BooleanState {
+struct AANonNullImpl : AANonNull {
IRPositionConstructorForward(AANonNullImpl, AANonNull);
- /// See AbstractAttribute::getState()
- /// {
- AbstractState &getState() override { return *this; }
- const AbstractState &getState() const override { return *this; }
- /// }
/// See AbstractAttribute::getAsStr().
const std::string getAsStr() const override {
return getAssumed() ? "nonnull" : "may-null";
}
- /// See AANonNull::isAssumedNonNull().
- bool isAssumedNonNull() const override { return getAssumed(); }
-
- /// See AANonNull::isKnownNonNull().
- bool isKnownNonNull() const override { return getKnown(); }
-
/// Generate a predicate that checks if a given value is assumed nonnull.
/// The generated function returns true if a value satisfies any of
/// following conditions.
@@ -1189,21 +1142,9 @@ AANonNullCallSiteArgument::updateImpl(At
/// ------------------------ Will-Return Attributes ----------------------------
-struct AAWillReturnImpl : public AAWillReturn, BooleanState {
+struct AAWillReturnImpl : public AAWillReturn {
IRPositionConstructorForward(AAWillReturnImpl, AAWillReturn);
- /// See AAWillReturn::isKnownWillReturn().
- bool isKnownWillReturn() const override { return getKnown(); }
-
- /// See AAWillReturn::isAssumedWillReturn().
- bool isAssumedWillReturn() const override { return getAssumed(); }
-
- /// See AbstractAttribute::getState(...).
- AbstractState &getState() override { return *this; }
-
- /// See AbstractAttribute::getState(...).
- const AbstractState &getState() const override { return *this; }
-
/// See AbstractAttribute::getAsStr()
const std::string getAsStr() const override {
return getAssumed() ? "willreturn" : "may-noreturn";
@@ -1283,24 +1224,12 @@ ChangeStatus AAWillReturnFunction::updat
/// ------------------------ NoAlias Argument Attribute ------------------------
-struct AANoAliasImpl : AANoAlias, BooleanState {
+struct AANoAliasImpl : AANoAlias {
IRPositionConstructorForward(AANoAliasImpl, AANoAlias);
- /// 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.
@@ -1363,7 +1292,7 @@ ChangeStatus AANoAliasReturned::updateIm
/// -------------------AAIsDead Function Attribute-----------------------
-struct AAIsDeadImpl : public AAIsDead, BooleanState {
+struct AAIsDeadImpl : public AAIsDead {
IRPositionConstructorForward(AAIsDeadImpl, AAIsDead);
void initialize(Attributor &A, InformationCache &InfoCache) override {
@@ -1502,12 +1431,6 @@ struct AAIsDeadImpl : public AAIsDead, B
return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
}
- /// See AbstractAttribute::getState()
- /// {
- AbstractState &getState() override { return *this; }
- const AbstractState &getState() const override { return *this; }
- /// }
-
/// Collection of to be explored paths.
SmallSetVector<const Instruction *, 8> ToBeExploredPaths;
@@ -1696,11 +1619,12 @@ struct DerefState : AbstractState {
struct AADereferenceableImpl : AADereferenceable, DerefState {
IRPositionConstructorForward(AADereferenceableImpl, AADereferenceable);
+ using StateType = DerefState;
/// See AbstractAttribute::getState()
/// {
- AbstractState &getState() override { return *this; }
- const AbstractState &getState() const override { return *this; }
+ StateType &getState() override { return *this; }
+ const StateType &getState() const override { return *this; }
/// }
/// See AADereferenceable::getAssumedDereferenceableBytes().
@@ -1963,30 +1887,18 @@ AADereferenceableCallSiteArgument::updat
// ------------------------ Align Argument Attribute ------------------------
-struct AAAlignImpl : AAAlign, IntegerState {
+struct AAAlignImpl : AAAlign {
IRPositionConstructorForward(AAAlignImpl, AAAlign);
// Max alignemnt value allowed in IR
static const unsigned MAX_ALIGN = 1U << 29;
- /// See AbstractAttribute::getState()
- /// {
- AbstractState &getState() override { return *this; }
- const AbstractState &getState() const override { return *this; }
- /// }
-
virtual const std::string getAsStr() const override {
return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
"-" + std::to_string(getAssumedAlign()) + ">")
: "unknown-align";
}
- /// See AAAlign::getAssumedAlign().
- unsigned getAssumedAlign() const override { return getAssumed(); }
-
- /// See AAAlign::getKnownAlign().
- unsigned getKnownAlign() const override { return getKnown(); }
-
/// See AbstractAttriubute::initialize(...).
void initialize(Attributor &A, InformationCache &InfoCache) override {
takeAssumedMinimum(MAX_ALIGN);
@@ -2135,21 +2047,9 @@ ChangeStatus AAAlignCallSiteArgument::up
}
/// ------------------ Function No-Return Attribute ----------------------------
-struct AANoReturnImpl : public AANoReturn, BooleanState {
+struct AANoReturnImpl : public AANoReturn {
IRPositionConstructorForward(AANoReturnImpl, AANoReturn);
- /// See AbstractAttribute::getState()
- /// {
- AbstractState &getState() override { return *this; }
- const AbstractState &getState() const override { return *this; }
- /// }
-
- /// Return true if the underlying object is known to never return.
- bool isKnownNoReturn() const override { return getKnown(); }
-
- /// Return true if the underlying object is assumed to never return.
- bool isAssumedNoReturn() const override { return getAssumed(); }
-
/// See AbstractAttribute::getAsStr().
const std::string getAsStr() const override {
return getAssumed() ? "noreturn" : "may-return";
More information about the llvm-commits
mailing list