<div dir="ltr">Had an unused variable warning that I fixed thusly:<div><br></div><div>echristo@athyra ~/s/llvm-project> git push<br>To github.com:llvm/llvm-project.git<br>   1d09ecf3617..3ac828b8f7a  master -> master<br></div><div><br></div><div>:)</div><div><br></div><div>-eric</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jul 23, 2020 at 12:47 PM Mircea Trofin via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
Author: Tarindu Jayatilaka<br>
Date: 2020-07-23T12:46:47-07:00<br>
New Revision: 06283661b34244f2db87aa55f2a40fe65903410e<br>
<br>
URL: <a href="https://github.com/llvm/llvm-project/commit/06283661b34244f2db87aa55f2a40fe65903410e" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/06283661b34244f2db87aa55f2a40fe65903410e</a><br>
DIFF: <a href="https://github.com/llvm/llvm-project/commit/06283661b34244f2db87aa55f2a40fe65903410e.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/06283661b34244f2db87aa55f2a40fe65903410e.diff</a><br>
<br>
LOG: Add new function properties to FunctionPropertiesAnalysis<br>
<br>
 Added  LoadInstCount, StoreInstCount, MaxLoopDepth, LoopCount<br>
<br>
Reviewed By: jdoerfert, mtrofin<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D82283" rel="noreferrer" target="_blank">https://reviews.llvm.org/D82283</a><br>
<br>
Added: <br>
<br>
<br>
Modified: <br>
    llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h<br>
    llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp<br>
    llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll<br>
    llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp<br>
<br>
Removed: <br>
<br>
<br>
<br>
################################################################################<br>
diff  --git a/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h b/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h<br>
index 99f91a92b31a..a39c4e5413d8 100644<br>
--- a/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h<br>
+++ b/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h<br>
@@ -14,6 +14,7 @@<br>
 #ifndef LLVM_FUNCTIONPROPERTIESANALYSIS_H_<br>
 #define LLVM_FUNCTIONPROPERTIESANALYSIS_H_<br>
<br>
+#include "llvm/Analysis/LoopInfo.h"<br>
 #include "llvm/IR/PassManager.h"<br>
<br>
 namespace llvm {<br>
@@ -21,6 +22,11 @@ class Function;<br>
<br>
 class FunctionPropertiesInfo {<br>
 public:<br>
+  static FunctionPropertiesInfo getFunctionPropertiesInfo(const Function &F,<br>
+                                                          const LoopInfo &LI);<br>
+<br>
+  void print(raw_ostream &OS) const;<br>
+<br>
   /// Number of basic blocks<br>
   int64_t BasicBlockCount = 0;<br>
<br>
@@ -40,9 +46,17 @@ class FunctionPropertiesInfo {<br>
   /// defined in this module.<br>
   int64_t DirectCallsToDefinedFunctions = 0;<br>
<br>
-  static FunctionPropertiesInfo getFunctionPropertiesInfo(const Function &F);<br>
+  // Load Instruction Count<br>
+  int64_t LoadInstCount = 0;<br>
<br>
-  void print(raw_ostream &OS) const;<br>
+  // Store Instruction Count<br>
+  int64_t StoreInstCount = 0;<br>
+<br>
+  // Maximum Loop Depth in the Function<br>
+  int64_t MaxLoopDepth = 0;<br>
+<br>
+  // Number of Top Level Loops in the Function<br>
+  int64_t TopLevelLoopCount = 0;<br>
 };<br>
<br>
 // Analysis pass<br>
<br>
diff  --git a/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp b/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp<br>
index 9b7caf1579a3..3db108c94985 100644<br>
--- a/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp<br>
+++ b/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp<br>
@@ -17,7 +17,8 @@<br>
 using namespace llvm;<br>
<br>
 FunctionPropertiesInfo<br>
-FunctionPropertiesInfo::getFunctionPropertiesInfo(const Function &F) {<br>
+FunctionPropertiesInfo::getFunctionPropertiesInfo(const Function &F,<br>
+                                                  const LoopInfo &LI) {<br>
<br>
   FunctionPropertiesInfo FPI;<br>
<br>
@@ -40,7 +41,20 @@ FunctionPropertiesInfo::getFunctionPropertiesInfo(const Function &F) {<br>
         if (Callee && !Callee->isIntrinsic() && !Callee->isDeclaration())<br>
           ++FPI.DirectCallsToDefinedFunctions;<br>
       }<br>
+      if (I.getOpcode() == Instruction::Load) {<br>
+        ++FPI.LoadInstCount;<br>
+      } else if (I.getOpcode() == Instruction::Store) {<br>
+        ++FPI.StoreInstCount;<br>
+      }<br>
     }<br>
+    // Loop Depth of the Basic Block<br>
+    int64_t LoopDepth;<br>
+    LoopDepth = LI.getLoopDepth(&BB);<br>
+    if (FPI.MaxLoopDepth < LoopDepth)<br>
+      FPI.MaxLoopDepth = LoopDepth;<br>
+  }<br>
+  for (Loop *L : LI) {<br>
+    ++FPI.TopLevelLoopCount;<br>
   }<br>
   return FPI;<br>
 }<br>
@@ -51,14 +65,19 @@ void FunctionPropertiesInfo::print(raw_ostream &OS) const {<br>
      << BlocksReachedFromConditionalInstruction << "\n"<br>
      << "Uses: " << Uses << "\n"<br>
      << "DirectCallsToDefinedFunctions: " << DirectCallsToDefinedFunctions<br>
-     << "\n\n";<br>
+     << "\n"<br>
+     << "LoadInstCount: " << LoadInstCount << "\n"<br>
+     << "StoreInstCount: " << StoreInstCount << "\n"<br>
+     << "MaxLoopDepth: " << MaxLoopDepth << "\n"<br>
+     << "TopLevelLoopCount: " << TopLevelLoopCount << "\n\n";<br>
 }<br>
<br>
 AnalysisKey FunctionPropertiesAnalysis::Key;<br>
<br>
 FunctionPropertiesInfo<br>
 FunctionPropertiesAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {<br>
-  return FunctionPropertiesInfo::getFunctionPropertiesInfo(F);<br>
+  return FunctionPropertiesInfo::getFunctionPropertiesInfo(<br>
+      F, FAM.getResult<LoopAnalysis>(F));<br>
 }<br>
<br>
 PreservedAnalyses<br>
<br>
diff  --git a/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll b/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll<br>
index 07e1fece5d3b..506914972a10 100644<br>
--- a/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll<br>
+++ b/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll<br>
@@ -21,6 +21,10 @@ entry:<br>
 ; CHECK-DAG: BlocksReachedFromConditionalInstruction: 0<br>
 ; CHECK-DAG: Uses: 1<br>
 ; CHECK-DAG: DirectCallsToDefinedFunctions: 1<br>
+; CHECK-DAG: LoadInstCount: 0<br>
+; CHECK-DAG: StoreInstCount: 1<br>
+; CHECK-DAG: MaxLoopDepth: 0<br>
+; CHECK-DAG: TopLevelLoopCount: 0<br>
<br>
 define void @multiply([2 x i32]* %mat1, [2 x i32]* %mat2, [2 x i32]* %res) {<br>
 ; CHECK-DAG: Printing analysis results of CFA for function 'multiply':<br>
@@ -129,4 +133,8 @@ for.end26:                                        ; preds = %for.cond<br>
 ; CHECK-DAG: BasicBlockCount: 13<br>
 ; CHECK-DAG: BlocksReachedFromConditionalInstruction: 6<br>
 ; CHECK-DAG: Uses: 2<br>
-; CHECK-DAG: DirectCallsToDefinedFunctions: 0<br>
\ No newline at end of file<br>
+; CHECK-DAG: DirectCallsToDefinedFunctions: 0<br>
+; CHECK-DAG: LoadInstCount: 21<br>
+; CHECK-DAG: StoreInstCount: 11<br>
+; CHECK-DAG: MaxLoopDepth: 3<br>
+; CHECK-DAG: TopLevelLoopCount: 1<br>
\ No newline at end of file<br>
<br>
diff  --git a/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp b/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp<br>
index b04d204b2703..7b2a985bba66 100644<br>
--- a/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp<br>
+++ b/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp<br>
@@ -8,6 +8,7 @@<br>
<br>
 #include "llvm/Analysis/FunctionPropertiesAnalysis.h"<br>
 #include "llvm/AsmParser/Parser.h"<br>
+#include "llvm/IR/Dominators.h"<br>
 #include "llvm/IR/Instructions.h"<br>
 #include "llvm/IR/LLVMContext.h"<br>
 #include "llvm/IR/Module.h"<br>
@@ -15,42 +16,49 @@<br>
 #include "gtest/gtest.h"<br>
<br>
 using namespace llvm;<br>
+namespace {<br>
<br>
-static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {<br>
-  SMDiagnostic Err;<br>
-  std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);<br>
-  if (!Mod)<br>
-    Err.print("MLAnalysisTests", errs());<br>
-  return Mod;<br>
-}<br>
+class FunctionPropertiesAnalysisTest : public testing::Test {<br>
+protected:<br>
+  std::unique_ptr<DominatorTree> DT;<br>
+  std::unique_ptr<LoopInfo> LI;<br>
+<br>
+  FunctionPropertiesInfo buildFPI(Function &F) {<br>
+    DT.reset(new DominatorTree(F));<br>
+    LI.reset(new LoopInfo(*DT));<br>
+    return FunctionPropertiesInfo::getFunctionPropertiesInfo(F, *LI);<br>
+  }<br>
<br>
-TEST(FunctionPropertiesTest, BasicTest) {<br>
+  std::unique_ptr<Module> makeLLVMModule(LLVMContext &C, const char *IR) {<br>
+    SMDiagnostic Err;<br>
+    std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);<br>
+    if (!Mod)<br>
+      Err.print("MLAnalysisTests", errs());<br>
+    return Mod;<br>
+  }<br>
+};<br>
+<br>
+TEST_F(FunctionPropertiesAnalysisTest, BasicTest) {<br>
   LLVMContext C;<br>
-  std::unique_ptr<Module> M = parseIR(C,<br>
-                                      R"IR(<br>
+  std::unique_ptr<Module> M = makeLLVMModule(C,<br>
+                                             R"IR(<br>
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"<br>
 target triple = "x86_64-pc-linux-gnu"<br>
-<br>
 declare i32 @f1(i32)<br>
 declare i32 @f2(i32)<br>
-<br>
 define i32 @branches(i32) {<br>
   %cond = icmp slt i32 %0, 3<br>
   br i1 %cond, label %then, label %else<br>
-<br>
 then:<br>
   %ret.1 = call i32 @f1(i32 %0)<br>
   br label %last.block<br>
-<br>
 else:<br>
   %ret.2 = call i32 @f2(i32 %0)<br>
   br label %last.block<br>
-<br>
 last.block:<br>
   %ret = phi i32 [%ret.1, %then], [%ret.2, %else]<br>
   ret i32 %ret<br>
 }<br>
-<br>
 define internal i32 @top() {<br>
   %1 = call i32 @branches(i32 2)<br>
   %2 = call i32 @f1(i32 %1)<br>
@@ -58,20 +66,28 @@ define internal i32 @top() {<br>
 }<br>
 )IR");<br>
<br>
-  FunctionAnalysisManager FAM;<br>
-  FunctionPropertiesAnalysis FPA;<br>
-<br>
-  auto BranchesFeatures = FPA.run(*M->getFunction("branches"), FAM);<br>
+  Function *BranchesFunction = M->getFunction("branches");<br>
+  FunctionPropertiesInfo BranchesFeatures = buildFPI(*BranchesFunction);<br>
   EXPECT_EQ(BranchesFeatures.BasicBlockCount, 4);<br>
   EXPECT_EQ(BranchesFeatures.BlocksReachedFromConditionalInstruction, 2);<br>
-  EXPECT_EQ(BranchesFeatures.DirectCallsToDefinedFunctions, 0);<br>
   // 2 Users: top is one. The other is added because @branches is not internal,<br>
   // so it may have external callers.<br>
   EXPECT_EQ(BranchesFeatures.Uses, 2);<br>
+  EXPECT_EQ(BranchesFeatures.DirectCallsToDefinedFunctions, 0);<br>
+  EXPECT_EQ(BranchesFeatures.LoadInstCount, 0);<br>
+  EXPECT_EQ(BranchesFeatures.StoreInstCount, 0);<br>
+  EXPECT_EQ(BranchesFeatures.MaxLoopDepth, 0);<br>
+  EXPECT_EQ(BranchesFeatures.TopLevelLoopCount, 0);<br>
<br>
-  auto TopFeatures = FPA.run(*M->getFunction("top"), FAM);<br>
+  Function *TopFunction = M->getFunction("top");<br>
+  FunctionPropertiesInfo TopFeatures = buildFPI(*TopFunction);<br>
   EXPECT_EQ(TopFeatures.BasicBlockCount, 1);<br>
   EXPECT_EQ(TopFeatures.BlocksReachedFromConditionalInstruction, 0);<br>
-  EXPECT_EQ(TopFeatures.DirectCallsToDefinedFunctions, 1);<br>
   EXPECT_EQ(TopFeatures.Uses, 0);<br>
+  EXPECT_EQ(TopFeatures.DirectCallsToDefinedFunctions, 1);<br>
+  EXPECT_EQ(BranchesFeatures.LoadInstCount, 0);<br>
+  EXPECT_EQ(BranchesFeatures.StoreInstCount, 0);<br>
+  EXPECT_EQ(BranchesFeatures.MaxLoopDepth, 0);<br>
+  EXPECT_EQ(BranchesFeatures.TopLevelLoopCount, 0);<br>
 }<br>
+} // end anonymous namespace<br>
\ No newline at end of file<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>