Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Unified Diff: src/IceGlobalContext.cpp

Issue 1147023007: Subzero: Basic Block Profiler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Adds Basic Block Profiling. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceGlobalContext.cpp
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index 8de57f3030fd4d3ace4e789030ef48123acb5df3..af594b55673188e4709de8668a782ad648a9c739 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -19,6 +19,7 @@
#include "llvm/Support/Timer.h"
#include "IceCfg.h"
+#include "IceCfgNode.h"
#include "IceClFlags.h"
#include "IceDefs.h"
#include "IceELFObjectWriter.h"
@@ -255,6 +256,17 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
}
}
+namespace {
+void addCallToProfileSummary(Cfg *Func) {
+ auto *Context = Func->getContext();
+ auto *ProfileSummarySym = Context->getConstantExternSym("profile_summary");
+ constexpr bool HasTailCall = false;
Jim Stichnoth 2015/06/08 23:45:32 We've been using "const bool ..." instead of const
John 2015/06/09 15:36:18 constexpr is a compile time constant, and the comp
+ auto *Call =
+ InstCall::create(Func, 0, nullptr, ProfileSummarySym, HasTailCall);
+ Func->getEntryNode()->getInsts().push_front(Call);
+}
+} // end of namespace
Jim Stichnoth 2015/06/08 23:45:31 end of anonymous namespace
John 2015/06/09 15:36:19 Done.
+
void GlobalContext::translateFunctions() {
while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) {
// Install Func in TLS for Cfg-specific container allocators.
@@ -277,6 +289,18 @@ void GlobalContext::translateFunctions() {
Cfg::setCurrentCfg(nullptr);
continue; // Func goes out of scope and gets deleted
}
+
+ // ProfilerInits contains the VariableDeclarations for all the
Jim Stichnoth 2015/06/08 23:45:32 Would it be reasonable to move this new code into
John 2015/06/09 15:36:20 I thought about that in the beginning, but then I
+ // profiler-related symbols. If profiling is disabled, this array
+ // will be null.
+ std::unique_ptr<VariableDeclarationList> ProfilerInits;
+ if (getFlags().getEnableBlockProfile()) {
+ ProfilerInits = Func->profileBlocks();
+ if (matchSymbolName(Func->getFunctionName(), "exit")) {
Jim Stichnoth 2015/06/08 23:45:32 Does a normal return from main() lead to a call to
John 2015/06/09 15:36:19 It does, at least in the current library:
+ addCallToProfileSummary(Func.get());
+ }
+ }
+
Func->translate();
EmitterWorkItem *Item = nullptr;
if (Func->hasError()) {
@@ -309,6 +333,7 @@ void GlobalContext::translateFunctions() {
}
Cfg::setCurrentCfg(nullptr);
assert(Item);
+ Item->setProfilerInits(std::move(ProfilerInits));
emitQueueBlockingPush(Item);
// The Cfg now gets deleted as Func goes out of scope.
}
@@ -316,6 +341,31 @@ void GlobalContext::translateFunctions() {
namespace {
+VariableDeclaration *blockProfileInfo(const VariableDeclarationList &Globals) {
+ auto *Var = VariableDeclaration::create();
+ Var->setAlignment(8);
+ Var->setIsConstant(true);
+ Var->setName("block_profile_info");
+ Var->setLinkage(llvm::GlobalValue::ExternalLinkage);
+ for (const auto *Global : Globals) {
+ if (Cfg::isProfileGlobal(*Global)) {
+ Var->addInitializer(new VariableDeclaration::RelocInitializer(Global, 0));
Jim Stichnoth 2015/06/08 23:45:32 Can you "document" the 0, and the 8 a few lines do
John 2015/06/09 15:36:20 Done.
+ }
+ }
+
+ Var->addInitializer(new VariableDeclaration::ZeroInitializer(8));
+
+ return Var;
+}
+
+void addBlockProfileInfoArrayToGlobals(VariableDeclarationList *Globals) {
+ // Purposefully create the Var temp to prevent bugs in case the compilers
Jim Stichnoth 2015/06/08 23:45:32 compilers ==> compiler
John 2015/06/09 15:36:19 Done.
+ // reorders instructions in a way that Globals is extended before the call
+ // to profileInfoArray.
+ auto *Var = blockProfileInfo(*Globals);
+ Globals->push_back(Var);
+}
+
void lowerGlobals(GlobalContext *Ctx,
std::unique_ptr<VariableDeclarationList> VariableDeclarations,
TargetDataLowering *DataLowering) {
@@ -331,6 +381,13 @@ void lowerGlobals(GlobalContext *Ctx,
}
if (Ctx->getFlags().getDisableTranslation())
return;
+
+ // There should be no need to emit the block_profile_info array if profiling
+ // is disabled. In practice, given that szrt_profiler.o will always be embeded
Jim Stichnoth 2015/06/08 23:45:31 embedded
John 2015/06/09 15:36:18 Done.
+ // in the application, we need to add it. In a non-profiled build this array
+ // will only contain the nullptr terminator.
+ addBlockProfileInfoArrayToGlobals(VariableDeclarations.get());
+
DataLowering->lowerGlobals(std::move(VariableDeclarations));
}
@@ -340,6 +397,13 @@ void resizePending(std::vector<EmitterWorkItem *> &Pending, uint32_t Index) {
Pending.resize(Index + 1);
}
+void AddAllIfNotNull(std::unique_ptr<VariableDeclarationList> src,
Jim Stichnoth 2015/06/08 23:45:32 AddAllIfNotNull ==> addAllIfNotNull
John 2015/06/09 15:36:20 Done.
+ VariableDeclarationList *dst) {
+ if (src != nullptr) {
+ dst->insert(dst->end(), src->begin(), src->end());
+ }
+}
+
} // end of anonymous namespace
void GlobalContext::emitItems() {
@@ -350,6 +414,8 @@ void GlobalContext::emitItems() {
// the work queue, and if it's not the item we're waiting for, we
// insert it into Pending and repeat. The work item is deleted
// after it is processed.
+ std::unique_ptr<VariableDeclarationList> GlobalInits(
+ new VariableDeclarationList());
std::vector<EmitterWorkItem *> Pending;
uint32_t DesiredSequenceNumber = getFirstSequenceNumber();
while (true) {
@@ -359,7 +425,7 @@ void GlobalContext::emitItems() {
if (RawItem == nullptr)
RawItem = emitQueueBlockingPop();
if (RawItem == nullptr)
- return;
+ break;
uint32_t ItemSeq = RawItem->getSequenceNumber();
if (Threaded && ItemSeq != DesiredSequenceNumber) {
resizePending(Pending, ItemSeq);
@@ -373,10 +439,10 @@ void GlobalContext::emitItems() {
case EmitterWorkItem::WI_Nop:
break;
case EmitterWorkItem::WI_GlobalInits: {
- lowerGlobals(this, Item->getGlobalInits(),
- TargetDataLowering::createLowering(this).get());
+ AddAllIfNotNull(Item->getGlobalInits(), GlobalInits.get());
} break;
case EmitterWorkItem::WI_Asm: {
+ AddAllIfNotNull(Item->getProfilerInits(), GlobalInits.get());
std::unique_ptr<Assembler> Asm = Item->getAsm();
Asm->alignFunction();
IceString MangledName = mangleName(Asm->getFunctionName());
@@ -398,6 +464,9 @@ void GlobalContext::emitItems() {
case EmitterWorkItem::WI_Cfg: {
if (!ALLOW_DUMP)
llvm::report_fatal_error("WI_Cfg work item created inappropriately");
+
+ AddAllIfNotNull(Item->getProfilerInits(), GlobalInits.get());
+
assert(getFlags().getOutFileType() == FT_Asm);
std::unique_ptr<Cfg> Func = Item->getCfg();
// Unfortunately, we have to temporarily install the Cfg in TLS
@@ -410,6 +479,9 @@ void GlobalContext::emitItems() {
} break;
}
}
+
+ lowerGlobals(this, std::move(GlobalInits),
+ TargetDataLowering::createLowering(this).get());
}
// Scan a string for S[0-9A-Z]*_ patterns and replace them with

Powered by Google App Engine
This is Rietveld 408576698