1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00
llvm-mirror/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
Nicolás Alvarez 0bad578cf3 [docs] Fix doxygen comments wrongly attached to the llvm namespace
Looking at the Doxygen-generated documentation for the llvm namespace
currently shows all sorts of random comments from different parts of the
codebase. These are mostly caused by:

- File doc comments that aren't marked with \file, so they're attached to
  the next declaration, which is usually "namespace llvm {".
- Class doc comments placed before the namespace rather than before the
  class.
- Code comments before the namespace that (in my opinion) shouldn't be
  extracted by doxygen at all.

This commit fixes these comments. The generated doxygen documentation now
has proper docs for several classes and files, and the docs for the llvm
and llvm::detail namespaces are now empty.

Reviewed By: thakis, mizvekov

Differential Revision: https://reviews.llvm.org/D96736
2021-04-07 01:20:18 +02:00

141 lines
5.0 KiB
C++

//===----- llvm/CodeGen/GlobalISel/GISelChangeObserver.h --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
/// This contains common code to allow clients to notify changes to machine
/// instr.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H
#define LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/MachineFunction.h"
namespace llvm {
class MachineInstr;
class MachineRegisterInfo;
/// Abstract class that contains various methods for clients to notify about
/// changes. This should be the preferred way for APIs to notify changes.
/// Typically calling erasingInstr/createdInstr multiple times should not affect
/// the result. The observer would likely need to check if it was already
/// notified earlier (consider using GISelWorkList).
class GISelChangeObserver {
SmallPtrSet<MachineInstr *, 4> ChangingAllUsesOfReg;
public:
virtual ~GISelChangeObserver() {}
/// An instruction is about to be erased.
virtual void erasingInstr(MachineInstr &MI) = 0;
/// An instruction has been created and inserted into the function.
/// Note that the instruction might not be a fully fledged instruction at this
/// point and won't be if the MachineFunction::Delegate is calling it. This is
/// because the delegate only sees the construction of the MachineInstr before
/// operands have been added.
virtual void createdInstr(MachineInstr &MI) = 0;
/// This instruction is about to be mutated in some way.
virtual void changingInstr(MachineInstr &MI) = 0;
/// This instruction was mutated in some way.
virtual void changedInstr(MachineInstr &MI) = 0;
/// All the instructions using the given register are being changed.
/// For convenience, finishedChangingAllUsesOfReg() will report the completion
/// of the changes. The use list may change between this call and
/// finishedChangingAllUsesOfReg().
void changingAllUsesOfReg(const MachineRegisterInfo &MRI, Register Reg);
/// All instructions reported as changing by changingAllUsesOfReg() have
/// finished being changed.
void finishedChangingAllUsesOfReg();
};
/// 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 Delegate 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();
};
/// A simple RAII based Observer installer.
/// Use this in a scope to install the Observer to the MachineFunction and reset
/// it at the end of the scope.
class RAIIMFObserverInstaller {
MachineFunction &MF;
public:
RAIIMFObserverInstaller(MachineFunction &MF, GISelChangeObserver &Observer);
~RAIIMFObserverInstaller();
};
/// Class to install both of the above.
class RAIIMFObsDelInstaller {
RAIIDelegateInstaller DelI;
RAIIMFObserverInstaller ObsI;
public:
RAIIMFObsDelInstaller(MachineFunction &MF, GISelObserverWrapper &Wrapper)
: DelI(MF, &Wrapper), ObsI(MF, Wrapper) {}
~RAIIMFObsDelInstaller() = default;
};
} // namespace llvm
#endif