1c931ac59Spaperchalice //===- MachineDomTreeUpdaterTest.cpp - MachineDomTreeUpdater unit tests ---===// 2c931ac59Spaperchalice // 3c931ac59Spaperchalice // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4c931ac59Spaperchalice // See https://llvm.org/LICENSE.txt for license information. 5c931ac59Spaperchalice // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6c931ac59Spaperchalice // 7c931ac59Spaperchalice //===----------------------------------------------------------------------===// 8c931ac59Spaperchalice 9c931ac59Spaperchalice #include "llvm/CodeGen/MachineDomTreeUpdater.h" 10c931ac59Spaperchalice #include "llvm/Analysis/CGSCCPassManager.h" 11c931ac59Spaperchalice #include "llvm/Analysis/LoopAnalysisManager.h" 12c931ac59Spaperchalice #include "llvm/CodeGen/MIRParser/MIRParser.h" 13c931ac59Spaperchalice #include "llvm/CodeGen/MachineFunctionAnalysis.h" 14c931ac59Spaperchalice #include "llvm/CodeGen/MachineModuleInfo.h" 15c931ac59Spaperchalice #include "llvm/CodeGen/MachinePassManager.h" 16c931ac59Spaperchalice #include "llvm/CodeGen/MachinePostDominators.h" 17c931ac59Spaperchalice #include "llvm/CodeGen/SelectionDAG.h" 18c931ac59Spaperchalice #include "llvm/CodeGen/TargetLowering.h" 1974deadf1SNikita Popov #include "llvm/IR/Module.h" 20c931ac59Spaperchalice #include "llvm/MC/TargetRegistry.h" 21c931ac59Spaperchalice #include "llvm/Passes/PassBuilder.h" 22c931ac59Spaperchalice #include "llvm/Support/SourceMgr.h" 23c931ac59Spaperchalice #include "llvm/Support/TargetSelect.h" 24c931ac59Spaperchalice #include "llvm/Target/TargetMachine.h" 25c931ac59Spaperchalice #include "gtest/gtest.h" 26c931ac59Spaperchalice 27c931ac59Spaperchalice using namespace llvm; 28c931ac59Spaperchalice 29c931ac59Spaperchalice class MachineDomTreeUpdaterTest : public testing::Test { 30c931ac59Spaperchalice public: 31c931ac59Spaperchalice LLVMContext Context; 32c931ac59Spaperchalice std::unique_ptr<TargetMachine> TM; 33c931ac59Spaperchalice std::unique_ptr<Module> M; 34c931ac59Spaperchalice std::unique_ptr<MachineModuleInfo> MMI; 35c931ac59Spaperchalice std::unique_ptr<MIRParser> MIR; 36c931ac59Spaperchalice 37c931ac59Spaperchalice LoopAnalysisManager LAM; 38c931ac59Spaperchalice MachineFunctionAnalysisManager MFAM; 39c931ac59Spaperchalice FunctionAnalysisManager FAM; 40c931ac59Spaperchalice CGSCCAnalysisManager CGAM; 41c931ac59Spaperchalice ModuleAnalysisManager MAM; 42c931ac59Spaperchalice 43c931ac59Spaperchalice ModulePassManager MPM; 44c931ac59Spaperchalice FunctionPassManager FPM; 45c931ac59Spaperchalice MachineFunctionPassManager MFPM; 46c931ac59Spaperchalice 47c931ac59Spaperchalice static void SetUpTestCase() { 48c931ac59Spaperchalice InitializeAllTargets(); 49c931ac59Spaperchalice InitializeAllTargetMCs(); 50c931ac59Spaperchalice } 51c931ac59Spaperchalice 52c931ac59Spaperchalice void SetUp() override { 53c931ac59Spaperchalice Triple TargetTriple("x86_64-unknown-linux-gnu"); 54c931ac59Spaperchalice std::string Error; 55c931ac59Spaperchalice const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); 56c931ac59Spaperchalice if (!T) 57c931ac59Spaperchalice GTEST_SKIP(); 58c931ac59Spaperchalice TargetOptions Options; 59c931ac59Spaperchalice TM = std::unique_ptr<TargetMachine>( 60c931ac59Spaperchalice T->createTargetMachine("X86", "", "", Options, std::nullopt)); 61c931ac59Spaperchalice if (!TM) 62c931ac59Spaperchalice GTEST_SKIP(); 63*bb3f5e1fSMatin Raayai MMI = std::make_unique<MachineModuleInfo>(TM.get()); 64c931ac59Spaperchalice 65c931ac59Spaperchalice PassBuilder PB(TM.get()); 66c931ac59Spaperchalice PB.registerModuleAnalyses(MAM); 67c931ac59Spaperchalice PB.registerCGSCCAnalyses(CGAM); 68c931ac59Spaperchalice PB.registerFunctionAnalyses(FAM); 69c931ac59Spaperchalice PB.registerLoopAnalyses(LAM); 70c931ac59Spaperchalice PB.registerMachineFunctionAnalyses(MFAM); 71c931ac59Spaperchalice PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM); 72c931ac59Spaperchalice MAM.registerPass([&] { return MachineModuleAnalysis(*MMI); }); 73c931ac59Spaperchalice } 74c931ac59Spaperchalice 7538c3855cSKyungwoo Lee bool parseMIR(StringRef MIRCode) { 76c931ac59Spaperchalice SMDiagnostic Diagnostic; 77c931ac59Spaperchalice std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode); 78c931ac59Spaperchalice MIR = createMIRParser(std::move(MBuffer), Context); 79c931ac59Spaperchalice if (!MIR) 80c931ac59Spaperchalice return false; 81c931ac59Spaperchalice 82c931ac59Spaperchalice M = MIR->parseIRModule(); 83c931ac59Spaperchalice M->setDataLayout(TM->createDataLayout()); 84c931ac59Spaperchalice 85c931ac59Spaperchalice if (MIR->parseMachineFunctions(*M, MAM)) { 86c931ac59Spaperchalice M.reset(); 87c931ac59Spaperchalice return false; 88c931ac59Spaperchalice } 89c931ac59Spaperchalice 90c931ac59Spaperchalice return true; 91c931ac59Spaperchalice } 92c931ac59Spaperchalice }; 93c931ac59Spaperchalice 94c931ac59Spaperchalice TEST_F(MachineDomTreeUpdaterTest, EagerUpdateBasicOperations) { 95c931ac59Spaperchalice StringRef MIRString = R"( 96c931ac59Spaperchalice --- | 97c931ac59Spaperchalice define i64 @f0(i64 %i, ptr %p) { 98c931ac59Spaperchalice bb0: 99c931ac59Spaperchalice store i64 %i, ptr %p, align 4 100c931ac59Spaperchalice switch i64 %i, label %bb1 [ 101c931ac59Spaperchalice i64 1, label %bb2 102c931ac59Spaperchalice i64 2, label %bb3 103c931ac59Spaperchalice ] 104c931ac59Spaperchalice bb1: ; preds = %bb0 105c931ac59Spaperchalice ret i64 1 106c931ac59Spaperchalice bb2: ; preds = %bb0 107c931ac59Spaperchalice ret i64 2 108c931ac59Spaperchalice bb3: ; preds = %bb0 109c931ac59Spaperchalice ret i64 3 110c931ac59Spaperchalice } 111c931ac59Spaperchalice ... 112c931ac59Spaperchalice --- 113c931ac59Spaperchalice name: f0 114c931ac59Spaperchalice body: | 115c931ac59Spaperchalice bb.0.bb0: 116c931ac59Spaperchalice successors: %bb.2, %bb.4 117c931ac59Spaperchalice liveins: $rdi, $rsi 118c931ac59Spaperchalice 119c931ac59Spaperchalice %1:gr32 = COPY $rsi 120c931ac59Spaperchalice %0:gr64 = COPY $rdi 121c931ac59Spaperchalice MOV64mr %1, 1, $noreg, 0, $noreg, %0 :: (store (s64) into %ir.p) 122c931ac59Spaperchalice %2:gr64 = SUB64ri32 %0, 1, implicit-def $eflags 123c931ac59Spaperchalice JCC_1 %bb.2, 4, implicit $eflags 124c931ac59Spaperchalice JMP_1 %bb.4 125c931ac59Spaperchalice 126c931ac59Spaperchalice bb.4.bb0: 127c931ac59Spaperchalice successors: %bb.3, %bb.1 128c931ac59Spaperchalice 129c931ac59Spaperchalice %3:gr64 = SUB64ri32 %0, 2, implicit-def $eflags 130c931ac59Spaperchalice JCC_1 %bb.3, 4, implicit $eflags 131c931ac59Spaperchalice JMP_1 %bb.1 132c931ac59Spaperchalice 133c931ac59Spaperchalice bb.1.bb1: 134c931ac59Spaperchalice %6:gr64 = MOV32ri64 1 135c931ac59Spaperchalice $rax = COPY %6 136c931ac59Spaperchalice RET 0, $rax 137c931ac59Spaperchalice 138c931ac59Spaperchalice bb.2.bb2: 139c931ac59Spaperchalice %5:gr64 = MOV32ri64 2 140c931ac59Spaperchalice $rax = COPY %5 141c931ac59Spaperchalice RET 0, $rax 142c931ac59Spaperchalice 143c931ac59Spaperchalice bb.3.bb3: 144c931ac59Spaperchalice %4:gr64 = MOV32ri64 3 145c931ac59Spaperchalice $rax = COPY %4 146c931ac59Spaperchalice RET 0, $rax 147c931ac59Spaperchalice 148c931ac59Spaperchalice ... 149c931ac59Spaperchalice )"; 150c931ac59Spaperchalice 15138c3855cSKyungwoo Lee ASSERT_TRUE(parseMIR(MIRString)); 152c931ac59Spaperchalice 153c931ac59Spaperchalice auto &MF = 154c931ac59Spaperchalice FAM.getResult<MachineFunctionAnalysis>(*M->getFunction("f0")).getMF(); 155c931ac59Spaperchalice 156c931ac59Spaperchalice MachineDominatorTree DT(MF); 157c931ac59Spaperchalice MachinePostDominatorTree PDT(MF); 158c931ac59Spaperchalice MachineDomTreeUpdater DTU(DT, PDT, 159c931ac59Spaperchalice MachineDomTreeUpdater::UpdateStrategy::Eager); 160c931ac59Spaperchalice 161c931ac59Spaperchalice ASSERT_TRUE(DTU.hasDomTree()); 162c931ac59Spaperchalice ASSERT_TRUE(DTU.hasPostDomTree()); 163c931ac59Spaperchalice ASSERT_TRUE(DTU.isEager()); 164c931ac59Spaperchalice ASSERT_FALSE(DTU.isLazy()); 165c931ac59Spaperchalice ASSERT_TRUE(DTU.getDomTree().verify()); 166c931ac59Spaperchalice ASSERT_TRUE(DTU.getPostDomTree().verify()); 167c931ac59Spaperchalice ASSERT_FALSE(DTU.hasPendingUpdates()); 168c931ac59Spaperchalice 169c931ac59Spaperchalice auto B = MF.begin(); 170c931ac59Spaperchalice [[maybe_unused]] auto BB0 = B; 171c931ac59Spaperchalice auto BB1 = ++B; 172c931ac59Spaperchalice auto BB2 = ++B; 173c931ac59Spaperchalice [[maybe_unused]] auto BB3 = ++B; 174c931ac59Spaperchalice auto BB4 = ++B; 175c931ac59Spaperchalice EXPECT_EQ(BB1->succ_size(), 2u); 176c931ac59Spaperchalice ASSERT_TRUE(DT.dominates(&*BB1, &*BB2)); 177c931ac59Spaperchalice ASSERT_TRUE(DT.dominates(&*BB1, &*BB4)); 178c931ac59Spaperchalice BB1->removeSuccessor(&*BB4); 179c931ac59Spaperchalice DTU.deleteBB(&*BB4); 180c931ac59Spaperchalice EXPECT_EQ(BB1->succ_size(), 1u); 181c931ac59Spaperchalice ASSERT_TRUE(DT.dominates(&*BB1, &*BB2)); 182c931ac59Spaperchalice } 183c931ac59Spaperchalice 184c931ac59Spaperchalice TEST_F(MachineDomTreeUpdaterTest, LazyUpdateBasicOperations) { 185c931ac59Spaperchalice StringRef MIRString = R"( 186c931ac59Spaperchalice --- | 187c931ac59Spaperchalice define i64 @f0(i64 %i, ptr %p) { 188c931ac59Spaperchalice bb0: 189c931ac59Spaperchalice store i64 %i, ptr %p, align 4 190c931ac59Spaperchalice switch i64 %i, label %bb1 [ 191c931ac59Spaperchalice i64 1, label %bb2 192c931ac59Spaperchalice i64 2, label %bb3 193c931ac59Spaperchalice ] 194c931ac59Spaperchalice bb1: ; preds = %bb0 195c931ac59Spaperchalice ret i64 1 196c931ac59Spaperchalice bb2: ; preds = %bb0 197c931ac59Spaperchalice ret i64 2 198c931ac59Spaperchalice bb3: ; preds = %bb0 199c931ac59Spaperchalice ret i64 3 200c931ac59Spaperchalice } 201c931ac59Spaperchalice ... 202c931ac59Spaperchalice --- 203c931ac59Spaperchalice name: f0 204c931ac59Spaperchalice body: | 205c931ac59Spaperchalice bb.0.bb0: 206c931ac59Spaperchalice successors: %bb.2, %bb.4 207c931ac59Spaperchalice liveins: $rdi, $rsi 208c931ac59Spaperchalice 209c931ac59Spaperchalice %1:gr32 = COPY $rsi 210c931ac59Spaperchalice %0:gr64 = COPY $rdi 211c931ac59Spaperchalice MOV64mr %1, 1, $noreg, 0, $noreg, %0 :: (store (s64) into %ir.p) 212c931ac59Spaperchalice %2:gr64 = SUB64ri32 %0, 1, implicit-def $eflags 213c931ac59Spaperchalice JCC_1 %bb.2, 4, implicit $eflags 214c931ac59Spaperchalice JMP_1 %bb.4 215c931ac59Spaperchalice 216c931ac59Spaperchalice bb.4.bb0: 217c931ac59Spaperchalice successors: %bb.3, %bb.1 218c931ac59Spaperchalice 219c931ac59Spaperchalice %3:gr64 = SUB64ri32 %0, 2, implicit-def $eflags 220c931ac59Spaperchalice JCC_1 %bb.3, 4, implicit $eflags 221c931ac59Spaperchalice JMP_1 %bb.1 222c931ac59Spaperchalice 223c931ac59Spaperchalice bb.1.bb1: 224c931ac59Spaperchalice %6:gr64 = MOV32ri64 1 225c931ac59Spaperchalice $rax = COPY %6 226c931ac59Spaperchalice RET 0, $rax 227c931ac59Spaperchalice 228c931ac59Spaperchalice bb.2.bb2: 229c931ac59Spaperchalice %5:gr64 = MOV32ri64 2 230c931ac59Spaperchalice $rax = COPY %5 231c931ac59Spaperchalice RET 0, $rax 232c931ac59Spaperchalice 233c931ac59Spaperchalice bb.3.bb3: 234c931ac59Spaperchalice %4:gr64 = MOV32ri64 3 235c931ac59Spaperchalice $rax = COPY %4 236c931ac59Spaperchalice RET 0, $rax 237c931ac59Spaperchalice 238c931ac59Spaperchalice ... 239c931ac59Spaperchalice )"; 240c931ac59Spaperchalice 24138c3855cSKyungwoo Lee ASSERT_TRUE(parseMIR(MIRString)); 242c931ac59Spaperchalice 243c931ac59Spaperchalice auto &MF = 244c931ac59Spaperchalice FAM.getResult<MachineFunctionAnalysis>(*M->getFunction("f0")).getMF(); 245c931ac59Spaperchalice 246c931ac59Spaperchalice MachineDominatorTree DT(MF); 247c931ac59Spaperchalice MachinePostDominatorTree PDT(MF); 248c931ac59Spaperchalice MachineDomTreeUpdater DTU(DT, PDT, 249c931ac59Spaperchalice MachineDomTreeUpdater::UpdateStrategy::Lazy); 250c931ac59Spaperchalice 251c931ac59Spaperchalice ASSERT_TRUE(DTU.hasDomTree()); 252c931ac59Spaperchalice ASSERT_TRUE(DTU.hasPostDomTree()); 253c931ac59Spaperchalice ASSERT_FALSE(DTU.isEager()); 254c931ac59Spaperchalice ASSERT_TRUE(DTU.isLazy()); 255c931ac59Spaperchalice ASSERT_TRUE(DTU.getDomTree().verify()); 256c931ac59Spaperchalice ASSERT_TRUE(DTU.getPostDomTree().verify()); 257c931ac59Spaperchalice ASSERT_FALSE(DTU.hasPendingUpdates()); 258c931ac59Spaperchalice 259c931ac59Spaperchalice auto B = MF.begin(); 260c931ac59Spaperchalice [[maybe_unused]] auto BB0 = B; 261c931ac59Spaperchalice auto BB1 = ++B; 262c931ac59Spaperchalice auto BB2 = ++B; 263c931ac59Spaperchalice [[maybe_unused]] auto BB3 = ++B; 264c931ac59Spaperchalice auto BB4 = ++B; 265c931ac59Spaperchalice EXPECT_EQ(BB1->succ_size(), 2u); 266c931ac59Spaperchalice ASSERT_TRUE(DT.dominates(&*BB1, &*BB2)); 267c931ac59Spaperchalice ASSERT_TRUE(DT.dominates(&*BB1, &*BB4)); 268c931ac59Spaperchalice BB1->removeSuccessor(&*BB4); 269c931ac59Spaperchalice DTU.deleteBB(&*BB4); 270bf528849Spaperchalice ASSERT_TRUE(DTU.hasPendingDeletedBB()); 271c931ac59Spaperchalice EXPECT_EQ(BB1->succ_size(), 1u); 272c931ac59Spaperchalice ASSERT_TRUE(DT.dominates(&*BB1, &*BB2)); 273c931ac59Spaperchalice ASSERT_NE(DT.getNode(&*BB4), nullptr); 274c931ac59Spaperchalice DTU.flush(); 275c931ac59Spaperchalice } 276