[llvm] r369142 - [Attributor] Introduce initialize calls and move code to keep attributes concise

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 16 12:36:17 PDT 2019


Author: jdoerfert
Date: Fri Aug 16 12:36:17 2019
New Revision: 369142

URL: http://llvm.org/viewvc/llvm-project?rev=369142&view=rev
Log:
[Attributor] Introduce initialize calls and move code to keep attributes concise

Summary:
This patch should not change the behavior except that the added
initialize methods might indicate an optimistic fixpoint earlier. The
code movement is done to keep the attribute definitions in a single
block where it makes sense. No functional changes intended there.

Reviewers: uenoku, sstefan1

Subscribers: hiraditya, bollu, llvm-commits

Tags: #llvm

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

Modified:
    llvm/trunk/lib/Transforms/IPO/Attributor.cpp

Modified: llvm/trunk/lib/Transforms/IPO/Attributor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Attributor.cpp?rev=369142&r1=369141&r2=369142&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Attributor.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Attributor.cpp Fri Aug 16 12:36:17 2019
@@ -457,12 +457,36 @@ void IRPosition::verify() {
 struct AANoUnwindImpl : AANoUnwind {
   AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
 
+  /// See AbstractAttribute::initialize(...).
+  void initialize(Attributor &A) override {
+    if (hasAttr({Attribute::NoUnwind}))
+      indicateOptimisticFixpoint();
+  }
+
   const std::string getAsStr() const override {
     return getAssumed() ? "nounwind" : "may-unwind";
   }
 
   /// See AbstractAttribute::updateImpl(...).
-  ChangeStatus updateImpl(Attributor &A) override;
+  ChangeStatus updateImpl(Attributor &A) override {
+    auto Opcodes = {
+        (unsigned)Instruction::Invoke,      (unsigned)Instruction::CallBr,
+        (unsigned)Instruction::Call,        (unsigned)Instruction::CleanupRet,
+        (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
+
+    auto CheckForNoUnwind = [&](Instruction &I) {
+      if (!I.mayThrow())
+        return true;
+
+      auto *NoUnwindAA = A.getAAFor<AANoUnwind>(*this, IRPosition::value(I));
+      return NoUnwindAA && NoUnwindAA->isAssumedNoUnwind();
+    };
+
+    if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
+      return indicatePessimisticFixpoint();
+
+    return ChangeStatus::UNCHANGED;
+  }
 };
 
 struct AANoUnwindFunction final : public AANoUnwindImpl {
@@ -472,28 +496,6 @@ struct AANoUnwindFunction final : public
   void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
 };
 
-ChangeStatus AANoUnwindImpl::updateImpl(Attributor &A) {
-
-  // The map from instruction opcodes to those instructions in the function.
-  auto Opcodes = {
-      (unsigned)Instruction::Invoke,      (unsigned)Instruction::CallBr,
-      (unsigned)Instruction::Call,        (unsigned)Instruction::CleanupRet,
-      (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
-
-  auto CheckForNoUnwind = [&](Instruction &I) {
-    if (!I.mayThrow())
-      return true;
-
-    auto *NoUnwindAA = A.getAAFor<AANoUnwind>(*this, IRPosition::value(I));
-    return NoUnwindAA && NoUnwindAA->isAssumedNoUnwind();
-  };
-
-  if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
-    return indicatePessimisticFixpoint();
-
-  return ChangeStatus::UNCHANGED;
-}
-
 /// --------------------- Function Return Values -------------------------------
 
 /// "Attribute" that collects all potential returned values and the return
@@ -834,6 +836,12 @@ struct AAReturnedValuesFunction final :
 struct AANoSyncImpl : AANoSync {
   AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
 
+  /// See AbstractAttribute::initialize(...).
+  void initialize(Attributor &A) override {
+    if (hasAttr({Attribute::NoSync}))
+      indicateOptimisticFixpoint();
+  }
+
   const std::string getAsStr() const override {
     return getAssumed() ? "nosync" : "may-sync";
   }
@@ -998,13 +1006,33 @@ ChangeStatus AANoSyncImpl::updateImpl(At
 struct AANoFreeImpl : public AANoFree {
   AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
 
+  /// See AbstractAttribute::initialize(...).
+  void initialize(Attributor &A) override {
+    if (hasAttr({Attribute::NoFree}))
+      indicateOptimisticFixpoint();
+  }
+
+  /// See AbstractAttribute::updateImpl(...).
+  ChangeStatus updateImpl(Attributor &A) override {
+    auto CheckForNoFree = [&](Instruction &I) {
+      ImmutableCallSite ICS(&I);
+      if (ICS.hasFnAttr(Attribute::NoFree))
+        return true;
+
+      auto *NoFreeAA =
+          A.getAAFor<AANoFreeImpl>(*this, IRPosition::callsite_function(ICS));
+      return NoFreeAA && NoFreeAA->isAssumedNoFree();
+    };
+
+    if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
+      return indicatePessimisticFixpoint();
+    return ChangeStatus::UNCHANGED;
+  }
+
   /// See AbstractAttribute::getAsStr().
   const std::string getAsStr() const override {
     return getAssumed() ? "nofree" : "may-free";
   }
-
-  /// See AbstractAttribute::updateImpl(...).
-  ChangeStatus updateImpl(Attributor &A) override;
 };
 
 struct AANoFreeFunction final : public AANoFreeImpl {
@@ -1014,23 +1042,6 @@ struct AANoFreeFunction final : public A
   void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
 };
 
-ChangeStatus AANoFreeImpl::updateImpl(Attributor &A) {
-
-  auto CheckForNoFree = [&](Instruction &I) {
-    ImmutableCallSite ICS(&I);
-    if (ICS.hasFnAttr(Attribute::NoFree))
-      return true;
-
-    auto *NoFreeAA =
-        A.getAAFor<AANoFreeImpl>(*this, IRPosition::callsite_function(ICS));
-    return NoFreeAA && NoFreeAA->isAssumedNoFree();
-  };
-
-  if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
-    return indicatePessimisticFixpoint();
-  return ChangeStatus::UNCHANGED;
-}
-
 /// ------------------------ NonNull Argument Attribute ------------------------
 struct AANonNullImpl : AANonNull {
   AANonNullImpl(const IRPosition &IRP) : AANonNull(IRP) {}
@@ -1084,28 +1095,53 @@ struct AANonNullReturned final : AANonNu
   AANonNullReturned(const IRPosition &IRP) : AANonNullImpl(IRP) {}
 
   /// See AbstractAttribute::updateImpl(...).
-  ChangeStatus updateImpl(Attributor &A) override;
+  ChangeStatus updateImpl(Attributor &A) override {
+    std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
+        this->generatePredicate(A);
+
+    if (!A.checkForAllReturnedValuesAndReturnInsts(Pred, *this))
+      return indicatePessimisticFixpoint();
+    return ChangeStatus::UNCHANGED;
+  }
 
   /// See AbstractAttribute::trackStatistics()
   void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
 };
 
-ChangeStatus AANonNullReturned::updateImpl(Attributor &A) {
-
-  std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
-      this->generatePredicate(A);
-
-  if (!A.checkForAllReturnedValuesAndReturnInsts(Pred, *this))
-    return indicatePessimisticFixpoint();
-  return ChangeStatus::UNCHANGED;
-}
-
 /// NonNull attribute for function argument.
 struct AANonNullArgument final : AANonNullImpl {
   AANonNullArgument(const IRPosition &IRP) : AANonNullImpl(IRP) {}
 
   /// See AbstractAttribute::updateImpl(...).
-  ChangeStatus updateImpl(Attributor &A) override;
+  ChangeStatus updateImpl(Attributor &A) override {
+    unsigned ArgNo = getArgNo();
+
+    // Callback function
+    std::function<bool(CallSite)> CallSiteCheck = [&](CallSite CS) {
+      assert(CS && "Sanity check: Call site was not initialized properly!");
+
+      IRPosition CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
+      if (CSArgPos.hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
+        return true;
+
+      // Check that NonNullAA is AANonNullCallSiteArgument.
+      if (auto *NonNullAA = A.getAAFor<AANonNullImpl>(*this, CSArgPos)) {
+        ImmutableCallSite ICS(&NonNullAA->getAnchorValue());
+        if (ICS && CS.getInstruction() == ICS.getInstruction())
+          return NonNullAA->isAssumedNonNull();
+        return false;
+      }
+
+      Value *V = CS.getArgOperand(ArgNo);
+      if (isKnownNonZero(V, A.getDataLayout()))
+        return true;
+
+      return false;
+    };
+    if (!A.checkForAllCallSites(CallSiteCheck, *this, true))
+      return indicatePessimisticFixpoint();
+    return ChangeStatus::UNCHANGED;
+  }
 
   /// See AbstractAttribute::trackStatistics()
   void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
@@ -1124,82 +1160,29 @@ struct AANonNullCallSiteArgument final :
   }
 
   /// See AbstractAttribute::updateImpl(Attributor &A).
-  ChangeStatus updateImpl(Attributor &A) override;
+  ChangeStatus updateImpl(Attributor &A) override {
+    // NOTE: Never look at the argument of the callee in this method.
+    //       If we do this, "nonnull" is always deduced because of the
+    //       assumption.
 
-  /// See AbstractAttribute::trackStatistics()
-  void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
-};
+    Value &V = getAssociatedValue();
+    auto *NonNullAA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
 
-ChangeStatus AANonNullArgument::updateImpl(Attributor &A) {
-  unsigned ArgNo = getArgNo();
+    if (!NonNullAA || !NonNullAA->isAssumedNonNull())
+      return indicatePessimisticFixpoint();
 
-  // Callback function
-  std::function<bool(CallSite)> CallSiteCheck = [&](CallSite CS) {
-    assert(CS && "Sanity check: Call site was not initialized properly!");
-
-    IRPosition CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
-    if (CSArgPos.hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
-      return true;
-
-    // Check that NonNullAA is AANonNullCallSiteArgument.
-    if (auto *NonNullAA = A.getAAFor<AANonNullImpl>(*this, CSArgPos)) {
-      ImmutableCallSite ICS(&NonNullAA->getAnchorValue());
-      if (ICS && CS.getInstruction() == ICS.getInstruction())
-        return NonNullAA->isAssumedNonNull();
-      return false;
-    }
-
-    Value *V = CS.getArgOperand(ArgNo);
-    if (isKnownNonZero(V, A.getDataLayout()))
-      return true;
-
-    return false;
-  };
-  if (!A.checkForAllCallSites(CallSiteCheck, *this, true))
-    return indicatePessimisticFixpoint();
-  return ChangeStatus::UNCHANGED;
-}
-
-ChangeStatus AANonNullCallSiteArgument::updateImpl(Attributor &A) {
-  // NOTE: Never look at the argument of the callee in this method.
-  //       If we do this, "nonnull" is always deduced because of the assumption.
-
-  Value &V = getAssociatedValue();
-  auto *NonNullAA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
-
-  if (!NonNullAA || !NonNullAA->isAssumedNonNull())
-    return indicatePessimisticFixpoint();
-
-  return ChangeStatus::UNCHANGED;
-}
-
-/// ------------------------ Will-Return Attributes ----------------------------
-
-struct AAWillReturnImpl : public AAWillReturn {
-  AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
-
-  /// See AbstractAttribute::getAsStr()
-  const std::string getAsStr() const override {
-    return getAssumed() ? "willreturn" : "may-noreturn";
+    return ChangeStatus::UNCHANGED;
   }
-};
-
-struct AAWillReturnFunction final : AAWillReturnImpl {
-  AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
-
-  /// See AbstractAttribute::initialize(...).
-  void initialize(Attributor &A) override;
-
-  /// See AbstractAttribute::updateImpl(...).
-  ChangeStatus updateImpl(Attributor &A) override;
 
   /// See AbstractAttribute::trackStatistics()
-  void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
+  void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
 };
 
+/// ------------------------ Will-Return Attributes ----------------------------
+
 // Helper function that checks whether a function has any cycle.
 // TODO: Replace with more efficent code
-bool containsCycle(Function &F) {
+static bool containsCycle(Function &F) {
   SmallPtrSet<BasicBlock *, 32> Visited;
 
   // Traverse BB by dfs and check whether successor is already visited.
@@ -1217,41 +1200,61 @@ bool containsCycle(Function &F) {
 // endless loop
 // FIXME: Any cycle is regarded as endless loop for now.
 //        We have to allow some patterns.
-bool containsPossiblyEndlessLoop(Function &F) { return containsCycle(F); }
+static bool containsPossiblyEndlessLoop(Function &F) {
+  return containsCycle(F);
+}
 
-void AAWillReturnFunction::initialize(Attributor &A) {
-  Function &F = *getAnchorScope();
+struct AAWillReturnImpl : public AAWillReturn {
+  AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
 
-  if (containsPossiblyEndlessLoop(F))
-    indicatePessimisticFixpoint();
-}
+  /// See AbstractAttribute::getAsStr()
+  const std::string getAsStr() const override {
+    return getAssumed() ? "willreturn" : "may-noreturn";
+  }
+};
 
-ChangeStatus AAWillReturnFunction::updateImpl(Attributor &A) {
-  // The map from instruction opcodes to those instructions in the function.
+struct AAWillReturnFunction final : AAWillReturnImpl {
+  AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
 
-  auto CheckForWillReturn = [&](Instruction &I) {
-    ImmutableCallSite ICS(&I);
-    if (ICS.hasFnAttr(Attribute::WillReturn))
-      return true;
+  /// See AbstractAttribute::initialize(...).
+  void initialize(Attributor &A) override {
+    Function &F = *getAnchorScope();
 
-    IRPosition IPos = IRPosition::callsite_function(ICS);
-    auto *WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
-    if (!WillReturnAA || !WillReturnAA->isAssumedWillReturn())
-      return false;
+    if (containsPossiblyEndlessLoop(F))
+      indicatePessimisticFixpoint();
+  }
 
-    // FIXME: Prohibit any recursion for now.
-    if (ICS.hasFnAttr(Attribute::NoRecurse))
-      return true;
+  /// See AbstractAttribute::updateImpl(...).
+  ChangeStatus updateImpl(Attributor &A) override {
+    // The map from instruction opcodes to those instructions in the function.
 
-    auto *NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
-    return NoRecurseAA && NoRecurseAA->isAssumedNoRecurse();
-  };
+    auto CheckForWillReturn = [&](Instruction &I) {
+      ImmutableCallSite ICS(&I);
+      if (ICS.hasFnAttr(Attribute::WillReturn))
+        return true;
 
-  if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
-    return indicatePessimisticFixpoint();
+      IRPosition IPos = IRPosition::callsite_function(ICS);
+      auto *WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
+      if (!WillReturnAA || !WillReturnAA->isAssumedWillReturn())
+        return false;
 
-  return ChangeStatus::UNCHANGED;
-}
+      // FIXME: Prohibit any recursion for now.
+      if (ICS.hasFnAttr(Attribute::NoRecurse))
+        return true;
+
+      auto *NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
+      return NoRecurseAA && NoRecurseAA->isAssumedNoRecurse();
+    };
+
+    if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
+      return indicatePessimisticFixpoint();
+
+    return ChangeStatus::UNCHANGED;
+  }
+
+  /// See AbstractAttribute::trackStatistics()
+  void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
+};
 
 /// ------------------------ NoAlias Argument Attribute ------------------------
 
@@ -1279,47 +1282,45 @@ struct AANoAliasReturned final : AANoAli
   }
 
   /// See AbstractAttribute::updateImpl(...).
-  virtual ChangeStatus updateImpl(Attributor &A) override;
+  virtual ChangeStatus updateImpl(Attributor &A) override {
 
-  /// See AbstractAttribute::trackStatistics()
-  void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
-};
-
-ChangeStatus AANoAliasReturned::updateImpl(Attributor &A) {
-
-  auto CheckReturnValue = [&](Value &RV) -> bool {
-    if (Constant *C = dyn_cast<Constant>(&RV))
-      if (C->isNullValue() || isa<UndefValue>(C))
-        return true;
+    auto CheckReturnValue = [&](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;
 
-    /// For now, we can only deduce noalias if we have call sites.
-    /// FIXME: add more support.
-    ImmutableCallSite ICS(&RV);
-    if (!ICS)
-      return false;
+      if (!ICS.returnDoesNotAlias()) {
+        auto *NoAliasAA =
+            A.getAAFor<AANoAlias>(*this, IRPosition::callsite_returned(ICS));
+        if (!NoAliasAA || !NoAliasAA->isAssumedNoAlias())
+          return false;
+      }
 
-    if (!ICS.returnDoesNotAlias()) {
-      auto *NoAliasAA =
-          A.getAAFor<AANoAlias>(*this, IRPosition::callsite_returned(ICS));
-      if (!NoAliasAA || !NoAliasAA->isAssumedNoAlias())
+      /// 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;
-    }
 
-    /// 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;
+    };
 
-    return true;
-  };
+    if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
+      return indicatePessimisticFixpoint();
 
-  if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
-    return indicatePessimisticFixpoint();
+    return ChangeStatus::UNCHANGED;
+  }
 
-  return ChangeStatus::UNCHANGED;
-}
+  /// See AbstractAttribute::trackStatistics()
+  void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
+};
 
 /// -------------------AAIsDead Function Attribute-----------------------
 




More information about the llvm-commits mailing list