[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