diff options
| author | Siddharth Bhat <siddu.druid@gmail.com> | 2017-06-02 08:01:22 +0000 |
|---|---|---|
| committer | Siddharth Bhat <siddu.druid@gmail.com> | 2017-06-02 08:01:22 +0000 |
| commit | 07bee290de7569b413831c75dface6edb240a8d8 (patch) | |
| tree | 68785f542fe688d058a988c82094b3ff074e641b /polly/lib/CodeGen/PerfMonitor.cpp | |
| parent | af199153ccc5a6b6165da3ab16fe6c8ead523b88 (diff) | |
| download | bcm5719-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.cpp | 101 |
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); } |

