1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_GRAPH_COLOR_H_ 18 #define ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_GRAPH_COLOR_H_ 19 20 #include "arch/instruction_set.h" 21 #include "base/arena_object.h" 22 #include "base/array_ref.h" 23 #include "base/macros.h" 24 #include "base/scoped_arena_containers.h" 25 #include "register_allocator.h" 26 27 namespace art { 28 29 class CodeGenerator; 30 class HBasicBlock; 31 class HGraph; 32 class HInstruction; 33 class HParallelMove; 34 class Location; 35 class SsaLivenessAnalysis; 36 class InterferenceNode; 37 struct CoalesceOpportunity; 38 enum class CoalesceKind; 39 40 /** 41 * A graph coloring register allocator. 42 * 43 * The algorithm proceeds as follows: 44 * (1) Build an interference graph, where nodes represent live intervals, and edges represent 45 * interferences between two intervals. Coloring this graph with k colors is isomorphic to 46 * finding a valid register assignment with k registers. 47 * (2) To color the graph, first prune all nodes with degree less than k, since these nodes are 48 * guaranteed a color. (No matter how we color their adjacent nodes, we can give them a 49 * different color.) As we prune nodes from the graph, more nodes may drop below degree k, 50 * enabling further pruning. The key is to maintain the pruning order in a stack, so that we 51 * can color the nodes in the reverse order. 52 * When there are no more nodes with degree less than k, we start pruning alternate nodes based 53 * on heuristics. Since these nodes are not guaranteed a color, we are careful to 54 * prioritize nodes that require a register. We also prioritize short intervals, because 55 * short intervals cannot be split very much if coloring fails (see below). "Prioritizing" 56 * a node amounts to pruning it later, since it will have fewer interferences if we prune other 57 * nodes first. 58 * (3) We color nodes in the reverse order in which we pruned them. If we cannot assign 59 * a node a color, we do one of two things: 60 * - If the node requires a register, we consider the current coloring attempt a failure. 61 * However, we split the node's live interval in order to make the interference graph 62 * sparser, so that future coloring attempts may succeed. 63 * - If the node does not require a register, we simply assign it a location on the stack. 64 * 65 * If iterative move coalescing is enabled, the algorithm also attempts to conservatively 66 * combine nodes in the graph that would prefer to have the same color. (For example, the output 67 * of a phi instruction would prefer to have the same register as at least one of its inputs.) 68 * There are several additional steps involved with this: 69 * - We look for coalesce opportunities by examining each live interval, a step similar to that 70 * used by linear scan when looking for register hints. 71 * - When pruning the graph, we maintain a worklist of coalesce opportunities, as well as a worklist 72 * of low degree nodes that have associated coalesce opportunities. Only when we run out of 73 * coalesce opportunities do we start pruning coalesce-associated nodes. 74 * - When pruning a node, if any nodes transition from high degree to low degree, we add 75 * associated coalesce opportunities to the worklist, since these opportunities may now succeed. 76 * - Whether two nodes can be combined is decided by two different heuristics--one used when 77 * coalescing uncolored nodes, and one used for coalescing an uncolored node with a colored node. 78 * It is vital that we only combine two nodes if the node that remains is guaranteed to receive 79 * a color. This is because additionally spilling is more costly than failing to coalesce. 80 * - Even if nodes are not coalesced while pruning, we keep the coalesce opportunities around 81 * to be used as last-chance register hints when coloring. If nothing else, we try to use 82 * caller-save registers before callee-save registers. 83 * 84 * A good reference for graph coloring register allocation is 85 * "Modern Compiler Implementation in Java" (Andrew W. Appel, 2nd Edition). 86 */ 87 class RegisterAllocatorGraphColor : public RegisterAllocator { 88 public: 89 RegisterAllocatorGraphColor(ScopedArenaAllocator* allocator, 90 CodeGenerator* codegen, 91 const SsaLivenessAnalysis& analysis, 92 bool iterative_move_coalescing = true); 93 ~RegisterAllocatorGraphColor() override; 94 95 void AllocateRegisters() override; 96 97 bool Validate(bool log_fatal_on_failure) override; 98 99 private: 100 // Collect all intervals and prepare for register allocation. 101 void ProcessInstructions(); 102 void ProcessInstruction(HInstruction* instruction); 103 104 // If any inputs require specific registers, block those registers 105 // at the position of this instruction. 106 void CheckForFixedInputs(HInstruction* instruction); 107 108 // If the output of an instruction requires a specific register, split 109 // the interval and assign the register to the first part. 110 void CheckForFixedOutput(HInstruction* instruction); 111 112 // Add all applicable safepoints to a live interval. 113 // Currently depends on instruction processing order. 114 void AddSafepointsFor(HInstruction* instruction); 115 116 // Collect all live intervals associated with the temporary locations 117 // needed by an instruction. 118 void CheckForTempLiveIntervals(HInstruction* instruction); 119 120 // If a safe point is needed, add a synthesized interval to later record 121 // the number of live registers at this point. 122 void CheckForSafepoint(HInstruction* instruction); 123 124 // Split an interval, but only if `position` is inside of `interval`. 125 // Return either the new interval, or the original interval if not split. 126 static LiveInterval* TrySplit(LiveInterval* interval, size_t position); 127 128 // To ensure every graph can be colored, split live intervals 129 // at their register defs and uses. This creates short intervals with low 130 // degree in the interference graph, which are prioritized during graph 131 // coloring. 132 void SplitAtRegisterUses(LiveInterval* interval); 133 134 // If the given instruction is a catch phi, give it a spill slot. 135 void AllocateSpillSlotForCatchPhi(HInstruction* instruction); 136 137 // Ensure that the given register cannot be allocated for a given range. 138 void BlockRegister(Location location, size_t start, size_t end); 139 void BlockRegisters(size_t start, size_t end, bool caller_save_only = false); 140 141 bool IsCallerSave(size_t reg, bool processing_core_regs); 142 143 // Assigns stack slots to a list of intervals, ensuring that interfering intervals are not 144 // assigned the same stack slot. 145 void ColorSpillSlots(ArrayRef<LiveInterval* const> nodes, /* out */ size_t* num_stack_slots_used); 146 147 // Provide stack slots to nodes that need them. 148 void AllocateSpillSlots(ArrayRef<InterferenceNode* const> nodes); 149 150 // Whether iterative move coalescing should be performed. Iterative move coalescing 151 // improves code quality, but increases compile time. 152 const bool iterative_move_coalescing_; 153 154 // Live intervals, split by kind (core and floating point). 155 // These should not contain high intervals, as those are represented by 156 // the corresponding low interval throughout register allocation. 157 ScopedArenaVector<LiveInterval*> core_intervals_; 158 ScopedArenaVector<LiveInterval*> fp_intervals_; 159 160 // Intervals for temporaries, saved for special handling in the resolution phase. 161 ScopedArenaVector<LiveInterval*> temp_intervals_; 162 163 // Safepoints, saved for special handling while processing instructions. 164 ScopedArenaVector<HInstruction*> safepoints_; 165 166 // Interference nodes representing specific registers. These are "pre-colored" nodes 167 // in the interference graph. 168 ScopedArenaVector<InterferenceNode*> physical_core_nodes_; 169 ScopedArenaVector<InterferenceNode*> physical_fp_nodes_; 170 171 // Allocated stack slot counters. 172 size_t num_int_spill_slots_; 173 size_t num_double_spill_slots_; 174 size_t num_float_spill_slots_; 175 size_t num_long_spill_slots_; 176 size_t catch_phi_spill_slot_counter_; 177 178 // Number of stack slots needed for the pointer to the current method. 179 // This is 1 for 32-bit architectures, and 2 for 64-bit architectures. 180 const size_t reserved_art_method_slots_; 181 182 // Number of stack slots needed for outgoing arguments. 183 const size_t reserved_out_slots_; 184 185 friend class ColoringIteration; 186 187 DISALLOW_COPY_AND_ASSIGN(RegisterAllocatorGraphColor); 188 }; 189 190 } // namespace art 191 192 #endif // ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_GRAPH_COLOR_H_ 193