Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
Line
Count
Source (jump to first uncovered line)
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
//
9
/// This contains common code to allow clients to notify changes to machine
10
/// instr.
11
//
12
//===----------------------------------------------------------------------===//
13
#ifndef LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H
14
#define LLVM_CODEGEN_GLOBALISEL_GISELCHANGEOBSERVER_H
15
16
#include "llvm/ADT/SmallPtrSet.h"
17
#include "llvm/CodeGen/MachineFunction.h"
18
19
namespace llvm {
20
class MachineInstr;
21
class MachineRegisterInfo;
22
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;
30
31
public:
32
1.47M
  virtual ~GISelChangeObserver() {}
33
34
  /// An instruction is about to be erased.
35
  virtual void erasingInstr(MachineInstr &MI) = 0;
36
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;
43
44
  /// This instruction is about to be mutated in some way.
45
  virtual void changingInstr(MachineInstr &MI) = 0;
46
47
  /// This instruction was mutated in some way.
48
  virtual void changedInstr(MachineInstr &MI) = 0;
49
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();
58
59
};
60
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;
68
69
public:
70
237k
  GISelObserverWrapper() = default;
71
  GISelObserverWrapper(ArrayRef<GISelChangeObserver *> Obs)
72
609k
      : Observers(Obs.begin(), Obs.end()) {}
73
  // Adds an observer.
74
477k
  void addObserver(GISelChangeObserver *O) { Observers.push_back(O); }
75
  // Removes an observer from the list and does nothing if observer is not
76
  // present.
77
0
  void removeObserver(GISelChangeObserver *O) {
78
0
    auto It = std::find(Observers.begin(), Observers.end(), O);
79
0
    if (It != Observers.end())
80
0
      Observers.erase(It);
81
0
  }
82
  // API for Observer.
83
3.28M
  void erasingInstr(MachineInstr &MI) override {
84
3.28M
    for (auto &O : Observers)
85
4.89M
      O->erasingInstr(MI);
86
3.28M
  }
87
26.4M
  void createdInstr(MachineInstr &MI) override {
88
26.4M
    for (auto &O : Observers)
89
31.6M
      O->createdInstr(MI);
90
26.4M
  }
91
3.07M
  void changingInstr(MachineInstr &MI) override {
92
3.07M
    for (auto &O : Observers)
93
4.36M
      O->changingInstr(MI);
94
3.07M
  }
95
3.07M
  void changedInstr(MachineInstr &MI) override {
96
3.07M
    for (auto &O : Observers)
97
4.36M
      O->changedInstr(MI);
98
3.07M
  }
99
  // API for MachineFunction::Delegate
100
23.9M
  void MF_HandleInsertion(MachineInstr &MI) override { createdInstr(MI); }
101
2.37M
  void MF_HandleRemoval(MachineInstr &MI) override { erasingInstr(MI); }
102
};
103
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 {
108
  MachineFunction &MF;
109
  MachineFunction::Delegate *Delegate;
110
111
public:
112
  RAIIDelegateInstaller(MachineFunction &MF, MachineFunction::Delegate *Del);
113
  ~RAIIDelegateInstaller();
114
};
115
116
} // namespace llvm
117
#endif