Index: include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h =================================================================== --- include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h +++ include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h @@ -30,6 +30,8 @@ virtual void erasingInstr(MachineInstr &MI) = 0; /// An instruction was created and inserted into the function. virtual void createdInstr(MachineInstr &MI) = 0; + /// This instruction is about to be mutated in some way. + virtual void changingInstr(MachineInstr &MI) = 0; /// This instruction was mutated in some way. virtual void changedInstr(MachineInstr &MI) = 0; }; Index: lib/CodeGen/GlobalISel/Combiner.cpp =================================================================== --- lib/CodeGen/GlobalISel/Combiner.cpp +++ lib/CodeGen/GlobalISel/Combiner.cpp @@ -44,16 +44,20 @@ virtual ~WorkListMaintainer() {} void erasingInstr(MachineInstr &MI) override { - LLVM_DEBUG(dbgs() << "Erased: "; MI.print(dbgs()); dbgs() << "\n"); + LLVM_DEBUG(dbgs() << "Erased: " << MI << "\n"); WorkList.remove(&MI); } void createdInstr(MachineInstr &MI) override { - LLVM_DEBUG(dbgs() << "Created: "; MI.print(dbgs()); dbgs() << "\n"); + LLVM_DEBUG(dbgs() << "Created: " << MI << "\n"); WorkList.insert(&MI); } + void changingInstr(MachineInstr &MI) override { + LLVM_DEBUG(dbgs() << "Changing: " << MI << "\n"); + WorkList.remove(&MI); + } // Currently changed conservatively assumes erased. void changedInstr(MachineInstr &MI) override { - LLVM_DEBUG(dbgs() << "Changed: "; MI.print(dbgs()); dbgs() << "\n"); + LLVM_DEBUG(dbgs() << "Changed: " << MI << "\n"); WorkList.remove(&MI); } }; Index: lib/CodeGen/GlobalISel/Legalizer.cpp =================================================================== --- lib/CodeGen/GlobalISel/Legalizer.cpp +++ lib/CodeGen/GlobalISel/Legalizer.cpp @@ -91,19 +91,23 @@ else InstList.insert(&MI); } - LLVM_DEBUG(dbgs() << ".. .. New MI: " << MI;); + LLVM_DEBUG(dbgs() << ".. .. New MI: " << MI); } void erasingInstr(MachineInstr &MI) override { - LLVM_DEBUG(dbgs() << ".. .. Erasing: " << MI;); + LLVM_DEBUG(dbgs() << ".. .. Erasing: " << MI); InstList.remove(&MI); ArtifactList.remove(&MI); } + void changingInstr(MachineInstr &MI) override { + LLVM_DEBUG(dbgs() << ".. .. Changing MI: " << MI); + } + void changedInstr(MachineInstr &MI) override { // When insts change, we want to revisit them to legalize them again. // We'll consider them the same as created. - LLVM_DEBUG(dbgs() << ".. .. Changed MI: " << MI;); + LLVM_DEBUG(dbgs() << ".. .. Changed MI: " << MI); createdInstr(MI); } }; Index: lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -711,6 +711,7 @@ } auto &TII = *MI.getMF()->getSubtarget().getInstrInfo(); // Make the original instruction a trunc now, and update its source. + Observer.changingInstr(MI); MI.setDesc(TII.get(TargetOpcode::G_TRUNC)); MI.getOperand(1).setReg(MIBNewOp->getOperand(0).getReg()); Observer.changedInstr(MI); @@ -726,6 +727,7 @@ // Perform operation at larger width (any extension is fine here, high bits // don't affect the result) and then truncate the result back to the // original type. + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT); widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT); widenScalarDst(MI, WideTy); @@ -733,6 +735,7 @@ return Legalized; case TargetOpcode::G_SHL: + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT); // The "number of bits to shift" operand must preserve its value as an // unsigned integer: @@ -743,6 +746,7 @@ case TargetOpcode::G_SDIV: case TargetOpcode::G_SREM: + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT); widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT); widenScalarDst(MI, WideTy); @@ -750,6 +754,7 @@ return Legalized; case TargetOpcode::G_ASHR: + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT); // The "number of bits to shift" operand must preserve its value as an // unsigned integer: @@ -761,6 +766,7 @@ case TargetOpcode::G_UDIV: case TargetOpcode::G_UREM: case TargetOpcode::G_LSHR: + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT); widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT); widenScalarDst(MI, WideTy); @@ -773,6 +779,7 @@ // Perform operation at larger width (any extension is fine here, high bits // don't affect the result) and then truncate the result back to the // original type. + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT); widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_ANYEXT); widenScalarDst(MI, WideTy); @@ -783,6 +790,7 @@ case TargetOpcode::G_FPTOUI: if (TypeIdx != 0) return UnableToLegalize; + Observer.changingInstr(MI); widenScalarDst(MI, WideTy); Observer.changedInstr(MI); return Legalized; @@ -790,6 +798,7 @@ case TargetOpcode::G_SITOFP: if (TypeIdx != 1) return UnableToLegalize; + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT); Observer.changedInstr(MI); return Legalized; @@ -797,6 +806,7 @@ case TargetOpcode::G_UITOFP: if (TypeIdx != 1) return UnableToLegalize; + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT); Observer.changedInstr(MI); return Legalized; @@ -804,6 +814,7 @@ case TargetOpcode::G_INSERT: if (TypeIdx != 0) return UnableToLegalize; + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT); widenScalarDst(MI, WideTy); Observer.changedInstr(MI); @@ -819,6 +830,7 @@ LLVM_FALLTHROUGH; case TargetOpcode::G_SEXTLOAD: case TargetOpcode::G_ZEXTLOAD: + Observer.changingInstr(MI); widenScalarDst(MI, WideTy); Observer.changedInstr(MI); return Legalized; @@ -828,6 +840,7 @@ WideTy != LLT::scalar(8)) return UnableToLegalize; + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 0, TargetOpcode::G_ZEXT); Observer.changedInstr(MI); return Legalized; @@ -836,6 +849,7 @@ MachineOperand &SrcMO = MI.getOperand(1); LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext(); const APInt &Val = SrcMO.getCImm()->getValue().sext(WideTy.getSizeInBits()); + Observer.changingInstr(MI); SrcMO.setCImm(ConstantInt::get(Ctx, Val)); widenScalarDst(MI, WideTy); @@ -857,6 +871,7 @@ default: llvm_unreachable("Unhandled fp widen type"); } + Observer.changingInstr(MI); SrcMO.setFPImm(ConstantFP::get(Ctx, Val)); widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC); @@ -864,11 +879,13 @@ return Legalized; } case TargetOpcode::G_BRCOND: + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 0, TargetOpcode::G_ANYEXT); Observer.changedInstr(MI); return Legalized; case TargetOpcode::G_FCMP: + Observer.changingInstr(MI); if (TypeIdx == 0) widenScalarDst(MI, WideTy); else { @@ -879,6 +896,7 @@ return Legalized; case TargetOpcode::G_ICMP: + Observer.changingInstr(MI); if (TypeIdx == 0) widenScalarDst(MI, WideTy); else { @@ -894,6 +912,7 @@ case TargetOpcode::G_GEP: assert(TypeIdx == 1 && "unable to legalize pointer of GEP"); + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT); Observer.changedInstr(MI); return Legalized; @@ -901,6 +920,7 @@ case TargetOpcode::G_PHI: { assert(TypeIdx == 0 && "Expecting only Idx 0"); + Observer.changingInstr(MI); for (unsigned I = 1; I < MI.getNumOperands(); I += 2) { MachineBasicBlock &OpMBB = *MI.getOperand(I + 1).getMBB(); MIRBuilder.setInsertPt(OpMBB, OpMBB.getFirstTerminator()); @@ -916,6 +936,7 @@ case TargetOpcode::G_EXTRACT_VECTOR_ELT: if (TypeIdx != 2) return UnableToLegalize; + Observer.changingInstr(MI); widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT); Observer.changedInstr(MI); return Legalized; @@ -1152,6 +1173,7 @@ return UnableToLegalize; case TargetOpcode::G_CTLZ_ZERO_UNDEF: { // This trivially expands to CTLZ. + Observer.changingInstr(MI); MI.setDesc(TII.get(TargetOpcode::G_CTLZ)); Observer.changedInstr(MI); return Legalized; @@ -1201,6 +1223,7 @@ } case TargetOpcode::G_CTTZ_ZERO_UNDEF: { // This trivially expands to CTTZ. + Observer.changingInstr(MI); MI.setDesc(TII.get(TargetOpcode::G_CTTZ)); Observer.changedInstr(MI); return Legalized; Index: unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp =================================================================== --- unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp +++ unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp @@ -13,6 +13,7 @@ class DummyGISelObserver : public GISelChangeObserver { public: + void changingInstr(MachineInstr &MI) override {} void changedInstr(MachineInstr &MI) override {} void createdInstr(MachineInstr &MI) override {} void erasingInstr(MachineInstr &MI) override {}