1 //===----- llvm/CodeGen/GlobalISel/GISelChangeObserver.h --------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 /// This contains common code to allow clients to notify changes to machine
12 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H
14 #define LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H
16 #include "llvm/ADT/SmallPtrSet.h"
17 #include "llvm/CodeGen/MachineFunction.h"
21 class MachineRegisterInfo
;
23 /// Abstract class that contains various methods for clients to notify about
24 /// changes. This should be the preferred way for APIs to notify changes.
25 /// Typically calling erasingInstr/createdInstr multiple times should not affect
26 /// the result. The observer would likely need to check if it was already
27 /// notified earlier (consider using GISelWorkList).
28 class GISelChangeObserver
{
29 SmallPtrSet
<MachineInstr
*, 4> ChangingAllUsesOfReg
;
32 virtual ~GISelChangeObserver() {}
34 /// An instruction is about to be erased.
35 virtual void erasingInstr(MachineInstr
&MI
) = 0;
37 /// An instruction has been created and inserted into the function.
38 /// Note that the instruction might not be a fully fledged instruction at this
39 /// point and won't be if the MachineFunction::Delegate is calling it. This is
40 /// because the delegate only sees the construction of the MachineInstr before
41 /// operands have been added.
42 virtual void createdInstr(MachineInstr
&MI
) = 0;
44 /// This instruction is about to be mutated in some way.
45 virtual void changingInstr(MachineInstr
&MI
) = 0;
47 /// This instruction was mutated in some way.
48 virtual void changedInstr(MachineInstr
&MI
) = 0;
50 /// All the instructions using the given register are being changed.
51 /// For convenience, finishedChangingAllUsesOfReg() will report the completion
52 /// of the changes. The use list may change between this call and
53 /// finishedChangingAllUsesOfReg().
54 void changingAllUsesOfReg(const MachineRegisterInfo
&MRI
, unsigned Reg
);
55 /// All instructions reported as changing by changingAllUsesOfReg() have
56 /// finished being changed.
57 void finishedChangingAllUsesOfReg();
61 /// Simple wrapper observer that takes several observers, and calls
62 /// each one for each event. If there are multiple observers (say CSE,
63 /// Legalizer, Combiner), it's sufficient to register this to the machine
64 /// function as the delegate.
65 class GISelObserverWrapper
: public MachineFunction::Delegate
,
66 public GISelChangeObserver
{
67 SmallVector
<GISelChangeObserver
*, 4> Observers
;
70 GISelObserverWrapper() = default;
71 GISelObserverWrapper(ArrayRef
<GISelChangeObserver
*> Obs
)
72 : Observers(Obs
.begin(), Obs
.end()) {}
74 void addObserver(GISelChangeObserver
*O
) { Observers
.push_back(O
); }
75 // Removes an observer from the list and does nothing if observer is not
77 void removeObserver(GISelChangeObserver
*O
) {
78 auto It
= std::find(Observers
.begin(), Observers
.end(), O
);
79 if (It
!= Observers
.end())
83 void erasingInstr(MachineInstr
&MI
) override
{
84 for (auto &O
: Observers
)
87 void createdInstr(MachineInstr
&MI
) override
{
88 for (auto &O
: Observers
)
91 void changingInstr(MachineInstr
&MI
) override
{
92 for (auto &O
: Observers
)
95 void changedInstr(MachineInstr
&MI
) override
{
96 for (auto &O
: Observers
)
99 // API for MachineFunction::Delegate
100 void MF_HandleInsertion(MachineInstr
&MI
) override
{ createdInstr(MI
); }
101 void MF_HandleRemoval(MachineInstr
&MI
) override
{ erasingInstr(MI
); }
104 /// A simple RAII based CSEInfo installer.
105 /// Use this in a scope to install a delegate to the MachineFunction and reset
106 /// it at the end of the scope.
107 class RAIIDelegateInstaller
{
109 MachineFunction::Delegate
*Delegate
;
112 RAIIDelegateInstaller(MachineFunction
&MF
, MachineFunction::Delegate
*Del
);
113 ~RAIIDelegateInstaller();