Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
Line
Count
Source (jump to first uncovered line)
1
///===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- 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
/// Optimization diagnostic interfaces for machine passes.  It's packaged as an
10
/// analysis pass so that by using this service passes become dependent on MBFI
11
/// as well.  MBFI is used to compute the "hotness" of the diagnostic message.
12
///
13
///===---------------------------------------------------------------------===//
14
15
#ifndef LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
16
#define LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
17
18
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
19
#include "llvm/CodeGen/MachineFunctionPass.h"
20
21
namespace llvm {
22
class MachineBasicBlock;
23
class MachineBlockFrequencyInfo;
24
class MachineInstr;
25
26
/// Common features for diagnostics dealing with optimization remarks
27
/// that are used by machine passes.
28
class DiagnosticInfoMIROptimization : public DiagnosticInfoOptimizationBase {
29
public:
30
  DiagnosticInfoMIROptimization(enum DiagnosticKind Kind, const char *PassName,
31
                                StringRef RemarkName,
32
                                const DiagnosticLocation &Loc,
33
                                const MachineBasicBlock *MBB)
34
      : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName,
35
                                       MBB->getParent()->getFunction(), Loc),
36
516k
        MBB(MBB) {}
37
38
  /// MI-specific kinds of diagnostic Arguments.
39
  struct MachineArgument : public DiagnosticInfoOptimizationBase::Argument {
40
    /// Print an entire MachineInstr.
41
    MachineArgument(StringRef Key, const MachineInstr &MI);
42
  };
43
44
0
  static bool classof(const DiagnosticInfo *DI) {
45
0
    return DI->getKind() >= DK_FirstMachineRemark &&
46
0
           DI->getKind() <= DK_LastMachineRemark;
47
0
  }
48
49
516k
  const MachineBasicBlock *getBlock() const { return MBB; }
50
51
private:
52
  const MachineBasicBlock *MBB;
53
};
54
55
/// Diagnostic information for applied optimization remarks.
56
class MachineOptimizationRemark : public DiagnosticInfoMIROptimization {
57
public:
58
  /// \p PassName is the name of the pass emitting this diagnostic. If this name
59
  /// matches the regular expression given in -Rpass=, then the diagnostic will
60
  /// be emitted.  \p RemarkName is a textual identifier for the remark.  \p
61
  /// Loc is the debug location and \p MBB is the block that the optimization
62
  /// operates in.
63
  MachineOptimizationRemark(const char *PassName, StringRef RemarkName,
64
                            const DiagnosticLocation &Loc,
65
                            const MachineBasicBlock *MBB)
66
      : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemark, PassName,
67
45
                                      RemarkName, Loc, MBB) {}
68
69
0
  static bool classof(const DiagnosticInfo *DI) {
70
0
    return DI->getKind() == DK_MachineOptimizationRemark;
71
0
  }
72
73
  /// \see DiagnosticInfoOptimizationBase::isEnabled.
74
45
  bool isEnabled() const override {
75
45
    const Function &Fn = getFunction();
76
45
    LLVMContext &Ctx = Fn.getContext();
77
45
    return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
78
45
  }
79
};
80
81
/// Diagnostic information for missed-optimization remarks.
82
class MachineOptimizationRemarkMissed : public DiagnosticInfoMIROptimization {
83
public:
84
  /// \p PassName is the name of the pass emitting this diagnostic. If this name
85
  /// matches the regular expression given in -Rpass-missed=, then the
86
  /// diagnostic will be emitted.  \p RemarkName is a textual identifier for the
87
  /// remark.  \p Loc is the debug location and \p MBB is the block that the
88
  /// optimization operates in.
89
  MachineOptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
90
                                  const DiagnosticLocation &Loc,
91
                                  const MachineBasicBlock *MBB)
92
      : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkMissed,
93
16.4k
                                      PassName, RemarkName, Loc, MBB) {}
94
95
0
  static bool classof(const DiagnosticInfo *DI) {
96
0
    return DI->getKind() == DK_MachineOptimizationRemarkMissed;
97
0
  }
98
99
  /// \see DiagnosticInfoOptimizationBase::isEnabled.
100
13.9k
  bool isEnabled() const override {
101
13.9k
    const Function &Fn = getFunction();
102
13.9k
    LLVMContext &Ctx = Fn.getContext();
103
13.9k
    return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
104
13.9k
  }
105
};
106
107
/// Diagnostic information for optimization analysis remarks.
108
class MachineOptimizationRemarkAnalysis : public DiagnosticInfoMIROptimization {
109
public:
110
  /// \p PassName is the name of the pass emitting this diagnostic. If this name
111
  /// matches the regular expression given in -Rpass-analysis=, then the
112
  /// diagnostic will be emitted.  \p RemarkName is a textual identifier for the
113
  /// remark.  \p Loc is the debug location and \p MBB is the block that the
114
  /// optimization operates in.
115
  MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
116
                                    const DiagnosticLocation &Loc,
117
                                    const MachineBasicBlock *MBB)
118
      : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis,
119
499k
                                      PassName, RemarkName, Loc, MBB) {}
120
121
0
  static bool classof(const DiagnosticInfo *DI) {
122
0
    return DI->getKind() == DK_MachineOptimizationRemarkAnalysis;
123
0
  }
124
125
  /// \see DiagnosticInfoOptimizationBase::isEnabled.
126
426k
  bool isEnabled() const override {
127
426k
    const Function &Fn = getFunction();
128
426k
    LLVMContext &Ctx = Fn.getContext();
129
426k
    return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName());
130
426k
  }
131
};
132
133
/// Extend llvm::ore:: with MI-specific helper names.
134
namespace ore {
135
using MNV = DiagnosticInfoMIROptimization::MachineArgument;
136
}
137
138
/// The optimization diagnostic interface.
139
///
140
/// It allows reporting when optimizations are performed and when they are not
141
/// along with the reasons for it.  Hotness information of the corresponding
142
/// code region can be included in the remark if DiagnosticsHotnessRequested is
143
/// enabled in the LLVM context.
144
class MachineOptimizationRemarkEmitter {
145
public:
146
  MachineOptimizationRemarkEmitter(MachineFunction &MF,
147
                                   MachineBlockFrequencyInfo *MBFI)
148
2.42M
      : MF(MF), MBFI(MBFI) {}
149
150
  /// Emit an optimization remark.
151
  void emit(DiagnosticInfoOptimizationBase &OptDiag);
152
153
  /// Whether we allow for extra compile-time budget to perform more
154
  /// analysis to be more informative.
155
  ///
156
  /// This is useful to enable additional missed optimizations to be reported
157
  /// that are normally too noisy.  In this mode, we can use the extra analysis
158
  /// (1) to filter trivial false positives or (2) to provide more context so
159
  /// that non-trivial false positives can be quickly detected by the user.
160
16.3k
  bool allowExtraAnalysis(StringRef PassName) const {
161
16.3k
    return (
162
16.3k
        MF.getFunction().getContext().getRemarkStreamer() ||
163
16.3k
        MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(
164
16.3k
            PassName));
165
16.3k
  }
166
167
  /// Take a lambda that returns a remark which will be emitted.  Second
168
  /// argument is only used to restrict this to functions.
169
  template <typename T>
170
525k
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171
525k
    // Avoid building the remark unless we know there are at least *some*
172
525k
    // remarks enabled. We can't currently check whether remarks are requested
173
525k
    // for the calling pass since that requires actually building the remark.
174
525k
175
525k
    if (MF.getFunction().getContext().getRemarkStreamer() ||
176
525k
        MF.getFunction()
177
525k
            .getContext()
178
525k
            .getDiagHandlerPtr()
179
525k
            ->isAnyRemarkEnabled()) {
180
1.00k
      auto R = RemarkBuilder();
181
1.00k
      emit((DiagnosticInfoOptimizationBase &)R);
182
1.00k
    }
183
525k
  }
MachineFunctionPass.cpp:void llvm::MachineOptimizationRemarkEmitter::emit<llvm::MachineFunctionPass::runOnFunction(llvm::Function&)::$_0>(llvm::MachineFunctionPass::runOnFunction(llvm::Function&)::$_0, decltype(fp())*)
Line
Count
Source
170
3
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171
3
    // Avoid building the remark unless we know there are at least *some*
172
3
    // remarks enabled. We can't currently check whether remarks are requested
173
3
    // for the calling pass since that requires actually building the remark.
174
3
175
3
    if (MF.getFunction().getContext().getRemarkStreamer() ||
176
3
        MF.getFunction()
177
0
            .getContext()
178
0
            .getDiagHandlerPtr()
179
3
            ->isAnyRemarkEnabled()) {
180
3
      auto R = RemarkBuilder();
181
3
      emit((DiagnosticInfoOptimizationBase &)R);
182
3
    }
183
3
  }
MachineOutliner.cpp:void llvm::MachineOptimizationRemarkEmitter::emit<(anonymous namespace)::MachineOutliner::emitNotOutliningCheaperRemark(unsigned int, std::__1::vector<llvm::outliner::Candidate, std::__1::allocator<llvm::outliner::Candidate> >&, llvm::outliner::OutlinedFunction&)::$_0>((anonymous namespace)::MachineOutliner::emitNotOutliningCheaperRemark(unsigned int, std::__1::vector<llvm::outliner::Candidate, std::__1::allocator<llvm::outliner::Candidate> >&, llvm::outliner::OutlinedFunction&)::$_0, decltype(fp())*)
Line
Count
Source
170
82
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171
82
    // Avoid building the remark unless we know there are at least *some*
172
82
    // remarks enabled. We can't currently check whether remarks are requested
173
82
    // for the calling pass since that requires actually building the remark.
174
82
175
82
    if (MF.getFunction().getContext().getRemarkStreamer() ||
176
82
        MF.getFunction()
177
76
            .getContext()
178
76
            .getDiagHandlerPtr()
179
76
            ->isAnyRemarkEnabled()) {
180
8
      auto R = RemarkBuilder();
181
8
      emit((DiagnosticInfoOptimizationBase &)R);
182
8
    }
183
82
  }
MachineOutliner.cpp:void llvm::MachineOptimizationRemarkEmitter::emit<(anonymous namespace)::MachineOutliner::emitInstrCountChangedRemark(llvm::Module const&, llvm::MachineModuleInfo const&, llvm::StringMap<unsigned int, llvm::MallocAllocator> const&)::$_6>((anonymous namespace)::MachineOutliner::emitInstrCountChangedRemark(llvm::Module const&, llvm::MachineModuleInfo const&, llvm::StringMap<unsigned int, llvm::MallocAllocator> const&)::$_6, decltype(fp())*)
Line
Count
Source
170
2
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171
2
    // Avoid building the remark unless we know there are at least *some*
172
2
    // remarks enabled. We can't currently check whether remarks are requested
173
2
    // for the calling pass since that requires actually building the remark.
174
2
175
2
    if (MF.getFunction().getContext().getRemarkStreamer() ||
176
2
        MF.getFunction()
177
0
            .getContext()
178
0
            .getDiagHandlerPtr()
179
2
            ->isAnyRemarkEnabled()) {
180
2
      auto R = RemarkBuilder();
181
2
      emit((DiagnosticInfoOptimizationBase &)R);
182
2
    }
183
2
  }
PrologEpilogInserter.cpp:void llvm::MachineOptimizationRemarkEmitter::emit<(anonymous namespace)::PEI::runOnMachineFunction(llvm::MachineFunction&)::$_1>((anonymous namespace)::PEI::runOnMachineFunction(llvm::MachineFunction&)::$_1, decltype(fp())*)
Line
Count
Source
170
497k
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171
497k
    // Avoid building the remark unless we know there are at least *some*
172
497k
    // remarks enabled. We can't currently check whether remarks are requested
173
497k
    // for the calling pass since that requires actually building the remark.
174
497k
175
497k
    if (MF.getFunction().getContext().getRemarkStreamer() ||
176
497k
        MF.getFunction()
177
496k
            .getContext()
178
496k
            .getDiagHandlerPtr()
179
496k
            ->isAnyRemarkEnabled()) {
180
961
      auto R = RemarkBuilder();
181
961
      emit((DiagnosticInfoOptimizationBase &)R);
182
961
    }
183
497k
  }
RegAllocGreedy.cpp:void llvm::MachineOptimizationRemarkEmitter::emit<(anonymous namespace)::RAGreedy::reportNumberOfSplillsReloads(llvm::MachineLoop*, unsigned int&, unsigned int&, unsigned int&, unsigned int&)::$_1>((anonymous namespace)::RAGreedy::reportNumberOfSplillsReloads(llvm::MachineLoop*, unsigned int&, unsigned int&, unsigned int&, unsigned int&)::$_1, decltype(fp())*)
Line
Count
Source
170
28.4k
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171
28.4k
    // Avoid building the remark unless we know there are at least *some*
172
28.4k
    // remarks enabled. We can't currently check whether remarks are requested
173
28.4k
    // for the calling pass since that requires actually building the remark.
174
28.4k
175
28.4k
    if (MF.getFunction().getContext().getRemarkStreamer() ||
176
28.4k
        MF.getFunction()
177
28.4k
            .getContext()
178
28.4k
            .getDiagHandlerPtr()
179
28.4k
            ->isAnyRemarkEnabled()) {
180
25
      auto R = RemarkBuilder();
181
25
      emit((DiagnosticInfoOptimizationBase &)R);
182
25
    }
183
28.4k
  }
ShrinkWrap.cpp:void llvm::MachineOptimizationRemarkEmitter::emit<giveUpWithRemarks(llvm::MachineOptimizationRemarkEmitter*, llvm::StringRef, llvm::StringRef, llvm::DiagnosticLocation const&, llvm::MachineBasicBlock const*)::$_0>(giveUpWithRemarks(llvm::MachineOptimizationRemarkEmitter*, llvm::StringRef, llvm::StringRef, llvm::DiagnosticLocation const&, llvm::MachineBasicBlock const*)::$_0, decltype(fp())*)
Line
Count
Source
170
52
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171
52
    // Avoid building the remark unless we know there are at least *some*
172
52
    // remarks enabled. We can't currently check whether remarks are requested
173
52
    // for the calling pass since that requires actually building the remark.
174
52
175
52
    if (MF.getFunction().getContext().getRemarkStreamer() ||
176
52
        MF.getFunction()
177
50
            .getContext()
178
50
            .getDiagHandlerPtr()
179
50
            ->isAnyRemarkEnabled()) {
180
2
      auto R = RemarkBuilder();
181
2
      emit((DiagnosticInfoOptimizationBase &)R);
182
2
    }
183
52
  }
184
185
private:
186
  MachineFunction &MF;
187
188
  /// MBFI is only set if hotness is requested.
189
  MachineBlockFrequencyInfo *MBFI;
190
191
  /// Compute hotness from IR value (currently assumed to be a block) if PGO is
192
  /// available.
193
  Optional<uint64_t> computeHotness(const MachineBasicBlock &MBB);
194
195
  /// Similar but use value from \p OptDiag and update hotness there.
196
  void computeHotness(DiagnosticInfoMIROptimization &Remark);
197
198
  /// Only allow verbose messages if we know we're filtering by hotness
199
  /// (BFI is only set in this case).
200
0
  bool shouldEmitVerbose() { return MBFI != nullptr; }
201
};
202
203
/// The analysis pass
204
///
205
/// Note that this pass shouldn't generally be marked as preserved by other
206
/// passes.  It's holding onto BFI, so if the pass does not preserve BFI, BFI
207
/// could be freed.
208
class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass {
209
  std::unique_ptr<MachineOptimizationRemarkEmitter> ORE;
210
211
public:
212
  MachineOptimizationRemarkEmitterPass();
213
214
  bool runOnMachineFunction(MachineFunction &MF) override;
215
216
  void getAnalysisUsage(AnalysisUsage &AU) const override;
217
218
1.84M
  MachineOptimizationRemarkEmitter &getORE() {
219
1.84M
    assert(ORE && "pass not run yet");
220
1.84M
    return *ORE;
221
1.84M
  }
222
223
  static char ID;
224
};
225
}
226
227
#endif