LLVM  4.0.0
OptimizationDiagnosticInfo.cpp
Go to the documentation of this file.
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 
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 
27  : F(F), BFI(nullptr) {
29  return;
30 
31  // First create a dominator tree.
32  DominatorTree DT;
33  DT.recalculate(*F);
34 
35  // Generate LoopInfo from it.
36  LoopInfo LI;
37  LI.analyze(DT);
38 
39  // Then compute BranchProbabilityInfo.
41  BPI.calculate(*F, LI);
42 
43  // Finally compute BFI.
44  OwnedBFI = llvm::make_unique<BlockFrequencyInfo>(*F, BPI, LI);
45  BFI = OwnedBFI.get();
46 }
47 
48 Optional<uint64_t> OptimizationRemarkEmitter::computeHotness(const Value *V) {
49  if (!BFI)
50  return None;
51 
52  return BFI->getBlockProfileCount(cast<BasicBlock>(V));
53 }
54 
55 namespace llvm {
56 namespace yaml {
57 
59  static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag) {
60  assert(io.outputting() && "input not yet implemented");
61 
62  if (io.mapTag("!Passed", OptDiag->getKind() == DK_OptimizationRemark))
63  ;
64  else if (io.mapTag("!Missed",
65  OptDiag->getKind() == DK_OptimizationRemarkMissed))
66  ;
67  else if (io.mapTag("!Analysis",
69  ;
70  else if (io.mapTag("!AnalysisFPCommute",
71  OptDiag->getKind() ==
73  ;
74  else if (io.mapTag("!AnalysisAliasing",
75  OptDiag->getKind() ==
77  ;
78  else
79  llvm_unreachable("todo");
80 
81  // These are read-only for now.
82  DebugLoc DL = OptDiag->getDebugLoc();
84  OptDiag->getFunction().getName());
85 
86  StringRef PassName(OptDiag->PassName);
87  io.mapRequired("Pass", PassName);
88  io.mapRequired("Name", OptDiag->RemarkName);
89  if (!io.outputting() || DL)
90  io.mapOptional("DebugLoc", DL);
91  io.mapRequired("Function", FN);
92  io.mapOptional("Hotness", OptDiag->Hotness);
93  io.mapOptional("Args", OptDiag->Args);
94  }
95 };
96 
97 template <> struct MappingTraits<DebugLoc> {
98  static void mapping(IO &io, DebugLoc &DL) {
99  assert(io.outputting() && "input not yet implemented");
100 
101  auto *Scope = cast<DIScope>(DL.getScope());
102  StringRef File = Scope->getFilename();
103  unsigned Line = DL.getLine();
104  unsigned Col = DL.getCol();
105 
106  io.mapRequired("File", File);
107  io.mapRequired("Line", Line);
108  io.mapRequired("Column", Col);
109  }
110 
111  static const bool flow = true;
112 };
113 
114 // Implement this as a mapping for now to get proper quotation for the value.
117  assert(io.outputting() && "input not yet implemented");
118  io.mapRequired(A.Key.data(), A.Val);
119  if (A.DLoc)
120  io.mapOptional("DebugLoc", A.DLoc);
121  }
122 };
123 
124 } // end namespace yaml
125 } // end namespace llvm
126 
128 
129 void OptimizationRemarkEmitter::computeHotness(
131  Value *V = OptDiag.getCodeRegion();
132  if (V)
133  OptDiag.setHotness(computeHotness(V));
134 }
135 
137  computeHotness(OptDiag);
138 
140  if (Out) {
141  auto *P = &const_cast<DiagnosticInfoOptimizationBase &>(OptDiag);
142  *Out << P;
143  }
144  // FIXME: now that IsVerbose is part of DI, filtering for this will be moved
145  // from here to clang.
146  if (!OptDiag.isVerbose() || shouldEmitVerbose())
147  F->getContext().diagnose(OptDiag);
148 }
149 
151  const DebugLoc &DLoc,
152  const Value *V,
153  const Twine &Msg) {
154  LLVMContext &Ctx = F->getContext();
155  Ctx.diagnose(OptimizationRemark(PassName, *F, DLoc, Msg, computeHotness(V)));
156 }
157 
159  Loop *L,
160  const Twine &Msg) {
161  emitOptimizationRemark(PassName, L->getStartLoc(), L->getHeader(), Msg);
162 }
163 
165  const char *PassName, const DebugLoc &DLoc, const Value *V,
166  const Twine &Msg, bool IsVerbose) {
167  LLVMContext &Ctx = F->getContext();
168  if (!IsVerbose || shouldEmitVerbose())
169  Ctx.diagnose(
170  OptimizationRemarkMissed(PassName, *F, DLoc, Msg, computeHotness(V)));
171 }
172 
174  const char *PassName, Loop *L, const Twine &Msg, bool IsVerbose) {
175  emitOptimizationRemarkMissed(PassName, L->getStartLoc(), L->getHeader(), Msg,
176  IsVerbose);
177 }
178 
180  const char *PassName, const DebugLoc &DLoc, const Value *V,
181  const Twine &Msg, bool IsVerbose) {
182  LLVMContext &Ctx = F->getContext();
183  if (!IsVerbose || shouldEmitVerbose())
184  Ctx.diagnose(
185  OptimizationRemarkAnalysis(PassName, *F, DLoc, Msg, computeHotness(V)));
186 }
187 
189  const char *PassName, Loop *L, const Twine &Msg, bool IsVerbose) {
191  Msg, IsVerbose);
192 }
193 
195  const char *PassName, const DebugLoc &DLoc, const Value *V,
196  const Twine &Msg) {
197  LLVMContext &Ctx = F->getContext();
198  Ctx.diagnose(OptimizationRemarkAnalysisFPCommute(PassName, *F, DLoc, Msg,
199  computeHotness(V)));
200 }
201 
203  const char *PassName, const DebugLoc &DLoc, const Value *V,
204  const Twine &Msg) {
205  LLVMContext &Ctx = F->getContext();
206  Ctx.diagnose(OptimizationRemarkAnalysisAliasing(PassName, *F, DLoc, Msg,
207  computeHotness(V)));
208 }
209 
211  const char *PassName, Loop *L, const Twine &Msg) {
213  L->getHeader(), Msg);
214 }
215 
217  : FunctionPass(ID) {
220 }
221 
224 
226  BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
227  else
228  BFI = nullptr;
229 
230  ORE = llvm::make_unique<OptimizationRemarkEmitter>(&Fn, BFI);
231  return false;
232 }
233 
235  AnalysisUsage &AU) const {
237  AU.setPreservesAll();
238 }
239 
240 AnalysisKey OptimizationRemarkEmitterAnalysis::Key;
241 
246 
248  BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
249  else
250  BFI = nullptr;
251 
252  return OptimizationRemarkEmitter(&F, BFI);
253 }
254 
256 static const char ore_name[] = "Optimization Remark Emitter";
257 #define ORE_NAME "opt-remark-emitter"
258 
260  false, true)
261 INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
263  false, true)
MachineLoop * L
static void mapping(IO &io, DiagnosticInfoOptimizationBase::Argument &A)
Diagnostic information for missed-optimization remarks.
void emitOptimizationRemarkAnalysisFPCommute(const char *PassName, const DebugLoc &DLoc, const Value *V, const Twine &Msg)
Emit an optimization analysis remark related to floating-point non-commutativity. ...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
void mapOptional(const char *Key, T &Val)
Definition: YAMLTraits.h:646
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:226
LLVM Argument representation.
Definition: Argument.h:34
Result run(Function &F, FunctionAnalysisManager &AM)
Run the analysis pass over a function and produce BFI.
MDNode * getScope() const
Definition: DebugLoc.cpp:35
const Function & getFunction() const
DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
Definition: LoopInfo.cpp:307
void initializeOptimizationRemarkEmitterWrapperPassPass(PassRegistry &)
A debug info location.
Definition: DebugLoc.h:34
#define LLVM_YAML_IS_SEQUENCE_VECTOR(_type)
Utility for declaring that a std::vector of a particular type should be considered a YAML sequence...
Definition: YAMLTraits.h:1565
INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name, false, true) INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass
void emitOptimizationRemarkAnalysis(const char *PassName, const DebugLoc &DLoc, const Value *V, const Twine &Msg, bool IsVerbose=false)
Emit an optimization analysis remark message.
const DebugLoc & getDebugLoc() const
BlockT * getHeader() const
Definition: LoopInfo.h:102
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:191
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:53
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
OptimizationRemarkEmitter(Function *F, BlockFrequencyInfo *BFI)
Diagnostic information for optimization analysis remarks.
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
#define F(x, y, z)
Definition: MD5.cpp:51
This class should be specialized by any type that needs to be converted to/from a YAML mapping...
Diagnostic information for optimization analysis remarks related to pointer aliasing.
virtual bool mapTag(StringRef Tag, bool Default=false)=0
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Definition: Dominators.h:96
yaml::Output * getDiagnosticsOutputFile()
Return the YAML file used by the backend to save optimization diagnostics.
unsigned getLine() const
Definition: DebugLoc.cpp:25
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
#define P(N)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:653
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:48
void emitOptimizationRemarkMissed(const char *PassName, const DebugLoc &DLoc, const Value *V, const Twine &Msg, bool IsVerbose=false)
Emit an optimization-missed message.
Diagnostic information for applied optimization remarks.
void analyze(const DominatorTreeBase< BlockT > &DomTree)
Create the loop forest using a stable algorithm.
Definition: LoopInfoImpl.h:475
static void mapping(IO &io, DebugLoc &DL)
Represent the analysis usage information of a pass.
void emitOptimizationRemark(const char *PassName, const DebugLoc &DLoc, const Value *V, const Twine &Msg)
Emit an optimization-applied message.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
The Output class is used to generate a yaml document from in-memory structs and vectors.
Definition: YAMLTraits.h:1249
Used in the streaming interface as the general argument type.
bool getDiagnosticHotnessRequested() const
Return if a code hotness metric should be included in optimization diagnostics.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getCol() const
Definition: DebugLoc.cpp:30
void calculate(const Function &F, const LoopInfo &LI)
Analysis pass which computes BlockFrequencyInfo.
Diagnostic information for optimization analysis remarks related to floating-point non-commutativity...
void emit(DiagnosticInfoOptimizationBase &OptDiag)
The new interface to emit remarks.
Common features for diagnostics dealing with optimization remarks.
static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag)
void emitOptimizationRemarkAnalysisAliasing(const char *PassName, const DebugLoc &DLoc, const Value *V, const Twine &Msg)
Emit an optimization analysis remark related to pointer aliasing.
void setPreservesAll()
Set by analyses that do not transform their input at all.
static void getLazyBFIAnalysisUsage(AnalysisUsage &AU)
Helper for client passes to set up the analysis usage on behalf of this pass.
Basic Alias true
static StringRef getRealLinkageName(StringRef Name)
If special LLVM prefix that is used to inform the asm printer to not emit usual symbol prefix before ...
Definition: GlobalValue.h:444
Analysis providing branch probability information.
Represents a single loop in the control flow graph.
Definition: LoopInfo.h:368
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
static const char ore_name[]
virtual bool outputting()=0
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:71
OptimizationRemarkEmitter legacy analysis pass.
#define ORE_NAME
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:125
void recalculate(FT &F)
recalculate - compute a dominator tree for the given function
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
A container for analyses that lazily runs them and caches their results.
void mapRequired(const char *Key, T &Val)
Definition: YAMLTraits.h:637
Optional< uint64_t > getBlockProfileCount(const BasicBlock *BB) const
Returns the estimated profile count of BB.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
The optimization diagnostic interface.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: PassManager.h:64