| Index: runtime/vm/flow_graph_allocator.h
|
| diff --git a/runtime/vm/flow_graph_allocator.h b/runtime/vm/flow_graph_allocator.h
|
| index ad20fd3a1f085d7e8da3be88aaf6207053ed19a5..27f8fc399c02565d2073fa90a5ce2badf30d368b 100644
|
| --- a/runtime/vm/flow_graph_allocator.h
|
| +++ b/runtime/vm/flow_graph_allocator.h
|
| @@ -94,13 +94,27 @@ class FlowGraphAllocator : public ValueObject {
|
| void ProcessOneInstruction(BlockEntryInstr* block, Instruction* instr);
|
| void ConnectIncomingPhiMoves(BlockEntryInstr* block);
|
| void BlockLocation(Location loc, intptr_t from, intptr_t to);
|
| + void BlockRegisterLocation(Location loc,
|
| + intptr_t from,
|
| + intptr_t to,
|
| + bool* blocked_registers,
|
| + LiveRange** blocking_ranges);
|
| +
|
| + intptr_t NumberOfRegisters() const { return number_of_registers_; }
|
|
|
| // Find all safepoints that are covered by this live range.
|
| void AssignSafepoints(LiveRange* range);
|
|
|
| + void PrepareForAllocation(Location::Kind register_kind,
|
| + intptr_t number_of_registers,
|
| + const GrowableArray<LiveRange*>& unallocated,
|
| + LiveRange** blocking_ranges,
|
| + bool* blocked_registers);
|
| +
|
| +
|
| // Process live ranges sorted by their start and assign registers
|
| // to them
|
| - void AllocateCPURegisters();
|
| + void AllocateUnallocatedRanges();
|
| void AdvanceActiveIntervals(const intptr_t start);
|
|
|
| // Connect split siblings over non-linear control flow edges.
|
| @@ -118,6 +132,7 @@ class FlowGraphAllocator : public ValueObject {
|
| // Add live range to the list of unallocated live ranges to be processed
|
| // by the allocator.
|
| void AddToUnallocated(LiveRange* range);
|
| + void CompleteRange(LiveRange* range, Location::Kind kind);
|
| #if defined(DEBUG)
|
| bool UnallocatedIsSorted();
|
| #endif
|
| @@ -135,16 +150,16 @@ class FlowGraphAllocator : public ValueObject {
|
| // evict any interference that can be evicted by splitting and spilling
|
| // parts of interfering live ranges. Place non-spilled parts into
|
| // the list of unallocated ranges.
|
| - void AssignNonFreeRegister(LiveRange* unallocated, Register reg);
|
| + void AssignNonFreeRegister(LiveRange* unallocated, intptr_t reg);
|
| bool EvictIntersection(LiveRange* allocated, LiveRange* unallocated);
|
| - void RemoveEvicted(Register reg, intptr_t first_evicted);
|
| + void RemoveEvicted(intptr_t reg, intptr_t first_evicted);
|
|
|
| // Find first intersection between unallocated live range and
|
| // live ranges currently allocated to the given register.
|
| - intptr_t FirstIntersectionWithAllocated(Register reg,
|
| + intptr_t FirstIntersectionWithAllocated(intptr_t reg,
|
| LiveRange* unallocated);
|
|
|
| - bool UpdateFreeUntil(Register reg,
|
| + bool UpdateFreeUntil(intptr_t reg,
|
| LiveRange* unallocated,
|
| intptr_t* cur_free_until,
|
| intptr_t* cur_blocked_at);
|
| @@ -171,6 +186,10 @@ class FlowGraphAllocator : public ValueObject {
|
|
|
| MoveOperands* AddMoveAt(intptr_t pos, Location to, Location from);
|
|
|
| + Location MakeRegisterLocation(intptr_t reg) {
|
| + return Location::MachineRegisterLocation(register_kind_, reg);
|
| + }
|
| +
|
| void PrintLiveRanges();
|
|
|
| const FlowGraph& flow_graph_;
|
| @@ -204,9 +223,14 @@ class FlowGraphAllocator : public ValueObject {
|
| // LiveRanges corresponding to SSA values.
|
| GrowableArray<LiveRange*> live_ranges_;
|
|
|
| - // Worklist for register allocator. Always maintained sorted according
|
| - // to ShouldBeAllocatedBefore predicate.
|
| - GrowableArray<LiveRange*> unallocated_;
|
| + GrowableArray<LiveRange*> unallocated_cpu_;
|
| + GrowableArray<LiveRange*> unallocated_xmm_;
|
| +
|
| + LiveRange* cpu_regs_[kNumberOfCpuRegisters];
|
| + LiveRange* xmm_regs_[kNumberOfXmmRegisters];
|
| +
|
| + bool blocked_cpu_registers_[kNumberOfCpuRegisters];
|
| + bool blocked_xmm_registers_[kNumberOfXmmRegisters];
|
|
|
| #if defined(DEBUG)
|
| GrowableArray<LiveRange*> temporaries_;
|
| @@ -218,17 +242,28 @@ class FlowGraphAllocator : public ValueObject {
|
| // List of instructions containing calls.
|
| GrowableArray<Instruction*> safepoints_;
|
|
|
| + Location::Kind register_kind_;
|
| +
|
| + intptr_t number_of_registers_;
|
| +
|
| // Per register lists of allocated live ranges. Contain only those
|
| // ranges that can be affected by future allocation decisions.
|
| // Those live ranges that end before the start of the current live range are
|
| // removed from the list and will not be affected.
|
| - GrowableArray<LiveRange*> cpu_regs_[kNumberOfCpuRegisters];
|
| + GrowableArray<LiveRange*> registers_[kNumberOfCpuRegisters];
|
| +
|
| + bool blocked_registers_[kNumberOfCpuRegisters];
|
| +
|
| +
|
| + // Worklist for register allocator. Always maintained sorted according
|
| + // to ShouldBeAllocatedBefore predicate.
|
| + GrowableArray<LiveRange*> unallocated_;
|
|
|
| // List of used spill slots. Contains positions after which spill slots
|
| // become free and can be reused for allocation.
|
| GrowableArray<intptr_t> spill_slots_;
|
| + intptr_t cpu_spill_slot_count_;
|
|
|
| - bool blocked_cpu_regs_[kNumberOfCpuRegisters];
|
|
|
| DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator);
|
| };
|
| @@ -275,7 +310,9 @@ class BlockInfo : public ZoneAllocated {
|
| class UsePosition : public ZoneAllocated {
|
| public:
|
| UsePosition(intptr_t pos, UsePosition* next, Location* location_slot)
|
| - : pos_(pos), location_slot_(location_slot), hint_(NULL), next_(next) { }
|
| + : pos_(pos), location_slot_(location_slot), hint_(NULL), next_(next) {
|
| + ASSERT(location_slot != NULL);
|
| + }
|
|
|
| Location* location_slot() const { return location_slot_; }
|
| void set_location_slot(Location* location_slot) {
|
|
|