1 //===- BranchProbabilityInfoTest.cpp - BranchProbabilityInfo unit tests ---===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/Analysis/BranchProbabilityInfo.h" 11 #include "llvm/Analysis/LoopInfo.h" 12 #include "llvm/AsmParser/Parser.h" 13 #include "llvm/IR/BasicBlock.h" 14 #include "llvm/IR/Constants.h" 15 #include "llvm/IR/Dominators.h" 16 #include "llvm/IR/Function.h" 17 #include "llvm/IR/Instructions.h" 18 #include "llvm/IR/LLVMContext.h" 19 #include "llvm/IR/Module.h" 20 #include "llvm/Support/DataTypes.h" 21 #include "llvm/Support/SourceMgr.h" 22 #include "llvm/Support/raw_ostream.h" 23 #include "gtest/gtest.h" 24 25 namespace llvm { 26 namespace { 27 28 struct BranchProbabilityInfoTest : public testing::Test { 29 std::unique_ptr<BranchProbabilityInfo> BPI; 30 std::unique_ptr<DominatorTree> DT; 31 std::unique_ptr<LoopInfo> LI; 32 LLVMContext C; 33 34 BranchProbabilityInfo &buildBPI(Function &F) { 35 DT.reset(new DominatorTree(F)); 36 LI.reset(new LoopInfo(*DT)); 37 BPI.reset(new BranchProbabilityInfo(F, *LI)); 38 return *BPI; 39 } 40 41 std::unique_ptr<Module> makeLLVMModule() { 42 const char *ModuleString = "define void @f() { exit: ret void }\n"; 43 SMDiagnostic Err; 44 return parseAssemblyString(ModuleString, Err, C); 45 } 46 }; 47 48 TEST_F(BranchProbabilityInfoTest, StressUnreachableHeuristic) { 49 auto M = makeLLVMModule(); 50 Function *F = M->getFunction("f"); 51 52 // define void @f() { 53 // entry: 54 // switch i32 undef, label %exit, [ 55 // i32 0, label %preexit 56 // ... ;;< Add lots of cases to stress the heuristic. 57 // ] 58 // preexit: 59 // unreachable 60 // exit: 61 // ret void 62 // } 63 64 auto *ExitBB = &F->back(); 65 auto *EntryBB = BasicBlock::Create(C, "entry", F, /*insertBefore=*/ExitBB); 66 67 auto *PreExitBB = 68 BasicBlock::Create(C, "preexit", F, /*insertBefore=*/ExitBB); 69 new UnreachableInst(C, PreExitBB); 70 71 unsigned NumCases = 4096; 72 auto *I32 = IntegerType::get(C, 32); 73 auto *Undef = UndefValue::get(I32); 74 auto *Switch = SwitchInst::Create(Undef, ExitBB, NumCases, EntryBB); 75 for (unsigned I = 0; I < NumCases; ++I) 76 Switch->addCase(ConstantInt::get(I32, I), PreExitBB); 77 78 BranchProbabilityInfo &BPI = buildBPI(*F); 79 80 // FIXME: This doesn't seem optimal. Since all of the cases handled by the 81 // switch have the *same* destination block ("preexit"), shouldn't it be the 82 // hot one? I'd expect the results to be reversed here... 83 EXPECT_FALSE(BPI.isEdgeHot(EntryBB, PreExitBB)); 84 EXPECT_TRUE(BPI.isEdgeHot(EntryBB, ExitBB)); 85 } 86 87 } // end anonymous namespace 88 } // end namespace llvm 89