Coverage Report

Created: 2018-09-23 16:00

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