1 //===- BlockFrequencyInfoTest.cpp - BlockFrequencyInfo 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/Analysis/BlockFrequencyInfo.h"
10 #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
11 #include "llvm/Analysis/BranchProbabilityInfo.h"
12 #include "llvm/Analysis/LoopInfo.h"
13 #include "llvm/AsmParser/Parser.h"
14 #include "llvm/IR/BasicBlock.h"
15 #include "llvm/IR/Dominators.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/LLVMContext.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Support/DataTypes.h"
20 #include "llvm/Support/SourceMgr.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include "gtest/gtest.h"
27 class BlockFrequencyInfoTest
: public testing::Test
{
29 std::unique_ptr
<BranchProbabilityInfo
> BPI
;
30 std::unique_ptr
<DominatorTree
> DT
;
31 std::unique_ptr
<LoopInfo
> LI
;
34 BlockFrequencyInfo
buildBFI(Function
&F
) {
35 DT
.reset(new DominatorTree(F
));
36 LI
.reset(new LoopInfo(*DT
));
37 BPI
.reset(new BranchProbabilityInfo(F
, *LI
));
38 return BlockFrequencyInfo(F
, *BPI
, *LI
);
40 std::unique_ptr
<Module
> makeLLVMModule() {
41 const char *ModuleStrig
= "define i32 @f(i32 %x) {\n"
43 " %y1 = icmp eq i32 %x, 0 \n"
44 " br i1 %y1, label %bb1, label %bb2 \n"
50 " %y2 = phi i32 [0, %bb1], [1, %bb2] \n"
54 return parseAssemblyString(ModuleStrig
, Err
, C
);
58 TEST_F(BlockFrequencyInfoTest
, Basic
) {
59 auto M
= makeLLVMModule();
60 Function
*F
= M
->getFunction("f");
61 F
->setEntryCount(100);
63 BlockFrequencyInfo BFI
= buildBFI(*F
);
64 BasicBlock
&BB0
= F
->getEntryBlock();
65 BasicBlock
*BB1
= BB0
.getTerminator()->getSuccessor(0);
66 BasicBlock
*BB2
= BB0
.getTerminator()->getSuccessor(1);
67 BasicBlock
*BB3
= BB1
->getSingleSuccessor();
69 uint64_t BB0Freq
= BFI
.getBlockFreq(&BB0
).getFrequency();
70 uint64_t BB1Freq
= BFI
.getBlockFreq(BB1
).getFrequency();
71 uint64_t BB2Freq
= BFI
.getBlockFreq(BB2
).getFrequency();
72 uint64_t BB3Freq
= BFI
.getBlockFreq(BB3
).getFrequency();
74 EXPECT_EQ(BB0Freq
, BB3Freq
);
75 EXPECT_EQ(BB0Freq
, BB1Freq
+ BB2Freq
);
76 EXPECT_EQ(BB0Freq
, BB3Freq
);
78 EXPECT_EQ(*BFI
.getBlockProfileCount(&BB0
), UINT64_C(100));
79 EXPECT_EQ(*BFI
.getBlockProfileCount(BB3
), UINT64_C(100));
80 EXPECT_EQ(*BFI
.getBlockProfileCount(BB1
),
81 (100 * BB1Freq
+ BB0Freq
/ 2) / BB0Freq
);
82 EXPECT_EQ(*BFI
.getBlockProfileCount(BB2
),
83 (100 * BB2Freq
+ BB0Freq
/ 2) / BB0Freq
);
85 // Scale the frequencies of BB0, BB1 and BB2 by a factor of two.
86 SmallPtrSet
<BasicBlock
*, 4> BlocksToScale({BB1
, BB2
});
87 BFI
.setBlockFreqAndScale(&BB0
, BlockFrequency(BB0Freq
* 2), BlocksToScale
);
88 EXPECT_EQ(BFI
.getBlockFreq(&BB0
).getFrequency(), 2 * BB0Freq
);
89 EXPECT_EQ(BFI
.getBlockFreq(BB1
).getFrequency(), 2 * BB1Freq
);
90 EXPECT_EQ(BFI
.getBlockFreq(BB2
).getFrequency(), 2 * BB2Freq
);
91 EXPECT_EQ(BFI
.getBlockFreq(BB3
).getFrequency(), BB3Freq
);
94 static_assert(std::is_trivially_copyable_v
<bfi_detail::BlockMass
>,
95 "trivially copyable");
97 } // end anonymous namespace
98 } // end namespace llvm