[llvm] 0628366 - Add new function properties to FunctionPropertiesAnalysis

Mircea Trofin via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 23 12:46:56 PDT 2020


Author: Tarindu Jayatilaka
Date: 2020-07-23T12:46:47-07:00
New Revision: 06283661b34244f2db87aa55f2a40fe65903410e

URL: https://github.com/llvm/llvm-project/commit/06283661b34244f2db87aa55f2a40fe65903410e
DIFF: https://github.com/llvm/llvm-project/commit/06283661b34244f2db87aa55f2a40fe65903410e.diff

LOG: Add new function properties to FunctionPropertiesAnalysis

 Added  LoadInstCount, StoreInstCount, MaxLoopDepth, LoopCount

Reviewed By: jdoerfert, mtrofin

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

Added: 
    

Modified: 
    llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
    llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
    llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll
    llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h b/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
index 99f91a92b31a..a39c4e5413d8 100644
--- a/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
+++ b/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_FUNCTIONPROPERTIESANALYSIS_H_
 #define LLVM_FUNCTIONPROPERTIESANALYSIS_H_
 
+#include "llvm/Analysis/LoopInfo.h"
 #include "llvm/IR/PassManager.h"
 
 namespace llvm {
@@ -21,6 +22,11 @@ class Function;
 
 class FunctionPropertiesInfo {
 public:
+  static FunctionPropertiesInfo getFunctionPropertiesInfo(const Function &F,
+                                                          const LoopInfo &LI);
+
+  void print(raw_ostream &OS) const;
+
   /// Number of basic blocks
   int64_t BasicBlockCount = 0;
 
@@ -40,9 +46,17 @@ class FunctionPropertiesInfo {
   /// defined in this module.
   int64_t DirectCallsToDefinedFunctions = 0;
 
-  static FunctionPropertiesInfo getFunctionPropertiesInfo(const Function &F);
+  // Load Instruction Count
+  int64_t LoadInstCount = 0;
 
-  void print(raw_ostream &OS) const;
+  // Store Instruction Count
+  int64_t StoreInstCount = 0;
+
+  // Maximum Loop Depth in the Function
+  int64_t MaxLoopDepth = 0;
+
+  // Number of Top Level Loops in the Function
+  int64_t TopLevelLoopCount = 0;
 };
 
 // Analysis pass

diff  --git a/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp b/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
index 9b7caf1579a3..3db108c94985 100644
--- a/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
+++ b/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
@@ -17,7 +17,8 @@
 using namespace llvm;
 
 FunctionPropertiesInfo
-FunctionPropertiesInfo::getFunctionPropertiesInfo(const Function &F) {
+FunctionPropertiesInfo::getFunctionPropertiesInfo(const Function &F,
+                                                  const LoopInfo &LI) {
 
   FunctionPropertiesInfo FPI;
 
@@ -40,7 +41,20 @@ FunctionPropertiesInfo::getFunctionPropertiesInfo(const Function &F) {
         if (Callee && !Callee->isIntrinsic() && !Callee->isDeclaration())
           ++FPI.DirectCallsToDefinedFunctions;
       }
+      if (I.getOpcode() == Instruction::Load) {
+        ++FPI.LoadInstCount;
+      } else if (I.getOpcode() == Instruction::Store) {
+        ++FPI.StoreInstCount;
+      }
     }
+    // Loop Depth of the Basic Block
+    int64_t LoopDepth;
+    LoopDepth = LI.getLoopDepth(&BB);
+    if (FPI.MaxLoopDepth < LoopDepth)
+      FPI.MaxLoopDepth = LoopDepth;
+  }
+  for (Loop *L : LI) {
+    ++FPI.TopLevelLoopCount;
   }
   return FPI;
 }
@@ -51,14 +65,19 @@ void FunctionPropertiesInfo::print(raw_ostream &OS) const {
      << BlocksReachedFromConditionalInstruction << "\n"
      << "Uses: " << Uses << "\n"
      << "DirectCallsToDefinedFunctions: " << DirectCallsToDefinedFunctions
-     << "\n\n";
+     << "\n"
+     << "LoadInstCount: " << LoadInstCount << "\n"
+     << "StoreInstCount: " << StoreInstCount << "\n"
+     << "MaxLoopDepth: " << MaxLoopDepth << "\n"
+     << "TopLevelLoopCount: " << TopLevelLoopCount << "\n\n";
 }
 
 AnalysisKey FunctionPropertiesAnalysis::Key;
 
 FunctionPropertiesInfo
 FunctionPropertiesAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
-  return FunctionPropertiesInfo::getFunctionPropertiesInfo(F);
+  return FunctionPropertiesInfo::getFunctionPropertiesInfo(
+      F, FAM.getResult<LoopAnalysis>(F));
 }
 
 PreservedAnalyses

diff  --git a/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll b/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll
index 07e1fece5d3b..506914972a10 100644
--- a/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll
+++ b/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll
@@ -21,6 +21,10 @@ entry:
 ; CHECK-DAG: BlocksReachedFromConditionalInstruction: 0
 ; CHECK-DAG: Uses: 1
 ; CHECK-DAG: DirectCallsToDefinedFunctions: 1
+; CHECK-DAG: LoadInstCount: 0
+; CHECK-DAG: StoreInstCount: 1
+; CHECK-DAG: MaxLoopDepth: 0
+; CHECK-DAG: TopLevelLoopCount: 0
 
 define void @multiply([2 x i32]* %mat1, [2 x i32]* %mat2, [2 x i32]* %res) {
 ; CHECK-DAG: Printing analysis results of CFA for function 'multiply':
@@ -129,4 +133,8 @@ for.end26:                                        ; preds = %for.cond
 ; CHECK-DAG: BasicBlockCount: 13
 ; CHECK-DAG: BlocksReachedFromConditionalInstruction: 6
 ; CHECK-DAG: Uses: 2
-; CHECK-DAG: DirectCallsToDefinedFunctions: 0
\ No newline at end of file
+; CHECK-DAG: DirectCallsToDefinedFunctions: 0
+; CHECK-DAG: LoadInstCount: 21
+; CHECK-DAG: StoreInstCount: 11
+; CHECK-DAG: MaxLoopDepth: 3
+; CHECK-DAG: TopLevelLoopCount: 1
\ No newline at end of file

diff  --git a/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp b/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp
index b04d204b2703..7b2a985bba66 100644
--- a/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp
+++ b/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/Analysis/FunctionPropertiesAnalysis.h"
 #include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/Dominators.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
@@ -15,42 +16,49 @@
 #include "gtest/gtest.h"
 
 using namespace llvm;
+namespace {
 
-static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
-  SMDiagnostic Err;
-  std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
-  if (!Mod)
-    Err.print("MLAnalysisTests", errs());
-  return Mod;
-}
+class FunctionPropertiesAnalysisTest : public testing::Test {
+protected:
+  std::unique_ptr<DominatorTree> DT;
+  std::unique_ptr<LoopInfo> LI;
+
+  FunctionPropertiesInfo buildFPI(Function &F) {
+    DT.reset(new DominatorTree(F));
+    LI.reset(new LoopInfo(*DT));
+    return FunctionPropertiesInfo::getFunctionPropertiesInfo(F, *LI);
+  }
 
-TEST(FunctionPropertiesTest, BasicTest) {
+  std::unique_ptr<Module> makeLLVMModule(LLVMContext &C, const char *IR) {
+    SMDiagnostic Err;
+    std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
+    if (!Mod)
+      Err.print("MLAnalysisTests", errs());
+    return Mod;
+  }
+};
+
+TEST_F(FunctionPropertiesAnalysisTest, BasicTest) {
   LLVMContext C;
-  std::unique_ptr<Module> M = parseIR(C,
-                                      R"IR(
+  std::unique_ptr<Module> M = makeLLVMModule(C,
+                                             R"IR(
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-linux-gnu"
-
 declare i32 @f1(i32)
 declare i32 @f2(i32)
-
 define i32 @branches(i32) {
   %cond = icmp slt i32 %0, 3
   br i1 %cond, label %then, label %else
-
 then:
   %ret.1 = call i32 @f1(i32 %0)
   br label %last.block
-
 else:
   %ret.2 = call i32 @f2(i32 %0)
   br label %last.block
-
 last.block:
   %ret = phi i32 [%ret.1, %then], [%ret.2, %else]
   ret i32 %ret
 }
-
 define internal i32 @top() {
   %1 = call i32 @branches(i32 2)
   %2 = call i32 @f1(i32 %1)
@@ -58,20 +66,28 @@ define internal i32 @top() {
 }
 )IR");
 
-  FunctionAnalysisManager FAM;
-  FunctionPropertiesAnalysis FPA;
-
-  auto BranchesFeatures = FPA.run(*M->getFunction("branches"), FAM);
+  Function *BranchesFunction = M->getFunction("branches");
+  FunctionPropertiesInfo BranchesFeatures = buildFPI(*BranchesFunction);
   EXPECT_EQ(BranchesFeatures.BasicBlockCount, 4);
   EXPECT_EQ(BranchesFeatures.BlocksReachedFromConditionalInstruction, 2);
-  EXPECT_EQ(BranchesFeatures.DirectCallsToDefinedFunctions, 0);
   // 2 Users: top is one. The other is added because @branches is not internal,
   // so it may have external callers.
   EXPECT_EQ(BranchesFeatures.Uses, 2);
+  EXPECT_EQ(BranchesFeatures.DirectCallsToDefinedFunctions, 0);
+  EXPECT_EQ(BranchesFeatures.LoadInstCount, 0);
+  EXPECT_EQ(BranchesFeatures.StoreInstCount, 0);
+  EXPECT_EQ(BranchesFeatures.MaxLoopDepth, 0);
+  EXPECT_EQ(BranchesFeatures.TopLevelLoopCount, 0);
 
-  auto TopFeatures = FPA.run(*M->getFunction("top"), FAM);
+  Function *TopFunction = M->getFunction("top");
+  FunctionPropertiesInfo TopFeatures = buildFPI(*TopFunction);
   EXPECT_EQ(TopFeatures.BasicBlockCount, 1);
   EXPECT_EQ(TopFeatures.BlocksReachedFromConditionalInstruction, 0);
-  EXPECT_EQ(TopFeatures.DirectCallsToDefinedFunctions, 1);
   EXPECT_EQ(TopFeatures.Uses, 0);
+  EXPECT_EQ(TopFeatures.DirectCallsToDefinedFunctions, 1);
+  EXPECT_EQ(BranchesFeatures.LoadInstCount, 0);
+  EXPECT_EQ(BranchesFeatures.StoreInstCount, 0);
+  EXPECT_EQ(BranchesFeatures.MaxLoopDepth, 0);
+  EXPECT_EQ(BranchesFeatures.TopLevelLoopCount, 0);
 }
+} // end anonymous namespace
\ No newline at end of file


        


More information about the llvm-commits mailing list