xref: /llvm-project/llvm/unittests/Analysis/BlockFrequencyInfoTest.cpp (revision 5181156b3743df29dc840e15990d9202b3501f60)
112b79aa0SEaswaran Raman //===- BlockFrequencyInfoTest.cpp - BlockFrequencyInfo unit tests ---------===//
212b79aa0SEaswaran Raman //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
612b79aa0SEaswaran Raman //
712b79aa0SEaswaran Raman //===----------------------------------------------------------------------===//
812b79aa0SEaswaran Raman 
912b79aa0SEaswaran Raman #include "llvm/Analysis/BlockFrequencyInfo.h"
10be88539bSSerge Guelton #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
1112b79aa0SEaswaran Raman #include "llvm/Analysis/BranchProbabilityInfo.h"
1212b79aa0SEaswaran Raman #include "llvm/Analysis/LoopInfo.h"
1312b79aa0SEaswaran Raman #include "llvm/AsmParser/Parser.h"
1412b79aa0SEaswaran Raman #include "llvm/IR/BasicBlock.h"
1512b79aa0SEaswaran Raman #include "llvm/IR/Dominators.h"
1612b79aa0SEaswaran Raman #include "llvm/IR/Function.h"
1712b79aa0SEaswaran Raman #include "llvm/IR/LLVMContext.h"
1812b79aa0SEaswaran Raman #include "llvm/IR/Module.h"
1912b79aa0SEaswaran Raman #include "llvm/Support/DataTypes.h"
2012b79aa0SEaswaran Raman #include "llvm/Support/SourceMgr.h"
2112b79aa0SEaswaran Raman #include "llvm/Support/raw_ostream.h"
2212b79aa0SEaswaran Raman #include "gtest/gtest.h"
2312b79aa0SEaswaran Raman 
2412b79aa0SEaswaran Raman namespace llvm {
2512b79aa0SEaswaran Raman namespace {
2612b79aa0SEaswaran Raman 
2712b79aa0SEaswaran Raman class BlockFrequencyInfoTest : public testing::Test {
2812b79aa0SEaswaran Raman protected:
2912b79aa0SEaswaran Raman   std::unique_ptr<BranchProbabilityInfo> BPI;
3012b79aa0SEaswaran Raman   std::unique_ptr<DominatorTree> DT;
3112b79aa0SEaswaran Raman   std::unique_ptr<LoopInfo> LI;
3203b42e41SMehdi Amini   LLVMContext C;
3312b79aa0SEaswaran Raman 
buildBFI(Function & F)3412b79aa0SEaswaran Raman   BlockFrequencyInfo buildBFI(Function &F) {
3512b79aa0SEaswaran Raman     DT.reset(new DominatorTree(F));
3612b79aa0SEaswaran Raman     LI.reset(new LoopInfo(*DT));
3712b79aa0SEaswaran Raman     BPI.reset(new BranchProbabilityInfo(F, *LI));
3812b79aa0SEaswaran Raman     return BlockFrequencyInfo(F, *BPI, *LI);
3912b79aa0SEaswaran Raman   }
makeLLVMModule()4012b79aa0SEaswaran Raman   std::unique_ptr<Module> makeLLVMModule() {
4112b79aa0SEaswaran Raman     const char *ModuleStrig = "define i32 @f(i32 %x) {\n"
4212b79aa0SEaswaran Raman                               "bb0:\n"
4312b79aa0SEaswaran Raman                               "  %y1 = icmp eq i32 %x, 0 \n"
4412b79aa0SEaswaran Raman                               "  br i1 %y1, label %bb1, label %bb2 \n"
4512b79aa0SEaswaran Raman                               "bb1:\n"
4612b79aa0SEaswaran Raman                               "  br label %bb3\n"
4712b79aa0SEaswaran Raman                               "bb2:\n"
4812b79aa0SEaswaran Raman                               "  br label %bb3\n"
4912b79aa0SEaswaran Raman                               "bb3:\n"
5012b79aa0SEaswaran Raman                               "  %y2 = phi i32 [0, %bb1], [1, %bb2] \n"
5112b79aa0SEaswaran Raman                               "  ret i32 %y2\n"
5212b79aa0SEaswaran Raman                               "}\n";
5312b79aa0SEaswaran Raman     SMDiagnostic Err;
5412b79aa0SEaswaran Raman     return parseAssemblyString(ModuleStrig, Err, C);
5512b79aa0SEaswaran Raman   }
5612b79aa0SEaswaran Raman };
5712b79aa0SEaswaran Raman 
TEST_F(BlockFrequencyInfoTest,Basic)5812b79aa0SEaswaran Raman TEST_F(BlockFrequencyInfoTest, Basic) {
5912b79aa0SEaswaran Raman   auto M = makeLLVMModule();
6012b79aa0SEaswaran Raman   Function *F = M->getFunction("f");
6112b79aa0SEaswaran Raman   F->setEntryCount(100);
6212b79aa0SEaswaran Raman 
6312b79aa0SEaswaran Raman   BlockFrequencyInfo BFI = buildBFI(*F);
6412b79aa0SEaswaran Raman   BasicBlock &BB0 = F->getEntryBlock();
6512b79aa0SEaswaran Raman   BasicBlock *BB1 = BB0.getTerminator()->getSuccessor(0);
6612b79aa0SEaswaran Raman   BasicBlock *BB2 = BB0.getTerminator()->getSuccessor(1);
6712b79aa0SEaswaran Raman   BasicBlock *BB3 = BB1->getSingleSuccessor();
6812b79aa0SEaswaran Raman 
6912b79aa0SEaswaran Raman   uint64_t BB0Freq = BFI.getBlockFreq(&BB0).getFrequency();
7012b79aa0SEaswaran Raman   uint64_t BB1Freq = BFI.getBlockFreq(BB1).getFrequency();
7112b79aa0SEaswaran Raman   uint64_t BB2Freq = BFI.getBlockFreq(BB2).getFrequency();
7212b79aa0SEaswaran Raman   uint64_t BB3Freq = BFI.getBlockFreq(BB3).getFrequency();
7312b79aa0SEaswaran Raman 
7412b79aa0SEaswaran Raman   EXPECT_EQ(BB0Freq, BB3Freq);
7512b79aa0SEaswaran Raman   EXPECT_EQ(BB0Freq, BB1Freq + BB2Freq);
7612b79aa0SEaswaran Raman   EXPECT_EQ(BB0Freq, BB3Freq);
7712b79aa0SEaswaran Raman 
7867ba5c50SFangrui Song   EXPECT_EQ(*BFI.getBlockProfileCount(&BB0), UINT64_C(100));
7967ba5c50SFangrui Song   EXPECT_EQ(*BFI.getBlockProfileCount(BB3), UINT64_C(100));
8067ba5c50SFangrui Song   EXPECT_EQ(*BFI.getBlockProfileCount(BB1),
81aca738b7SEaswaran Raman             (100 * BB1Freq + BB0Freq / 2) / BB0Freq);
8267ba5c50SFangrui Song   EXPECT_EQ(*BFI.getBlockProfileCount(BB2),
83aca738b7SEaswaran Raman             (100 * BB2Freq + BB0Freq / 2) / BB0Freq);
846c8f511fSEaswaran Raman 
856c8f511fSEaswaran Raman   // Scale the frequencies of BB0, BB1 and BB2 by a factor of two.
866c8f511fSEaswaran Raman   SmallPtrSet<BasicBlock *, 4> BlocksToScale({BB1, BB2});
87*5181156bSMatthias Braun   BFI.setBlockFreqAndScale(&BB0, BlockFrequency(BB0Freq * 2), BlocksToScale);
886c8f511fSEaswaran Raman   EXPECT_EQ(BFI.getBlockFreq(&BB0).getFrequency(), 2 * BB0Freq);
896c8f511fSEaswaran Raman   EXPECT_EQ(BFI.getBlockFreq(BB1).getFrequency(), 2 * BB1Freq);
906c8f511fSEaswaran Raman   EXPECT_EQ(BFI.getBlockFreq(BB2).getFrequency(), 2 * BB2Freq);
916c8f511fSEaswaran Raman   EXPECT_EQ(BFI.getBlockFreq(BB3).getFrequency(), BB3Freq);
9212b79aa0SEaswaran Raman }
9312b79aa0SEaswaran Raman 
946aa050a6SNathan James static_assert(std::is_trivially_copyable_v<bfi_detail::BlockMass>,
95be88539bSSerge Guelton               "trivially copyable");
96be88539bSSerge Guelton 
9712b79aa0SEaswaran Raman } // end anonymous namespace
9812b79aa0SEaswaran Raman } // end namespace llvm
99