michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef jit_StupidAllocator_h michael@0: #define jit_StupidAllocator_h michael@0: michael@0: #include "jit/RegisterAllocator.h" michael@0: michael@0: // Simple register allocator that only carries registers within basic blocks. michael@0: michael@0: namespace js { michael@0: namespace jit { michael@0: michael@0: class StupidAllocator : public RegisterAllocator michael@0: { michael@0: static const uint32_t MAX_REGISTERS = Registers::Allocatable + FloatRegisters::Allocatable; michael@0: static const uint32_t MISSING_ALLOCATION = UINT32_MAX; michael@0: michael@0: struct AllocatedRegister { michael@0: AnyRegister reg; michael@0: michael@0: // The type of the value in the register. michael@0: LDefinition::Type type; michael@0: michael@0: // Virtual register this physical reg backs, or MISSING_ALLOCATION. michael@0: uint32_t vreg; michael@0: michael@0: // id of the instruction which most recently used this register. michael@0: uint32_t age; michael@0: michael@0: // Whether the physical register is not synced with the backing stack slot. michael@0: bool dirty; michael@0: michael@0: void set(uint32_t vreg, LInstruction *ins = nullptr, bool dirty = false) { michael@0: this->vreg = vreg; michael@0: this->age = ins ? ins->id() : 0; michael@0: this->dirty = dirty; michael@0: } michael@0: }; michael@0: michael@0: // Active allocation for the current code position. michael@0: mozilla::Array registers; michael@0: uint32_t registerCount; michael@0: michael@0: // Type indicating an index into registers. michael@0: typedef uint32_t RegisterIndex; michael@0: michael@0: // Information about each virtual register. michael@0: Vector virtualRegisters; michael@0: michael@0: public: michael@0: StupidAllocator(MIRGenerator *mir, LIRGenerator *lir, LIRGraph &graph) michael@0: : RegisterAllocator(mir, lir, graph) michael@0: { michael@0: } michael@0: michael@0: bool go(); michael@0: michael@0: private: michael@0: bool init(); michael@0: michael@0: void syncForBlockEnd(LBlock *block, LInstruction *ins); michael@0: void allocateForInstruction(LInstruction *ins); michael@0: void allocateForDefinition(LInstruction *ins, LDefinition *def); michael@0: michael@0: LAllocation *stackLocation(uint32_t vreg); michael@0: michael@0: RegisterIndex registerIndex(AnyRegister reg); michael@0: michael@0: AnyRegister ensureHasRegister(LInstruction *ins, uint32_t vreg); michael@0: RegisterIndex allocateRegister(LInstruction *ins, uint32_t vreg); michael@0: michael@0: void syncRegister(LInstruction *ins, RegisterIndex index); michael@0: void evictRegister(LInstruction *ins, RegisterIndex index); michael@0: void loadRegister(LInstruction *ins, uint32_t vreg, RegisterIndex index, LDefinition::Type type); michael@0: michael@0: RegisterIndex findExistingRegister(uint32_t vreg); michael@0: michael@0: bool allocationRequiresRegister(const LAllocation *alloc, AnyRegister reg); michael@0: bool registerIsReserved(LInstruction *ins, AnyRegister reg); michael@0: }; michael@0: michael@0: } // namespace jit michael@0: } // namespace js michael@0: michael@0: #endif /* jit_StupidAllocator_h */