• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- SizeOptsTest.cpp - SizeOpts 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/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"
23 
24 using namespace llvm;
25 
26 namespace {
27 
28 class SizeOptsTest : public testing::Test {
29 protected:
30   static const char* IRString;
31   LLVMContext C;
32   std::unique_ptr<Module> M;
33   struct BFIData {
34     std::unique_ptr<DominatorTree> DT;
35     std::unique_ptr<LoopInfo> LI;
36     std::unique_ptr<BranchProbabilityInfo> BPI;
37     std::unique_ptr<BlockFrequencyInfo> BFI;
BFIData__anon3a7864020111::SizeOptsTest::BFIData38     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));
43     }
get__anon3a7864020111::SizeOptsTest::BFIData44     BlockFrequencyInfo *get() { return BFI.get(); }
45   };
46 
SetUp()47   void SetUp() override {
48     SMDiagnostic Err;
49     M = parseAssemblyString(IRString, Err, C);
50   }
51 };
52 
TEST_F(SizeOptsTest,Test)53 TEST_F(SizeOptsTest, Test) {
54   Function *F = M->getFunction("f");
55   Function *G = M->getFunction("g");
56   Function *H = M->getFunction("h");
57 
58   ProfileSummaryInfo PSI(*M.get());
59   BFIData BFID_F(*F);
60   BFIData BFID_G(*G);
61   BFIData BFID_H(*H);
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();
69 
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));
78 }
79 
80 const char* SizeOptsTest::IRString = R"IR(
81   define i32 @g(i32 %x) !prof !14 {
82     ret i32 0
83   }
84 
85   define i32 @h(i32 %x) !prof !15 {
86     ret i32 0
87   }
88 
89   define i32 @f(i32 %x) !prof !16 {
90   bb0:
91     %y1 = icmp eq i32 %x, 0
92     br i1 %y1, label %bb1, label %bb2, !prof !17
93 
94   bb1:                                              ; preds = %bb0
95     %z1 = call i32 @g(i32 %x)
96     br label %bb3
97 
98   bb2:                                              ; preds = %bb0
99     %z2 = call i32 @h(i32 %x)
100     br label %bb3
101 
102   bb3:                                              ; preds = %bb2, %bb1
103     %y2 = phi i32 [ 0, %bb1 ], [ 1, %bb2 ]
104     ret i32 %y2
105   }
106 
107   !llvm.module.flags = !{!0}
108 
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}
127 )IR";
128 
129 } // end anonymous namespace
130