Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===----- llvm/CodeGen/GlobalISel/GISelChangeObserver.h --------*- C++ -*-===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
/// \file
9
/// This contains common code to allow clients to notify changes to machine
10
/// instr.
11
///
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() = default;
34
 
35
  /// An instruction is about to be erased.
36
  virtual void erasingInstr(MachineInstr &MI) = 0;
37
 
38
  /// An instruction has been created and inserted into the function.
39
  /// Note that the instruction might not be a fully fledged instruction at this
40
  /// point and won't be if the MachineFunction::Delegate is calling it. This is
41
  /// because the delegate only sees the construction of the MachineInstr before
42
  /// operands have been added.
43
  virtual void createdInstr(MachineInstr &MI) = 0;
44
 
45
  /// This instruction is about to be mutated in some way.
46
  virtual void changingInstr(MachineInstr &MI) = 0;
47
 
48
  /// This instruction was mutated in some way.
49
  virtual void changedInstr(MachineInstr &MI) = 0;
50
 
51
  /// All the instructions using the given register are being changed.
52
  /// For convenience, finishedChangingAllUsesOfReg() will report the completion
53
  /// of the changes. The use list may change between this call and
54
  /// finishedChangingAllUsesOfReg().
55
  void changingAllUsesOfReg(const MachineRegisterInfo &MRI, Register Reg);
56
  /// All instructions reported as changing by changingAllUsesOfReg() have
57
  /// finished being changed.
58
  void finishedChangingAllUsesOfReg();
59
 
60
};
61
 
62
/// Simple wrapper observer that takes several observers, and calls
63
/// each one for each event. If there are multiple observers (say CSE,
64
/// Legalizer, Combiner), it's sufficient to register this to the machine
65
/// function as the delegate.
66
class GISelObserverWrapper : public MachineFunction::Delegate,
67
                             public GISelChangeObserver {
68
  SmallVector<GISelChangeObserver *, 4> Observers;
69
 
70
public:
71
  GISelObserverWrapper() = default;
72
  GISelObserverWrapper(ArrayRef<GISelChangeObserver *> Obs)
73
      : Observers(Obs.begin(), Obs.end()) {}
74
  // Adds an observer.
75
  void addObserver(GISelChangeObserver *O) { Observers.push_back(O); }
76
  // Removes an observer from the list and does nothing if observer is not
77
  // present.
78
  void removeObserver(GISelChangeObserver *O) {
79
    auto It = llvm::find(Observers, O);
80
    if (It != Observers.end())
81
      Observers.erase(It);
82
  }
83
  // API for Observer.
84
  void erasingInstr(MachineInstr &MI) override {
85
    for (auto &O : Observers)
86
      O->erasingInstr(MI);
87
  }
88
  void createdInstr(MachineInstr &MI) override {
89
    for (auto &O : Observers)
90
      O->createdInstr(MI);
91
  }
92
  void changingInstr(MachineInstr &MI) override {
93
    for (auto &O : Observers)
94
      O->changingInstr(MI);
95
  }
96
  void changedInstr(MachineInstr &MI) override {
97
    for (auto &O : Observers)
98
      O->changedInstr(MI);
99
  }
100
  // API for MachineFunction::Delegate
101
  void MF_HandleInsertion(MachineInstr &MI) override { createdInstr(MI); }
102
  void MF_HandleRemoval(MachineInstr &MI) override { erasingInstr(MI); }
103
};
104
 
105
/// A simple RAII based Delegate installer.
106
/// Use this in a scope to install a delegate to the MachineFunction and reset
107
/// it at the end of the scope.
108
class RAIIDelegateInstaller {
109
  MachineFunction &MF;
110
  MachineFunction::Delegate *Delegate;
111
 
112
public:
113
  RAIIDelegateInstaller(MachineFunction &MF, MachineFunction::Delegate *Del);
114
  ~RAIIDelegateInstaller();
115
};
116
 
117
/// A simple RAII based Observer installer.
118
/// Use this in a scope to install the Observer to the MachineFunction and reset
119
/// it at the end of the scope.
120
class RAIIMFObserverInstaller {
121
  MachineFunction &MF;
122
 
123
public:
124
  RAIIMFObserverInstaller(MachineFunction &MF, GISelChangeObserver &Observer);
125
  ~RAIIMFObserverInstaller();
126
};
127
 
128
/// Class to install both of the above.
129
class RAIIMFObsDelInstaller {
130
  RAIIDelegateInstaller DelI;
131
  RAIIMFObserverInstaller ObsI;
132
 
133
public:
134
  RAIIMFObsDelInstaller(MachineFunction &MF, GISelObserverWrapper &Wrapper)
135
      : DelI(MF, &Wrapper), ObsI(MF, Wrapper) {}
136
  ~RAIIMFObsDelInstaller() = default;
137
};
138
 
139
} // namespace llvm
140
#endif