Index: include/llvm/CodeGen/MachineFunction.h =================================================================== --- include/llvm/CodeGen/MachineFunction.h +++ include/llvm/CodeGen/MachineFunction.h @@ -363,6 +363,25 @@ int Slot, const DILocation *Loc) : Var(Var), Expr(Expr), Slot(Slot), Loc(Loc) {} }; + + class Delegate { + virtual void anchor(); + + public: + virtual ~Delegate() = default; + virtual void MF_HandleInsertion(const MachineInstr *MI) = 0; + virtual void MF_HandleRemoval(const MachineInstr *MI) = 0; + }; + +private: + Delegate *TheDelegate = nullptr; + + // Callbacks for insertion and removal. + void handleInsertion(const MachineInstr *MI); + void handleRemoval(const MachineInstr *MI); + friend struct ilist_traits; + +public: using VariableDbgInfoMapTy = SmallVector; VariableDbgInfoMapTy VariableDbgInfos; @@ -379,6 +398,23 @@ init(); } + void resetDelegate(Delegate *delegate) { + // Ensure another delegate does not take over unless the current + // delegate first unattaches itself. If we ever need to multicast + // notifications, we will need to change to using a list. + assert(TheDelegate == delegate && + "Only the current delegate can perform reset!"); + TheDelegate = nullptr; + } + + void setDelegate(Delegate *delegate) { + assert(delegate && !TheDelegate && + "Attempted to set delegate to null, or to change it without " + "first resetting it!"); + + TheDelegate = delegate; + } + MachineModuleInfo &getMMI() const { return MMI; } MCContext &getContext() const { return Ctx; } Index: lib/CodeGen/MachineBasicBlock.cpp =================================================================== --- lib/CodeGen/MachineBasicBlock.cpp +++ lib/CodeGen/MachineBasicBlock.cpp @@ -110,6 +110,7 @@ // use/def lists. MachineFunction *MF = Parent->getParent(); N->AddRegOperandsToUseLists(MF->getRegInfo()); + MF->handleInsertion(N); } /// When we remove an instruction from a basic block list, we update its parent @@ -118,8 +119,10 @@ assert(N->getParent() && "machine instruction not in a basic block"); // Remove from the use/def lists. - if (MachineFunction *MF = N->getMF()) + if (MachineFunction *MF = N->getMF()) { + MF->handleRemoval(N); N->RemoveRegOperandsFromUseLists(MF->getRegInfo()); + } N->setParent(nullptr); } Index: lib/CodeGen/MachineFunction.cpp =================================================================== --- lib/CodeGen/MachineFunction.cpp +++ lib/CodeGen/MachineFunction.cpp @@ -99,6 +99,9 @@ llvm_unreachable("Invalid machine function property"); } +// Pin the vtable to this file. +void MachineFunction::Delegate::anchor() {} + void MachineFunctionProperties::print(raw_ostream &OS) const { const char *Separator = ""; for (BitVector::size_type I = 0; I < Properties.size(); ++I) { @@ -135,6 +138,16 @@ init(); } +void MachineFunction::handleInsertion(const MachineInstr *MI) { + if (TheDelegate) + TheDelegate->MF_HandleInsertion(MI); +} + +void MachineFunction::handleRemoval(const MachineInstr *MI) { + if (TheDelegate) + TheDelegate->MF_HandleRemoval(MI); +} + void MachineFunction::init() { // Assume the function starts in SSA form with correct liveness. Properties.set(MachineFunctionProperties::Property::IsSSA);