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