1 #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" 2 #include "GISelMITest.h" 3 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 4 #include "llvm/CodeGen/TargetPassConfig.h" 5 #include "llvm/IR/LegacyPassManager.h" 6 7 namespace { 8 9 class EraseMockInstructionSelector : public InstructionSelector { 10 public: 11 int NumSelected = 0; 12 SmallVector<MachineInstr *> MIs; 13 14 bool select(MachineInstr &MI) override { 15 ++NumSelected; 16 switch (NumSelected) { 17 case 1: 18 EXPECT_EQ(&MI, MIs[8]); 19 // Erase previous instructions 20 MIs[7]->eraseFromParent(); 21 MIs[6]->eraseFromParent(); 22 // Don't erase this MI before step 3 to prevent DCE 23 return true; 24 case 2: 25 EXPECT_EQ(&MI, MIs[5]); 26 // Erase previous instructions reversed 27 MIs[3]->eraseFromParent(); 28 MIs[4]->eraseFromParent(); 29 MI.eraseFromParent(); 30 return true; 31 case 3: 32 EXPECT_EQ(&MI, MIs[2]); 33 MIs[8]->eraseFromParent(); 34 // Erase first instructions 35 MIs[0]->eraseFromParent(); 36 MIs[1]->eraseFromParent(); 37 MI.eraseFromParent(); 38 return true; 39 default: 40 ADD_FAILURE(); 41 return false; 42 } 43 } 44 45 void setupGeneratedPerFunctionState(MachineFunction &MF) override {} 46 }; 47 48 TEST_F(AArch64GISelMITest, TestInstructionSelectErase) { 49 StringRef MIRString = R"( 50 $x0 = COPY %2(s64) 51 $x0 = COPY %2(s64) 52 $x0 = COPY %2(s64) 53 $x0 = COPY %2(s64) 54 $x0 = COPY %2(s64) 55 $x0 = COPY %2(s64) 56 )"; 57 setUp(MIRString); 58 if (!TM) 59 GTEST_SKIP(); 60 61 legacy::PassManager PM; 62 std::unique_ptr<TargetPassConfig> TPC(TM->createPassConfig(PM)); 63 64 EraseMockInstructionSelector ISel; 65 ISel.TPC = TPC.get(); 66 for (auto &MI : *EntryMBB) { 67 ISel.MIs.push_back(&MI); 68 } 69 70 InstructionSelect ISelPass; 71 ISelPass.setInstructionSelector(&ISel); 72 ISelPass.selectMachineFunction(*MF); 73 EXPECT_EQ(ISel.NumSelected, 3); 74 } 75 76 } // namespace 77