OSDN Git Service

Subzero. Uses unique_ptrs in the emit queue.
authorJohn Porto <jpp@chromium.org>
Tue, 15 Mar 2016 18:06:25 +0000 (11:06 -0700)
committerJohn Porto <jpp@chromium.org>
Tue, 15 Mar 2016 18:06:25 +0000 (11:06 -0700)
Because explicit memory ownership is awesome!

BUG=
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/1804133002 .

src/IceCfg.h
src/IceGlobalContext.cpp
src/IceGlobalContext.h
src/IceThreading.cpp
src/IceThreading.h
src/IceTranslator.cpp
src/IceTranslator.h

index f326cf3..95d79bc 100644 (file)
@@ -174,7 +174,9 @@ public:
   template <typename T = Assembler> T *getAssembler() const {
     return llvm::dyn_cast<T>(TargetAssembler.get());
   }
-  Assembler *releaseAssembler() { return TargetAssembler.release(); }
+  std::unique_ptr<Assembler> releaseAssembler() {
+    return std::move(TargetAssembler);
+  }
   bool hasComputedFrame() const;
   bool getFocusedTiming() const { return FocusedTiming; }
   void setFocusedTiming() { FocusedTiming = true; }
index 33e8006..505ce49 100644 (file)
@@ -319,14 +319,14 @@ void GlobalContext::translateFunctions() {
     }
 
     Func->translate();
-    EmitterWorkItem *Item = nullptr;
+    std::unique_ptr<EmitterWorkItem> 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<EmitterWorkItem>(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<EmitterWorkItem>(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<VariableDeclarationList> GlobalInits =
             Func->getGlobalInits();
-        Item = new EmitterWorkItem(Func->getSequenceNumber(), Func.release());
+        Item = makeUnique<EmitterWorkItem>(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<EmitterWorkItem *> &Pending, uint32_t Index) {
-  if (Index >= Pending.size())
-    Utils::reserveAndResize(Pending, Index + 1);
+void resizePending(std::vector<std::unique_ptr<EmitterWorkItem>> *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<EmitterWorkItem *> Pending;
+  std::vector<std::unique_ptr<EmitterWorkItem>> 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<EmitterWorkItem> Item(Pending[I]);
+      std::unique_ptr<EmitterWorkItem> Item = std::move(Pending[I]);
 
       switch (Item->getKind()) {
       case EmitterWorkItem::WI_Nop:
@@ -862,7 +866,7 @@ void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> 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<Cfg> GlobalContext::optQueueBlockingPop() {
   return std::unique_ptr<Cfg>(OptQ.blockingPop());
 }
 
-void GlobalContext::emitQueueBlockingPush(EmitterWorkItem *Item) {
+void GlobalContext::emitQueueBlockingPush(
+    std::unique_ptr<EmitterWorkItem> 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<EmitterWorkItem> GlobalContext::emitQueueBlockingPop() {
   TimerMarker _(TimerStack::TT_qEmitPop, this);
   return EmitQ.blockingPop();
 }
index 773faf3..f01ac85 100644 (file)
 
 #include <array>
 #include <functional>
+#include <memory>
 #include <mutex>
 #include <thread>
 #include <type_traits>
+#include <utility>
 #include <vector>
 
 namespace Ice {
@@ -336,8 +338,8 @@ public:
 
   void lowerJumpTables();
 
-  void emitQueueBlockingPush(EmitterWorkItem *Item);
-  EmitterWorkItem *emitQueueBlockingPop();
+  void emitQueueBlockingPush(std::unique_ptr<EmitterWorkItem> Item);
+  std::unique_ptr<EmitterWorkItem> emitQueueBlockingPop();
   void emitQueueNotifyEnd() { EmitQ.notifyEnd(); }
 
   void initParserThread() {
index f186d97..95978a1 100644 (file)
@@ -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<VariableDeclarationList> D)
+    : Sequence(Seq), Kind(WI_GlobalInits), GlobalInits(std::move(D)),
+      Function(nullptr), RawFunc(nullptr) {}
+EmitterWorkItem::EmitterWorkItem(uint32_t Seq, std::unique_ptr<Assembler> 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<Cfg> F)
     : Sequence(Seq), Kind(WI_Cfg), GlobalInits(nullptr), Function(nullptr),
-      RawFunc(F) {}
+      RawFunc(std::move(F)) {}
 
 void EmitterWorkItem::setGlobalInits(
     std::unique_ptr<VariableDeclarationList> GloblInits) {
index ecc350e..40ada47 100644 (file)
@@ -18,7 +18,9 @@
 #include "IceDefs.h"
 
 #include <condition_variable>
+#include <memory>
 #include <mutex>
+#include <utility>
 
 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<T> Item) {
     {
       std::unique_lock<GlobalLockType> 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<T> blockingPop() {
+    std::unique_ptr<T> Item;
     bool ShouldNotifyProducer = false;
     {
       std::unique_lock<GlobalLockType> L(Lock);
@@ -95,7 +97,7 @@ private:
 
   ICE_CACHELINE_BOUNDARY;
   /// WorkItems and Lock are read/written by all.
-  T *WorkItems[MaxStaticSize];
+  std::unique_ptr<T> 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<T> Item) {
+    WorkItems[Back++ & MaxStaticSizeMask] = std::move(Item);
     assert(size() <= MaxStaticSize);
   }
-  T *pop() {
+  std::unique_ptr<T> 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<VariableDeclarationList> D);
   /// Constructor for a WI_Asm work item.
-  EmitterWorkItem(uint32_t Seq, Assembler *A);
+  EmitterWorkItem(uint32_t Seq, std::unique_ptr<Assembler> A);
   /// Constructor for a WI_Cfg work item.
-  EmitterWorkItem(uint32_t Seq, Cfg *F);
+  EmitterWorkItem(uint32_t Seq, std::unique_ptr<Cfg> F);
   uint32_t getSequenceNumber() const { return Sequence; }
   ItemKind getKind() const { return Kind; }
   void setGlobalInits(std::unique_ptr<VariableDeclarationList> GloblInits);
index 01fb537..ce54c21 100644 (file)
 
 #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 <utility>
+
+namespace Ice {
 
 Translator::Translator(GlobalContext *Ctx)
     : Ctx(Ctx), NextSequenceNumber(GlobalContext::getFirstSequenceNumber()),
@@ -58,7 +60,8 @@ void Translator::translateFcn(std::unique_ptr<Cfg> Func) {
 
 void Translator::lowerGlobals(
     std::unique_ptr<VariableDeclarationList> VariableDeclarations) {
-  EmitterWorkItem *Item = new EmitterWorkItem(getNextSequenceNumber(),
-                                              VariableDeclarations.release());
-  Ctx->emitQueueBlockingPush(Item);
+  Ctx->emitQueueBlockingPush(makeUnique<EmitterWorkItem>(
+      getNextSequenceNumber(), std::move(VariableDeclarations)));
 }
+
+} // end of namespace Ice
index 1ecd998..5c62c04 100644 (file)
@@ -19,6 +19,8 @@
 #include "IceDefs.h"
 #include "IceGlobalContext.h"
 
+#include <memory>
+
 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<Cfg> Func);
 
   /// Lowers the given list of global addresses to target. Generates list of