js/src/jit/LinearScan.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef jit_LinearScan_h
     8 #define jit_LinearScan_h
    10 #include "jit/LiveRangeAllocator.h"
    11 #include "js/Vector.h"
    13 namespace js {
    14 namespace jit {
    16 class LinearScanVirtualRegister : public VirtualRegister
    17 {
    18   private:
    19     LAllocation *canonicalSpill_;
    20     CodePosition spillPosition_ ;
    22     bool spillAtDefinition_ : 1;
    24     // This bit is used to determine whether both halves of a nunbox have been
    25     // processed by freeAllocation().
    26     bool finished_ : 1;
    28   public:
    29     LinearScanVirtualRegister(TempAllocator &alloc)
    30       : VirtualRegister(alloc)
    31     {}
    32     void setCanonicalSpill(LAllocation *alloc) {
    33         canonicalSpill_ = alloc;
    34     }
    35     LAllocation *canonicalSpill() const {
    36         return canonicalSpill_;
    37     }
    38     unsigned canonicalSpillSlot() const {
    39         return canonicalSpill_->toStackSlot()->slot();
    40     }
    41     void setFinished() {
    42         finished_ = true;
    43     }
    44     bool finished() const {
    45         return finished_;
    46     }
    47     void setSpillAtDefinition(CodePosition pos) {
    48         spillAtDefinition_ = true;
    49         setSpillPosition(pos);
    50     }
    51     bool mustSpillAtDefinition() const {
    52         return spillAtDefinition_;
    53     }
    54     CodePosition spillPosition() const {
    55         return spillPosition_;
    56     }
    57     void setSpillPosition(CodePosition pos) {
    58         spillPosition_ = pos;
    59     }
    60 };
    62 class LinearScanAllocator
    63   : private LiveRangeAllocator<LinearScanVirtualRegister, /* forLSRA = */ true>
    64 {
    65     friend class C1Spewer;
    66     friend class JSONSpewer;
    68     // Work set of LiveIntervals, sorted by start() and then by priority,
    69     // non-monotonically descending from tail to head.
    70     class UnhandledQueue : public InlineList<LiveInterval>
    71     {
    72       public:
    73         void enqueueForward(LiveInterval *after, LiveInterval *interval);
    74         void enqueueBackward(LiveInterval *interval);
    76         void assertSorted();
    78         LiveInterval *dequeue();
    79     };
    81     typedef Vector<LiveInterval *, 0, SystemAllocPolicy> SlotList;
    82     SlotList finishedSlots_;
    83     SlotList finishedDoubleSlots_;
    84 #ifdef JS_NUNBOX32
    85     SlotList finishedNunboxSlots_;
    86 #endif
    88     // Run-time state
    89     UnhandledQueue unhandled;
    90     InlineList<LiveInterval> active;
    91     InlineList<LiveInterval> inactive;
    92     InlineList<LiveInterval> fixed;
    93     InlineList<LiveInterval> handled;
    94     LiveInterval *current;
    96     bool allocateRegisters();
    97     bool resolveControlFlow();
    98     bool reifyAllocations();
    99     bool populateSafepoints();
   101     // Optimization for the UnsortedQueue.
   102     void enqueueVirtualRegisterIntervals();
   104     uint32_t allocateSlotFor(const LiveInterval *interval);
   105     bool splitInterval(LiveInterval *interval, CodePosition pos);
   106     bool splitBlockingIntervals(LAllocation allocation);
   107     bool assign(LAllocation allocation);
   108     bool spill();
   109     void freeAllocation(LiveInterval *interval, LAllocation *alloc);
   110     void finishInterval(LiveInterval *interval);
   111     AnyRegister::Code findBestFreeRegister(CodePosition *freeUntil);
   112     AnyRegister::Code findBestBlockedRegister(CodePosition *nextUsed);
   113     bool canCoexist(LiveInterval *a, LiveInterval *b);
   114     bool moveInputAlloc(CodePosition pos, LAllocation *from, LAllocation *to, LDefinition::Type type);
   115     void setIntervalRequirement(LiveInterval *interval);
   116     bool isSpilledAt(LiveInterval *interval, CodePosition pos);
   118 #ifdef DEBUG
   119     void validateIntervals();
   120     void validateAllocations();
   121 #else
   122     inline void validateIntervals() { }
   123     inline void validateAllocations() { }
   124 #endif
   126   public:
   127     LinearScanAllocator(MIRGenerator *mir, LIRGenerator *lir, LIRGraph &graph)
   128       : LiveRangeAllocator<LinearScanVirtualRegister, /* forLSRA = */ true>(mir, lir, graph)
   129     {
   130     }
   132     bool go();
   133 };
   135 } // namespace jit
   136 } // namespace js
   138 #endif /* jit_LinearScan_h */

mercurial