8
8
9
9
#include " llvm/Analysis/FunctionPropertiesAnalysis.h"
10
10
#include " llvm/AsmParser/Parser.h"
11
+ #include " llvm/IR/Dominators.h"
11
12
#include " llvm/IR/Instructions.h"
12
13
#include " llvm/IR/LLVMContext.h"
13
14
#include " llvm/IR/Module.h"
14
15
#include " llvm/Support/SourceMgr.h"
15
16
#include " gtest/gtest.h"
16
17
17
18
using namespace llvm ;
19
+ namespace {
18
20
19
- static std::unique_ptr<Module> parseIR (LLVMContext &C, const char *IR) {
20
- SMDiagnostic Err;
21
- std::unique_ptr<Module> Mod = parseAssemblyString (IR, Err, C);
22
- if (!Mod)
23
- Err.print (" MLAnalysisTests" , errs ());
24
- return Mod;
25
- }
21
+ class FunctionPropertiesAnalysisTest : public testing ::Test {
22
+ protected:
23
+ std::unique_ptr<DominatorTree> DT;
24
+ std::unique_ptr<LoopInfo> LI;
25
+
26
+ FunctionPropertiesInfo buildFPI (Function &F) {
27
+ DT.reset (new DominatorTree (F));
28
+ LI.reset (new LoopInfo (*DT));
29
+ return FunctionPropertiesInfo::getFunctionPropertiesInfo (F, *LI);
30
+ }
26
31
27
- TEST (FunctionPropertiesTest, BasicTest) {
32
+ std::unique_ptr<Module> makeLLVMModule (LLVMContext &C, const char *IR) {
33
+ SMDiagnostic Err;
34
+ std::unique_ptr<Module> Mod = parseAssemblyString (IR, Err, C);
35
+ if (!Mod)
36
+ Err.print (" MLAnalysisTests" , errs ());
37
+ return Mod;
38
+ }
39
+ };
40
+
41
+ TEST_F (FunctionPropertiesAnalysisTest, BasicTest) {
28
42
LLVMContext C;
29
- std::unique_ptr<Module> M = parseIR (C,
30
- R"IR(
43
+ std::unique_ptr<Module> M = makeLLVMModule (C,
44
+ R"IR(
31
45
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
32
46
target triple = "x86_64-pc-linux-gnu"
33
-
34
47
declare i32 @f1(i32)
35
48
declare i32 @f2(i32)
36
-
37
49
define i32 @branches(i32) {
38
50
%cond = icmp slt i32 %0, 3
39
51
br i1 %cond, label %then, label %else
40
-
41
52
then:
42
53
%ret.1 = call i32 @f1(i32 %0)
43
54
br label %last.block
44
-
45
55
else:
46
56
%ret.2 = call i32 @f2(i32 %0)
47
57
br label %last.block
48
-
49
58
last.block:
50
59
%ret = phi i32 [%ret.1, %then], [%ret.2, %else]
51
60
ret i32 %ret
52
61
}
53
-
54
62
define internal i32 @top() {
55
63
%1 = call i32 @branches(i32 2)
56
64
%2 = call i32 @f1(i32 %1)
57
65
ret i32 %2
58
66
}
59
67
)IR" );
60
68
61
- FunctionAnalysisManager FAM;
62
- FunctionPropertiesAnalysis FPA;
63
-
64
- auto BranchesFeatures = FPA.run (*M->getFunction (" branches" ), FAM);
69
+ Function *BranchesFunction = M->getFunction (" branches" );
70
+ FunctionPropertiesInfo BranchesFeatures = buildFPI (*BranchesFunction);
65
71
EXPECT_EQ (BranchesFeatures.BasicBlockCount , 4 );
66
72
EXPECT_EQ (BranchesFeatures.BlocksReachedFromConditionalInstruction , 2 );
67
- EXPECT_EQ (BranchesFeatures.DirectCallsToDefinedFunctions , 0 );
68
73
// 2 Users: top is one. The other is added because @branches is not internal,
69
74
// so it may have external callers.
70
75
EXPECT_EQ (BranchesFeatures.Uses , 2 );
76
+ EXPECT_EQ (BranchesFeatures.DirectCallsToDefinedFunctions , 0 );
77
+ EXPECT_EQ (BranchesFeatures.LoadInstCount , 0 );
78
+ EXPECT_EQ (BranchesFeatures.StoreInstCount , 0 );
79
+ EXPECT_EQ (BranchesFeatures.MaxLoopDepth , 0 );
80
+ EXPECT_EQ (BranchesFeatures.TopLevelLoopCount , 0 );
71
81
72
- auto TopFeatures = FPA.run (*M->getFunction (" top" ), FAM);
82
+ Function *TopFunction = M->getFunction (" top" );
83
+ FunctionPropertiesInfo TopFeatures = buildFPI (*TopFunction);
73
84
EXPECT_EQ (TopFeatures.BasicBlockCount , 1 );
74
85
EXPECT_EQ (TopFeatures.BlocksReachedFromConditionalInstruction , 0 );
75
- EXPECT_EQ (TopFeatures.DirectCallsToDefinedFunctions , 1 );
76
86
EXPECT_EQ (TopFeatures.Uses , 0 );
87
+ EXPECT_EQ (TopFeatures.DirectCallsToDefinedFunctions , 1 );
88
+ EXPECT_EQ (BranchesFeatures.LoadInstCount , 0 );
89
+ EXPECT_EQ (BranchesFeatures.StoreInstCount , 0 );
90
+ EXPECT_EQ (BranchesFeatures.MaxLoopDepth , 0 );
91
+ EXPECT_EQ (BranchesFeatures.TopLevelLoopCount , 0 );
77
92
}
93
+ } // end anonymous namespace
0 commit comments