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/. */
6 
7 #ifndef jit_StupidAllocator_h
8 #define jit_StupidAllocator_h
9 
10 #include "jit/RegisterAllocator.h"
11 
12 // Simple register allocator that only carries registers within basic blocks.
13 
14 namespace js {
15 namespace jit {
16 
17 class StupidAllocator : public RegisterAllocator
18 {
19     static const uint32_t MAX_REGISTERS = AnyRegister::Total;
20     static const uint32_t MISSING_ALLOCATION = UINT32_MAX;
21 
22     struct AllocatedRegister {
23         AnyRegister reg;
24 
25         // The type of the value in the register.
26         LDefinition::Type type;
27 
28         // Virtual register this physical reg backs, or MISSING_ALLOCATION.
29         uint32_t vreg;
30 
31         // id of the instruction which most recently used this register.
32         uint32_t age;
33 
34         // Whether the physical register is not synced with the backing stack slot.
35         bool dirty;
36 
37         void set(uint32_t vreg, LInstruction* ins = nullptr, bool dirty = false) {
38             this->vreg = vreg;
39             this->age = ins ? ins->id() : 0;
40             this->dirty = dirty;
41         }
42     };
43 
44     // Active allocation for the current code position.
45     mozilla::Array<AllocatedRegister, MAX_REGISTERS> registers;
46     uint32_t registerCount;
47 
48     // Type indicating an index into registers.
49     typedef uint32_t RegisterIndex;
50 
51     // Information about each virtual register.
52     Vector<LDefinition*, 0, SystemAllocPolicy> virtualRegisters;
53 
54   public:
StupidAllocator(MIRGenerator * mir,LIRGenerator * lir,LIRGraph & graph)55     StupidAllocator(MIRGenerator* mir, LIRGenerator* lir, LIRGraph& graph)
56       : RegisterAllocator(mir, lir, graph)
57     {
58     }
59 
60     MOZ_MUST_USE bool go();
61 
62   private:
63     MOZ_MUST_USE bool init();
64 
65     void syncForBlockEnd(LBlock* block, LInstruction* ins);
66     void allocateForInstruction(LInstruction* ins);
67     void allocateForDefinition(LInstruction* ins, LDefinition* def);
68 
69     LAllocation* stackLocation(uint32_t vreg);
70 
71     RegisterIndex registerIndex(AnyRegister reg);
72 
73     AnyRegister ensureHasRegister(LInstruction* ins, uint32_t vreg);
74     RegisterIndex allocateRegister(LInstruction* ins, uint32_t vreg);
75 
76     void syncRegister(LInstruction* ins, RegisterIndex index);
77     void evictRegister(LInstruction* ins, RegisterIndex index);
78     void evictAliasedRegister(LInstruction* ins, RegisterIndex index);
79     void loadRegister(LInstruction* ins, uint32_t vreg, RegisterIndex index, LDefinition::Type type);
80 
81     RegisterIndex findExistingRegister(uint32_t vreg);
82 
83     bool allocationRequiresRegister(const LAllocation* alloc, AnyRegister reg);
84     bool registerIsReserved(LInstruction* ins, AnyRegister reg);
85 };
86 
87 } // namespace jit
88 } // namespace js
89 
90 #endif /* jit_StupidAllocator_h */
91