[llvm] 16f777f - [NFC] Add debug and stat counters to assume queries and assume builder

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 14 12:49:35 PDT 2020


Author: Tyker
Date: 2020-07-14T21:49:14+02:00
New Revision: 16f777f4217cfcdcf6ddce8eb1e3525a65563c43

URL: https://github.com/llvm/llvm-project/commit/16f777f4217cfcdcf6ddce8eb1e3525a65563c43
DIFF: https://github.com/llvm/llvm-project/commit/16f777f4217cfcdcf6ddce8eb1e3525a65563c43.diff

LOG: [NFC] Add debug and stat counters to assume queries and assume builder

Summary:
Add debug counter and stats counter to assume queries and assume builder
here is the collected stats on a build of check-llvm + check-clang.
  "assume-builder.NumAssumeBuilt": 2720879,
  "assume-builder.NumAssumesMerged": 761396,
  "assume-builder.NumAssumesRemoved": 1576212,
  "assume-builder.NumBundlesInAssumes": 6518809,
  "assume-queries.NumAssumeQueries": 85566380,
  "assume-queries.NumUsefullAssumeQueries": 2727360,
the NumUsefullAssumeQueries stat is actually pessimistic because in a few places queries
ask to keep providing information to try to get better information. and this isn't counted
as a usefull query evem tho it can be usefull

Reviewers: jdoerfert

Reviewed By: jdoerfert

Subscribers: hiraditya, llvm-commits

Tags: #llvm

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

Added: 
    llvm/test/Analysis/ValueTracking/assume-queries-counter.ll
    llvm/test/Transforms/Util/assume-builder-counter.ll

Modified: 
    llvm/lib/Analysis/AssumeBundleQueries.cpp
    llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/AssumeBundleQueries.cpp b/llvm/lib/Analysis/AssumeBundleQueries.cpp
index af81216f6526..05fe05a0bd85 100644
--- a/llvm/lib/Analysis/AssumeBundleQueries.cpp
+++ b/llvm/lib/Analysis/AssumeBundleQueries.cpp
@@ -6,17 +6,29 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define DEBUG_TYPE "assume-queries"
+
 #include "llvm/Analysis/AssumeBundleQueries.h"
+#include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/InstIterator.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/PatternMatch.h"
+#include "llvm/Support/DebugCounter.h"
 
 using namespace llvm;
 using namespace llvm::PatternMatch;
 
+STATISTIC(NumAssumeQueries, "Number of Queries into an assume assume bundles");
+STATISTIC(
+    NumUsefullAssumeQueries,
+    "Number of Queries into an assume assume bundles that were satisfied");
+
+DEBUG_COUNTER(AssumeQueryCounter, "assume-queries-counter",
+              "Controls which assumes gets created");
+
 static bool bundleHasArgument(const CallBase::BundleOpInfo &BOI, unsigned Idx) {
   return BOI.End - BOI.Begin > Idx;
 }
@@ -158,6 +170,9 @@ llvm::getKnowledgeForValue(const Value *V,
                            function_ref<bool(RetainedKnowledge, Instruction *,
                                              const CallBase::BundleOpInfo *)>
                                Filter) {
+  NumAssumeQueries++;
+  if (!DebugCounter::shouldExecute(AssumeQueryCounter))
+    return RetainedKnowledge::none();
   if (AC) {
     for (AssumptionCache::ResultElem &Elem : AC->assumptionsFor(V)) {
       IntrinsicInst *II = cast_or_null<IntrinsicInst>(Elem.Assume);
@@ -166,20 +181,24 @@ llvm::getKnowledgeForValue(const Value *V,
       if (RetainedKnowledge RK = getKnowledgeFromBundle(
               *II, II->bundle_op_info_begin()[Elem.Index]))
         if (is_contained(AttrKinds, RK.AttrKind) &&
-            Filter(RK, II, &II->bundle_op_info_begin()[Elem.Index]))
+            Filter(RK, II, &II->bundle_op_info_begin()[Elem.Index])) {
+          NumUsefullAssumeQueries++;
           return RK;
+        }
     }
     return RetainedKnowledge::none();
   }
-  for (auto &U : V->uses()) {
+  for (const auto &U : V->uses()) {
     CallInst::BundleOpInfo* Bundle = getBundleFromUse(&U);
     if (!Bundle)
       continue;
     if (RetainedKnowledge RK =
             getKnowledgeFromBundle(*cast<CallInst>(U.getUser()), *Bundle))
       if (is_contained(AttrKinds, RK.AttrKind) &&
-          Filter(RK, cast<Instruction>(U.getUser()), Bundle))
+          Filter(RK, cast<Instruction>(U.getUser()), Bundle)) {
+        NumUsefullAssumeQueries++;
         return RK;
+      }
   }
   return RetainedKnowledge::none();
 }

diff  --git a/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp b/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
index f2208edd5b19..7ff73fcdada7 100644
--- a/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
+++ b/llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
@@ -6,9 +6,12 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define DEBUG_TYPE "assume-builder"
+
 #include "llvm/Transforms/Utils/AssumeBundleBuilder.h"
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/AssumeBundleQueries.h"
 #include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Analysis/ValueTracking.h"
@@ -19,6 +22,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/DebugCounter.h"
 #include "llvm/Transforms/Utils/Local.h"
 
 using namespace llvm;
@@ -33,6 +37,16 @@ cl::opt<bool> EnableKnowledgeRetention(
     cl::desc(
         "enable preservation of attributes throughout code transformation"));
 
+STATISTIC(NumAssumeBuilt, "Number of assume built by the assume builder");
+STATISTIC(NumBundlesInAssumes, "Total number of Bundles in the assume built");
+STATISTIC(NumAssumesMerged,
+          "Number of assume merged by the assume simplify pass");
+STATISTIC(NumAssumesRemoved,
+          "Number of assume removed by the assume simplify pass");
+
+DEBUG_COUNTER(BuildAssumeCounter, "assume-builder-counter",
+              "Controls which assumes gets created");
+
 namespace {
 
 bool isUsefullToPreserve(Attribute::AttrKind Kind) {
@@ -204,6 +218,8 @@ struct AssumeBuilderState {
   IntrinsicInst *build() {
     if (AssumedKnowledgeMap.empty())
       return nullptr;
+    if (!DebugCounter::shouldExecute(BuildAssumeCounter))
+      return nullptr;
     Function *FnAssume = Intrinsic::getDeclaration(M, Intrinsic::assume);
     LLVMContext &C = M->getContext();
     SmallVector<OperandBundleDef, 8> OpBundle;
@@ -220,7 +236,9 @@ struct AssumeBuilderState {
       OpBundle.push_back(OperandBundleDefT<Value *>(
           std::string(Attribute::getNameFromAttrKind(MapElem.first.second)),
           Args));
+      NumBundlesInAssumes++;
     }
+    NumAssumeBuilt++;
     return cast<IntrinsicInst>(CallInst::Create(
         FnAssume, ArrayRef<Value *>({ConstantInt::getTrue(C)}), OpBundle));
   }
@@ -328,6 +346,10 @@ struct AssumeSimplify {
           (!ForceCleanup && !isAssumeWithEmptyBundle(*Assume)))
         continue;
       MadeChange = true;
+      if (ForceCleanup)
+        NumAssumesMerged++;
+      else
+        NumAssumesRemoved++;
       Assume->eraseFromParent();
     }
     CleanupToDo.clear();

diff  --git a/llvm/test/Analysis/ValueTracking/assume-queries-counter.ll b/llvm/test/Analysis/ValueTracking/assume-queries-counter.ll
new file mode 100644
index 000000000000..476b0ef04d34
--- /dev/null
+++ b/llvm/test/Analysis/ValueTracking/assume-queries-counter.ll
@@ -0,0 +1,110 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine --debug-counter=assume-queries-counter-skip=0,assume-queries-counter-count=1 -S | FileCheck %s --check-prefixes=SAME,COUNTER1
+; RUN: opt < %s -instcombine --debug-counter=assume-queries-counter-skip=1,assume-queries-counter-count=2 -S | FileCheck %s --check-prefixes=SAME,COUNTER2
+; RUN: opt < %s -instcombine --debug-counter=assume-queries-counter-skip=2,assume-queries-counter-count=1 -S | FileCheck %s --check-prefixes=SAME,COUNTER3
+
+declare i1 @get_val()
+declare void @llvm.assume(i1)
+
+define dso_local i1 @test1(i32* readonly %0) {
+; COUNTER1-LABEL: @test1(
+; COUNTER1-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP0:%.*]]) ]
+; COUNTER1-NEXT:    ret i1 false
+;
+; COUNTER2-LABEL: @test1(
+; COUNTER2-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP0:%.*]]) ]
+; COUNTER2-NEXT:    [[TMP2:%.*]] = icmp eq i32* [[TMP0]], null
+; COUNTER2-NEXT:    ret i1 [[TMP2]]
+;
+; COUNTER3-LABEL: @test1(
+; COUNTER3-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP0:%.*]]) ]
+; COUNTER3-NEXT:    [[TMP2:%.*]] = icmp eq i32* [[TMP0]], null
+; COUNTER3-NEXT:    ret i1 [[TMP2]]
+;
+  call void @llvm.assume(i1 true) ["nonnull"(i32* %0)]
+  %2 = icmp eq i32* %0, null
+  ret i1 %2
+}
+
+define dso_local i1 @test2(i32* readonly %0) {
+; COUNTER1-LABEL: @test2(
+; COUNTER1-NEXT:    [[TMP2:%.*]] = icmp eq i32* [[TMP0:%.*]], null
+; COUNTER1-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP0]]) ]
+; COUNTER1-NEXT:    ret i1 [[TMP2]]
+;
+; COUNTER2-LABEL: @test2(
+; COUNTER2-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP0:%.*]]) ]
+; COUNTER2-NEXT:    ret i1 false
+;
+; COUNTER3-LABEL: @test2(
+; COUNTER3-NEXT:    [[TMP2:%.*]] = icmp eq i32* [[TMP0:%.*]], null
+; COUNTER3-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(i32* [[TMP0]]) ]
+; COUNTER3-NEXT:    ret i1 [[TMP2]]
+;
+  %2 = icmp eq i32* %0, null
+  call void @llvm.assume(i1 true) ["nonnull"(i32* %0)]
+  ret i1 %2
+}
+
+define dso_local i32 @test4(i32* readonly %0, i1 %cond) {
+; COUNTER1-LABEL: @test4(
+; COUNTER1-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP0:%.*]], i32 4) ]
+; COUNTER1-NEXT:    br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]]
+; COUNTER1:       B:
+; COUNTER1-NEXT:    br label [[A]]
+; COUNTER1:       A:
+; COUNTER1-NEXT:    [[TMP2:%.*]] = icmp eq i32* [[TMP0]], null
+; COUNTER1-NEXT:    br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
+; COUNTER1:       3:
+; COUNTER1-NEXT:    [[TMP4:%.*]] = load i32, i32* [[TMP0]], align 4
+; COUNTER1-NEXT:    br label [[TMP5]]
+; COUNTER1:       5:
+; COUNTER1-NEXT:    [[TMP6:%.*]] = phi i32 [ [[TMP4]], [[TMP3]] ], [ 0, [[A]] ]
+; COUNTER1-NEXT:    ret i32 [[TMP6]]
+;
+; COUNTER2-LABEL: @test4(
+; COUNTER2-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP0:%.*]], i32 4) ]
+; COUNTER2-NEXT:    br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]]
+; COUNTER2:       B:
+; COUNTER2-NEXT:    br label [[A]]
+; COUNTER2:       A:
+; COUNTER2-NEXT:    br i1 false, label [[TMP4:%.*]], label [[TMP2:%.*]]
+; COUNTER2:       2:
+; COUNTER2-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+; COUNTER2-NEXT:    br label [[TMP4]]
+; COUNTER2:       4:
+; COUNTER2-NEXT:    [[TMP5:%.*]] = phi i32 [ [[TMP3]], [[TMP2]] ], [ 0, [[A]] ]
+; COUNTER2-NEXT:    ret i32 [[TMP5]]
+;
+; COUNTER3-LABEL: @test4(
+; COUNTER3-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[TMP0:%.*]], i32 4) ]
+; COUNTER3-NEXT:    br i1 [[COND:%.*]], label [[A:%.*]], label [[B:%.*]]
+; COUNTER3:       B:
+; COUNTER3-NEXT:    br label [[A]]
+; COUNTER3:       A:
+; COUNTER3-NEXT:    br i1 false, label [[TMP4:%.*]], label [[TMP2:%.*]]
+; COUNTER3:       2:
+; COUNTER3-NEXT:    [[TMP3:%.*]] = load i32, i32* [[TMP0]], align 4
+; COUNTER3-NEXT:    br label [[TMP4]]
+; COUNTER3:       4:
+; COUNTER3-NEXT:    [[TMP5:%.*]] = phi i32 [ [[TMP3]], [[TMP2]] ], [ 0, [[A]] ]
+; COUNTER3-NEXT:    ret i32 [[TMP5]]
+;
+  call void @llvm.assume(i1 true) ["dereferenceable"(i32* %0, i32 4)]
+  br i1 %cond, label %A, label %B
+
+B:
+  br label %A
+
+A:
+  %2 = icmp eq i32* %0, null
+  br i1 %2, label %5, label %3
+
+3:                                                ; preds = %1
+  %4 = load i32, i32* %0, align 4
+  br label %5
+
+5:                                                ; preds = %1, %3
+  %6 = phi i32 [ %4, %3 ], [ 0, %A ]
+  ret i32 %6
+}

diff  --git a/llvm/test/Transforms/Util/assume-builder-counter.ll b/llvm/test/Transforms/Util/assume-builder-counter.ll
new file mode 100644
index 000000000000..380b88314032
--- /dev/null
+++ b/llvm/test/Transforms/Util/assume-builder-counter.ll
@@ -0,0 +1,79 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
+; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention --debug-counter=assume-builder-counter-skip=5,assume-builder-counter-count=1 -S %s | FileCheck %s --check-prefixes=COUNTER1
+; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention --debug-counter=assume-builder-counter-skip=1,assume-builder-counter-count=3 -S %s | FileCheck %s --check-prefixes=COUNTER2
+; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention --debug-counter=assume-builder-counter-skip=2,assume-builder-counter-count=200 -S %s | FileCheck %s --check-prefixes=COUNTER3
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
+declare void @func(i32*, i32*)
+declare void @func_cold(i32*) cold willreturn nounwind
+declare void @func_strbool(i32*) "no-jump-tables"
+declare void @func_many(i32*) "no-jump-tables" nounwind "less-precise-fpmad" willreturn norecurse
+declare void @func_argattr(i32* align 8, i32* nonnull) nounwind
+declare void @may_throw()
+
+define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
+; COUNTER1-LABEL: define {{[^@]+}}@test
+; COUNTER1-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]])
+; COUNTER1-NEXT:    call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
+; COUNTER1-NEXT:    call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
+; COUNTER1-NEXT:    call void @func_cold(i32* dereferenceable(12) [[P1]]) #5
+; COUNTER1-NEXT:    call void @func_cold(i32* dereferenceable(12) [[P1]])
+; COUNTER1-NEXT:    call void @func(i32* [[P1]], i32* [[P]])
+; COUNTER1-NEXT:    call void @func_strbool(i32* [[P1]])
+; COUNTER1-NEXT:    call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
+; COUNTER1-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8) ]
+; COUNTER1-NEXT:    call void @func_many(i32* align 8 [[P1]])
+; COUNTER1-NEXT:    call void @func_argattr(i32* [[P2]], i32* [[P3]])
+; COUNTER1-NEXT:    call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
+; COUNTER1-NEXT:    ret void
+;
+; COUNTER2-LABEL: define {{[^@]+}}@test
+; COUNTER2-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]])
+; COUNTER2-NEXT:    call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
+; COUNTER2-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 12), "nonnull"(i32* [[P]]) ]
+; COUNTER2-NEXT:    call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
+; COUNTER2-NEXT:    call void @llvm.assume(i1 true) [ "cold"() ]
+; COUNTER2-NEXT:    call void @func_cold(i32* dereferenceable(12) [[P1]]) #5
+; COUNTER2-NEXT:    call void @llvm.assume(i1 true) [ "cold"() ]
+; COUNTER2-NEXT:    call void @func_cold(i32* dereferenceable(12) [[P1]])
+; COUNTER2-NEXT:    call void @func(i32* [[P1]], i32* [[P]])
+; COUNTER2-NEXT:    call void @func_strbool(i32* [[P1]])
+; COUNTER2-NEXT:    call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
+; COUNTER2-NEXT:    call void @func_many(i32* align 8 [[P1]])
+; COUNTER2-NEXT:    call void @func_argattr(i32* [[P2]], i32* [[P3]])
+; COUNTER2-NEXT:    call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
+; COUNTER2-NEXT:    ret void
+;
+; COUNTER3-LABEL: define {{[^@]+}}@test
+; COUNTER3-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]])
+; COUNTER3-NEXT:    call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
+; COUNTER3-NEXT:    call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
+; COUNTER3-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 12), "cold"() ]
+; COUNTER3-NEXT:    call void @func_cold(i32* dereferenceable(12) [[P1]]) #5
+; COUNTER3-NEXT:    call void @llvm.assume(i1 true) [ "cold"() ]
+; COUNTER3-NEXT:    call void @func_cold(i32* dereferenceable(12) [[P1]])
+; COUNTER3-NEXT:    call void @func(i32* [[P1]], i32* [[P]])
+; COUNTER3-NEXT:    call void @func_strbool(i32* [[P1]])
+; COUNTER3-NEXT:    call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
+; COUNTER3-NEXT:    call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
+; COUNTER3-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8) ]
+; COUNTER3-NEXT:    call void @func_many(i32* align 8 [[P1]])
+; COUNTER3-NEXT:    call void @llvm.assume(i1 true) [ "align"(i32* [[P2]], i64 8), "nonnull"(i32* [[P3]]) ]
+; COUNTER3-NEXT:    call void @func_argattr(i32* [[P2]], i32* [[P3]])
+; COUNTER3-NEXT:    call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "nonnull"(i32* [[P]]) ]
+; COUNTER3-NEXT:    call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
+; COUNTER3-NEXT:    ret void
+;
+  call void @func(i32* nonnull dereferenceable(16) %P, i32* null)
+  call void @func(i32* dereferenceable(12) %P1, i32* nonnull %P)
+  call void @func_cold(i32* dereferenceable(12) %P1) cold
+  call void @func_cold(i32* dereferenceable(12) %P1)
+  call void @func(i32* %P1, i32* %P)
+  call void @func_strbool(i32* %P1)
+  call void @func(i32* dereferenceable(32) %P, i32* dereferenceable(8) %P)
+  call void @func_many(i32* align 8 %P1)
+  call void @func_argattr(i32* %P2, i32* %P3)
+  call void @func(i32* nonnull %P1, i32* nonnull %P)
+  ret void
+}


        


More information about the llvm-commits mailing list