Chromium Code Reviews| Index: src/IceGlobalContext.cpp |
| diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp |
| index 8de57f3030fd4d3ace4e789030ef48123acb5df3..b7f251addc2c4166568314f8e5eb8755498cb51f 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" |
| @@ -277,6 +278,7 @@ void GlobalContext::translateFunctions() { |
| Cfg::setCurrentCfg(nullptr); |
| continue; // Func goes out of scope and gets deleted |
| } |
| + |
| Func->translate(); |
| EmitterWorkItem *Item = nullptr; |
| if (Func->hasError()) { |
| @@ -285,6 +287,7 @@ void GlobalContext::translateFunctions() { |
| getStrError() << "ICE translation error: " << Func->getFunctionName() |
| << ": " << Func->getError() << "\n"; |
| Item = new EmitterWorkItem(Func->getSequenceNumber()); |
| + Item->setGlobalInits(Func->getGlobalInits()); |
| } else { |
| Func->getAssembler<>()->setInternal(Func->getInternal()); |
| switch (getFlags().getOutFileType()) { |
| @@ -299,11 +302,15 @@ void GlobalContext::translateFunctions() { |
| // Copy relevant fields into Asm before Func is deleted. |
| Asm->setFunctionName(Func->getFunctionName()); |
| Item = new EmitterWorkItem(Func->getSequenceNumber(), Asm); |
| + Item->setGlobalInits(Func->getGlobalInits()); |
| } break; |
| case FT_Asm: |
| // The Cfg has not been emitted yet, so stats are not ready |
| // to be dumped. |
| + std::unique_ptr<VariableDeclarationList> GlobalInits = |
| + Func->getGlobalInits(); |
| Item = new EmitterWorkItem(Func->getSequenceNumber(), Func.release()); |
| + Item->setGlobalInits(std::move(GlobalInits)); |
| break; |
| } |
| } |
| @@ -316,6 +323,35 @@ void GlobalContext::translateFunctions() { |
| namespace { |
| +VariableDeclaration *blockProfileInfo(const VariableDeclarationList &Globals) { |
| + auto *Var = VariableDeclaration::create(); |
| + Var->setAlignment(8); |
| + Var->setIsConstant(true); |
| + Var->setName("__Sz_block_profile_info"); |
| + Var->setLinkage(llvm::GlobalValue::ExternalLinkage); |
| + for (const auto *Global : Globals) { |
| + if (Cfg::isProfileGlobal(*Global)) { |
| + constexpr RelocOffsetT BlockExecutionCounterOffset = 0; |
| + Var->addInitializer(new VariableDeclaration::RelocInitializer( |
| + Global, BlockExecutionCounterOffset)); |
| + } |
| + } |
| + |
| + constexpr SizeT ByteCountOf64BitNullPtr = 8; |
|
Jim Stichnoth
2015/06/09 16:39:46
I think the 8 could be typeWidthInBytes(IceType_i6
John
2015/06/09 22:01:16
Done.
|
| + Var->addInitializer( |
| + new VariableDeclaration::ZeroInitializer(ByteCountOf64BitNullPtr)); |
| + |
| + return Var; |
| +} |
| + |
| +void addBlockProfileInfoArrayToGlobals(VariableDeclarationList *Globals) { |
| + // Purposefully create the Var temp to prevent bugs in case the compiler |
| + // 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 +367,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 |
| + // embedded 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 +383,13 @@ void resizePending(std::vector<EmitterWorkItem *> &Pending, uint32_t Index) { |
| Pending.resize(Index + 1); |
| } |
| +void addAllIfNotNull(std::unique_ptr<VariableDeclarationList> src, |
| + VariableDeclarationList *dst) { |
| + if (src != nullptr) { |
| + dst->insert(dst->end(), src->begin(), src->end()); |
| + } |
| +} |
| + |
| } // end of anonymous namespace |
| void GlobalContext::emitItems() { |
| @@ -350,6 +400,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 +411,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 +425,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->getGlobalInits(), GlobalInits.get()); |
| std::unique_ptr<Assembler> Asm = Item->getAsm(); |
| Asm->alignFunction(); |
| IceString MangledName = mangleName(Asm->getFunctionName()); |
| @@ -398,6 +450,9 @@ void GlobalContext::emitItems() { |
| case EmitterWorkItem::WI_Cfg: { |
| if (!ALLOW_DUMP) |
| llvm::report_fatal_error("WI_Cfg work item created inappropriately"); |
| + |
| + addAllIfNotNull(Item->getGlobalInits(), 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 +465,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 |