]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
Vendor import of llvm trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / include / llvm / CodeGen / GlobalISel / GISelChangeObserver.h
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
20 namespace llvm {
21 class MachineInstr;
22 class 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).
29 class GISelChangeObserver {
30   SmallPtrSet<MachineInstr *, 4> ChangingAllUsesOfReg;
31
32 public:
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.
59 class GISelObserverWrapper : public MachineFunction::Delegate,
60                              public GISelChangeObserver {
61   SmallVector<GISelChangeObserver *, 4> Observers;
62
63 public:
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.
101 class RAIIDelegateInstaller {
102   MachineFunction &MF;
103   MachineFunction::Delegate *Delegate;
104
105 public:
106   RAIIDelegateInstaller(MachineFunction &MF, MachineFunction::Delegate *Del);
107   ~RAIIDelegateInstaller();
108 };
109
110 } // namespace llvm
111 #endif