GISelChangeObserver.h revision 344779
1//===----- llvm/CodeGen/GlobalISel/GISelChangeObserver.h ------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10/// This contains common code to allow clients to notify changes to machine 11/// instr. 12// 13//===----------------------------------------------------------------------===// 14#ifndef LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H 15#define LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H 16 17#include "llvm/ADT/SmallPtrSet.h" 18#include "llvm/CodeGen/MachineFunction.h" 19 20namespace llvm { 21class MachineInstr; 22class MachineRegisterInfo; 23 24/// Abstract class that contains various methods for clients to notify about 25/// changes. This should be the preferred way for APIs to notify changes. 26/// Typically calling erasingInstr/createdInstr multiple times should not affect 27/// the result. The observer would likely need to check if it was already 28/// notified earlier (consider using GISelWorkList). 29class GISelChangeObserver { 30 SmallPtrSet<MachineInstr *, 4> ChangingAllUsesOfReg; 31 32public: 33 virtual ~GISelChangeObserver() {} 34 35 /// An instruction is about to be erased. 36 virtual void erasingInstr(MachineInstr &MI) = 0; 37 /// An instruction was created and inserted into the function. 38 virtual void createdInstr(MachineInstr &MI) = 0; 39 /// This instruction is about to be mutated in some way. 40 virtual void changingInstr(MachineInstr &MI) = 0; 41 /// This instruction was mutated in some way. 42 virtual void changedInstr(MachineInstr &MI) = 0; 43 44 /// All the instructions using the given register are being changed. 45 /// For convenience, finishedChangingAllUsesOfReg() will report the completion 46 /// of the changes. The use list may change between this call and 47 /// finishedChangingAllUsesOfReg(). 48 void changingAllUsesOfReg(const MachineRegisterInfo &MRI, unsigned Reg); 49 /// All instructions reported as changing by changingAllUsesOfReg() have 50 /// finished being changed. 51 void finishedChangingAllUsesOfReg(); 52 53}; 54 55/// Simple wrapper observer that takes several observers, and calls 56/// each one for each event. If there are multiple observers (say CSE, 57/// Legalizer, Combiner), it's sufficient to register this to the machine 58/// function as the delegate. 59class GISelObserverWrapper : public MachineFunction::Delegate, 60 public GISelChangeObserver { 61 SmallVector<GISelChangeObserver *, 4> Observers; 62 63public: 64 GISelObserverWrapper() = default; 65 GISelObserverWrapper(ArrayRef<GISelChangeObserver *> Obs) 66 : Observers(Obs.begin(), Obs.end()) {} 67 // Adds an observer. 68 void addObserver(GISelChangeObserver *O) { Observers.push_back(O); } 69 // Removes an observer from the list and does nothing if observer is not 70 // present. 71 void removeObserver(GISelChangeObserver *O) { 72 auto It = std::find(Observers.begin(), Observers.end(), O); 73 if (It != Observers.end()) 74 Observers.erase(It); 75 } 76 // API for Observer. 77 void erasingInstr(MachineInstr &MI) override { 78 for (auto &O : Observers) 79 O->erasingInstr(MI); 80 } 81 void createdInstr(MachineInstr &MI) override { 82 for (auto &O : Observers) 83 O->createdInstr(MI); 84 } 85 void changingInstr(MachineInstr &MI) override { 86 for (auto &O : Observers) 87 O->changingInstr(MI); 88 } 89 void changedInstr(MachineInstr &MI) override { 90 for (auto &O : Observers) 91 O->changedInstr(MI); 92 } 93 // API for MachineFunction::Delegate 94 void MF_HandleInsertion(MachineInstr &MI) override { createdInstr(MI); } 95 void MF_HandleRemoval(MachineInstr &MI) override { erasingInstr(MI); } 96}; 97 98/// A simple RAII based CSEInfo installer. 99/// Use this in a scope to install a delegate to the MachineFunction and reset 100/// it at the end of the scope. 101class RAIIDelegateInstaller { 102 MachineFunction &MF; 103 MachineFunction::Delegate *Delegate; 104 105public: 106 RAIIDelegateInstaller(MachineFunction &MF, MachineFunction::Delegate *Del); 107 ~RAIIDelegateInstaller(); 108}; 109 110} // namespace llvm 111#endif 112