Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  141.