Coverage Report

Created: 2018-07-19 03:59

/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
496k
        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
496k
  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
23
                                      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
23
  bool isEnabled() const override {
76
23
    const Function &Fn = getFunction();
77
23
    LLVMContext &Ctx = Fn.getContext();
78
23
    return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
79
23
  }
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
39.6k
                                      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
457k
                                      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
385k
  bool isEnabled() const override {
128
385k
    const Function &Fn = getFunction();
129
385k
    LLVMContext &Ctx = Fn.getContext();
130
385k
    return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName());
131
385k
  }
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.03M
      : 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
39.6k
  bool allowExtraAnalysis(StringRef PassName) const {
162
39.6k
    return (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
163
39.6k
            MF.getFunction().getContext()
164
39.6k
            .getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
165
39.6k
  }
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
484k
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171
484k
    // Avoid building the remark unless we know there are at least *some*
172
484k
    // remarks enabled. We can't currently check whether remarks are requested
173
484k
    // for the calling pass since that requires actually building the remark.
174
484k
175
484k
    if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
176
484k
        
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()484k
) {
177
282
      auto R = RemarkBuilder();
178
282
      emit((DiagnosticInfoOptimizationBase &)R);
179
282
    }
180
484k
  }
MachineOutliner.cpp:void llvm::MachineOptimizationRemarkEmitter::emit<(anonymous namespace)::MachineOutliner::findCandidates((anonymous namespace)::SuffixTree&, llvm::TargetInstrInfo const&, (anonymous namespace)::InstructionMapper&, std::__1::vector<std::__1::shared_ptr<llvm::outliner::Candidate>, std::__1::allocator<std::__1::shared_ptr<llvm::outliner::Candidate> > >&, std::__1::vector<llvm::outliner::OutlinedFunction, std::__1::allocator<llvm::outliner::OutlinedFunction> >&)::$_1>((anonymous namespace)::MachineOutliner::findCandidates((anonymous namespace)::SuffixTree&, llvm::TargetInstrInfo const&, (anonymous namespace)::InstructionMapper&, std::__1::vector<std::__1::shared_ptr<llvm::outliner::Candidate>, std::__1::allocator<std::__1::shared_ptr<llvm::outliner::Candidate> > >&, std::__1::vector<llvm::outliner::OutlinedFunction, std::__1::allocator<llvm::outliner::OutlinedFunction> >&)::$_1, decltype(fp())*)
Line
Count
Source
170
65
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171
65
    // Avoid building the remark unless we know there are at least *some*
172
65
    // remarks enabled. We can't currently check whether remarks are requested
173
65
    // for the calling pass since that requires actually building the remark.
174
65
175
65
    if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
176
65
        
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()58
) {
177
14
      auto R = RemarkBuilder();
178
14
      emit((DiagnosticInfoOptimizationBase &)R);
179
14
    }
180
65
  }
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
455k
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171
455k
    // Avoid building the remark unless we know there are at least *some*
172
455k
    // remarks enabled. We can't currently check whether remarks are requested
173
455k
    // for the calling pass since that requires actually building the remark.
174
455k
175
455k
    if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
176
455k
        
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()455k
) {
177
243
      auto R = RemarkBuilder();
178
243
      emit((DiagnosticInfoOptimizationBase &)R);
179
243
    }
180
455k
  }
RegAllocGreedy.cpp:void llvm::MachineOptimizationRemarkEmitter::emit<(anonymous namespace)::RAGreedy::reportNumberOfSplillsReloads(llvm::MachineLoop*, unsigned int&, unsigned int&, unsigned int&, unsigned int&)::$_0>((anonymous namespace)::RAGreedy::reportNumberOfSplillsReloads(llvm::MachineLoop*, unsigned int&, unsigned int&, unsigned int&, unsigned int&)::$_0, decltype(fp())*)
Line
Count
Source
170
29.3k
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171
29.3k
    // Avoid building the remark unless we know there are at least *some*
172
29.3k
    // remarks enabled. We can't currently check whether remarks are requested
173
29.3k
    // for the calling pass since that requires actually building the remark.
174
29.3k
175
29.3k
    if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
176
29.3k
        
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()29.3k
) {
177
23
      auto R = RemarkBuilder();
178
23
      emit((DiagnosticInfoOptimizationBase &)R);
179
23
    }
180
29.3k
  }
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
43
  void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171
43
    // Avoid building the remark unless we know there are at least *some*
172
43
    // remarks enabled. We can't currently check whether remarks are requested
173
43
    // for the calling pass since that requires actually building the remark.
174
43
175
43
    if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
176
43
        
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()41
) {
177
2
      auto R = RemarkBuilder();
178
2
      emit((DiagnosticInfoOptimizationBase &)R);
179
2
    }
180
43
  }
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.70M
  MachineOptimizationRemarkEmitter &getORE() {
216
1.70M
    assert(ORE && "pass not run yet");
217
1.70M
    return *ORE;
218
1.70M
  }
219
220
  static char ID;
221
};
222
}
223
224
#endif