summaryrefslogtreecommitdiffstats
path: root/polly/lib/CodeGen/PerfMonitor.cpp
diff options
context:
space:
mode:
authorSiddharth Bhat <siddu.druid@gmail.com>2017-06-02 08:01:22 +0000
committerSiddharth Bhat <siddu.druid@gmail.com>2017-06-02 08:01:22 +0000
commit07bee290de7569b413831c75dface6edb240a8d8 (patch)
tree68785f542fe688d058a988c82094b3ff074e641b /polly/lib/CodeGen/PerfMonitor.cpp
parentaf199153ccc5a6b6165da3ab16fe6c8ead523b88 (diff)
downloadbcm5719-llvm-07bee290de7569b413831c75dface6edb240a8d8.tar.gz
bcm5719-llvm-07bee290de7569b413831c75dface6edb240a8d8.zip
[CodeGen] Extend Performance Counter to track per-scop information.
Previously, we would generate one performance counter for all scops. Now, we generate both the old information, as well as a per-scop performance counter to generate finer grained information. This patch needed a way to generate a unique name for a `Scop`. The start region, end region, and function name combined provides a unique `Scop` name. So, `Scop` has a new public API to provide its start and end region names. Differential Revision: https://reviews.llvm.org/D33723 llvm-svn: 304528
Diffstat (limited to 'polly/lib/CodeGen/PerfMonitor.cpp')
-rw-r--r--polly/lib/CodeGen/PerfMonitor.cpp101
1 files changed, 74 insertions, 27 deletions
diff --git a/polly/lib/CodeGen/PerfMonitor.cpp b/polly/lib/CodeGen/PerfMonitor.cpp
index 7a85cd363fa..811a75acda4 100644
--- a/polly/lib/CodeGen/PerfMonitor.cpp
+++ b/polly/lib/CodeGen/PerfMonitor.cpp
@@ -11,8 +11,10 @@
#include "polly/CodeGen/PerfMonitor.h"
#include "polly/CodeGen/RuntimeDebugBuilder.h"
+#include "polly/ScopInfo.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/Intrinsics.h"
+#include <sstream>
using namespace llvm;
using namespace polly;
@@ -60,51 +62,73 @@ Function *PerfMonitor::getRDTSCP() {
return Intrinsic::getDeclaration(M, Intrinsic::x86_rdtscp);
}
-PerfMonitor::PerfMonitor(Module *M) : M(M), Builder(M->getContext()) {
+PerfMonitor::PerfMonitor(const Scop &S, Module *M)
+ : M(M), Builder(M->getContext()), S(S) {
if (Triple(M->getTargetTriple()).getArch() == llvm::Triple::x86_64)
Supported = true;
else
Supported = false;
}
-void PerfMonitor::addGlobalVariables() {
- auto TryRegisterGlobal = [=](const char *Name, Constant *InitialValue,
- Value **Location) {
- *Location = M->getGlobalVariable(Name);
+static void TryRegisterGlobal(Module *M, const char *Name,
+ Constant *InitialValue, Value **Location) {
+ *Location = M->getGlobalVariable(Name);
+
+ if (!*Location)
+ *Location = new GlobalVariable(
+ *M, InitialValue->getType(), true, GlobalValue::WeakAnyLinkage,
+ InitialValue, Name, nullptr, GlobalVariable::InitialExecTLSModel);
+};
+
+// Generate a unique name that is usable as a LLVM name for a scop to name its
+// performance counter.
+static std::string GetScopUniqueVarname(const Scop &S) {
+ std::stringstream Name;
+ std::string EntryString, ExitString;
+ std::tie(EntryString, ExitString) = S.getEntryExitStr();
+
+ Name << "__polly_perf_cycles_in_" << std::string(S.getFunction().getName())
+ << "_from__" << EntryString << "__to__" << ExitString;
+ return Name.str();
+}
- if (!*Location)
- *Location = new GlobalVariable(
- *M, InitialValue->getType(), true, GlobalValue::WeakAnyLinkage,
- InitialValue, Name, nullptr, GlobalVariable::InitialExecTLSModel);
- };
+void PerfMonitor::addScopCounter() {
+ const std::string varname = GetScopUniqueVarname(S);
+ TryRegisterGlobal(M, varname.c_str(), Builder.getInt64(0),
+ &CyclesInCurrentScopPtr);
+}
- TryRegisterGlobal("__polly_perf_cycles_total_start", Builder.getInt64(0),
+void PerfMonitor::addGlobalVariables() {
+ TryRegisterGlobal(M, "__polly_perf_cycles_total_start", Builder.getInt64(0),
&CyclesTotalStartPtr);
- TryRegisterGlobal("__polly_perf_initialized", Builder.getInt1(0),
+ TryRegisterGlobal(M, "__polly_perf_initialized", Builder.getInt1(0),
&AlreadyInitializedPtr);
- TryRegisterGlobal("__polly_perf_cycles_in_scops", Builder.getInt64(0),
+ TryRegisterGlobal(M, "__polly_perf_cycles_in_scops", Builder.getInt64(0),
&CyclesInScopsPtr);
- TryRegisterGlobal("__polly_perf_cycles_in_scop_start", Builder.getInt64(0),
+ TryRegisterGlobal(M, "__polly_perf_cycles_in_scop_start", Builder.getInt64(0),
&CyclesInScopStartPtr);
- TryRegisterGlobal("__polly_perf_write_loation", Builder.getInt32(0),
+ TryRegisterGlobal(M, "__polly_perf_write_loation", Builder.getInt32(0),
&RDTSCPWriteLocation);
}
static const char *InitFunctionName = "__polly_perf_init";
static const char *FinalReportingFunctionName = "__polly_perf_final";
+static BasicBlock *FinalStartBB = nullptr;
+static ReturnInst *ReturnFromFinal = nullptr;
+
Function *PerfMonitor::insertFinalReporting() {
// Create new function.
GlobalValue::LinkageTypes Linkage = Function::WeakODRLinkage;
FunctionType *Ty = FunctionType::get(Builder.getVoidTy(), {}, false);
Function *ExitFn =
Function::Create(Ty, Linkage, FinalReportingFunctionName, M);
- BasicBlock *Start = BasicBlock::Create(M->getContext(), "start", ExitFn);
- Builder.SetInsertPoint(Start);
+ FinalStartBB = BasicBlock::Create(M->getContext(), "start", ExitFn);
+ Builder.SetInsertPoint(FinalStartBB);
if (!Supported) {
RuntimeDebugBuilder::createCPUPrinter(
@@ -128,23 +152,42 @@ Function *PerfMonitor::insertFinalReporting() {
RuntimeDebugBuilder::createCPUPrinter(Builder, "Total: ", CyclesTotal, "\n");
RuntimeDebugBuilder::createCPUPrinter(Builder, "Scops: ", CyclesInScops,
"\n");
-
- // Finalize function.
- Builder.CreateRetVoid();
+ ReturnFromFinal = Builder.CreateRetVoid();
return ExitFn;
}
+void PerfMonitor::AppendScopReporting() {
+ Builder.SetInsertPoint(FinalStartBB);
+ ReturnFromFinal->eraseFromParent();
+
+ Value *CyclesInCurrentScop =
+ Builder.CreateLoad(this->CyclesInCurrentScopPtr, true);
+ std::string EntryName, ExitName;
+ std::tie(EntryName, ExitName) = S.getEntryExitStr();
+
+ RuntimeDebugBuilder::createCPUPrinter(
+ Builder, "Scop(", S.getFunction().getName(), " |from: ", EntryName,
+ " |to: ", ExitName, "): ", CyclesInCurrentScop, "\n");
+
+ ReturnFromFinal = Builder.CreateRetVoid();
+}
+
+static Function *FinalReporting = nullptr;
+
void PerfMonitor::initialize() {
addGlobalVariables();
+ addScopCounter();
- Function *F = M->getFunction(InitFunctionName);
- if (F)
- return;
+ // Ensure that we only add the final reporting function once.
+ // On later invocations, append to the reporting function.
+ if (!FinalReporting) {
+ FinalReporting = insertFinalReporting();
+
+ Function *InitFn = insertInitFunction(FinalReporting);
+ addToGlobalConstructors(InitFn);
+ }
- // initialize
- Function *FinalReporting = insertFinalReporting();
- Function *InitFn = insertInitFunction(FinalReporting);
- addToGlobalConstructors(InitFn);
+ AppendScopReporting();
}
Function *PerfMonitor::insertInitFunction(Function *FinalReporting) {
@@ -223,4 +266,8 @@ void PerfMonitor::insertRegionEnd(Instruction *InsertBefore) {
Value *CyclesInScops = Builder.CreateLoad(CyclesInScopsPtr, true);
CyclesInScops = Builder.CreateAdd(CyclesInScops, CyclesInScop);
Builder.CreateStore(CyclesInScops, CyclesInScopsPtr, true);
+
+ Value *CyclesInCurrentScop = Builder.CreateLoad(CyclesInCurrentScopPtr, true);
+ CyclesInCurrentScop = Builder.CreateAdd(CyclesInCurrentScop, CyclesInScop);
+ Builder.CreateStore(CyclesInCurrentScop, CyclesInCurrentScopPtr, true);
}
OpenPOWER on IntegriCloud