2017-10-10 01:19:02 +02:00
|
|
|
//===- OptimizationRemarkEmitter.cpp - Optimization Diagnostic --*- C++ -*-===//
|
2016-07-15 19:23:20 +02:00
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2016-07-15 19:23:20 +02:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// Optimization diagnostic interfaces. It's packaged as an analysis pass so
|
|
|
|
// that by using this service passes become dependent on BFI as well. BFI is
|
|
|
|
// used to compute the "hotness" of the diagnostic message.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2017-10-10 01:19:02 +02:00
|
|
|
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
2016-08-10 02:44:44 +02:00
|
|
|
#include "llvm/Analysis/BranchProbabilityInfo.h"
|
2016-07-15 19:23:20 +02:00
|
|
|
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
|
|
|
|
#include "llvm/Analysis/LoopInfo.h"
|
2020-11-17 19:43:02 +01:00
|
|
|
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
2016-07-15 19:23:20 +02:00
|
|
|
#include "llvm/IR/DiagnosticInfo.h"
|
2016-08-10 02:44:44 +02:00
|
|
|
#include "llvm/IR/Dominators.h"
|
2016-07-15 19:23:20 +02:00
|
|
|
#include "llvm/IR/LLVMContext.h"
|
Sink all InitializePasses.h includes
This file lists every pass in LLVM, and is included by Pass.h, which is
very popular. Every time we add, remove, or rename a pass in LLVM, it
caused lots of recompilation.
I found this fact by looking at this table, which is sorted by the
number of times a file was changed over the last 100,000 git commits
multiplied by the number of object files that depend on it in the
current checkout:
recompiles touches affected_files header
342380 95 3604 llvm/include/llvm/ADT/STLExtras.h
314730 234 1345 llvm/include/llvm/InitializePasses.h
307036 118 2602 llvm/include/llvm/ADT/APInt.h
213049 59 3611 llvm/include/llvm/Support/MathExtras.h
170422 47 3626 llvm/include/llvm/Support/Compiler.h
162225 45 3605 llvm/include/llvm/ADT/Optional.h
158319 63 2513 llvm/include/llvm/ADT/Triple.h
140322 39 3598 llvm/include/llvm/ADT/StringRef.h
137647 59 2333 llvm/include/llvm/Support/Error.h
131619 73 1803 llvm/include/llvm/Support/FileSystem.h
Before this change, touching InitializePasses.h would cause 1345 files
to recompile. After this change, touching it only causes 550 compiles in
an incremental rebuild.
Reviewers: bkramer, asbirlea, bollu, jdoerfert
Differential Revision: https://reviews.llvm.org/D70211
2019-11-13 22:15:01 +01:00
|
|
|
#include "llvm/InitializePasses.h"
|
2016-07-15 19:23:20 +02:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2017-02-22 08:38:17 +01:00
|
|
|
OptimizationRemarkEmitter::OptimizationRemarkEmitter(const Function *F)
|
2016-08-10 02:44:44 +02:00
|
|
|
: F(F), BFI(nullptr) {
|
[ORE] Unify spelling as "diagnostics hotness"
Summary:
To enable profile hotness information in diagnostics output, Clang takes
the option `-fdiagnostics-show-hotness` -- that's "diagnostics", with an
"s" at the end. Clang also defines `CodeGenOptions::DiagnosticsWithHotness`.
LLVM, on the other hand, defines
`LLVMContext::getDiagnosticHotnessRequested` -- that's "diagnostic", not
"diagnostics". It's a small difference, but it's confusing, typo-inducing, and
frustrating.
Add a new method with the spelling "diagnostics", and "deprecate" the
old spelling.
Reviewers: anemet, davidxl
Reviewed By: anemet
Subscribers: llvm-commits, mehdi_amini
Differential Revision: https://reviews.llvm.org/D34864
llvm-svn: 306848
2017-06-30 20:13:59 +02:00
|
|
|
if (!F->getContext().getDiagnosticsHotnessRequested())
|
2016-08-10 02:44:44 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
// First create a dominator tree.
|
|
|
|
DominatorTree DT;
|
2017-02-22 08:38:17 +01:00
|
|
|
DT.recalculate(*const_cast<Function *>(F));
|
2016-08-10 02:44:44 +02:00
|
|
|
|
|
|
|
// Generate LoopInfo from it.
|
|
|
|
LoopInfo LI;
|
|
|
|
LI.analyze(DT);
|
|
|
|
|
|
|
|
// Then compute BranchProbabilityInfo.
|
2020-06-18 11:20:55 +02:00
|
|
|
BranchProbabilityInfo BPI(*F, LI, nullptr, &DT, nullptr);
|
2016-08-10 02:44:44 +02:00
|
|
|
|
|
|
|
// Finally compute BFI.
|
2019-08-15 17:54:37 +02:00
|
|
|
OwnedBFI = std::make_unique<BlockFrequencyInfo>(*F, BPI, LI);
|
2016-08-10 02:44:44 +02:00
|
|
|
BFI = OwnedBFI.get();
|
|
|
|
}
|
|
|
|
|
2017-01-15 09:20:50 +01:00
|
|
|
bool OptimizationRemarkEmitter::invalidate(
|
|
|
|
Function &F, const PreservedAnalyses &PA,
|
|
|
|
FunctionAnalysisManager::Invalidator &Inv) {
|
Compute ORE, BPI, BFI in Loop passes.
Summary:
Passes ORE, BPI, BFI are not being preserved by Loop passes, hence it
is incorrect to retrieve these passes as cached.
This patch makes the loop passes in question compute a new instance.
In some of these cases, however, it may be beneficial to change the Loop pass to
a Function pass instead, similar to the change for LoopUnrollAndJam.
Reviewers: chandlerc, dmgreen, jdoerfert, reames
Subscribers: mehdi_amini, hiraditya, zzheng, steven_wu, dexonsmith, Whitney, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D72891
2020-01-17 00:32:30 +01:00
|
|
|
if (OwnedBFI.get()) {
|
|
|
|
OwnedBFI.reset();
|
|
|
|
BFI = nullptr;
|
|
|
|
}
|
2017-01-15 09:20:50 +01:00
|
|
|
// This analysis has no state and so can be trivially preserved but it needs
|
|
|
|
// a fresh view of BFI if it was constructed with one.
|
|
|
|
if (BFI && Inv.invalidate<BlockFrequencyAnalysis>(F, PA))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Otherwise this analysis result remains valid.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-07-20 23:44:22 +02:00
|
|
|
Optional<uint64_t> OptimizationRemarkEmitter::computeHotness(const Value *V) {
|
2016-07-15 19:23:20 +02:00
|
|
|
if (!BFI)
|
|
|
|
return None;
|
|
|
|
|
|
|
|
return BFI->getBlockProfileCount(cast<BasicBlock>(V));
|
|
|
|
}
|
|
|
|
|
Output optimization remarks in YAML
(Re-committed after moving the template specialization under the yaml
namespace. GCC was complaining about this.)
This allows various presentation of this data using an external tool.
This was first recommended here[1].
As an example, consider this module:
1 int foo();
2 int bar();
3
4 int baz() {
5 return foo() + bar();
6 }
The inliner generates these missed-optimization remarks today (the
hotness information is pulled from PGO):
remark: /tmp/s.c:5:10: foo will not be inlined into baz (hotness: 30)
remark: /tmp/s.c:5:18: bar will not be inlined into baz (hotness: 30)
Now with -pass-remarks-output=<yaml-file>, we generate this YAML file:
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 10 }
Function: baz
Hotness: 30
Args:
- Callee: foo
- String: will not be inlined into
- Caller: baz
...
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 18 }
Function: baz
Hotness: 30
Args:
- Callee: bar
- String: will not be inlined into
- Caller: baz
...
This is a summary of the high-level decisions:
* There is a new streaming interface to emit optimization remarks.
E.g. for the inliner remark above:
ORE.emit(DiagnosticInfoOptimizationRemarkMissed(
DEBUG_TYPE, "NotInlined", &I)
<< NV("Callee", Callee) << " will not be inlined into "
<< NV("Caller", CS.getCaller()) << setIsVerbose());
NV stands for named value and allows the YAML client to process a remark
using its name (NotInlined) and the named arguments (Callee and Caller)
without parsing the text of the message.
Subsequent patches will update ORE users to use the new streaming API.
* I am using YAML I/O for writing the YAML file. YAML I/O requires you
to specify reading and writing at once but reading is highly non-trivial
for some of the more complex LLVM types. Since it's not clear that we
(ever) want to use LLVM to parse this YAML file, the code supports and
asserts that we're writing only.
On the other hand, I did experiment that the class hierarchy starting at
DiagnosticInfoOptimizationBase can be mapped back from YAML generated
here (see D24479).
* The YAML stream is stored in the LLVM context.
* In the example, we can probably further specify the IR value used,
i.e. print "Function" rather than "Value".
* As before hotness is computed in the analysis pass instead of
DiganosticInfo. This avoids the layering problem since BFI is in
Analysis while DiagnosticInfo is in IR.
[1] https://reviews.llvm.org/D19678#419445
Differential Revision: https://reviews.llvm.org/D24587
llvm-svn: 282539
2016-09-27 22:55:07 +02:00
|
|
|
void OptimizationRemarkEmitter::computeHotness(
|
2017-01-26 00:20:25 +01:00
|
|
|
DiagnosticInfoIROptimization &OptDiag) {
|
2017-02-22 08:38:17 +01:00
|
|
|
const Value *V = OptDiag.getCodeRegion();
|
Output optimization remarks in YAML
(Re-committed after moving the template specialization under the yaml
namespace. GCC was complaining about this.)
This allows various presentation of this data using an external tool.
This was first recommended here[1].
As an example, consider this module:
1 int foo();
2 int bar();
3
4 int baz() {
5 return foo() + bar();
6 }
The inliner generates these missed-optimization remarks today (the
hotness information is pulled from PGO):
remark: /tmp/s.c:5:10: foo will not be inlined into baz (hotness: 30)
remark: /tmp/s.c:5:18: bar will not be inlined into baz (hotness: 30)
Now with -pass-remarks-output=<yaml-file>, we generate this YAML file:
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 10 }
Function: baz
Hotness: 30
Args:
- Callee: foo
- String: will not be inlined into
- Caller: baz
...
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 18 }
Function: baz
Hotness: 30
Args:
- Callee: bar
- String: will not be inlined into
- Caller: baz
...
This is a summary of the high-level decisions:
* There is a new streaming interface to emit optimization remarks.
E.g. for the inliner remark above:
ORE.emit(DiagnosticInfoOptimizationRemarkMissed(
DEBUG_TYPE, "NotInlined", &I)
<< NV("Callee", Callee) << " will not be inlined into "
<< NV("Caller", CS.getCaller()) << setIsVerbose());
NV stands for named value and allows the YAML client to process a remark
using its name (NotInlined) and the named arguments (Callee and Caller)
without parsing the text of the message.
Subsequent patches will update ORE users to use the new streaming API.
* I am using YAML I/O for writing the YAML file. YAML I/O requires you
to specify reading and writing at once but reading is highly non-trivial
for some of the more complex LLVM types. Since it's not clear that we
(ever) want to use LLVM to parse this YAML file, the code supports and
asserts that we're writing only.
On the other hand, I did experiment that the class hierarchy starting at
DiagnosticInfoOptimizationBase can be mapped back from YAML generated
here (see D24479).
* The YAML stream is stored in the LLVM context.
* In the example, we can probably further specify the IR value used,
i.e. print "Function" rather than "Value".
* As before hotness is computed in the analysis pass instead of
DiganosticInfo. This avoids the layering problem since BFI is in
Analysis while DiagnosticInfo is in IR.
[1] https://reviews.llvm.org/D19678#419445
Differential Revision: https://reviews.llvm.org/D24587
llvm-svn: 282539
2016-09-27 22:55:07 +02:00
|
|
|
if (V)
|
|
|
|
OptDiag.setHotness(computeHotness(V));
|
|
|
|
}
|
|
|
|
|
2017-01-26 00:20:25 +01:00
|
|
|
void OptimizationRemarkEmitter::emit(
|
|
|
|
DiagnosticInfoOptimizationBase &OptDiagBase) {
|
|
|
|
auto &OptDiag = cast<DiagnosticInfoIROptimization>(OptDiagBase);
|
Output optimization remarks in YAML
(Re-committed after moving the template specialization under the yaml
namespace. GCC was complaining about this.)
This allows various presentation of this data using an external tool.
This was first recommended here[1].
As an example, consider this module:
1 int foo();
2 int bar();
3
4 int baz() {
5 return foo() + bar();
6 }
The inliner generates these missed-optimization remarks today (the
hotness information is pulled from PGO):
remark: /tmp/s.c:5:10: foo will not be inlined into baz (hotness: 30)
remark: /tmp/s.c:5:18: bar will not be inlined into baz (hotness: 30)
Now with -pass-remarks-output=<yaml-file>, we generate this YAML file:
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 10 }
Function: baz
Hotness: 30
Args:
- Callee: foo
- String: will not be inlined into
- Caller: baz
...
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 18 }
Function: baz
Hotness: 30
Args:
- Callee: bar
- String: will not be inlined into
- Caller: baz
...
This is a summary of the high-level decisions:
* There is a new streaming interface to emit optimization remarks.
E.g. for the inliner remark above:
ORE.emit(DiagnosticInfoOptimizationRemarkMissed(
DEBUG_TYPE, "NotInlined", &I)
<< NV("Callee", Callee) << " will not be inlined into "
<< NV("Caller", CS.getCaller()) << setIsVerbose());
NV stands for named value and allows the YAML client to process a remark
using its name (NotInlined) and the named arguments (Callee and Caller)
without parsing the text of the message.
Subsequent patches will update ORE users to use the new streaming API.
* I am using YAML I/O for writing the YAML file. YAML I/O requires you
to specify reading and writing at once but reading is highly non-trivial
for some of the more complex LLVM types. Since it's not clear that we
(ever) want to use LLVM to parse this YAML file, the code supports and
asserts that we're writing only.
On the other hand, I did experiment that the class hierarchy starting at
DiagnosticInfoOptimizationBase can be mapped back from YAML generated
here (see D24479).
* The YAML stream is stored in the LLVM context.
* In the example, we can probably further specify the IR value used,
i.e. print "Function" rather than "Value".
* As before hotness is computed in the analysis pass instead of
DiganosticInfo. This avoids the layering problem since BFI is in
Analysis while DiagnosticInfo is in IR.
[1] https://reviews.llvm.org/D19678#419445
Differential Revision: https://reviews.llvm.org/D24587
llvm-svn: 282539
2016-09-27 22:55:07 +02:00
|
|
|
computeHotness(OptDiag);
|
2017-12-01 21:41:38 +01:00
|
|
|
|
|
|
|
// Only emit it if its hotness meets the threshold.
|
|
|
|
if (OptDiag.getHotness().getValueOr(0) <
|
|
|
|
F->getContext().getDiagnosticsHotnessThreshold()) {
|
2017-07-01 01:14:53 +02:00
|
|
|
return;
|
|
|
|
}
|
Output optimization remarks in YAML
(Re-committed after moving the template specialization under the yaml
namespace. GCC was complaining about this.)
This allows various presentation of this data using an external tool.
This was first recommended here[1].
As an example, consider this module:
1 int foo();
2 int bar();
3
4 int baz() {
5 return foo() + bar();
6 }
The inliner generates these missed-optimization remarks today (the
hotness information is pulled from PGO):
remark: /tmp/s.c:5:10: foo will not be inlined into baz (hotness: 30)
remark: /tmp/s.c:5:18: bar will not be inlined into baz (hotness: 30)
Now with -pass-remarks-output=<yaml-file>, we generate this YAML file:
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 10 }
Function: baz
Hotness: 30
Args:
- Callee: foo
- String: will not be inlined into
- Caller: baz
...
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 18 }
Function: baz
Hotness: 30
Args:
- Callee: bar
- String: will not be inlined into
- Caller: baz
...
This is a summary of the high-level decisions:
* There is a new streaming interface to emit optimization remarks.
E.g. for the inliner remark above:
ORE.emit(DiagnosticInfoOptimizationRemarkMissed(
DEBUG_TYPE, "NotInlined", &I)
<< NV("Callee", Callee) << " will not be inlined into "
<< NV("Caller", CS.getCaller()) << setIsVerbose());
NV stands for named value and allows the YAML client to process a remark
using its name (NotInlined) and the named arguments (Callee and Caller)
without parsing the text of the message.
Subsequent patches will update ORE users to use the new streaming API.
* I am using YAML I/O for writing the YAML file. YAML I/O requires you
to specify reading and writing at once but reading is highly non-trivial
for some of the more complex LLVM types. Since it's not clear that we
(ever) want to use LLVM to parse this YAML file, the code supports and
asserts that we're writing only.
On the other hand, I did experiment that the class hierarchy starting at
DiagnosticInfoOptimizationBase can be mapped back from YAML generated
here (see D24479).
* The YAML stream is stored in the LLVM context.
* In the example, we can probably further specify the IR value used,
i.e. print "Function" rather than "Value".
* As before hotness is computed in the analysis pass instead of
DiganosticInfo. This avoids the layering problem since BFI is in
Analysis while DiagnosticInfo is in IR.
[1] https://reviews.llvm.org/D19678#419445
Differential Revision: https://reviews.llvm.org/D24587
llvm-svn: 282539
2016-09-27 22:55:07 +02:00
|
|
|
|
2017-10-04 06:26:23 +02:00
|
|
|
F->getContext().diagnose(OptDiag);
|
Output optimization remarks in YAML
(Re-committed after moving the template specialization under the yaml
namespace. GCC was complaining about this.)
This allows various presentation of this data using an external tool.
This was first recommended here[1].
As an example, consider this module:
1 int foo();
2 int bar();
3
4 int baz() {
5 return foo() + bar();
6 }
The inliner generates these missed-optimization remarks today (the
hotness information is pulled from PGO):
remark: /tmp/s.c:5:10: foo will not be inlined into baz (hotness: 30)
remark: /tmp/s.c:5:18: bar will not be inlined into baz (hotness: 30)
Now with -pass-remarks-output=<yaml-file>, we generate this YAML file:
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 10 }
Function: baz
Hotness: 30
Args:
- Callee: foo
- String: will not be inlined into
- Caller: baz
...
--- !Missed
Pass: inline
Name: NotInlined
DebugLoc: { File: /tmp/s.c, Line: 5, Column: 18 }
Function: baz
Hotness: 30
Args:
- Callee: bar
- String: will not be inlined into
- Caller: baz
...
This is a summary of the high-level decisions:
* There is a new streaming interface to emit optimization remarks.
E.g. for the inliner remark above:
ORE.emit(DiagnosticInfoOptimizationRemarkMissed(
DEBUG_TYPE, "NotInlined", &I)
<< NV("Callee", Callee) << " will not be inlined into "
<< NV("Caller", CS.getCaller()) << setIsVerbose());
NV stands for named value and allows the YAML client to process a remark
using its name (NotInlined) and the named arguments (Callee and Caller)
without parsing the text of the message.
Subsequent patches will update ORE users to use the new streaming API.
* I am using YAML I/O for writing the YAML file. YAML I/O requires you
to specify reading and writing at once but reading is highly non-trivial
for some of the more complex LLVM types. Since it's not clear that we
(ever) want to use LLVM to parse this YAML file, the code supports and
asserts that we're writing only.
On the other hand, I did experiment that the class hierarchy starting at
DiagnosticInfoOptimizationBase can be mapped back from YAML generated
here (see D24479).
* The YAML stream is stored in the LLVM context.
* In the example, we can probably further specify the IR value used,
i.e. print "Function" rather than "Value".
* As before hotness is computed in the analysis pass instead of
DiganosticInfo. This avoids the layering problem since BFI is in
Analysis while DiagnosticInfo is in IR.
[1] https://reviews.llvm.org/D19678#419445
Differential Revision: https://reviews.llvm.org/D24587
llvm-svn: 282539
2016-09-27 22:55:07 +02:00
|
|
|
}
|
|
|
|
|
2016-07-18 18:29:21 +02:00
|
|
|
OptimizationRemarkEmitterWrapperPass::OptimizationRemarkEmitterWrapperPass()
|
|
|
|
: FunctionPass(ID) {
|
|
|
|
initializeOptimizationRemarkEmitterWrapperPassPass(
|
|
|
|
*PassRegistry::getPassRegistry());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OptimizationRemarkEmitterWrapperPass::runOnFunction(Function &Fn) {
|
|
|
|
BlockFrequencyInfo *BFI;
|
2016-07-15 19:23:20 +02:00
|
|
|
|
2020-11-17 19:43:02 +01:00
|
|
|
auto &Context = Fn.getContext();
|
|
|
|
if (Context.getDiagnosticsHotnessRequested()) {
|
2016-07-15 19:23:20 +02:00
|
|
|
BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
|
2020-11-17 19:43:02 +01:00
|
|
|
// Get hotness threshold from PSI. This should only happen once.
|
|
|
|
if (Context.isDiagnosticsHotnessThresholdSetFromPSI()) {
|
|
|
|
if (ProfileSummaryInfo *PSI =
|
|
|
|
&getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI())
|
|
|
|
Context.setDiagnosticsHotnessThreshold(
|
|
|
|
PSI->getOrCompHotCountThreshold());
|
|
|
|
}
|
|
|
|
} else
|
2016-07-15 19:23:20 +02:00
|
|
|
BFI = nullptr;
|
|
|
|
|
2019-08-15 17:54:37 +02:00
|
|
|
ORE = std::make_unique<OptimizationRemarkEmitter>(&Fn, BFI);
|
2016-07-15 19:23:20 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-07-18 18:29:21 +02:00
|
|
|
void OptimizationRemarkEmitterWrapperPass::getAnalysisUsage(
|
|
|
|
AnalysisUsage &AU) const {
|
2016-07-15 19:23:20 +02:00
|
|
|
LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
|
2020-11-17 19:43:02 +01:00
|
|
|
AU.addRequired<ProfileSummaryInfoWrapperPass>();
|
2016-07-15 19:23:20 +02:00
|
|
|
AU.setPreservesAll();
|
|
|
|
}
|
|
|
|
|
2016-11-23 18:53:26 +01:00
|
|
|
AnalysisKey OptimizationRemarkEmitterAnalysis::Key;
|
2016-07-18 18:29:21 +02:00
|
|
|
|
|
|
|
OptimizationRemarkEmitter
|
2016-07-20 23:44:18 +02:00
|
|
|
OptimizationRemarkEmitterAnalysis::run(Function &F,
|
2016-08-09 02:28:15 +02:00
|
|
|
FunctionAnalysisManager &AM) {
|
2016-07-18 18:29:21 +02:00
|
|
|
BlockFrequencyInfo *BFI;
|
2020-11-17 19:43:02 +01:00
|
|
|
auto &Context = F.getContext();
|
2016-07-18 18:29:21 +02:00
|
|
|
|
2020-11-17 19:43:02 +01:00
|
|
|
if (Context.getDiagnosticsHotnessRequested()) {
|
2016-07-18 18:29:21 +02:00
|
|
|
BFI = &AM.getResult<BlockFrequencyAnalysis>(F);
|
2020-11-17 19:43:02 +01:00
|
|
|
// Get hotness threshold from PSI. This should only happen once.
|
|
|
|
if (Context.isDiagnosticsHotnessThresholdSetFromPSI()) {
|
|
|
|
auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
|
|
|
|
if (ProfileSummaryInfo *PSI =
|
|
|
|
MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent()))
|
|
|
|
Context.setDiagnosticsHotnessThreshold(
|
|
|
|
PSI->getOrCompHotCountThreshold());
|
|
|
|
}
|
|
|
|
} else
|
2016-07-18 18:29:21 +02:00
|
|
|
BFI = nullptr;
|
|
|
|
|
|
|
|
return OptimizationRemarkEmitter(&F, BFI);
|
|
|
|
}
|
|
|
|
|
|
|
|
char OptimizationRemarkEmitterWrapperPass::ID = 0;
|
2016-07-15 19:23:20 +02:00
|
|
|
static const char ore_name[] = "Optimization Remark Emitter";
|
|
|
|
#define ORE_NAME "opt-remark-emitter"
|
|
|
|
|
2016-07-18 18:29:21 +02:00
|
|
|
INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
|
|
|
|
false, true)
|
2016-07-15 19:23:20 +02:00
|
|
|
INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
|
2020-11-17 19:43:02 +01:00
|
|
|
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
|
2016-07-18 18:29:21 +02:00
|
|
|
INITIALIZE_PASS_END(OptimizationRemarkEmitterWrapperPass, ORE_NAME, ore_name,
|
|
|
|
false, true)
|