[llvm] ee6f0e1 - Add a Printer to the FunctionPropertiesAnalysis

Mircea Trofin via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 23 11:57:21 PDT 2020


Author: Tarindu Jayatilaka
Date: 2020-07-23T11:57:11-07:00
New Revision: ee6f0e109cb2376b44f778db63711e92e90c2ef2

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

LOG: Add a Printer to the FunctionPropertiesAnalysis

 A printer pass and a lit test case was added.

Reviewed By: mtrofin

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

Added: 
    llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll

Modified: 
    llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
    llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
    llvm/lib/Passes/PassRegistry.def
    llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h b/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
index e26a4ee8ffcf..99f91a92b31a 100644
--- a/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
+++ b/llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h
@@ -1,4 +1,4 @@
-//==- FunctionPropertiesAnalysis.h - Function Properties Analysis -*-C++ -*-==//
+//=- FunctionPropertiesAnalysis.h - Function Properties Analysis --*- C++ -*-=//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -41,6 +41,8 @@ class FunctionPropertiesInfo {
   int64_t DirectCallsToDefinedFunctions = 0;
 
   static FunctionPropertiesInfo getFunctionPropertiesInfo(const Function &F);
+
+  void print(raw_ostream &OS) const;
 };
 
 // Analysis pass
@@ -55,5 +57,16 @@ class FunctionPropertiesAnalysis
   Result run(Function &F, FunctionAnalysisManager &FAM);
 };
 
+/// Printer pass for the FunctionPropertiesAnalysis results.
+class FunctionPropertiesPrinterPass
+    : public PassInfoMixin<FunctionPropertiesPrinterPass> {
+  raw_ostream &OS;
+
+public:
+  explicit FunctionPropertiesPrinterPass(raw_ostream &OS) : OS(OS) {}
+
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
 } // namespace llvm
 #endif // LLVM_FUNCTIONPROPERTIESANALYSIS_H_
\ No newline at end of file

diff  --git a/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp b/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
index 0a085fc018d5..9b7caf1579a3 100644
--- a/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
+++ b/llvm/lib/Analysis/FunctionPropertiesAnalysis.cpp
@@ -1,4 +1,4 @@
-//===- FunctionPropertiesAnalysis.cpp - Function properties extraction ----===//
+//===- FunctionPropertiesAnalysis.cpp - Function Properties Analysis ------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements an analysis extracting function properties, which may be
-// used by ML-driven policies, for example.
+// This file defines the FunctionPropertiesInfo and FunctionPropertiesAnalysis
+// classes used to extract function properties.
 //
 //===----------------------------------------------------------------------===//
 
@@ -45,9 +45,27 @@ FunctionPropertiesInfo::getFunctionPropertiesInfo(const Function &F) {
   return FPI;
 }
 
+void FunctionPropertiesInfo::print(raw_ostream &OS) const {
+  OS << "BasicBlockCount: " << BasicBlockCount << "\n"
+     << "BlocksReachedFromConditionalInstruction: "
+     << BlocksReachedFromConditionalInstruction << "\n"
+     << "Uses: " << Uses << "\n"
+     << "DirectCallsToDefinedFunctions: " << DirectCallsToDefinedFunctions
+     << "\n\n";
+}
+
 AnalysisKey FunctionPropertiesAnalysis::Key;
 
 FunctionPropertiesInfo
 FunctionPropertiesAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
   return FunctionPropertiesInfo::getFunctionPropertiesInfo(F);
+}
+
+PreservedAnalyses
+FunctionPropertiesPrinterPass::run(Function &F, FunctionAnalysisManager &AM) {
+  OS << "Printing analysis results of CFA for function "
+     << "'" << F.getName() << "':"
+     << "\n";
+  AM.getResult<FunctionPropertiesAnalysis>(F).print(OS);
+  return PreservedAnalyses::all();
 }
\ No newline at end of file

diff  --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index f323d37ca46a..edaca9ebf609 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -129,10 +129,10 @@ FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis())
 FUNCTION_ANALYSIS("postdomtree", PostDominatorTreeAnalysis())
 FUNCTION_ANALYSIS("demanded-bits", DemandedBitsAnalysis())
 FUNCTION_ANALYSIS("domfrontier", DominanceFrontierAnalysis())
+FUNCTION_ANALYSIS("func-properties", FunctionPropertiesAnalysis())
 FUNCTION_ANALYSIS("loops", LoopAnalysis())
 FUNCTION_ANALYSIS("lazy-value-info", LazyValueAnalysis())
 FUNCTION_ANALYSIS("da", DependenceAnalysis())
-FUNCTION_ANALYSIS("func-properties", FunctionPropertiesAnalysis())
 FUNCTION_ANALYSIS("inliner-size-estimator", InlineSizeEstimatorAnalysis())
 FUNCTION_ANALYSIS("memdep", MemoryDependenceAnalysis())
 FUNCTION_ANALYSIS("memoryssa", MemorySSAAnalysis())
@@ -234,6 +234,7 @@ FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs()))
 FUNCTION_PASS("print<postdomtree>", PostDominatorTreePrinterPass(dbgs()))
 FUNCTION_PASS("print<demanded-bits>", DemandedBitsPrinterPass(dbgs()))
 FUNCTION_PASS("print<domfrontier>", DominanceFrontierPrinterPass(dbgs()))
+FUNCTION_PASS("print<func-properties>", FunctionPropertiesPrinterPass(dbgs()))
 FUNCTION_PASS("print<inline-cost>", InlineCostAnnotationPrinterPass(dbgs()))
 FUNCTION_PASS("print<inliner-size-estimator>", 
   InlineSizeEstimatorAnalysisPrinterPass(dbgs()))

diff  --git a/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll b/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll
new file mode 100644
index 000000000000..07e1fece5d3b
--- /dev/null
+++ b/llvm/test/Analysis/FunctionPropertiesAnalysis/matmul.ll
@@ -0,0 +1,132 @@
+; RUN: opt < %s -passes='print<func-properties>' -disable-output 2>&1 | FileCheck %s
+
+define i32 @main() {
+; CHECK-DAG: Printing analysis results of CFA for function 'main':
+
+entry:
+  %retval = alloca i32, align 4
+  %mat1 = alloca [2 x [2 x i32]], align 16
+  %mat2 = alloca [2 x [2 x i32]], align 16
+  %res = alloca [2 x [2 x i32]], align 16
+  %i = alloca i32, align 4
+  %j = alloca i32, align 4
+  store i32 0, i32* %retval, align 4
+  %arraydecay = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %mat1, i64 0, i64 0
+  %arraydecay1 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %mat2, i64 0, i64 0
+  %arraydecay2 = getelementptr inbounds [2 x [2 x i32]], [2 x [2 x i32]]* %res, i64 0, i64 0
+  call void @multiply([2 x i32]* %arraydecay, [2 x i32]* %arraydecay1, [2 x i32]* %arraydecay2)
+  ret i32 0
+}
+; CHECK-DAG: BasicBlockCount: 1
+; CHECK-DAG: BlocksReachedFromConditionalInstruction: 0
+; CHECK-DAG: Uses: 1
+; CHECK-DAG: DirectCallsToDefinedFunctions: 1
+
+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':
+entry:
+  %mat1.addr = alloca [2 x i32]*, align 8
+  %mat2.addr = alloca [2 x i32]*, align 8
+  %res.addr = alloca [2 x i32]*, align 8
+  %i = alloca i32, align 4
+  %j = alloca i32, align 4
+  %k = alloca i32, align 4
+  store [2 x i32]* %mat1, [2 x i32]** %mat1.addr, align 8
+  store [2 x i32]* %mat2, [2 x i32]** %mat2.addr, align 8
+  store [2 x i32]* %res, [2 x i32]** %res.addr, align 8
+  store i32 0, i32* %i, align 4
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc24, %entry
+  %0 = load i32, i32* %i, align 4
+  %cmp = icmp slt i32 %0, 2
+  br i1 %cmp, label %for.body, label %for.end26
+
+for.body:                                         ; preds = %for.cond
+  store i32 0, i32* %j, align 4
+  br label %for.cond1
+
+for.cond1:                                        ; preds = %for.inc21, %for.body
+  %1 = load i32, i32* %j, align 4
+  %cmp2 = icmp slt i32 %1, 2
+  br i1 %cmp2, label %for.body3, label %for.end23
+
+for.body3:                                        ; preds = %for.cond1
+  %2 = load [2 x i32]*, [2 x i32]** %res.addr, align 8
+  %3 = load i32, i32* %i, align 4
+  %idxprom = sext i32 %3 to i64
+  %arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 %idxprom
+  %4 = load i32, i32* %j, align 4
+  %idxprom4 = sext i32 %4 to i64
+  %arrayidx5 = getelementptr inbounds [2 x i32], [2 x i32]* %arrayidx, i64 0, i64 %idxprom4
+  store i32 0, i32* %arrayidx5, align 4
+  store i32 0, i32* %k, align 4
+  br label %for.cond6
+
+for.cond6:                                        ; preds = %for.inc, %for.body3
+  %5 = load i32, i32* %k, align 4
+  %cmp7 = icmp slt i32 %5, 2
+  br i1 %cmp7, label %for.body8, label %for.end
+
+for.body8:                                        ; preds = %for.cond6
+  %6 = load [2 x i32]*, [2 x i32]** %mat1.addr, align 8
+  %7 = load i32, i32* %i, align 4
+  %idxprom9 = sext i32 %7 to i64
+  %arrayidx10 = getelementptr inbounds [2 x i32], [2 x i32]* %6, i64 %idxprom9
+  %8 = load i32, i32* %k, align 4
+  %idxprom11 = sext i32 %8 to i64
+  %arrayidx12 = getelementptr inbounds [2 x i32], [2 x i32]* %arrayidx10, i64 0, i64 %idxprom11
+  %9 = load i32, i32* %arrayidx12, align 4
+  %10 = load [2 x i32]*, [2 x i32]** %mat2.addr, align 8
+  %11 = load i32, i32* %k, align 4
+  %idxprom13 = sext i32 %11 to i64
+  %arrayidx14 = getelementptr inbounds [2 x i32], [2 x i32]* %10, i64 %idxprom13
+  %12 = load i32, i32* %j, align 4
+  %idxprom15 = sext i32 %12 to i64
+  %arrayidx16 = getelementptr inbounds [2 x i32], [2 x i32]* %arrayidx14, i64 0, i64 %idxprom15
+  %13 = load i32, i32* %arrayidx16, align 4
+  %mul = mul nsw i32 %9, %13
+  %14 = load [2 x i32]*, [2 x i32]** %res.addr, align 8
+  %15 = load i32, i32* %i, align 4
+  %idxprom17 = sext i32 %15 to i64
+  %arrayidx18 = getelementptr inbounds [2 x i32], [2 x i32]* %14, i64 %idxprom17
+  %16 = load i32, i32* %j, align 4
+  %idxprom19 = sext i32 %16 to i64
+  %arrayidx20 = getelementptr inbounds [2 x i32], [2 x i32]* %arrayidx18, i64 0, i64 %idxprom19
+  %17 = load i32, i32* %arrayidx20, align 4
+  %add = add nsw i32 %17, %mul
+  store i32 %add, i32* %arrayidx20, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body8
+  %18 = load i32, i32* %k, align 4
+  %inc = add nsw i32 %18, 1
+  store i32 %inc, i32* %k, align 4
+  br label %for.cond6
+
+for.end:                                          ; preds = %for.cond6
+  br label %for.inc21
+
+for.inc21:                                        ; preds = %for.end
+  %19 = load i32, i32* %j, align 4
+  %inc22 = add nsw i32 %19, 1
+  store i32 %inc22, i32* %j, align 4
+  br label %for.cond1
+
+for.end23:                                        ; preds = %for.cond1
+  br label %for.inc24
+
+for.inc24:                                        ; preds = %for.end23
+  %20 = load i32, i32* %i, align 4
+  %inc25 = add nsw i32 %20, 1
+  store i32 %inc25, i32* %i, align 4
+  br label %for.cond
+
+for.end26:                                        ; preds = %for.cond
+  ret void
+}
+
+; CHECK-DAG: BasicBlockCount: 13
+; CHECK-DAG: BlocksReachedFromConditionalInstruction: 6
+; CHECK-DAG: Uses: 2
+; CHECK-DAG: DirectCallsToDefinedFunctions: 0
\ No newline at end of file

diff  --git a/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp b/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp
index 5ffbbb3de0fc..b04d204b2703 100644
--- a/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp
+++ b/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp
@@ -59,9 +59,9 @@ define internal i32 @top() {
 )IR");
 
   FunctionAnalysisManager FAM;
-  FunctionPropertiesAnalysis FA;
+  FunctionPropertiesAnalysis FPA;
 
-  auto BranchesFeatures = FA.run(*M->getFunction("branches"), FAM);
+  auto BranchesFeatures = FPA.run(*M->getFunction("branches"), FAM);
   EXPECT_EQ(BranchesFeatures.BasicBlockCount, 4);
   EXPECT_EQ(BranchesFeatures.BlocksReachedFromConditionalInstruction, 2);
   EXPECT_EQ(BranchesFeatures.DirectCallsToDefinedFunctions, 0);
@@ -69,7 +69,7 @@ define internal i32 @top() {
   // so it may have external callers.
   EXPECT_EQ(BranchesFeatures.Uses, 2);
 
-  auto TopFeatures = FA.run(*M->getFunction("top"), FAM);
+  auto TopFeatures = FPA.run(*M->getFunction("top"), FAM);
   EXPECT_EQ(TopFeatures.BasicBlockCount, 1);
   EXPECT_EQ(TopFeatures.BlocksReachedFromConditionalInstruction, 0);
   EXPECT_EQ(TopFeatures.DirectCallsToDefinedFunctions, 1);


        


More information about the llvm-commits mailing list