xref: /llvm-project/llvm/unittests/Analysis/FunctionPropertiesAnalysisTest.cpp (revision ee6f0e109cb2376b44f778db63711e92e90c2ef2)
1 //===- FunctionPropertiesAnalysisTest.cpp - Function Properties Unit Tests-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Analysis/FunctionPropertiesAnalysis.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/IR/Instructions.h"
12 #include "llvm/IR/LLVMContext.h"
13 #include "llvm/IR/Module.h"
14 #include "llvm/Support/SourceMgr.h"
15 #include "gtest/gtest.h"
16 
17 using namespace llvm;
18 
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 }
26 
27 TEST(FunctionPropertiesTest, BasicTest) {
28   LLVMContext C;
29   std::unique_ptr<Module> M = parseIR(C,
30                                       R"IR(
31 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
32 target triple = "x86_64-pc-linux-gnu"
33 
34 declare i32 @f1(i32)
35 declare i32 @f2(i32)
36 
37 define i32 @branches(i32) {
38   %cond = icmp slt i32 %0, 3
39   br i1 %cond, label %then, label %else
40 
41 then:
42   %ret.1 = call i32 @f1(i32 %0)
43   br label %last.block
44 
45 else:
46   %ret.2 = call i32 @f2(i32 %0)
47   br label %last.block
48 
49 last.block:
50   %ret = phi i32 [%ret.1, %then], [%ret.2, %else]
51   ret i32 %ret
52 }
53 
54 define internal i32 @top() {
55   %1 = call i32 @branches(i32 2)
56   %2 = call i32 @f1(i32 %1)
57   ret i32 %2
58 }
59 )IR");
60 
61   FunctionAnalysisManager FAM;
62   FunctionPropertiesAnalysis FPA;
63 
64   auto BranchesFeatures = FPA.run(*M->getFunction("branches"), FAM);
65   EXPECT_EQ(BranchesFeatures.BasicBlockCount, 4);
66   EXPECT_EQ(BranchesFeatures.BlocksReachedFromConditionalInstruction, 2);
67   EXPECT_EQ(BranchesFeatures.DirectCallsToDefinedFunctions, 0);
68   // 2 Users: top is one. The other is added because @branches is not internal,
69   // so it may have external callers.
70   EXPECT_EQ(BranchesFeatures.Uses, 2);
71 
72   auto TopFeatures = FPA.run(*M->getFunction("top"), FAM);
73   EXPECT_EQ(TopFeatures.BasicBlockCount, 1);
74   EXPECT_EQ(TopFeatures.BlocksReachedFromConditionalInstruction, 0);
75   EXPECT_EQ(TopFeatures.DirectCallsToDefinedFunctions, 1);
76   EXPECT_EQ(TopFeatures.Uses, 0);
77 }
78