| Index: src/IceThreading.h
 | 
| diff --git a/src/IceThreading.h b/src/IceThreading.h
 | 
| index f59f46e3bad590a55b23ba71732a95f6e2a864d9..b0bcc013931aea245257ec16e9a218f0e95de538 100644
 | 
| --- a/src/IceThreading.h
 | 
| +++ b/src/IceThreading.h
 | 
| @@ -22,31 +22,29 @@
 | 
|  
 | 
|  namespace Ice {
 | 
|  
 | 
| -/// BoundedProducerConsumerQueue is a work queue that allows multiple
 | 
| -/// producers and multiple consumers.  A producer adds entries using
 | 
| -/// blockingPush(), and may block if the queue is "full".  A producer
 | 
| -/// uses notifyEnd() to indicate that no more entries will be added.  A
 | 
| -/// consumer removes an item using blockingPop(), which will return
 | 
| -/// nullptr if notifyEnd() has been called and the queue is empty (it
 | 
| -/// never returns nullptr if the queue contained any items).
 | 
| +/// BoundedProducerConsumerQueue is a work queue that allows multiple producers
 | 
| +/// and multiple consumers. A producer adds entries using blockingPush(), and
 | 
| +/// may block if the queue is "full". A producer uses notifyEnd() to indicate
 | 
| +/// that no more entries will be added. A consumer removes an item using
 | 
| +/// blockingPop(), which will return nullptr if notifyEnd() has been called and
 | 
| +/// the queue is empty (it never returns nullptr if the queue contained any
 | 
| +/// items).
 | 
|  ///
 | 
| -/// The MaxSize ctor arg controls the maximum size the queue can grow
 | 
| -/// to (subject to a hard limit of MaxStaticSize-1).  The Sequential
 | 
| -/// arg indicates purely sequential execution in which the single
 | 
| -/// thread should never wait().
 | 
| +/// The MaxSize ctor arg controls the maximum size the queue can grow to
 | 
| +/// (subject to a hard limit of MaxStaticSize-1). The Sequential arg indicates
 | 
| +/// purely sequential execution in which the single thread should never wait().
 | 
|  ///
 | 
| -/// Two condition variables are used in the implementation.
 | 
| -/// GrewOrEnded signals a waiting worker that a producer has changed
 | 
| -/// the state of the queue.  Shrunk signals a blocked producer that a
 | 
| -/// consumer has changed the state of the queue.
 | 
| +/// Two condition variables are used in the implementation. GrewOrEnded signals
 | 
| +/// a waiting worker that a producer has changed the state of the queue. Shrunk
 | 
| +/// signals a blocked producer that a consumer has changed the state of the
 | 
| +/// queue.
 | 
|  ///
 | 
| -/// The methods begin with Sequential-specific code to be most clear.
 | 
| -/// The lock and condition variables are not used in the Sequential
 | 
| -/// case.
 | 
| +/// The methods begin with Sequential-specific code to be most clear. The lock
 | 
| +/// and condition variables are not used in the Sequential case.
 | 
|  ///
 | 
|  /// Internally, the queue is implemented as a circular array of size
 | 
| -/// MaxStaticSize, where the queue boundaries are denoted by the Front
 | 
| -/// and Back fields.  Front==Back indicates an empty queue.
 | 
| +/// MaxStaticSize, where the queue boundaries are denoted by the Front and Back
 | 
| +/// fields. Front==Back indicates an empty queue.
 | 
|  template <typename T, size_t MaxStaticSize = 128>
 | 
|  class BoundedProducerConsumerQueue {
 | 
|    BoundedProducerConsumerQueue() = delete;
 | 
| @@ -60,8 +58,8 @@ public:
 | 
|    void blockingPush(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.
 | 
| +      // 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);
 | 
|      }
 | 
| @@ -103,27 +101,23 @@ private:
 | 
|    GlobalLockType Lock;
 | 
|  
 | 
|    ICE_CACHELINE_BOUNDARY;
 | 
| -  /// GrewOrEnded is written by the producers and read by the
 | 
| -  /// consumers.  It is notified (by the producer) when something is
 | 
| -  /// added to the queue, in case consumers are waiting for a non-empty
 | 
| -  /// queue.
 | 
| +  /// GrewOrEnded is written by the producers and read by the consumers. It is
 | 
| +  /// notified (by the producer) when something is added to the queue, in case
 | 
| +  /// consumers are waiting for a non-empty queue.
 | 
|    std::condition_variable GrewOrEnded;
 | 
| -  /// Back is the index into WorkItems[] of where the next element will
 | 
| -  /// be pushed.  (More precisely, Back&MaxStaticSize is the index.)
 | 
| -  /// It is written by the producers, and read by all via size() and
 | 
| -  /// empty().
 | 
| +  /// Back is the index into WorkItems[] of where the next element will be
 | 
| +  /// pushed. (More precisely, Back&MaxStaticSize is the index.) It is written
 | 
| +  /// by the producers, and read by all via size() and empty().
 | 
|    size_t Back = 0;
 | 
|  
 | 
|    ICE_CACHELINE_BOUNDARY;
 | 
| -  /// Shrunk is notified (by the consumer) when something is removed
 | 
| -  /// from the queue, in case a producer is waiting for the queue to
 | 
| -  /// drop below maximum capacity.  It is written by the consumers and
 | 
| -  /// read by the producers.
 | 
| +  /// Shrunk is notified (by the consumer) when something is removed from the
 | 
| +  /// queue, in case a producer is waiting for the queue to drop below maximum
 | 
| +  /// capacity. It is written by the consumers and read by the producers.
 | 
|    std::condition_variable Shrunk;
 | 
| -  /// Front is the index into WorkItems[] of the oldest element,
 | 
| -  /// i.e. the next to be popped.  (More precisely Front&MaxStaticSize
 | 
| -  /// is the index.)  It is written by the consumers, and read by all
 | 
| -  /// via size() and empty().
 | 
| +  /// Front is the index into WorkItems[] of the oldest element, i.e. the next
 | 
| +  /// to be popped. (More precisely Front&MaxStaticSize is the index.) It is
 | 
| +  /// written by the consumers, and read by all via size() and empty().
 | 
|    size_t Front = 0;
 | 
|  
 | 
|    ICE_CACHELINE_BOUNDARY;
 | 
| @@ -131,8 +125,7 @@ private:
 | 
|    /// MaxSize and Sequential are read by all and written by none.
 | 
|    const size_t MaxSize;
 | 
|    const bool Sequential;
 | 
| -  /// IsEnded is read by the consumers, and only written once by the
 | 
| -  /// producer.
 | 
| +  /// IsEnded is read by the consumers, and only written once by the producer.
 | 
|    bool IsEnded = false;
 | 
|  
 | 
|    /// The lock must be held when the following methods are called.
 | 
| @@ -148,15 +141,14 @@ private:
 | 
|    }
 | 
|  };
 | 
|  
 | 
| -/// EmitterWorkItem is a simple wrapper around a pointer that
 | 
| -/// represents a work item to be emitted, i.e. a function or a set of
 | 
| -/// global declarations and initializers, and it includes a sequence
 | 
| -/// number so that work items can be emitted in a particular order for
 | 
| -/// deterministic output.  It acts like an interface class, but instead
 | 
| -/// of making the classes of interest inherit from EmitterWorkItem, it
 | 
| -/// wraps pointers to these classes.  Some space is wasted compared to
 | 
| -/// storing the pointers in a union, but not too much due to the work
 | 
| -/// granularity.
 | 
| +/// EmitterWorkItem is a simple wrapper around a pointer that represents a work
 | 
| +/// item to be emitted, i.e. a function or a set of global declarations and
 | 
| +/// initializers, and it includes a sequence number so that work items can be
 | 
| +/// emitted in a particular order for deterministic output. It acts like an
 | 
| +/// interface class, but instead of making the classes of interest inherit from
 | 
| +/// EmitterWorkItem, it wraps pointers to these classes. Some space is wasted
 | 
| +/// compared to storing the pointers in a union, but not too much due to the
 | 
| +/// work granularity.
 | 
|  class EmitterWorkItem {
 | 
|    EmitterWorkItem() = delete;
 | 
|    EmitterWorkItem(const EmitterWorkItem &) = delete;
 | 
| @@ -165,20 +157,19 @@ class EmitterWorkItem {
 | 
|  public:
 | 
|    /// ItemKind can be one of the following:
 | 
|    ///
 | 
| -  /// WI_Nop: No actual work.  This is a placeholder to maintain
 | 
| -  /// sequence numbers in case there is a translation error.
 | 
| +  /// WI_Nop: No actual work. This is a placeholder to maintain sequence numbers
 | 
| +  /// in case there is a translation error.
 | 
|    ///
 | 
|    /// WI_GlobalInits: A list of global declarations and initializers.
 | 
|    ///
 | 
| -  /// WI_Asm: A function that has already had emitIAS() called on it.
 | 
| -  /// The work is transferred via the Assembler buffer, and the
 | 
| -  /// originating Cfg has been deleted (to recover lots of memory).
 | 
| +  /// WI_Asm: A function that has already had emitIAS() called on it. The work
 | 
| +  /// is transferred via the Assembler buffer, and the originating Cfg has been
 | 
| +  /// deleted (to recover lots of memory).
 | 
|    ///
 | 
| -  /// WI_Cfg: A Cfg that has not yet had emit() or emitIAS() called on
 | 
| -  /// it.  This is only used as a debugging configuration when we want
 | 
| -  /// to emit "readable" assembly code, possibly annotated with
 | 
| -  /// liveness and other information only available in the Cfg and not
 | 
| -  /// in the Assembler buffer.
 | 
| +  /// WI_Cfg: A Cfg that has not yet had emit() or emitIAS() called on it. This
 | 
| +  /// is only used as a debugging configuration when we want to emit "readable"
 | 
| +  /// assembly code, possibly annotated with liveness and other information only
 | 
| +  /// available in the Cfg and not in the Assembler buffer.
 | 
|    enum ItemKind { WI_Nop, WI_GlobalInits, WI_Asm, WI_Cfg };
 | 
|    /// Constructor for a WI_Nop work item.
 | 
|    explicit EmitterWorkItem(uint32_t Seq);
 | 
| 
 |