[llvm] [CodeGen] Introduce `MachineDomTreeUpdater` (PR #95369)
Jakub Kuderski via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 23 19:54:24 PDT 2024
================
@@ -0,0 +1,276 @@
+//===- MachineDomTreeUpdaterTest.cpp - MachineDomTreeUpdater unit tests ---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineDomTreeUpdater.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/LoopAnalysisManager.h"
+#include "llvm/CodeGen/MIRParser/MIRParser.h"
+#include "llvm/CodeGen/MachineFunctionAnalysis.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/MachinePostDominators.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+class MachineDomTreeUpdaterTest : public testing::Test {
+public:
+ LLVMContext Context;
+ std::unique_ptr<TargetMachine> TM;
+ std::unique_ptr<Module> M;
+ std::unique_ptr<MachineModuleInfo> MMI;
+ std::unique_ptr<MIRParser> MIR;
+
+ LoopAnalysisManager LAM;
+ MachineFunctionAnalysisManager MFAM;
+ FunctionAnalysisManager FAM;
+ CGSCCAnalysisManager CGAM;
+ ModuleAnalysisManager MAM;
+
+ ModulePassManager MPM;
+ FunctionPassManager FPM;
+ MachineFunctionPassManager MFPM;
+
+ static void SetUpTestCase() {
+ InitializeAllTargets();
+ InitializeAllTargetMCs();
+ }
+
+ void SetUp() override {
+ Triple TargetTriple("x86_64-unknown-linux-gnu");
+ std::string Error;
+ const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
+ if (!T)
+ GTEST_SKIP();
+ TargetOptions Options;
+ TM = std::unique_ptr<TargetMachine>(
+ T->createTargetMachine("X86", "", "", Options, std::nullopt));
+ if (!TM)
+ GTEST_SKIP();
+ MMI = std::make_unique<MachineModuleInfo>(
+ static_cast<LLVMTargetMachine *>(TM.get()));
+
+ PassBuilder PB(TM.get());
+ PB.registerModuleAnalyses(MAM);
+ PB.registerCGSCCAnalyses(CGAM);
+ PB.registerFunctionAnalyses(FAM);
+ PB.registerLoopAnalyses(LAM);
+ PB.registerMachineFunctionAnalyses(MFAM);
+ PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);
+ MAM.registerPass([&] { return MachineModuleAnalysis(*MMI); });
+ }
+
+ bool parseMIR(StringRef MIRCode, const char *FnName) {
+ SMDiagnostic Diagnostic;
+ std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
+ MIR = createMIRParser(std::move(MBuffer), Context);
+ if (!MIR)
+ return false;
+
+ M = MIR->parseIRModule();
+ M->setDataLayout(TM->createDataLayout());
+
+ if (MIR->parseMachineFunctions(*M, MAM)) {
+ M.reset();
+ return false;
+ }
+
+ return true;
+ }
+};
+
+TEST_F(MachineDomTreeUpdaterTest, EagerUpdateBasicOperations) {
+ StringRef MIRString = R"(
+--- |
+ define i64 @f0(i64 %i, ptr %p) {
+ bb0:
+ store i64 %i, ptr %p, align 4
+ switch i64 %i, label %bb1 [
+ i64 1, label %bb2
+ i64 2, label %bb3
+ ]
+ bb1: ; preds = %bb0
+ ret i64 1
+ bb2: ; preds = %bb0
+ ret i64 2
+ bb3: ; preds = %bb0
+ ret i64 3
+ }
+...
+---
+name: f0
+body: |
+ bb.0.bb0:
+ successors: %bb.2, %bb.4
+ liveins: $rdi, $rsi
+
+ %1:gr32 = COPY $rsi
+ %0:gr64 = COPY $rdi
+ MOV64mr %1, 1, $noreg, 0, $noreg, %0 :: (store (s64) into %ir.p)
+ %2:gr64 = SUB64ri32 %0, 1, implicit-def $eflags
+ JCC_1 %bb.2, 4, implicit $eflags
+ JMP_1 %bb.4
+
+ bb.4.bb0:
+ successors: %bb.3, %bb.1
+
+ %3:gr64 = SUB64ri32 %0, 2, implicit-def $eflags
+ JCC_1 %bb.3, 4, implicit $eflags
+ JMP_1 %bb.1
+
+ bb.1.bb1:
+ %6:gr64 = MOV32ri64 1
+ $rax = COPY %6
+ RET 0, $rax
+
+ bb.2.bb2:
+ %5:gr64 = MOV32ri64 2
+ $rax = COPY %5
+ RET 0, $rax
+
+ bb.3.bb3:
+ %4:gr64 = MOV32ri64 3
+ $rax = COPY %4
+ RET 0, $rax
+
+...
+)";
+
+ ASSERT_TRUE(parseMIR(MIRString, "f0"));
+
+ auto &MF =
+ FAM.getResult<MachineFunctionAnalysis>(*M->getFunction("f0")).getMF();
+
+ MachineDominatorTree DT(MF);
+ MachinePostDominatorTree PDT(MF);
+ MachineDomTreeUpdater DTU(DT, PDT,
+ MachineDomTreeUpdater::UpdateStrategy::Eager);
+
+ ASSERT_TRUE(DTU.hasDomTree());
+ ASSERT_TRUE(DTU.hasPostDomTree());
+ ASSERT_TRUE(DTU.isEager());
+ ASSERT_FALSE(DTU.isLazy());
+ ASSERT_TRUE(DTU.getDomTree().verify());
+ ASSERT_TRUE(DTU.getPostDomTree().verify());
+ ASSERT_FALSE(DTU.hasPendingUpdates());
+
+ auto B = MF.begin();
+ [[maybe_unused]] auto BB0 = B;
+ auto BB1 = ++B;
+ auto BB2 = ++B;
+ [[maybe_unused]] auto BB3 = ++B;
+ auto BB4 = ++B;
+ EXPECT_EQ(BB1->succ_size(), 2u);
+ ASSERT_TRUE(DT.dominates(&*BB1, &*BB2));
+ ASSERT_TRUE(DT.dominates(&*BB1, &*BB4));
+ BB1->removeSuccessor(&*BB4);
+ DTU.deleteBB(&*BB4);
+ EXPECT_EQ(BB1->succ_size(), 1u);
+ ASSERT_TRUE(DT.dominates(&*BB1, &*BB2));
+ ASSERT_TRUE(DT.getNode(&*BB4) == nullptr);
+}
+
+TEST_F(MachineDomTreeUpdaterTest, LazyUpdateBasicOperations) {
+ StringRef MIRString = R"(
+--- |
+ define i64 @f0(i64 %i, ptr %p) {
+ bb0:
+ store i64 %i, ptr %p, align 4
+ switch i64 %i, label %bb1 [
+ i64 1, label %bb2
+ i64 2, label %bb3
+ ]
+ bb1: ; preds = %bb0
+ ret i64 1
+ bb2: ; preds = %bb0
+ ret i64 2
+ bb3: ; preds = %bb0
+ ret i64 3
+ }
+...
+---
+name: f0
+body: |
+ bb.0.bb0:
+ successors: %bb.2, %bb.4
+ liveins: $rdi, $rsi
+
+ %1:gr32 = COPY $rsi
+ %0:gr64 = COPY $rdi
+ MOV64mr %1, 1, $noreg, 0, $noreg, %0 :: (store (s64) into %ir.p)
+ %2:gr64 = SUB64ri32 %0, 1, implicit-def $eflags
+ JCC_1 %bb.2, 4, implicit $eflags
+ JMP_1 %bb.4
+
+ bb.4.bb0:
+ successors: %bb.3, %bb.1
+
+ %3:gr64 = SUB64ri32 %0, 2, implicit-def $eflags
+ JCC_1 %bb.3, 4, implicit $eflags
+ JMP_1 %bb.1
+
+ bb.1.bb1:
+ %6:gr64 = MOV32ri64 1
+ $rax = COPY %6
+ RET 0, $rax
+
+ bb.2.bb2:
+ %5:gr64 = MOV32ri64 2
+ $rax = COPY %5
+ RET 0, $rax
+
+ bb.3.bb3:
+ %4:gr64 = MOV32ri64 3
+ $rax = COPY %4
+ RET 0, $rax
+
+...
+)";
+
+ ASSERT_TRUE(parseMIR(MIRString, "f0"));
+
+ auto &MF =
+ FAM.getResult<MachineFunctionAnalysis>(*M->getFunction("f0")).getMF();
+
+ MachineDominatorTree DT(MF);
+ MachinePostDominatorTree PDT(MF);
+ MachineDomTreeUpdater DTU(DT, PDT,
+ MachineDomTreeUpdater::UpdateStrategy::Lazy);
+
+ ASSERT_TRUE(DTU.hasDomTree());
+ ASSERT_TRUE(DTU.hasPostDomTree());
+ ASSERT_FALSE(DTU.isEager());
+ ASSERT_TRUE(DTU.isLazy());
+ ASSERT_TRUE(DTU.getDomTree().verify());
+ ASSERT_TRUE(DTU.getPostDomTree().verify());
+ ASSERT_FALSE(DTU.hasPendingUpdates());
+
+ auto B = MF.begin();
+ [[maybe_unused]] auto BB0 = B;
+ auto BB1 = ++B;
+ auto BB2 = ++B;
+ [[maybe_unused]] auto BB3 = ++B;
+ auto BB4 = ++B;
+ EXPECT_EQ(BB1->succ_size(), 2u);
+ ASSERT_TRUE(DT.dominates(&*BB1, &*BB2));
+ ASSERT_TRUE(DT.dominates(&*BB1, &*BB4));
+ BB1->removeSuccessor(&*BB4);
+ DTU.deleteBB(&*BB4);
+ EXPECT_EQ(BB1->succ_size(), 1u);
+ ASSERT_TRUE(DT.dominates(&*BB1, &*BB2));
+ ASSERT_FALSE(DT.getNode(&*BB4) == nullptr);
+ DTU.flush();
+ ASSERT_TRUE(DT.getNode(&*BB4) == nullptr);
----------------
kuhar wrote:
```suggestion
ASSERT_EQ(DT.getNode(&*BB4), nullptr);
```
https://github.com/llvm/llvm-project/pull/95369
More information about the llvm-commits
mailing list