From 2aaa4b5532d30c4e65d8892b556400bb61f9dc8c Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Thu, 17 Sep 2015 17:03:26 +0100 Subject: Optimizing: Tag more arena allocations. Replace GrowableArray with ArenaVector and tag arena allocations with new allocation types. As part of this, make the register allocator a bit more efficient, doing bulk insert/erase. Some loops are now O(n) instead of O(n^2). Change-Id: Ifac0871ffb34b121cc0447801a2d07eefd308c14 --- compiler/optimizing/register_allocator.h | 49 ++++++++++++++------------------ 1 file changed, 21 insertions(+), 28 deletions(-) (limited to 'compiler/optimizing/register_allocator.h') diff --git a/compiler/optimizing/register_allocator.h b/compiler/optimizing/register_allocator.h index e0304643e6..58600b789b 100644 --- a/compiler/optimizing/register_allocator.h +++ b/compiler/optimizing/register_allocator.h @@ -18,9 +18,9 @@ #define ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_H_ #include "arch/instruction_set.h" +#include "base/arena_containers.h" #include "base/macros.h" #include "primitive.h" -#include "utils/growable_array.h" namespace art { @@ -59,7 +59,7 @@ class RegisterAllocator { } // Helper method for validation. Used by unit testing. - static bool ValidateIntervals(const GrowableArray& intervals, + static bool ValidateIntervals(const ArenaVector& intervals, size_t number_of_spill_slots, size_t number_of_out_slots, const CodeGenerator& codegen, @@ -70,10 +70,10 @@ class RegisterAllocator { static bool CanAllocateRegistersFor(const HGraph& graph, InstructionSet instruction_set); size_t GetNumberOfSpillSlots() const { - return int_spill_slots_.Size() - + long_spill_slots_.Size() - + float_spill_slots_.Size() - + double_spill_slots_.Size() + return int_spill_slots_.size() + + long_spill_slots_.size() + + float_spill_slots_.size() + + double_spill_slots_.size() + catch_phi_spill_slots_; } @@ -87,7 +87,7 @@ class RegisterAllocator { void Resolve(); // Add `interval` in the given sorted list. - static void AddSorted(GrowableArray* array, LiveInterval* interval); + static void AddSorted(ArenaVector* array, LiveInterval* interval); // Split `interval` at the position `position`. The new interval starts at `position`. LiveInterval* Split(LiveInterval* interval, size_t position); @@ -159,13 +159,6 @@ class RegisterAllocator { size_t first_register_use, size_t* next_use); - // If `interval` has another half, remove it from the list of `intervals`. - // `index` holds the index at which `interval` is in `intervals`. - // Returns whether there is another half. - bool PotentiallyRemoveOtherHalf(LiveInterval* interval, - GrowableArray* intervals, - size_t index); - ArenaAllocator* const allocator_; CodeGenerator* const codegen_; const SsaLivenessAnalysis& liveness_; @@ -173,43 +166,43 @@ class RegisterAllocator { // List of intervals for core registers that must be processed, ordered by start // position. Last entry is the interval that has the lowest start position. // This list is initially populated before doing the linear scan. - GrowableArray unhandled_core_intervals_; + ArenaVector unhandled_core_intervals_; // List of intervals for floating-point registers. Same comments as above. - GrowableArray unhandled_fp_intervals_; + ArenaVector unhandled_fp_intervals_; // Currently processed list of unhandled intervals. Either `unhandled_core_intervals_` // or `unhandled_fp_intervals_`. - GrowableArray* unhandled_; + ArenaVector* unhandled_; // List of intervals that have been processed. - GrowableArray handled_; + ArenaVector handled_; // List of intervals that are currently active when processing a new live interval. // That is, they have a live range that spans the start of the new interval. - GrowableArray active_; + ArenaVector active_; // List of intervals that are currently inactive when processing a new live interval. // That is, they have a lifetime hole that spans the start of the new interval. - GrowableArray inactive_; + ArenaVector inactive_; // Fixed intervals for physical registers. Such intervals cover the positions // where an instruction requires a specific register. - GrowableArray physical_core_register_intervals_; - GrowableArray physical_fp_register_intervals_; + ArenaVector physical_core_register_intervals_; + ArenaVector physical_fp_register_intervals_; // Intervals for temporaries. Such intervals cover the positions // where an instruction requires a temporary. - GrowableArray temp_intervals_; + ArenaVector temp_intervals_; // The spill slots allocated for live intervals. We ensure spill slots // are typed to avoid (1) doing moves and swaps between two different kinds // of registers, and (2) swapping between a single stack slot and a double // stack slot. This simplifies the parallel move resolver. - GrowableArray int_spill_slots_; - GrowableArray long_spill_slots_; - GrowableArray float_spill_slots_; - GrowableArray double_spill_slots_; + ArenaVector int_spill_slots_; + ArenaVector long_spill_slots_; + ArenaVector float_spill_slots_; + ArenaVector double_spill_slots_; // Spill slots allocated to catch phis. This category is special-cased because // (1) slots are allocated prior to linear scan and in reverse linear order, @@ -217,7 +210,7 @@ class RegisterAllocator { size_t catch_phi_spill_slots_; // Instructions that need a safepoint. - GrowableArray safepoints_; + ArenaVector safepoints_; // True if processing core registers. False if processing floating // point registers. -- cgit v1.2.3-59-g8ed1b