| #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" | |
| #include "GISelMITest.h" | |
| #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" | |
| #include "llvm/CodeGen/TargetPassConfig.h" | |
| #include "llvm/IR/LegacyPassManager.h" | |
| namespace { | |
| class EraseMockInstructionSelector : public InstructionSelector { | |
| public: | |
| int NumSelected = 0; | |
| SmallVector<MachineInstr *> MIs; | |
| bool select(MachineInstr &MI) override { | |
| ++NumSelected; | |
| switch (NumSelected) { | |
| case 1: | |
| EXPECT_EQ(&MI, MIs[8]); | |
| // Erase previous instructions | |
| MIs[7]->eraseFromParent(); | |
| MIs[6]->eraseFromParent(); | |
| // Don't erase this MI before step 3 to prevent DCE | |
| return true; | |
| case 2: | |
| EXPECT_EQ(&MI, MIs[5]); | |
| // Erase previous instructions reversed | |
| MIs[3]->eraseFromParent(); | |
| MIs[4]->eraseFromParent(); | |
| MI.eraseFromParent(); | |
| return true; | |
| case 3: | |
| EXPECT_EQ(&MI, MIs[2]); | |
| MIs[8]->eraseFromParent(); | |
| // Erase first instructions | |
| MIs[0]->eraseFromParent(); | |
| MIs[1]->eraseFromParent(); | |
| MI.eraseFromParent(); | |
| return true; | |
| default: | |
| ADD_FAILURE(); | |
| return false; | |
| } | |
| } | |
| void setupGeneratedPerFunctionState(MachineFunction &MF) override {} | |
| }; | |
| TEST_F(AArch64GISelMITest, TestInstructionSelectErase) { | |
| StringRef MIRString = R"( | |
| $x0 = COPY %2(s64) | |
| $x0 = COPY %2(s64) | |
| $x0 = COPY %2(s64) | |
| $x0 = COPY %2(s64) | |
| $x0 = COPY %2(s64) | |
| $x0 = COPY %2(s64) | |
| )"; | |
| setUp(MIRString); | |
| if (!TM) | |
| GTEST_SKIP(); | |
| legacy::PassManager PM; | |
| std::unique_ptr<TargetPassConfig> TPC(TM->createPassConfig(PM)); | |
| EraseMockInstructionSelector ISel; | |
| ISel.TPC = TPC.get(); | |
| for (auto &MI : *EntryMBB) { | |
| ISel.MIs.push_back(&MI); | |
| } | |
| InstructionSelect ISelPass; | |
| ISelPass.setInstructionSelector(&ISel); | |
| ISelPass.selectMachineFunction(*MF); | |
| EXPECT_EQ(ISel.NumSelected, 3); | |
| } | |
| } // namespace |