1 //===- SizeOptsTest.cpp - SizeOpts unit tests -----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Transforms/Utils/SizeOpts.h"
10 #include "llvm/Analysis/ProfileSummaryInfo.h"
11 #include "llvm/Analysis/BlockFrequencyInfo.h"
12 #include "llvm/Analysis/BranchProbabilityInfo.h"
13 #include "llvm/Analysis/LoopInfo.h"
14 #include "llvm/AsmParser/Parser.h"
15 #include "llvm/IR/BasicBlock.h"
16 #include "llvm/IR/Dominators.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/IR/LLVMContext.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/Support/FormatVariadic.h"
21 #include "llvm/Support/SourceMgr.h"
22 #include "gtest/gtest.h"
28 class SizeOptsTest
: public testing::Test
{
30 static const char* IRString
;
32 std::unique_ptr
<Module
> M
;
34 std::unique_ptr
<DominatorTree
> DT
;
35 std::unique_ptr
<LoopInfo
> LI
;
36 std::unique_ptr
<BranchProbabilityInfo
> BPI
;
37 std::unique_ptr
<BlockFrequencyInfo
> BFI
;
38 BFIData(Function
&F
) {
39 DT
.reset(new DominatorTree(F
));
40 LI
.reset(new LoopInfo(*DT
));
41 BPI
.reset(new BranchProbabilityInfo(F
, *LI
));
42 BFI
.reset(new BlockFrequencyInfo(F
, *BPI
, *LI
));
44 BlockFrequencyInfo
*get() { return BFI
.get(); }
47 void SetUp() override
{
49 M
= parseAssemblyString(IRString
, Err
, C
);
53 TEST_F(SizeOptsTest
, Test
) {
54 Function
*F
= M
->getFunction("f");
55 Function
*G
= M
->getFunction("g");
56 Function
*H
= M
->getFunction("h");
58 ProfileSummaryInfo
PSI(*M
.get());
62 BlockFrequencyInfo
*BFI_F
= BFID_F
.get();
63 BlockFrequencyInfo
*BFI_G
= BFID_G
.get();
64 BlockFrequencyInfo
*BFI_H
= BFID_H
.get();
65 BasicBlock
&BB0
= F
->getEntryBlock();
66 BasicBlock
*BB1
= BB0
.getTerminator()->getSuccessor(0);
67 BasicBlock
*BB2
= BB0
.getTerminator()->getSuccessor(1);
68 BasicBlock
*BB3
= BB1
->getSingleSuccessor();
70 EXPECT_TRUE(PSI
.hasProfileSummary());
71 EXPECT_FALSE(shouldOptimizeForSize(F
, &PSI
, BFI_F
, PGSOQueryType::Test
));
72 EXPECT_TRUE(shouldOptimizeForSize(G
, &PSI
, BFI_G
, PGSOQueryType::Test
));
73 EXPECT_FALSE(shouldOptimizeForSize(H
, &PSI
, BFI_H
, PGSOQueryType::Test
));
74 EXPECT_FALSE(shouldOptimizeForSize(&BB0
, &PSI
, BFI_F
, PGSOQueryType::Test
));
75 EXPECT_FALSE(shouldOptimizeForSize(BB1
, &PSI
, BFI_F
, PGSOQueryType::Test
));
76 EXPECT_TRUE(shouldOptimizeForSize(BB2
, &PSI
, BFI_F
, PGSOQueryType::Test
));
77 EXPECT_FALSE(shouldOptimizeForSize(BB3
, &PSI
, BFI_F
, PGSOQueryType::Test
));
80 const char* SizeOptsTest::IRString
= R
"IR(
81 define i32 @g(i32 %x) !prof !14 {
85 define i32 @h(i32 %x) !prof !15 {
89 define i32 @f(i32 %x) !prof !16 {
91 %y1 = icmp eq i32 %x, 0
92 br i1 %y1, label %bb1, label %bb2, !prof !17
95 %z1 = call i32 @g(i32 %x)
99 %z2 = call i32 @h(i32 %x)
102 bb3: ; preds = %bb2, %bb1
103 %y2 = phi i32 [ 0, %bb1 ], [ 1, %bb2 ]
107 !llvm.module.flags = !{!0}
109 !0 = !{i32 1, !"ProfileSummary
", !1}
110 !1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
111 !2 = !{!"ProfileFormat
", !"InstrProf
"}
112 !3 = !{!"TotalCount
", i64 10000}
113 !4 = !{!"MaxCount
", i64 10}
114 !5 = !{!"MaxInternalCount
", i64 1}
115 !6 = !{!"MaxFunctionCount
", i64 1000}
116 !7 = !{!"NumCounts
", i64 3}
117 !8 = !{!"NumFunctions
", i64 3}
118 !9 = !{!"DetailedSummary
", !10}
119 !10 = !{!11, !12, !13}
120 !11 = !{i32 10000, i64 1000, i32 1}
121 !12 = !{i32 999000, i64 300, i32 3}
122 !13 = !{i32 999999, i64 5, i32 10}
123 !14 = !{!"function_entry_count
", i64 1}
124 !15 = !{!"function_entry_count
", i64 100}
125 !16 = !{!"function_entry_count
", i64 400}
126 !17 = !{!"branch_weights
", i32 100, i32 1}
129 } // end anonymous namespace