diff options
Diffstat (limited to 'llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h')
-rw-r--r-- | llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h | 64 |
1 files changed, 60 insertions, 4 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h b/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h index d21c73309a5..c8e8a7a5a7c 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h @@ -15,6 +15,7 @@ #define LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/CodeGen/MachineFunction.h" namespace llvm { class MachineInstr; @@ -32,13 +33,13 @@ public: virtual ~GISelChangeObserver() {} /// An instruction is about to be erased. - virtual void erasingInstr(const MachineInstr &MI) = 0; + virtual void erasingInstr(MachineInstr &MI) = 0; /// An instruction was created and inserted into the function. - virtual void createdInstr(const MachineInstr &MI) = 0; + virtual void createdInstr(MachineInstr &MI) = 0; /// This instruction is about to be mutated in some way. - virtual void changingInstr(const MachineInstr &MI) = 0; + virtual void changingInstr(MachineInstr &MI) = 0; /// This instruction was mutated in some way. - virtual void changedInstr(const MachineInstr &MI) = 0; + virtual void changedInstr(MachineInstr &MI) = 0; /// All the instructions using the given register are being changed. /// For convenience, finishedChangingAllUsesOfReg() will report the completion @@ -51,5 +52,60 @@ public: }; +/// Simple wrapper observer that takes several observers, and calls +/// each one for each event. If there are multiple observers (say CSE, +/// Legalizer, Combiner), it's sufficient to register this to the machine +/// function as the delegate. +class GISelObserverWrapper : public MachineFunction::Delegate, + public GISelChangeObserver { + SmallVector<GISelChangeObserver *, 4> Observers; + +public: + GISelObserverWrapper() = default; + GISelObserverWrapper(ArrayRef<GISelChangeObserver *> Obs) + : Observers(Obs.begin(), Obs.end()) {} + // Adds an observer. + void addObserver(GISelChangeObserver *O) { Observers.push_back(O); } + // Removes an observer from the list and does nothing if observer is not + // present. + void removeObserver(GISelChangeObserver *O) { + auto It = std::find(Observers.begin(), Observers.end(), O); + if (It != Observers.end()) + Observers.erase(It); + } + // API for Observer. + void erasingInstr(MachineInstr &MI) override { + for (auto &O : Observers) + O->erasingInstr(MI); + } + void createdInstr(MachineInstr &MI) override { + for (auto &O : Observers) + O->createdInstr(MI); + } + void changingInstr(MachineInstr &MI) override { + for (auto &O : Observers) + O->changingInstr(MI); + } + void changedInstr(MachineInstr &MI) override { + for (auto &O : Observers) + O->changedInstr(MI); + } + // API for MachineFunction::Delegate + void MF_HandleInsertion(MachineInstr &MI) override { createdInstr(MI); } + void MF_HandleRemoval(MachineInstr &MI) override { erasingInstr(MI); } +}; + +/// A simple RAII based CSEInfo installer. +/// Use this in a scope to install a delegate to the MachineFunction and reset +/// it at the end of the scope. +class RAIIDelegateInstaller { + MachineFunction &MF; + MachineFunction::Delegate *Delegate; + +public: + RAIIDelegateInstaller(MachineFunction &MF, MachineFunction::Delegate *Del); + ~RAIIDelegateInstaller(); +}; + } // namespace llvm #endif |