Coverage Report

Created: 2019-02-20 00:17

/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
494k
        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
494k
  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
46
                                      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
46
  bool isEnabled() const override {
75
46
    const Function &Fn = getFunction();
76
46
    LLVMContext &Ctx = Fn.getContext();
77
46
    return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
78
46
  }
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
18.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
14.2k
  bool isEnabled() const override {
101
14.2k
    const Function &Fn = getFunction();
102
14.2k
    LLVMContext &Ctx = Fn.getContext();
103
14.2k
    return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
104
14.2k
  }
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
475k
                                      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
403k
  bool isEnabled() const override {
127
403k
    const Function &Fn = getFunction();
128
403k
    LLVMContext &Ctx = Fn.getContext();
129
403k
    return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName());
130
403k
  }
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.33M
      : 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
18.3k
  bool allowExtraAnalysis(StringRef PassName) const {
161
18.3k
    return (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
162
18.3k
            MF.getFunction().getContext()
163
18.3k
            .getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
164
18.3k
  }
165
166
  /// Take a lambda that returns a remark which will be emitted.  Second
167
  /// argument is only used to restrict this to functions.
168
  template <typename T>
169
504k
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
170
504k
    // Avoid building the remark unless we know there are at least *some*
171
504k
    // remarks enabled. We can't currently check whether remarks are requested
172
504k
    // for the calling pass since that requires actually building the remark.
173
504k
174
504k
    if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
175
504k
        
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()504k
) {
176
765
      auto R = RemarkBuilder();
177
765
      emit((DiagnosticInfoOptimizationBase &)R);
178
765
    }
179
504k
  }
MachineFunctionPass.cpp:void llvm::MachineOptimizationRemarkEmitter::emit<llvm::MachineFunctionPass::runOnFunction(llvm::Function&)::$_0>(llvm::MachineFunctionPass::runOnFunction(llvm::Function&)::$_0, decltype(fp())*)
Line
Count
Source
169
3
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
170
3
    // Avoid building the remark unless we know there are at least *some*
171
3
    // remarks enabled. We can't currently check whether remarks are requested
172
3
    // for the calling pass since that requires actually building the remark.
173
3
174
3
    if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
175
3
        
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()0
) {
176
3
      auto R = RemarkBuilder();
177
3
      emit((DiagnosticInfoOptimizationBase &)R);
178
3
    }
179
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
169
90
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
170
90
    // Avoid building the remark unless we know there are at least *some*
171
90
    // remarks enabled. We can't currently check whether remarks are requested
172
90
    // for the calling pass since that requires actually building the remark.
173
90
174
90
    if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
175
90
        
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()84
) {
176
8
      auto R = RemarkBuilder();
177
8
      emit((DiagnosticInfoOptimizationBase &)R);
178
8
    }
179
90
  }
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
169
2
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
170
2
    // Avoid building the remark unless we know there are at least *some*
171
2
    // remarks enabled. We can't currently check whether remarks are requested
172
2
    // for the calling pass since that requires actually building the remark.
173
2
174
2
    if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
175
2
        
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()0
) {
176
2
      auto R = RemarkBuilder();
177
2
      emit((DiagnosticInfoOptimizationBase &)R);
178
2
    }
179
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
169
473k
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
170
473k
    // Avoid building the remark unless we know there are at least *some*
171
473k
    // remarks enabled. We can't currently check whether remarks are requested
172
473k
    // for the calling pass since that requires actually building the remark.
173
473k
174
473k
    if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
175
473k
        
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()473k
) {
176
727
      auto R = RemarkBuilder();
177
727
      emit((DiagnosticInfoOptimizationBase &)R);
178
727
    }
179
473k
  }
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
169
31.1k
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
170
31.1k
    // Avoid building the remark unless we know there are at least *some*
171
31.1k
    // remarks enabled. We can't currently check whether remarks are requested
172
31.1k
    // for the calling pass since that requires actually building the remark.
173
31.1k
174
31.1k
    if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
175
31.1k
        
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()31.1k
) {
176
23
      auto R = RemarkBuilder();
177
23
      emit((DiagnosticInfoOptimizationBase &)R);
178
23
    }
179
31.1k
  }
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
169
53
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
170
53
    // Avoid building the remark unless we know there are at least *some*
171
53
    // remarks enabled. We can't currently check whether remarks are requested
172
53
    // for the calling pass since that requires actually building the remark.
173
53
174
53
    if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
175
53
        
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()51
) {
176
2
      auto R = RemarkBuilder();
177
2
      emit((DiagnosticInfoOptimizationBase &)R);
178
2
    }
179
53
  }
180
181
private:
182
  MachineFunction &MF;
183
184
  /// MBFI is only set if hotness is requested.
185
  MachineBlockFrequencyInfo *MBFI;
186
187
  /// Compute hotness from IR value (currently assumed to be a block) if PGO is
188
  /// available.
189
  Optional<uint64_t> computeHotness(const MachineBasicBlock &MBB);
190
191
  /// Similar but use value from \p OptDiag and update hotness there.
192
  void computeHotness(DiagnosticInfoMIROptimization &Remark);
193
194
  /// Only allow verbose messages if we know we're filtering by hotness
195
  /// (BFI is only set in this case).
196
  bool shouldEmitVerbose() { return MBFI != nullptr; }
197
};
198
199
/// The analysis pass
200
///
201
/// Note that this pass shouldn't generally be marked as preserved by other
202
/// passes.  It's holding onto BFI, so if the pass does not preserve BFI, BFI
203
/// could be freed.
204
class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass {
205
  std::unique_ptr<MachineOptimizationRemarkEmitter> ORE;
206
207
public:
208
  MachineOptimizationRemarkEmitterPass();
209
210
  bool runOnMachineFunction(MachineFunction &MF) override;
211
212
  void getAnalysisUsage(AnalysisUsage &AU) const override;
213
214
1.76M
  MachineOptimizationRemarkEmitter &getORE() {
215
1.76M
    assert(ORE && "pass not run yet");
216
1.76M
    return *ORE;
217
1.76M
  }
218
219
  static char ID;
220
};
221
}
222
223
#endif