[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