summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAdam Nemet <anemet@apple.com>2016-07-15 17:23:20 +0000
committerAdam Nemet <anemet@apple.com>2016-07-15 17:23:20 +0000
commitaad816083e3e0b6a195e57a9eab0fa61afea2ab5 (patch)
tree900f10703ddf216011bf6eba647993575ce19905 /llvm/lib
parent5d9a17742e5c97ef252a86cdd5dc7db5dfc04c79 (diff)
downloadbcm5719-llvm-aad816083e3e0b6a195e57a9eab0fa61afea2ab5.tar.gz
bcm5719-llvm-aad816083e3e0b6a195e57a9eab0fa61afea2ab5.zip
[OptRemark,LDist] RFC: Add hotness attribute
Summary: This is the first set of changes implementing the RFC from http://thread.gmane.org/gmane.comp.compilers.llvm.devel/98334 This is a cross-sectional patch; rather than implementing the hotness attribute for all optimization remarks and all passes in a patch set, it implements it for the 'missed-optimization' remark for Loop Distribution. My goal is to shake out the design issues before scaling it up to other types and passes. Hotness is computed as an integer as the multiplication of the block frequency with the function entry count. It's only printed in opt currently since clang prints the diagnostic fields directly. E.g.: remark: /tmp/t.c:3:3: loop not distributed: use -Rpass-analysis=loop-distribute for more info (hotness: 300) A new API added is similar to emitOptimizationRemarkMissed. The difference is that it additionally takes a code region that the diagnostic corresponds to. From this, hotness is computed using BFI. The new API is exposed via an analysis pass so that it can be made dependent on LazyBFI. (Thanks to Hal for the analysis pass idea.) This feature can all be enabled by setDiagnosticHotnessRequested in the LLVM context. If this is off, LazyBFI is not calculated (D22141) so there should be no overhead. A new command-line option is added to turn this on in opt. My plan is to switch all user of emitOptimizationRemark* to use this module instead. Reviewers: hfinkel Subscribers: rcox2, mzolotukhin, llvm-commits Differential Revision: http://reviews.llvm.org/D21771 llvm-svn: 275583
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/Analysis.cpp1
-rw-r--r--llvm/lib/Analysis/CMakeLists.txt1
-rw-r--r--llvm/lib/Analysis/OptimizationDiagnosticInfo.cpp69
-rw-r--r--llvm/lib/IR/DiagnosticInfo.cpp2
-rw-r--r--llvm/lib/IR/LLVMContext.cpp7
-rw-r--r--llvm/lib/IR/LLVMContextImpl.cpp1
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h1
-rw-r--r--llvm/lib/Transforms/Scalar/LoopDistribute.cpp16
8 files changed, 93 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/Analysis.cpp b/llvm/lib/Analysis/Analysis.cpp
index 2bcfe402e68..ffc4b2ef592 100644
--- a/llvm/lib/Analysis/Analysis.cpp
+++ b/llvm/lib/Analysis/Analysis.cpp
@@ -64,6 +64,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
initializeModuleDebugInfoPrinterPass(Registry);
initializeModuleSummaryIndexWrapperPassPass(Registry);
initializeObjCARCAAWrapperPassPass(Registry);
+ initializeOptimizationRemarkEmitterPass(Registry);
initializePostDominatorTreeWrapperPassPass(Registry);
initializeRegionInfoPassPass(Registry);
initializeRegionViewerPass(Registry);
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index 5c6011d77ce..57ad437ef4f 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -57,6 +57,7 @@ add_llvm_library(LLVMAnalysis
ObjCARCAliasAnalysis.cpp
ObjCARCAnalysisUtils.cpp
ObjCARCInstKind.cpp
+ OptimizationDiagnosticInfo.cpp
OrderedBasicBlock.cpp
PHITransAddr.cpp
PostDominators.cpp
diff --git a/llvm/lib/Analysis/OptimizationDiagnosticInfo.cpp b/llvm/lib/Analysis/OptimizationDiagnosticInfo.cpp
new file mode 100644
index 00000000000..9a22633b6e4
--- /dev/null
+++ b/llvm/lib/Analysis/OptimizationDiagnosticInfo.cpp
@@ -0,0 +1,69 @@
+//===- OptimizationDiagnosticInfo.cpp - Optimization Diagnostic -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// 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.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
+#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/LLVMContext.h"
+
+using namespace llvm;
+
+OptimizationRemarkEmitter::OptimizationRemarkEmitter() : FunctionPass(ID) {
+ initializeOptimizationRemarkEmitterPass(*PassRegistry::getPassRegistry());
+}
+
+Optional<uint64_t> OptimizationRemarkEmitter::computeHotness(Value *V) {
+ if (!BFI)
+ return None;
+
+ return BFI->getBlockProfileCount(cast<BasicBlock>(V));
+}
+
+void OptimizationRemarkEmitter::emitOptimizationRemarkMissed(
+ const char *PassName, const DebugLoc &DLoc, Value *V, const Twine &Msg) {
+ LLVMContext &Ctx = F->getContext();
+ Ctx.diagnose(DiagnosticInfoOptimizationRemarkMissed(PassName, *F, DLoc, Msg,
+ computeHotness(V)));
+}
+
+void OptimizationRemarkEmitter::emitOptimizationRemarkMissed(
+ const char *PassName, Loop *L, const Twine &Msg) {
+ emitOptimizationRemarkMissed(PassName, L->getStartLoc(), L->getHeader(), Msg);
+}
+
+bool OptimizationRemarkEmitter::runOnFunction(Function &Fn) {
+ F = &Fn;
+
+ if (Fn.getContext().getDiagnosticHotnessRequested())
+ BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
+ else
+ BFI = nullptr;
+
+ return false;
+}
+
+void OptimizationRemarkEmitter::getAnalysisUsage(AnalysisUsage &AU) const {
+ LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
+ AU.setPreservesAll();
+}
+
+char OptimizationRemarkEmitter::ID = 0;
+static const char ore_name[] = "Optimization Remark Emitter";
+#define ORE_NAME "opt-remark-emitter"
+
+INITIALIZE_PASS_BEGIN(OptimizationRemarkEmitter, ORE_NAME, ore_name, false,
+ true)
+INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
+INITIALIZE_PASS_END(OptimizationRemarkEmitter, ORE_NAME, ore_name, false, true)
diff --git a/llvm/lib/IR/DiagnosticInfo.cpp b/llvm/lib/IR/DiagnosticInfo.cpp
index a3214d72132..ce67be328ab 100644
--- a/llvm/lib/IR/DiagnosticInfo.cpp
+++ b/llvm/lib/IR/DiagnosticInfo.cpp
@@ -172,6 +172,8 @@ const std::string DiagnosticInfoWithDebugLocBase::getLocationStr() const {
void DiagnosticInfoOptimizationBase::print(DiagnosticPrinter &DP) const {
DP << getLocationStr() << ": " << getMsg();
+ if (Hotness)
+ DP << " (hotness: " << *Hotness << ")";
}
bool DiagnosticInfoOptimizationRemark::isEnabled() const {
diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp
index c7ba400ced1..d27fcfb1b7a 100644
--- a/llvm/lib/IR/LLVMContext.cpp
+++ b/llvm/lib/IR/LLVMContext.cpp
@@ -196,6 +196,13 @@ void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler,
pImpl->RespectDiagnosticFilters = RespectFilters;
}
+void LLVMContext::setDiagnosticHotnessRequested(bool Requested) {
+ pImpl->DiagnosticHotnessRequested = Requested;
+}
+bool LLVMContext::getDiagnosticHotnessRequested() const {
+ return pImpl->DiagnosticHotnessRequested;
+}
+
LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const {
return pImpl->DiagnosticHandler;
}
diff --git a/llvm/lib/IR/LLVMContextImpl.cpp b/llvm/lib/IR/LLVMContextImpl.cpp
index 3e354b5e0cf..b0b2c61bdf1 100644
--- a/llvm/lib/IR/LLVMContextImpl.cpp
+++ b/llvm/lib/IR/LLVMContextImpl.cpp
@@ -45,6 +45,7 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
DiagnosticHandler = nullptr;
DiagnosticContext = nullptr;
RespectDiagnosticFilters = false;
+ DiagnosticHotnessRequested = false;
YieldCallback = nullptr;
YieldOpaqueHandle = nullptr;
NamedStructTypesUniqueID = 0;
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index cb4e79ac74e..7820e2ab958 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1043,6 +1043,7 @@ public:
LLVMContext::DiagnosticHandlerTy DiagnosticHandler;
void *DiagnosticContext;
bool RespectDiagnosticFilters;
+ bool DiagnosticHotnessRequested;
LLVMContext::YieldCallbackTy YieldCallback;
void *YieldOpaqueHandle;
diff --git a/llvm/lib/Transforms/Scalar/LoopDistribute.cpp b/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
index 6133c251f3b..e09b33b29f7 100644
--- a/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopDistribute.cpp
@@ -26,8 +26,10 @@
#include "llvm/ADT/EquivalenceClasses.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/OptimizationDiagnosticInfo.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/Pass.h"
@@ -589,8 +591,8 @@ private:
class LoopDistributeForLoop {
public:
LoopDistributeForLoop(Loop *L, Function *F, LoopInfo *LI, DominatorTree *DT,
- ScalarEvolution *SE)
- : L(L), F(F), LI(LI), LAI(nullptr), DT(DT), SE(SE) {
+ ScalarEvolution *SE, OptimizationRemarkEmitter *ORE)
+ : L(L), F(F), LI(LI), LAI(nullptr), DT(DT), SE(SE), ORE(ORE) {
setForced();
}
@@ -757,8 +759,8 @@ public:
DEBUG(dbgs() << "Skipping; " << Message << "\n");
// With Rpass-missed report that distribution failed.
- emitOptimizationRemarkMissed(
- Ctx, LDIST_NAME, *F, L->getStartLoc(),
+ ORE->emitOptimizationRemarkMissed(
+ LDIST_NAME, L,
"loop not distributed: use -Rpass-analysis=loop-distribute for more "
"info");
@@ -847,6 +849,7 @@ private:
const LoopAccessInfo *LAI;
DominatorTree *DT;
ScalarEvolution *SE;
+ OptimizationRemarkEmitter *ORE;
/// \brief Indicates whether distribution is forced to be enabled/disabled for
/// the loop.
@@ -880,6 +883,7 @@ public:
auto *LAA = &getAnalysis<LoopAccessLegacyAnalysis>();
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
+ auto *ORE = &getAnalysis<OptimizationRemarkEmitter>();
// Build up a worklist of inner-loops to vectorize. This is necessary as the
// act of distributing a loop creates new loops and can invalidate iterators
@@ -895,7 +899,7 @@ public:
// Now walk the identified inner loops.
bool Changed = false;
for (Loop *L : Worklist) {
- LoopDistributeForLoop LDL(L, &F, LI, DT, SE);
+ LoopDistributeForLoop LDL(L, &F, LI, DT, SE, ORE);
// If distribution was forced for the specific loop to be
// enabled/disabled, follow that. Otherwise use the global flag.
@@ -914,6 +918,7 @@ public:
AU.addRequired<LoopAccessLegacyAnalysis>();
AU.addRequired<DominatorTreeWrapperPass>();
AU.addPreserved<DominatorTreeWrapperPass>();
+ AU.addRequired<OptimizationRemarkEmitter>();
}
static char ID;
@@ -933,6 +938,7 @@ INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopAccessLegacyAnalysis)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitter)
INITIALIZE_PASS_END(LoopDistribute, LDIST_NAME, ldist_name, false, false)
namespace llvm {
OpenPOWER on IntegriCloud