blob: 548687f784226f8d4b035f2c245ddb7726f149d8 [file] [log] [blame]
Matthew Gharrityd9ffd0d2016-06-22 10:27:55 -07001/*
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_containers.h"
22#include "base/arena_object.h"
23#include "base/macros.h"
24#include "primitive.h"
25#include "register_allocator.h"
26
27namespace art {
28
29class CodeGenerator;
30class HBasicBlock;
31class HGraph;
32class HInstruction;
33class HParallelMove;
34class Location;
35class SsaLivenessAnalysis;
36class InterferenceNode;
Matthew Gharrity2ccae4a2016-08-12 16:10:45 +000037struct CoalesceOpportunity;
38enum class CoalesceKind;
Matthew Gharrityd9ffd0d2016-06-22 10:27:55 -070039
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 *
Matthew Gharrity2ccae4a2016-08-12 16:10:45 +000065 * 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 *
Matthew Gharrityd9ffd0d2016-06-22 10:27:55 -070084 * A good reference for graph coloring register allocation is
85 * "Modern Compiler Implementation in Java" (Andrew W. Appel, 2nd Edition).
86 */
87class RegisterAllocatorGraphColor : public RegisterAllocator {
88 public:
89 RegisterAllocatorGraphColor(ArenaAllocator* allocator,
90 CodeGenerator* codegen,
Matthew Gharrity2ccae4a2016-08-12 16:10:45 +000091 const SsaLivenessAnalysis& analysis,
92 bool iterative_move_coalescing = true);
Matthew Gharrityd9ffd0d2016-06-22 10:27:55 -070093 ~RegisterAllocatorGraphColor() OVERRIDE {}
94
95 void AllocateRegisters() OVERRIDE;
96
97 bool Validate(bool log_fatal_on_failure);
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
Matthew Gharrity2ccae4a2016-08-12 16:10:45 +0000141 bool IsCallerSave(size_t reg, bool processing_core_regs);
Matthew Gharrityd9ffd0d2016-06-22 10:27:55 -0700142
Matthew Gharrityb6722ff2016-08-12 19:07:11 -0700143 // Assigns stack slots to a list of intervals, ensuring that interfering intervals are not
144 // assigned the same stack slot.
145 void ColorSpillSlots(ArenaVector<LiveInterval*>* nodes,
146 size_t* num_stack_slots_used);
147
148 // Provide stack slots to nodes that need them.
149 void AllocateSpillSlots(const ArenaVector<InterferenceNode*>& nodes);
Matthew Gharrityd9ffd0d2016-06-22 10:27:55 -0700150
Matthew Gharrity2ccae4a2016-08-12 16:10:45 +0000151 // Whether iterative move coalescing should be performed. Iterative move coalescing
152 // improves code quality, but increases compile time.
153 const bool iterative_move_coalescing_;
154
Matthew Gharrityd9ffd0d2016-06-22 10:27:55 -0700155 // Live intervals, split by kind (core and floating point).
156 // These should not contain high intervals, as those are represented by
157 // the corresponding low interval throughout register allocation.
158 ArenaVector<LiveInterval*> core_intervals_;
159 ArenaVector<LiveInterval*> fp_intervals_;
160
161 // Intervals for temporaries, saved for special handling in the resolution phase.
162 ArenaVector<LiveInterval*> temp_intervals_;
163
164 // Safepoints, saved for special handling while processing instructions.
165 ArenaVector<HInstruction*> safepoints_;
166
Matthew Gharrity2ccae4a2016-08-12 16:10:45 +0000167 // Interference nodes representing specific registers. These are "pre-colored" nodes
Matthew Gharrityd9ffd0d2016-06-22 10:27:55 -0700168 // in the interference graph.
Matthew Gharrity2ccae4a2016-08-12 16:10:45 +0000169 ArenaVector<InterferenceNode*> physical_core_nodes_;
170 ArenaVector<InterferenceNode*> physical_fp_nodes_;
Matthew Gharrityd9ffd0d2016-06-22 10:27:55 -0700171
172 // Allocated stack slot counters.
Matthew Gharrityb6722ff2016-08-12 19:07:11 -0700173 size_t num_int_spill_slots_;
174 size_t num_double_spill_slots_;
175 size_t num_float_spill_slots_;
176 size_t num_long_spill_slots_;
Matthew Gharrityd9ffd0d2016-06-22 10:27:55 -0700177 size_t catch_phi_spill_slot_counter_;
178
179 // Number of stack slots needed for the pointer to the current method.
180 // This is 1 for 32-bit architectures, and 2 for 64-bit architectures.
181 const size_t reserved_art_method_slots_;
182
183 // Number of stack slots needed for outgoing arguments.
184 const size_t reserved_out_slots_;
185
Matthew Gharrity2ccae4a2016-08-12 16:10:45 +0000186 friend class ColoringIteration;
Matthew Gharrityd9ffd0d2016-06-22 10:27:55 -0700187
Matthew Gharrityd9ffd0d2016-06-22 10:27:55 -0700188 DISALLOW_COPY_AND_ASSIGN(RegisterAllocatorGraphColor);
189};
190
191} // namespace art
192
193#endif // ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_GRAPH_COLOR_H_