From: John Porto Date: Tue, 15 Mar 2016 18:06:25 +0000 (-0700) Subject: Subzero. Uses unique_ptrs in the emit queue. X-Git-Tag: android-x86-7.1-r1~148^2~306 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=bd2e2315b9897593b2cf804241a5e3726ec209c4;p=android-x86%2Fexternal-swiftshader.git Subzero. Uses unique_ptrs in the emit queue. Because explicit memory ownership is awesome! BUG= R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1804133002 . --- diff --git a/src/IceCfg.h b/src/IceCfg.h index f326cf3cf..95d79bcba 100644 --- a/src/IceCfg.h +++ b/src/IceCfg.h @@ -174,7 +174,9 @@ public: template T *getAssembler() const { return llvm::dyn_cast(TargetAssembler.get()); } - Assembler *releaseAssembler() { return TargetAssembler.release(); } + std::unique_ptr releaseAssembler() { + return std::move(TargetAssembler); + } bool hasComputedFrame() const; bool getFocusedTiming() const { return FocusedTiming; } void setFocusedTiming() { FocusedTiming = true; } diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp index 33e80069a..505ce497b 100644 --- a/src/IceGlobalContext.cpp +++ b/src/IceGlobalContext.cpp @@ -319,14 +319,14 @@ void GlobalContext::translateFunctions() { } Func->translate(); - EmitterWorkItem *Item = nullptr; + std::unique_ptr Item; if (Func->hasError()) { getErrorStatus()->assign(EC_Translation); OstreamLocker L(this); getStrError() << "ICE translation error: " << Func->getFunctionName() << ": " << Func->getError() << ": " << Func->getFunctionNameAndSize() << "\n"; - Item = new EmitterWorkItem(Func->getSequenceNumber()); + Item = makeUnique(Func->getSequenceNumber()); } else { Func->getAssembler<>()->setInternal(Func->getInternal()); switch (getFlags().getOutFileType()) { @@ -337,10 +337,11 @@ void GlobalContext::translateFunctions() { // stats have been fully collected into this thread's TLS. // Dump them before TLS is reset for the next Cfg. dumpStats(Func->getFunctionNameAndSize()); - Assembler *Asm = Func->releaseAssembler(); + auto Asm = Func->releaseAssembler(); // Copy relevant fields into Asm before Func is deleted. Asm->setFunctionName(Func->getFunctionName()); - Item = new EmitterWorkItem(Func->getSequenceNumber(), Asm); + Item = makeUnique(Func->getSequenceNumber(), + std::move(Asm)); Item->setGlobalInits(Func->getGlobalInits()); } break; case FT_Asm: @@ -348,13 +349,14 @@ void GlobalContext::translateFunctions() { // to be dumped. std::unique_ptr GlobalInits = Func->getGlobalInits(); - Item = new EmitterWorkItem(Func->getSequenceNumber(), Func.release()); + Item = makeUnique(Func->getSequenceNumber(), + std::move(Func)); Item->setGlobalInits(std::move(GlobalInits)); break; } } - assert(Item); - emitQueueBlockingPush(Item); + assert(Item != nullptr); + emitQueueBlockingPush(std::move(Item)); // The Cfg now gets deleted as Func goes out of scope. } } @@ -362,9 +364,10 @@ void GlobalContext::translateFunctions() { namespace { // Ensure Pending is large enough that Pending[Index] is valid. -void resizePending(std::vector &Pending, uint32_t Index) { - if (Index >= Pending.size()) - Utils::reserveAndResize(Pending, Index + 1); +void resizePending(std::vector> *Pending, + uint32_t Index) { + if (Index >= Pending->size()) + Utils::reserveAndResize(*Pending, Index + 1); } } // end of anonymous namespace @@ -471,7 +474,7 @@ 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::vector Pending; + std::vector> Pending; uint32_t DesiredSequenceNumber = getFirstSequenceNumber(); uint32_t ShuffleStartIndex = DesiredSequenceNumber; uint32_t ShuffleEndIndex = DesiredSequenceNumber; @@ -483,12 +486,11 @@ void GlobalContext::emitItems() { RandomNumberGenerator RNG(getFlags().getRandomSeed(), RPE_FunctionReordering); while (!EmitQueueEmpty) { - resizePending(Pending, DesiredSequenceNumber); + resizePending(&Pending, DesiredSequenceNumber); // See if Pending contains DesiredSequenceNumber. - EmitterWorkItem *RawItem = Pending[DesiredSequenceNumber]; - if (RawItem == nullptr) { + if (Pending[DesiredSequenceNumber] == nullptr) { // We need to fetch an EmitterWorkItem from the queue. - RawItem = emitQueueBlockingPop(); + auto RawItem = emitQueueBlockingPop(); if (RawItem == nullptr) { // This is the notifier for an empty queue. EmitQueueEmpty = true; @@ -498,16 +500,18 @@ void GlobalContext::emitItems() { if (Threaded && ItemSeq != DesiredSequenceNumber) { // Not the desired one, add it to Pending but do not increase // DesiredSequenceNumber. Continue the loop, do not emit the item. - resizePending(Pending, ItemSeq); - Pending[ItemSeq] = RawItem; + resizePending(&Pending, ItemSeq); + Pending[ItemSeq] = std::move(RawItem); continue; } // ItemSeq == DesiredSequenceNumber, we need to check if we should // emit it or not. If !Threaded, we're OK with ItemSeq != // DesiredSequenceNumber. - Pending[DesiredSequenceNumber] = RawItem; + Pending[DesiredSequenceNumber] = std::move(RawItem); } } + const auto *CurrentWorkItem = Pending[DesiredSequenceNumber].get(); + // We have the desired EmitterWorkItem or nullptr as the end notifier. // If the emitter queue is not empty, increase DesiredSequenceNumber and // ShuffleEndIndex. @@ -524,7 +528,7 @@ void GlobalContext::emitItems() { // holding an arbitrarily large GlobalDeclarationList. if (!EmitQueueEmpty && ShuffleEndIndex - ShuffleStartIndex < ShuffleWindowSize && - RawItem->getKind() != EmitterWorkItem::WI_GlobalInits) + CurrentWorkItem->getKind() != EmitterWorkItem::WI_GlobalInits) continue; // Emit the EmitterWorkItem between Pending[ShuffleStartIndex] to @@ -538,7 +542,7 @@ void GlobalContext::emitItems() { // Emit the item from ShuffleStartIndex to ShuffleEndIndex. for (uint32_t I = ShuffleStartIndex; I < ShuffleEndIndex; I++) { - std::unique_ptr Item(Pending[I]); + std::unique_ptr Item = std::move(Pending[I]); switch (Item->getKind()) { case EmitterWorkItem::WI_Nop: @@ -862,7 +866,7 @@ void GlobalContext::optQueueBlockingPush(std::unique_ptr Func) { assert(Func); { TimerMarker _(TimerStack::TT_qTransPush, this); - OptQ.blockingPush(Func.release()); + OptQ.blockingPush(std::move(Func)); } if (getFlags().isSequential()) translateFunctions(); @@ -873,17 +877,18 @@ std::unique_ptr GlobalContext::optQueueBlockingPop() { return std::unique_ptr(OptQ.blockingPop()); } -void GlobalContext::emitQueueBlockingPush(EmitterWorkItem *Item) { +void GlobalContext::emitQueueBlockingPush( + std::unique_ptr Item) { assert(Item); { TimerMarker _(TimerStack::TT_qEmitPush, this); - EmitQ.blockingPush(Item); + EmitQ.blockingPush(std::move(Item)); } if (getFlags().isSequential()) emitItems(); } -EmitterWorkItem *GlobalContext::emitQueueBlockingPop() { +std::unique_ptr GlobalContext::emitQueueBlockingPop() { TimerMarker _(TimerStack::TT_qEmitPop, this); return EmitQ.blockingPop(); } diff --git a/src/IceGlobalContext.h b/src/IceGlobalContext.h index 773faf32d..f01ac856e 100644 --- a/src/IceGlobalContext.h +++ b/src/IceGlobalContext.h @@ -28,9 +28,11 @@ #include #include +#include #include #include #include +#include #include namespace Ice { @@ -336,8 +338,8 @@ public: void lowerJumpTables(); - void emitQueueBlockingPush(EmitterWorkItem *Item); - EmitterWorkItem *emitQueueBlockingPop(); + void emitQueueBlockingPush(std::unique_ptr Item); + std::unique_ptr emitQueueBlockingPop(); void emitQueueNotifyEnd() { EmitQ.notifyEnd(); } void initParserThread() { diff --git a/src/IceThreading.cpp b/src/IceThreading.cpp index f186d972d..95978a15a 100644 --- a/src/IceThreading.cpp +++ b/src/IceThreading.cpp @@ -22,15 +22,16 @@ namespace Ice { EmitterWorkItem::EmitterWorkItem(uint32_t Seq) : Sequence(Seq), Kind(WI_Nop), GlobalInits(nullptr), Function(nullptr), RawFunc(nullptr) {} -EmitterWorkItem::EmitterWorkItem(uint32_t Seq, VariableDeclarationList *D) - : Sequence(Seq), Kind(WI_GlobalInits), GlobalInits(D), Function(nullptr), +EmitterWorkItem::EmitterWorkItem(uint32_t Seq, + std::unique_ptr D) + : Sequence(Seq), Kind(WI_GlobalInits), GlobalInits(std::move(D)), + Function(nullptr), RawFunc(nullptr) {} +EmitterWorkItem::EmitterWorkItem(uint32_t Seq, std::unique_ptr A) + : Sequence(Seq), Kind(WI_Asm), GlobalInits(nullptr), Function(std::move(A)), RawFunc(nullptr) {} -EmitterWorkItem::EmitterWorkItem(uint32_t Seq, Assembler *A) - : Sequence(Seq), Kind(WI_Asm), GlobalInits(nullptr), Function(A), - RawFunc(nullptr) {} -EmitterWorkItem::EmitterWorkItem(uint32_t Seq, Cfg *F) +EmitterWorkItem::EmitterWorkItem(uint32_t Seq, std::unique_ptr F) : Sequence(Seq), Kind(WI_Cfg), GlobalInits(nullptr), Function(nullptr), - RawFunc(F) {} + RawFunc(std::move(F)) {} void EmitterWorkItem::setGlobalInits( std::unique_ptr GloblInits) { diff --git a/src/IceThreading.h b/src/IceThreading.h index ecc350e0d..40ada47c1 100644 --- a/src/IceThreading.h +++ b/src/IceThreading.h @@ -18,7 +18,9 @@ #include "IceDefs.h" #include +#include #include +#include namespace Ice { @@ -55,18 +57,18 @@ class BoundedProducerConsumerQueue { public: BoundedProducerConsumerQueue(bool Sequential, size_t MaxSize = MaxStaticSize) : MaxSize(std::min(MaxSize, MaxStaticSize)), Sequential(Sequential) {} - void blockingPush(T *Item) { + void blockingPush(std::unique_ptr Item) { { std::unique_lock L(Lock); // If the work queue is already "full", wait for a consumer to grab an // element and shrink the queue. Shrunk.wait(L, [this] { return size() < MaxSize || Sequential; }); - push(Item); + push(std::move(Item)); } GrewOrEnded.notify_one(); } - T *blockingPop() { - T *Item = nullptr; + std::unique_ptr blockingPop() { + std::unique_ptr Item; bool ShouldNotifyProducer = false; { std::unique_lock L(Lock); @@ -95,7 +97,7 @@ private: ICE_CACHELINE_BOUNDARY; /// WorkItems and Lock are read/written by all. - T *WorkItems[MaxStaticSize]; + std::unique_ptr WorkItems[MaxStaticSize]; ICE_CACHELINE_BOUNDARY; /// Lock guards access to WorkItems, Front, Back, and IsEnded. GlobalLockType Lock; @@ -131,13 +133,13 @@ private: /// The lock must be held when the following methods are called. bool empty() const { return Front == Back; } size_t size() const { return Back - Front; } - void push(T *Item) { - WorkItems[Back++ & MaxStaticSizeMask] = Item; + void push(std::unique_ptr Item) { + WorkItems[Back++ & MaxStaticSizeMask] = std::move(Item); assert(size() <= MaxStaticSize); } - T *pop() { + std::unique_ptr pop() { assert(!empty()); - return WorkItems[Front++ & MaxStaticSizeMask]; + return std::move(WorkItems[Front++ & MaxStaticSizeMask]); } }; @@ -174,11 +176,11 @@ public: /// Constructor for a WI_Nop work item. explicit EmitterWorkItem(uint32_t Seq); /// Constructor for a WI_GlobalInits work item. - EmitterWorkItem(uint32_t Seq, VariableDeclarationList *D); + EmitterWorkItem(uint32_t Seq, std::unique_ptr D); /// Constructor for a WI_Asm work item. - EmitterWorkItem(uint32_t Seq, Assembler *A); + EmitterWorkItem(uint32_t Seq, std::unique_ptr A); /// Constructor for a WI_Cfg work item. - EmitterWorkItem(uint32_t Seq, Cfg *F); + EmitterWorkItem(uint32_t Seq, std::unique_ptr F); uint32_t getSequenceNumber() const { return Sequence; } ItemKind getKind() const { return Kind; } void setGlobalInits(std::unique_ptr GloblInits); diff --git a/src/IceTranslator.cpp b/src/IceTranslator.cpp index 01fb537c2..ce54c2184 100644 --- a/src/IceTranslator.cpp +++ b/src/IceTranslator.cpp @@ -14,13 +14,15 @@ #include "IceTranslator.h" +#include "IceDefs.h" #include "IceCfg.h" #include "IceClFlags.h" -#include "IceDefs.h" #include "IceGlobalInits.h" #include "IceTargetLowering.h" -using namespace Ice; +#include + +namespace Ice { Translator::Translator(GlobalContext *Ctx) : Ctx(Ctx), NextSequenceNumber(GlobalContext::getFirstSequenceNumber()), @@ -58,7 +60,8 @@ void Translator::translateFcn(std::unique_ptr Func) { void Translator::lowerGlobals( std::unique_ptr VariableDeclarations) { - EmitterWorkItem *Item = new EmitterWorkItem(getNextSequenceNumber(), - VariableDeclarations.release()); - Ctx->emitQueueBlockingPush(Item); + Ctx->emitQueueBlockingPush(makeUnique( + getNextSequenceNumber(), std::move(VariableDeclarations))); } + +} // end of namespace Ice diff --git a/src/IceTranslator.h b/src/IceTranslator.h index 1ecd998ca..5c62c04cf 100644 --- a/src/IceTranslator.h +++ b/src/IceTranslator.h @@ -19,6 +19,8 @@ #include "IceDefs.h" #include "IceGlobalContext.h" +#include + namespace llvm { class Module; } // end of namespace llvm @@ -48,8 +50,7 @@ public: const ClFlags &getFlags() const { return Ctx->getFlags(); } - /// Translates the constructed ICE function Fcn to machine code. Takes - /// ownership of Func. + /// Translates the constructed ICE function Func to machine code. void translateFcn(std::unique_ptr Func); /// Lowers the given list of global addresses to target. Generates list of