<div dir="ltr"><div>Thanks!</div><div>+ Tarindu </div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jul 23, 2020 at 3:05 PM Eric Christopher <<a href="mailto:echristo@gmail.com">echristo@gmail.com</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"><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" target="_blank">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>
</blockquote></div>