Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Analysis/OptimizationDiagnosticInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- OptimizationDiagnosticInfo.cpp - Optimization Diagnostic -*- 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
//
10
// Optimization diagnostic interfaces.  It's packaged as an analysis pass so
11
// that by using this service passes become dependent on BFI as well.  BFI is
12
// used to compute the "hotness" of the diagnostic message.
13
//===----------------------------------------------------------------------===//
14
15
#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
16
#include "llvm/Analysis/BranchProbabilityInfo.h"
17
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
18
#include "llvm/Analysis/LoopInfo.h"
19
#include "llvm/IR/DebugInfo.h"
20
#include "llvm/IR/DiagnosticInfo.h"
21
#include "llvm/IR/Dominators.h"
22
#include "llvm/IR/LLVMContext.h"
23
24
using namespace llvm;
25
26
OptimizationRemarkEmitter::OptimizationRemarkEmitter(const Function *F)
27
7.46M
    : F(F), BFI(nullptr) {
28
7.46M
  if (!F->getContext().getDiagnosticsHotnessRequested())
29
7.46M
    return;
30
126
31
126
  // First create a dominator tree.
32
126
  DominatorTree DT;
33
126
  DT.recalculate(*const_cast<Function *>(F));
34
126
35
126
  // Generate LoopInfo from it.
36
126
  LoopInfo LI;
37
126
  LI.analyze(DT);
38
126
39
126
  // Then compute BranchProbabilityInfo.
40
126
  BranchProbabilityInfo BPI;
41
126
  BPI.calculate(*F, LI);
42
126
43
126
  // Finally compute BFI.
44
126
  OwnedBFI = llvm::make_unique<BlockFrequencyInfo>(*F, BPI, LI);
45
126
  BFI = OwnedBFI.get();
46
126
}
47
48
bool OptimizationRemarkEmitter::invalidate(
49
    Function &F, const PreservedAnalyses &PA,
50
1.14k
    FunctionAnalysisManager::Invalidator &Inv) {
51
1.14k
  // This analysis has no state and so can be trivially preserved but it needs
52
1.14k
  // a fresh view of BFI if it was constructed with one.
53
1.14k
  if (
BFI && 1.14k
Inv.invalidate<BlockFrequencyAnalysis>(F, PA)18
)
54
14
    return true;
55
1.13k
56
1.13k
  // Otherwise this analysis result remains valid.
57
1.13k
  return false;
58
1.13k
}
59
60
2.97M
Optional<uint64_t> OptimizationRemarkEmitter::computeHotness(const Value *V) {
61
2.97M
  if (!BFI)
62
2.97M
    return None;
63
86
64
86
  return BFI->getBlockProfileCount(cast<BasicBlock>(V));
65
86
}
66
67
namespace llvm {
68
namespace yaml {
69
70
void MappingTraits<DiagnosticInfoOptimizationBase *>::mapping(
71
213
    IO &io, DiagnosticInfoOptimizationBase *&OptDiag) {
72
213
  assert(io.outputting() && "input not yet implemented");
73
213
74
213
  if (io.mapTag("!Passed",
75
213
                (OptDiag->getKind() == DK_OptimizationRemark ||
76
150
                 OptDiag->getKind() == DK_MachineOptimizationRemark)))
77
63
    ;
78
150
  else 
if (150
io.mapTag(
79
150
               "!Missed",
80
150
               (OptDiag->getKind() == DK_OptimizationRemarkMissed ||
81
109
                OptDiag->getKind() == DK_MachineOptimizationRemarkMissed)))
82
47
    ;
83
103
  else 
if (103
io.mapTag(
84
103
               "!Analysis",
85
103
               (OptDiag->getKind() == DK_OptimizationRemarkAnalysis ||
86
77
                OptDiag->getKind() == DK_MachineOptimizationRemarkAnalysis)))
87
100
    ;
88
3
  else 
if (3
io.mapTag("!AnalysisFPCommute",
89
3
                     OptDiag->getKind() ==
90
3
                         DK_OptimizationRemarkAnalysisFPCommute))
91
0
    ;
92
3
  else 
if (3
io.mapTag("!AnalysisAliasing",
93
3
                     OptDiag->getKind() ==
94
3
                         DK_OptimizationRemarkAnalysisAliasing))
95
1
    ;
96
2
  else 
if (2
io.mapTag("!Failure", OptDiag->getKind() == DK_OptimizationFailure)2
)
97
2
    ;
98
2
  else
99
0
    llvm_unreachable("Unknown remark type");
100
213
101
213
  // These are read-only for now.
102
213
  DiagnosticLocation DL = OptDiag->getLocation();
103
213
  StringRef FN =
104
213
      GlobalValue::dropLLVMManglingEscape(OptDiag->getFunction().getName());
105
213
106
213
  StringRef PassName(OptDiag->PassName);
107
213
  io.mapRequired("Pass", PassName);
108
213
  io.mapRequired("Name", OptDiag->RemarkName);
109
213
  if (
!io.outputting() || 213
DL.isValid()213
)
110
86
    io.mapOptional("DebugLoc", DL);
111
213
  io.mapRequired("Function", FN);
112
213
  io.mapOptional("Hotness", OptDiag->Hotness);
113
213
  io.mapOptional("Args", OptDiag->Args);
114
213
}
115
116
template <> struct MappingTraits<DiagnosticLocation> {
117
111
  static void mapping(IO &io, DiagnosticLocation &DL) {
118
111
    assert(io.outputting() && "input not yet implemented");
119
111
120
111
    StringRef File = DL.getFilename();
121
111
    unsigned Line = DL.getLine();
122
111
    unsigned Col = DL.getColumn();
123
111
124
111
    io.mapRequired("File", File);
125
111
    io.mapRequired("Line", Line);
126
111
    io.mapRequired("Column", Col);
127
111
  }
128
129
  static const bool flow = true;
130
};
131
132
// Implement this as a mapping for now to get proper quotation for the value.
133
template <> struct MappingTraits<DiagnosticInfoOptimizationBase::Argument> {
134
695
  static void mapping(IO &io, DiagnosticInfoOptimizationBase::Argument &A) {
135
695
    assert(io.outputting() && "input not yet implemented");
136
695
    io.mapRequired(A.Key.data(), A.Val);
137
695
    if (A.Loc.isValid())
138
25
      io.mapOptional("DebugLoc", A.Loc);
139
695
  }
140
};
141
142
} // end namespace yaml
143
} // end namespace llvm
144
145
LLVM_YAML_IS_SEQUENCE_VECTOR(DiagnosticInfoOptimizationBase::Argument)
146
147
void OptimizationRemarkEmitter::computeHotness(
148
2.97M
    DiagnosticInfoIROptimization &OptDiag) {
149
2.97M
  const Value *V = OptDiag.getCodeRegion();
150
2.97M
  if (V)
151
2.97M
    OptDiag.setHotness(computeHotness(V));
152
2.97M
}
153
154
void OptimizationRemarkEmitter::emit(
155
2.97M
    DiagnosticInfoOptimizationBase &OptDiagBase) {
156
2.97M
  auto &OptDiag = cast<DiagnosticInfoIROptimization>(OptDiagBase);
157
2.97M
  computeHotness(OptDiag);
158
2.97M
  // If a diagnostic has a hotness value, then only emit it if its hotness
159
2.97M
  // meets the threshold.
160
2.97M
  if (OptDiag.getHotness() &&
161
62
      *OptDiag.getHotness() <
162
2.97M
          F->getContext().getDiagnosticsHotnessThreshold()) {
163
6
    return;
164
6
  }
165
2.97M
166
2.97M
  yaml::Output *Out = F->getContext().getDiagnosticsOutputFile();
167
2.97M
  if (
Out2.97M
) {
168
133
    // For remarks the << operator takes a reference to a pointer.
169
133
    auto *P = &OptDiagBase;
170
133
    *Out << P;
171
133
  }
172
2.97M
  // FIXME: now that IsVerbose is part of DI, filtering for this will be moved
173
2.97M
  // from here to clang.
174
2.97M
  if (
!OptDiag.isVerbose() || 2.97M
shouldEmitVerbose()660k
)
175
2.31M
    F->getContext().diagnose(OptDiag);
176
2.97M
}
177
178
OptimizationRemarkEmitterWrapperPass::OptimizationRemarkEmitterWrapperPass()
179
276k
    : FunctionPass(ID) {
180
276k
  initializeOptimizationRemarkEmitterWrapperPassPass(
181
276k
      *PassRegistry::getPassRegistry());
182
276k
}
183
184
7.83M
bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function &Fn) {
185
7.83M
  BlockFrequencyInfo *BFI;
186
7.83M
187
7.83M
  if (Fn.getContext().getDiagnosticsHotnessRequested())
188
138
    BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
189
7.83M
  else
190
7.83M
    BFI = nullptr;
191
7.83M
192
7.83M
  ORE = llvm::make_unique<OptimizationRemarkEmitter>(&Fn, BFI);
193
7.83M
  return false;
194
7.83M
}
195
196
void OptimizationRemarkEmitterWrapperPass::getAnalysisUsage(
197
276k
    AnalysisUsage &AU) const {
198
276k
  LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
199
276k
  AU.setPreservesAll();
200
276k
}
201
202
AnalysisKey OptimizationRemarkEmitterAnalysis::Key;
203
204
OptimizationRemarkEmitter
205
OptimizationRemarkEmitterAnalysis::run(Function &F,
206
929
                                       FunctionAnalysisManager &AM) {
207
929
  BlockFrequencyInfo *BFI;
208
929
209
929
  if (F.getContext().getDiagnosticsHotnessRequested())
210
18
    BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
211
929
  else
212
911
    BFI = nullptr;
213
929
214
929
  return OptimizationRemarkEmitter(&F, BFI);
215
929
}
216
217
char OptimizationRemarkEmitterWrapperPass::ID = 0;
218
static const char ore_name[] = "Optimization Remark Emitter";
219
#define ORE_NAME "opt-remark-emitter"
220
221
58.7k
INITIALIZE_PASS_BEGIN58.7k
(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
222
58.7k
                      false, true)
223
58.7k
INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
224
58.7k
INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
225
                    false, true)