annotate src/share/vm/c1/c1_LinearScan.hpp @ 1721:413ad0331a0c

6977924: Changes for 6975078 produce build error with certain gcc versions Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error. Reviewed-by: jcoomes, ysr, phh
author johnc
date Wed, 18 Aug 2010 10:59:06 -0700
parents b812ff5abc73
children f02a8bbe6ed4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 337
diff changeset
2 * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 337
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 337
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 337
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 class DebugInfoCache;
a61af66fc99e Initial load
duke
parents:
diff changeset
26 class FpuStackAllocator;
a61af66fc99e Initial load
duke
parents:
diff changeset
27 class IRScopeDebugInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
28 class Interval;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 class IntervalWalker;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 class LIRGenerator;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 class LinearScan;
a61af66fc99e Initial load
duke
parents:
diff changeset
32 class MoveResolver;
a61af66fc99e Initial load
duke
parents:
diff changeset
33 class Range;
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 define_array(IntervalArray, Interval*)
a61af66fc99e Initial load
duke
parents:
diff changeset
36 define_stack(IntervalList, IntervalArray)
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 define_array(IntervalsArray, IntervalList*)
a61af66fc99e Initial load
duke
parents:
diff changeset
39 define_stack(IntervalsList, IntervalsArray)
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 define_array(OopMapArray, OopMap*)
a61af66fc99e Initial load
duke
parents:
diff changeset
42 define_stack(OopMapList, OopMapArray)
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 define_array(ScopeValueArray, ScopeValue*)
a61af66fc99e Initial load
duke
parents:
diff changeset
45
a61af66fc99e Initial load
duke
parents:
diff changeset
46 define_array(LIR_OpListArray, LIR_OpList*);
a61af66fc99e Initial load
duke
parents:
diff changeset
47 define_stack(LIR_OpListStack, LIR_OpListArray);
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 enum IntervalUseKind {
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // priority of use kinds must be ascending
a61af66fc99e Initial load
duke
parents:
diff changeset
52 noUse = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
53 loopEndMarker = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
54 shouldHaveRegister = 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
55 mustHaveRegister = 3,
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 firstValidKind = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
58 lastValidKind = 3
a61af66fc99e Initial load
duke
parents:
diff changeset
59 };
a61af66fc99e Initial load
duke
parents:
diff changeset
60 define_array(UseKindArray, IntervalUseKind)
a61af66fc99e Initial load
duke
parents:
diff changeset
61 define_stack(UseKindStack, UseKindArray)
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 enum IntervalKind {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 fixedKind = 0, // interval pre-colored by LIR_Generator
a61af66fc99e Initial load
duke
parents:
diff changeset
66 anyKind = 1, // no register/memory allocated by LIR_Generator
a61af66fc99e Initial load
duke
parents:
diff changeset
67 nofKinds,
a61af66fc99e Initial load
duke
parents:
diff changeset
68 firstKind = fixedKind
a61af66fc99e Initial load
duke
parents:
diff changeset
69 };
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // during linear scan an interval is in one of four states in
a61af66fc99e Initial load
duke
parents:
diff changeset
73 enum IntervalState {
a61af66fc99e Initial load
duke
parents:
diff changeset
74 unhandledState = 0, // unhandled state (not processed yet)
a61af66fc99e Initial load
duke
parents:
diff changeset
75 activeState = 1, // life and is in a physical register
a61af66fc99e Initial load
duke
parents:
diff changeset
76 inactiveState = 2, // in a life time hole and is in a physical register
a61af66fc99e Initial load
duke
parents:
diff changeset
77 handledState = 3, // spilled or not life again
a61af66fc99e Initial load
duke
parents:
diff changeset
78 invalidState = -1
a61af66fc99e Initial load
duke
parents:
diff changeset
79 };
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 enum IntervalSpillState {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 noDefinitionFound, // starting state of calculation: no definition found yet
a61af66fc99e Initial load
duke
parents:
diff changeset
84 oneDefinitionFound, // one definition has already been found.
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // Note: two consecutive definitions are treated as one (e.g. consecutive move and add because of two-operand LIR form)
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // the position of this definition is stored in _definition_pos
a61af66fc99e Initial load
duke
parents:
diff changeset
87 oneMoveInserted, // one spill move has already been inserted.
a61af66fc99e Initial load
duke
parents:
diff changeset
88 storeAtDefinition, // the interval should be stored immediately after its definition because otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // there would be multiple redundant stores
a61af66fc99e Initial load
duke
parents:
diff changeset
90 startInMemory, // the interval starts in memory (e.g. method parameter), so a store is never necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
91 noOptimization // the interval has more then one definition (e.g. resulting from phi moves), so stores to memory are not optimized
a61af66fc99e Initial load
duke
parents:
diff changeset
92 };
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 #define for_each_interval_kind(kind) \
a61af66fc99e Initial load
duke
parents:
diff changeset
96 for (IntervalKind kind = firstKind; kind < nofKinds; kind = (IntervalKind)(kind + 1))
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 #define for_each_visitor_mode(mode) \
a61af66fc99e Initial load
duke
parents:
diff changeset
99 for (LIR_OpVisitState::OprMode mode = LIR_OpVisitState::firstMode; mode < LIR_OpVisitState::numModes; mode = (LIR_OpVisitState::OprMode)(mode + 1))
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 class LinearScan : public CompilationResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // declare classes used by LinearScan as friends because they
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // need a wide variety of functions declared here
a61af66fc99e Initial load
duke
parents:
diff changeset
105 //
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // Only the small interface to the rest of the compiler is public
a61af66fc99e Initial load
duke
parents:
diff changeset
107 friend class Interval;
a61af66fc99e Initial load
duke
parents:
diff changeset
108 friend class IntervalWalker;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 friend class LinearScanWalker;
a61af66fc99e Initial load
duke
parents:
diff changeset
110 friend class FpuStackAllocator;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 friend class MoveResolver;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 friend class LinearScanStatistic;
a61af66fc99e Initial load
duke
parents:
diff changeset
113 friend class LinearScanTimers;
a61af66fc99e Initial load
duke
parents:
diff changeset
114 friend class RegisterVerifier;
a61af66fc99e Initial load
duke
parents:
diff changeset
115
a61af66fc99e Initial load
duke
parents:
diff changeset
116 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
117 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 any_reg = -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
119 nof_cpu_regs = pd_nof_cpu_regs_linearscan,
a61af66fc99e Initial load
duke
parents:
diff changeset
120 nof_fpu_regs = pd_nof_fpu_regs_linearscan,
a61af66fc99e Initial load
duke
parents:
diff changeset
121 nof_xmm_regs = pd_nof_xmm_regs_linearscan,
a61af66fc99e Initial load
duke
parents:
diff changeset
122 nof_regs = nof_cpu_regs + nof_fpu_regs + nof_xmm_regs
a61af66fc99e Initial load
duke
parents:
diff changeset
123 };
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
126 Compilation* _compilation;
a61af66fc99e Initial load
duke
parents:
diff changeset
127 IR* _ir;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 LIRGenerator* _gen;
a61af66fc99e Initial load
duke
parents:
diff changeset
129 FrameMap* _frame_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 BlockList _cached_blocks; // cached list with all blocks in linear-scan order (only correct if original list keeps unchanged)
a61af66fc99e Initial load
duke
parents:
diff changeset
132 int _num_virtual_regs; // number of virtual registers (without new registers introduced because of splitting intervals)
a61af66fc99e Initial load
duke
parents:
diff changeset
133 bool _has_fpu_registers; // true if this method uses any floating point registers (and so fpu stack allocation is necessary)
a61af66fc99e Initial load
duke
parents:
diff changeset
134 int _num_calls; // total number of calls in this method
a61af66fc99e Initial load
duke
parents:
diff changeset
135 int _max_spills; // number of stack slots used for intervals allocated to memory
a61af66fc99e Initial load
duke
parents:
diff changeset
136 int _unused_spill_slot; // unused spill slot for a single-word value because of alignment of a double-word value
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 IntervalList _intervals; // mapping from register number to interval
a61af66fc99e Initial load
duke
parents:
diff changeset
139 IntervalList* _new_intervals_from_allocation; // list with all intervals created during allocation when an existing interval is split
a61af66fc99e Initial load
duke
parents:
diff changeset
140 IntervalArray* _sorted_intervals; // intervals sorted by Interval::from()
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 LIR_OpArray _lir_ops; // mapping from LIR_Op id to LIR_Op node
a61af66fc99e Initial load
duke
parents:
diff changeset
143 BlockBeginArray _block_of_op; // mapping from LIR_Op id to the BlockBegin containing this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
144 BitMap _has_info; // bit set for each LIR_Op id that has a CodeEmitInfo
a61af66fc99e Initial load
duke
parents:
diff changeset
145 BitMap _has_call; // bit set for each LIR_Op id that destroys all caller save registers
a61af66fc99e Initial load
duke
parents:
diff changeset
146 BitMap2D _interval_in_loop; // bit set for each virtual register that is contained in each loop
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // cached debug info to prevent multiple creation of same object
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // TODO: cached scope values for registers could be static
a61af66fc99e Initial load
duke
parents:
diff changeset
150 ScopeValueArray _scope_value_cache;
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 static ConstantOopWriteValue _oop_null_scope_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 static ConstantIntValue _int_m1_scope_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
154 static ConstantIntValue _int_0_scope_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
155 static ConstantIntValue _int_1_scope_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
156 static ConstantIntValue _int_2_scope_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
159 IR* ir() const { return _ir; }
a61af66fc99e Initial load
duke
parents:
diff changeset
160 Compilation* compilation() const { return _compilation; }
a61af66fc99e Initial load
duke
parents:
diff changeset
161 LIRGenerator* gen() const { return _gen; }
a61af66fc99e Initial load
duke
parents:
diff changeset
162 FrameMap* frame_map() const { return _frame_map; }
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // unified bailout support
a61af66fc99e Initial load
duke
parents:
diff changeset
165 void bailout(const char* msg) const { compilation()->bailout(msg); }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 bool bailed_out() const { return compilation()->bailed_out(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // access to block list (sorted in linear scan order)
a61af66fc99e Initial load
duke
parents:
diff changeset
169 int block_count() const { assert(_cached_blocks.length() == ir()->linear_scan_order()->length(), "invalid cached block list"); return _cached_blocks.length(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
170 BlockBegin* block_at(int idx) const { assert(_cached_blocks.at(idx) == ir()->linear_scan_order()->at(idx), "invalid cached block list"); return _cached_blocks.at(idx); }
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 int num_virtual_regs() const { return _num_virtual_regs; }
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // size of live_in and live_out sets of BasicBlocks (BitMap needs rounded size for iteration)
a61af66fc99e Initial load
duke
parents:
diff changeset
174 int live_set_size() const { return round_to(_num_virtual_regs, BitsPerWord); }
a61af66fc99e Initial load
duke
parents:
diff changeset
175 bool has_fpu_registers() const { return _has_fpu_registers; }
a61af66fc99e Initial load
duke
parents:
diff changeset
176 int num_loops() const { return ir()->num_loops(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
177 bool is_interval_in_loop(int interval, int loop) const { return _interval_in_loop.at(interval, loop); }
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // handling of fpu stack allocation (platform dependent, needed for debug information generation)
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
180 #ifdef X86
0
a61af66fc99e Initial load
duke
parents:
diff changeset
181 FpuStackAllocator* _fpu_stack_allocator;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 bool use_fpu_stack_allocation() const { return UseSSE < 2 && has_fpu_registers(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
183 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
184 bool use_fpu_stack_allocation() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
185 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // access to interval list
a61af66fc99e Initial load
duke
parents:
diff changeset
189 int interval_count() const { return _intervals.length(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
190 Interval* interval_at(int reg_num) const { return _intervals.at(reg_num); }
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 IntervalList* new_intervals_from_allocation() const { return _new_intervals_from_allocation; }
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // access to LIR_Ops and Blocks indexed by op_id
a61af66fc99e Initial load
duke
parents:
diff changeset
195 int max_lir_op_id() const { assert(_lir_ops.length() > 0, "no operations"); return (_lir_ops.length() - 1) << 1; }
a61af66fc99e Initial load
duke
parents:
diff changeset
196 LIR_Op* lir_op_with_id(int op_id) const { assert(op_id >= 0 && op_id <= max_lir_op_id() && op_id % 2 == 0, "op_id out of range or not even"); return _lir_ops.at(op_id >> 1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
197 BlockBegin* block_of_op_with_id(int op_id) const { assert(_block_of_op.length() > 0 && op_id >= 0 && op_id <= max_lir_op_id() + 1, "op_id out of range"); return _block_of_op.at(op_id >> 1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
198
a61af66fc99e Initial load
duke
parents:
diff changeset
199 bool is_block_begin(int op_id) { return op_id == 0 || block_of_op_with_id(op_id) != block_of_op_with_id(op_id - 1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
200 bool covers_block_begin(int op_id_1, int op_id_2) { return block_of_op_with_id(op_id_1) != block_of_op_with_id(op_id_2); }
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 bool has_call(int op_id) { assert(op_id % 2 == 0, "must be even"); return _has_call.at(op_id >> 1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 bool has_info(int op_id) { assert(op_id % 2 == 0, "must be even"); return _has_info.at(op_id >> 1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // functions for converting LIR-Operands to register numbers
a61af66fc99e Initial load
duke
parents:
diff changeset
207 static bool is_valid_reg_num(int reg_num) { return reg_num >= 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
208 static int reg_num(LIR_Opr opr);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 static int reg_numHi(LIR_Opr opr);
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // functions for classification of intervals
a61af66fc99e Initial load
duke
parents:
diff changeset
212 static bool is_precolored_interval(const Interval* i);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 static bool is_virtual_interval(const Interval* i);
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 static bool is_precolored_cpu_interval(const Interval* i);
a61af66fc99e Initial load
duke
parents:
diff changeset
216 static bool is_virtual_cpu_interval(const Interval* i);
a61af66fc99e Initial load
duke
parents:
diff changeset
217 static bool is_precolored_fpu_interval(const Interval* i);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 static bool is_virtual_fpu_interval(const Interval* i);
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 static bool is_in_fpu_register(const Interval* i);
a61af66fc99e Initial load
duke
parents:
diff changeset
221 static bool is_oop_interval(const Interval* i);
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // General helper functions
a61af66fc99e Initial load
duke
parents:
diff changeset
225 int allocate_spill_slot(bool double_word);
a61af66fc99e Initial load
duke
parents:
diff changeset
226 void assign_spill_slot(Interval* it);
a61af66fc99e Initial load
duke
parents:
diff changeset
227 void propagate_spill_slots();
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 Interval* create_interval(int reg_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 void append_interval(Interval* it);
a61af66fc99e Initial load
duke
parents:
diff changeset
231 void copy_register_flags(Interval* from, Interval* to);
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 // platform dependent functions
a61af66fc99e Initial load
duke
parents:
diff changeset
234 static bool is_processed_reg_num(int reg_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
235 static int num_physical_regs(BasicType type);
a61af66fc99e Initial load
duke
parents:
diff changeset
236 static bool requires_adjacent_regs(BasicType type);
a61af66fc99e Initial load
duke
parents:
diff changeset
237 static bool is_caller_save(int assigned_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // spill move optimization: eliminate moves from register to stack if
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // stack slot is known to be correct
a61af66fc99e Initial load
duke
parents:
diff changeset
241 void change_spill_definition_pos(Interval* interval, int def_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
242 void change_spill_state(Interval* interval, int spill_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 static bool must_store_at_definition(const Interval* i);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 void eliminate_spill_moves();
a61af66fc99e Initial load
duke
parents:
diff changeset
245
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // Phase 1: number all instructions in all blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
247 void number_instructions();
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // Phase 2: compute local live sets separately for each block
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // (sets live_gen and live_kill for each block)
a61af66fc99e Initial load
duke
parents:
diff changeset
251 //
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // helper methods used by compute_local_live_sets()
a61af66fc99e Initial load
duke
parents:
diff changeset
253 void set_live_gen_kill(Value value, LIR_Op* op, BitMap& live_gen, BitMap& live_kill);
a61af66fc99e Initial load
duke
parents:
diff changeset
254
a61af66fc99e Initial load
duke
parents:
diff changeset
255 void compute_local_live_sets();
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // Phase 3: perform a backward dataflow analysis to compute global live sets
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // (sets live_in and live_out for each block)
a61af66fc99e Initial load
duke
parents:
diff changeset
259 void compute_global_live_sets();
a61af66fc99e Initial load
duke
parents:
diff changeset
260
a61af66fc99e Initial load
duke
parents:
diff changeset
261
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // Phase 4: build intervals
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // (fills the list _intervals)
a61af66fc99e Initial load
duke
parents:
diff changeset
264 //
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // helper methods used by build_intervals()
a61af66fc99e Initial load
duke
parents:
diff changeset
266 void add_use (Value value, int from, int to, IntervalUseKind use_kind);
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268 void add_def (LIR_Opr opr, int def_pos, IntervalUseKind use_kind);
a61af66fc99e Initial load
duke
parents:
diff changeset
269 void add_use (LIR_Opr opr, int from, int to, IntervalUseKind use_kind);
a61af66fc99e Initial load
duke
parents:
diff changeset
270 void add_temp(LIR_Opr opr, int temp_pos, IntervalUseKind use_kind);
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 void add_def (int reg_num, int def_pos, IntervalUseKind use_kind, BasicType type);
a61af66fc99e Initial load
duke
parents:
diff changeset
273 void add_use (int reg_num, int from, int to, IntervalUseKind use_kind, BasicType type);
a61af66fc99e Initial load
duke
parents:
diff changeset
274 void add_temp(int reg_num, int temp_pos, IntervalUseKind use_kind, BasicType type);
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // Add platform dependent kills for particular LIR ops. Can be used
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // to add platform dependent behaviour for some operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
278 void pd_add_temps(LIR_Op* op);
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 IntervalUseKind use_kind_of_output_operand(LIR_Op* op, LIR_Opr opr);
a61af66fc99e Initial load
duke
parents:
diff changeset
281 IntervalUseKind use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 void handle_method_arguments(LIR_Op* op);
a61af66fc99e Initial load
duke
parents:
diff changeset
283 void handle_doubleword_moves(LIR_Op* op);
a61af66fc99e Initial load
duke
parents:
diff changeset
284 void add_register_hints(LIR_Op* op);
a61af66fc99e Initial load
duke
parents:
diff changeset
285
a61af66fc99e Initial load
duke
parents:
diff changeset
286 void build_intervals();
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // Phase 5: actual register allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // (Uses LinearScanWalker)
a61af66fc99e Initial load
duke
parents:
diff changeset
291 //
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // helper functions for building a sorted list of intervals
a61af66fc99e Initial load
duke
parents:
diff changeset
293 NOT_PRODUCT(bool is_sorted(IntervalArray* intervals);)
a61af66fc99e Initial load
duke
parents:
diff changeset
294 static int interval_cmp(Interval** a, Interval** b);
a61af66fc99e Initial load
duke
parents:
diff changeset
295 void add_to_list(Interval** first, Interval** prev, Interval* interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
296 void create_unhandled_lists(Interval** list1, Interval** list2, bool (is_list1)(const Interval* i), bool (is_list2)(const Interval* i));
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 void sort_intervals_before_allocation();
a61af66fc99e Initial load
duke
parents:
diff changeset
299 void sort_intervals_after_allocation();
a61af66fc99e Initial load
duke
parents:
diff changeset
300 void allocate_registers();
a61af66fc99e Initial load
duke
parents:
diff changeset
301
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // Phase 6: resolve data flow
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // (insert moves at edges between blocks if intervals have been split)
a61af66fc99e Initial load
duke
parents:
diff changeset
305 //
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // helper functions for resolve_data_flow()
a61af66fc99e Initial load
duke
parents:
diff changeset
307 Interval* split_child_at_op_id(Interval* interval, int op_id, LIR_OpVisitState::OprMode mode);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 Interval* interval_at_block_begin(BlockBegin* block, int reg_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
309 Interval* interval_at_block_end(BlockBegin* block, int reg_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
310 Interval* interval_at_op_id(int reg_num, int op_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 void resolve_collect_mappings(BlockBegin* from_block, BlockBegin* to_block, MoveResolver &move_resolver);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 void resolve_find_insert_pos(BlockBegin* from_block, BlockBegin* to_block, MoveResolver &move_resolver);
a61af66fc99e Initial load
duke
parents:
diff changeset
313 void resolve_data_flow();
a61af66fc99e Initial load
duke
parents:
diff changeset
314
a61af66fc99e Initial load
duke
parents:
diff changeset
315 void resolve_exception_entry(BlockBegin* block, int reg_num, MoveResolver &move_resolver);
a61af66fc99e Initial load
duke
parents:
diff changeset
316 void resolve_exception_entry(BlockBegin* block, MoveResolver &move_resolver);
a61af66fc99e Initial load
duke
parents:
diff changeset
317 void resolve_exception_edge(XHandler* handler, int throwing_op_id, int reg_num, Phi* phi, MoveResolver &move_resolver);
a61af66fc99e Initial load
duke
parents:
diff changeset
318 void resolve_exception_edge(XHandler* handler, int throwing_op_id, MoveResolver &move_resolver);
a61af66fc99e Initial load
duke
parents:
diff changeset
319 void resolve_exception_handlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // Phase 7: assign register numbers back to LIR
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // (includes computation of debug information and oop maps)
a61af66fc99e Initial load
duke
parents:
diff changeset
323 //
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // helper functions for assign_reg_num()
a61af66fc99e Initial load
duke
parents:
diff changeset
325 VMReg vm_reg_for_interval(Interval* interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
326 VMReg vm_reg_for_operand(LIR_Opr opr);
a61af66fc99e Initial load
duke
parents:
diff changeset
327
a61af66fc99e Initial load
duke
parents:
diff changeset
328 static LIR_Opr operand_for_interval(Interval* interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
329 static LIR_Opr calc_operand_for_interval(const Interval* interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
330 LIR_Opr canonical_spill_opr(Interval* interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 LIR_Opr color_lir_opr(LIR_Opr opr, int id, LIR_OpVisitState::OprMode);
a61af66fc99e Initial load
duke
parents:
diff changeset
333
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // methods used for oop map computation
a61af66fc99e Initial load
duke
parents:
diff changeset
335 IntervalWalker* init_compute_oop_maps();
a61af66fc99e Initial load
duke
parents:
diff changeset
336 OopMap* compute_oop_map(IntervalWalker* iw, LIR_Op* op, CodeEmitInfo* info, bool is_call_site);
a61af66fc99e Initial load
duke
parents:
diff changeset
337 void compute_oop_map(IntervalWalker* iw, const LIR_OpVisitState &visitor, LIR_Op* op);
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // methods used for debug information computation
a61af66fc99e Initial load
duke
parents:
diff changeset
340 void init_compute_debug_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
341
a61af66fc99e Initial load
duke
parents:
diff changeset
342 MonitorValue* location_for_monitor_index(int monitor_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
343 LocationValue* location_for_name(int name, Location::Type loc_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345 int append_scope_value_for_constant(LIR_Opr opr, GrowableArray<ScopeValue*>* scope_values);
a61af66fc99e Initial load
duke
parents:
diff changeset
346 int append_scope_value_for_operand(LIR_Opr opr, GrowableArray<ScopeValue*>* scope_values);
a61af66fc99e Initial load
duke
parents:
diff changeset
347 int append_scope_value(int op_id, Value value, GrowableArray<ScopeValue*>* scope_values);
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 IRScopeDebugInfo* compute_debug_info_for_scope(int op_id, IRScope* cur_scope, ValueStack* cur_state, ValueStack* innermost_state, int cur_bci, int stack_end, int locks_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
350 void compute_debug_info(CodeEmitInfo* info, int op_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 void assign_reg_num(LIR_OpList* instructions, IntervalWalker* iw);
a61af66fc99e Initial load
duke
parents:
diff changeset
353 void assign_reg_num();
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // Phase 8: fpu stack allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // (Used only on x86 when fpu operands are present)
a61af66fc99e Initial load
duke
parents:
diff changeset
358 void allocate_fpu_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
359
a61af66fc99e Initial load
duke
parents:
diff changeset
360
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // helper functions for printing state
a61af66fc99e Initial load
duke
parents:
diff changeset
362 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
363 static void print_bitmap(BitMap& bitmap);
a61af66fc99e Initial load
duke
parents:
diff changeset
364 void print_intervals(const char* label);
a61af66fc99e Initial load
duke
parents:
diff changeset
365 void print_lir(int level, const char* label, bool hir_valid = true);
a61af66fc99e Initial load
duke
parents:
diff changeset
366 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
367
a61af66fc99e Initial load
duke
parents:
diff changeset
368 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
369 // verification functions for allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // (check that all intervals have a correct register and that no registers are overwritten)
a61af66fc99e Initial load
duke
parents:
diff changeset
371 void verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
372 void verify_intervals();
a61af66fc99e Initial load
duke
parents:
diff changeset
373 void verify_no_oops_in_fixed_intervals();
a61af66fc99e Initial load
duke
parents:
diff changeset
374 void verify_constants();
a61af66fc99e Initial load
duke
parents:
diff changeset
375 void verify_registers();
a61af66fc99e Initial load
duke
parents:
diff changeset
376 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // creation
a61af66fc99e Initial load
duke
parents:
diff changeset
380 LinearScan(IR* ir, LIRGenerator* gen, FrameMap* frame_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
381
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // main entry function: perform linear scan register allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
383 void do_linear_scan();
a61af66fc99e Initial load
duke
parents:
diff changeset
384
a61af66fc99e Initial load
duke
parents:
diff changeset
385 // accessors used by Compilation
a61af66fc99e Initial load
duke
parents:
diff changeset
386 int max_spills() const { return _max_spills; }
a61af66fc99e Initial load
duke
parents:
diff changeset
387 int num_calls() const { assert(_num_calls >= 0, "not set"); return _num_calls; }
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // entry functions for printing
a61af66fc99e Initial load
duke
parents:
diff changeset
390 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
391 static void print_statistics();
a61af66fc99e Initial load
duke
parents:
diff changeset
392 static void print_timers(double total);
a61af66fc99e Initial load
duke
parents:
diff changeset
393 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
394 };
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // Helper class for ordering moves that are inserted at the same position in the LIR
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // When moves between registers are inserted, it is important that the moves are
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // ordered such that no register is overwritten. So moves from register to stack
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // are processed prior to moves from stack to register. When moves have circular
a61af66fc99e Initial load
duke
parents:
diff changeset
401 // dependencies, a temporary stack slot is used to break the circle.
a61af66fc99e Initial load
duke
parents:
diff changeset
402 // The same logic is used in the LinearScanWalker and in LinearScan during resolve_data_flow
a61af66fc99e Initial load
duke
parents:
diff changeset
403 // and therefore factored out in a separate class
a61af66fc99e Initial load
duke
parents:
diff changeset
404 class MoveResolver: public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
405 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
406 LinearScan* _allocator;
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 LIR_List* _insert_list;
a61af66fc99e Initial load
duke
parents:
diff changeset
409 int _insert_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
410 LIR_InsertionBuffer _insertion_buffer; // buffer where moves are inserted
a61af66fc99e Initial load
duke
parents:
diff changeset
411
a61af66fc99e Initial load
duke
parents:
diff changeset
412 IntervalList _mapping_from;
a61af66fc99e Initial load
duke
parents:
diff changeset
413 LIR_OprList _mapping_from_opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
414 IntervalList _mapping_to;
a61af66fc99e Initial load
duke
parents:
diff changeset
415 bool _multiple_reads_allowed;
a61af66fc99e Initial load
duke
parents:
diff changeset
416 int _register_blocked[LinearScan::nof_regs];
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418 int register_blocked(int reg) { assert(reg >= 0 && reg < LinearScan::nof_regs, "out of bounds"); return _register_blocked[reg]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
419 void set_register_blocked(int reg, int direction) { assert(reg >= 0 && reg < LinearScan::nof_regs, "out of bounds"); assert(direction == 1 || direction == -1, "out of bounds"); _register_blocked[reg] += direction; }
a61af66fc99e Initial load
duke
parents:
diff changeset
420
a61af66fc99e Initial load
duke
parents:
diff changeset
421 void block_registers(Interval* it);
a61af66fc99e Initial load
duke
parents:
diff changeset
422 void unblock_registers(Interval* it);
a61af66fc99e Initial load
duke
parents:
diff changeset
423 bool save_to_process_move(Interval* from, Interval* to);
a61af66fc99e Initial load
duke
parents:
diff changeset
424
a61af66fc99e Initial load
duke
parents:
diff changeset
425 void create_insertion_buffer(LIR_List* list);
a61af66fc99e Initial load
duke
parents:
diff changeset
426 void append_insertion_buffer();
a61af66fc99e Initial load
duke
parents:
diff changeset
427 void insert_move(Interval* from_interval, Interval* to_interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
428 void insert_move(LIR_Opr from_opr, Interval* to_interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
429
a61af66fc99e Initial load
duke
parents:
diff changeset
430 DEBUG_ONLY(void verify_before_resolve();)
a61af66fc99e Initial load
duke
parents:
diff changeset
431 void resolve_mappings();
a61af66fc99e Initial load
duke
parents:
diff changeset
432 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
433 MoveResolver(LinearScan* allocator);
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435 DEBUG_ONLY(void check_empty();)
a61af66fc99e Initial load
duke
parents:
diff changeset
436 void set_multiple_reads_allowed() { _multiple_reads_allowed = true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
437 void set_insert_position(LIR_List* insert_list, int insert_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
438 void move_insert_position(LIR_List* insert_list, int insert_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 void add_mapping(Interval* from, Interval* to);
a61af66fc99e Initial load
duke
parents:
diff changeset
440 void add_mapping(LIR_Opr from, Interval* to);
a61af66fc99e Initial load
duke
parents:
diff changeset
441 void resolve_and_append_moves();
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443 LinearScan* allocator() { return _allocator; }
a61af66fc99e Initial load
duke
parents:
diff changeset
444 bool has_mappings() { return _mapping_from.length() > 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
445 };
a61af66fc99e Initial load
duke
parents:
diff changeset
446
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 class Range : public CompilationResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
449 friend class Interval;
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
452 static Range* _end; // sentinel (from == to == max_jint)
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 int _from; // from (inclusive)
a61af66fc99e Initial load
duke
parents:
diff changeset
455 int _to; // to (exclusive)
a61af66fc99e Initial load
duke
parents:
diff changeset
456 Range* _next; // linear list of Ranges
a61af66fc99e Initial load
duke
parents:
diff changeset
457
a61af66fc99e Initial load
duke
parents:
diff changeset
458 // used only by class Interval, so hide them
a61af66fc99e Initial load
duke
parents:
diff changeset
459 bool intersects(Range* r) const { return intersects_at(r) != -1; }
a61af66fc99e Initial load
duke
parents:
diff changeset
460 int intersects_at(Range* r) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
461
a61af66fc99e Initial load
duke
parents:
diff changeset
462 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
463 Range(int from, int to, Range* next);
a61af66fc99e Initial load
duke
parents:
diff changeset
464
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1552
diff changeset
465 static void initialize(Arena* arena);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
466 static Range* end() { return _end; }
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 int from() const { return _from; }
a61af66fc99e Initial load
duke
parents:
diff changeset
469 int to() const { return _to; }
a61af66fc99e Initial load
duke
parents:
diff changeset
470 Range* next() const { return _next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
471 void set_from(int from) { _from = from; }
a61af66fc99e Initial load
duke
parents:
diff changeset
472 void set_to(int to) { _to = to; }
a61af66fc99e Initial load
duke
parents:
diff changeset
473 void set_next(Range* next) { _next = next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
474
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // for testing
a61af66fc99e Initial load
duke
parents:
diff changeset
476 void print(outputStream* out = tty) const PRODUCT_RETURN;
a61af66fc99e Initial load
duke
parents:
diff changeset
477 };
a61af66fc99e Initial load
duke
parents:
diff changeset
478
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // Interval is an ordered list of disjoint ranges.
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482 // For pre-colored double word LIR_Oprs, one interval is created for
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // the low word register and one is created for the hi word register.
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // On Intel for FPU double registers only one interval is created. At
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // all times assigned_reg contains the reg. number of the physical
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // register.
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 // For LIR_Opr in virtual registers a single interval can represent
a61af66fc99e Initial load
duke
parents:
diff changeset
489 // single and double word values. When a physical register is
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // assigned to the interval, assigned_reg contains the
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // phys. reg. number and for double word values assigned_regHi the
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // phys. reg. number of the hi word if there is any. For spilled
a61af66fc99e Initial load
duke
parents:
diff changeset
493 // intervals assigned_reg contains the stack index. assigned_regHi is
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // always -1.
a61af66fc99e Initial load
duke
parents:
diff changeset
495
a61af66fc99e Initial load
duke
parents:
diff changeset
496 class Interval : public CompilationResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
498 static Interval* _end; // sentinel (interval with only range Range::end())
a61af66fc99e Initial load
duke
parents:
diff changeset
499
a61af66fc99e Initial load
duke
parents:
diff changeset
500 int _reg_num;
a61af66fc99e Initial load
duke
parents:
diff changeset
501 BasicType _type; // valid only for virtual registers
a61af66fc99e Initial load
duke
parents:
diff changeset
502 Range* _first; // sorted list of Ranges
a61af66fc99e Initial load
duke
parents:
diff changeset
503 intStack _use_pos_and_kinds; // sorted list of use-positions and their according use-kinds
a61af66fc99e Initial load
duke
parents:
diff changeset
504
a61af66fc99e Initial load
duke
parents:
diff changeset
505 Range* _current; // interval iteration: the current Range
a61af66fc99e Initial load
duke
parents:
diff changeset
506 Interval* _next; // interval iteration: sorted list of Intervals (ends with sentinel)
a61af66fc99e Initial load
duke
parents:
diff changeset
507 IntervalState _state; // interval iteration: to which set belongs this interval
a61af66fc99e Initial load
duke
parents:
diff changeset
508
a61af66fc99e Initial load
duke
parents:
diff changeset
509
a61af66fc99e Initial load
duke
parents:
diff changeset
510 int _assigned_reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
511 int _assigned_regHi;
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 int _cached_to; // cached value: to of last range (-1: not cached)
a61af66fc99e Initial load
duke
parents:
diff changeset
514 LIR_Opr _cached_opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
515 VMReg _cached_vm_reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
516
a61af66fc99e Initial load
duke
parents:
diff changeset
517 Interval* _split_parent; // the original interval where this interval is derived from
a61af66fc99e Initial load
duke
parents:
diff changeset
518 IntervalList _split_children; // list of all intervals that are split off from this interval (only available for split parents)
a61af66fc99e Initial load
duke
parents:
diff changeset
519 Interval* _current_split_child; // the current split child that has been active or inactive last (always stored in split parents)
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521 int _canonical_spill_slot; // the stack slot where all split parts of this interval are spilled to (always stored in split parents)
a61af66fc99e Initial load
duke
parents:
diff changeset
522 bool _insert_move_when_activated; // true if move is inserted between _current_split_child and this interval when interval gets active the first time
a61af66fc99e Initial load
duke
parents:
diff changeset
523 IntervalSpillState _spill_state; // for spill move optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
524 int _spill_definition_pos; // position where the interval is defined (if defined only once)
a61af66fc99e Initial load
duke
parents:
diff changeset
525 Interval* _register_hint; // this interval should be in the same register as the hint interval
a61af66fc99e Initial load
duke
parents:
diff changeset
526
a61af66fc99e Initial load
duke
parents:
diff changeset
527 int calc_to();
a61af66fc99e Initial load
duke
parents:
diff changeset
528 Interval* new_split_child();
a61af66fc99e Initial load
duke
parents:
diff changeset
529 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
530 Interval(int reg_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
531
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1552
diff changeset
532 static void initialize(Arena* arena);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
533 static Interval* end() { return _end; }
a61af66fc99e Initial load
duke
parents:
diff changeset
534
a61af66fc99e Initial load
duke
parents:
diff changeset
535 // accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
536 int reg_num() const { return _reg_num; }
a61af66fc99e Initial load
duke
parents:
diff changeset
537 void set_reg_num(int r) { assert(_reg_num == -1, "cannot change reg_num"); _reg_num = r; }
a61af66fc99e Initial load
duke
parents:
diff changeset
538 BasicType type() const { assert(_reg_num == -1 || _reg_num >= LIR_OprDesc::vreg_base, "cannot access type for fixed interval"); return _type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
539 void set_type(BasicType type) { assert(_reg_num < LIR_OprDesc::vreg_base || _type == T_ILLEGAL || _type == type, "overwriting existing type"); _type = type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
540
a61af66fc99e Initial load
duke
parents:
diff changeset
541 Range* first() const { return _first; }
a61af66fc99e Initial load
duke
parents:
diff changeset
542 int from() const { return _first->from(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
543 int to() { if (_cached_to == -1) _cached_to = calc_to(); assert(_cached_to == calc_to(), "invalid cached value"); return _cached_to; }
a61af66fc99e Initial load
duke
parents:
diff changeset
544 int num_use_positions() const { return _use_pos_and_kinds.length() / 2; }
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 Interval* next() const { return _next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
547 Interval** next_addr() { return &_next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
548 void set_next(Interval* next) { _next = next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
549
a61af66fc99e Initial load
duke
parents:
diff changeset
550 int assigned_reg() const { return _assigned_reg; }
a61af66fc99e Initial load
duke
parents:
diff changeset
551 int assigned_regHi() const { return _assigned_regHi; }
a61af66fc99e Initial load
duke
parents:
diff changeset
552 void assign_reg(int reg) { _assigned_reg = reg; _assigned_regHi = LinearScan::any_reg; }
a61af66fc99e Initial load
duke
parents:
diff changeset
553 void assign_reg(int reg,int regHi) { _assigned_reg = reg; _assigned_regHi = regHi; }
a61af66fc99e Initial load
duke
parents:
diff changeset
554
a61af66fc99e Initial load
duke
parents:
diff changeset
555 Interval* register_hint(bool search_split_child = true) const; // calculation needed
a61af66fc99e Initial load
duke
parents:
diff changeset
556 void set_register_hint(Interval* i) { _register_hint = i; }
a61af66fc99e Initial load
duke
parents:
diff changeset
557
a61af66fc99e Initial load
duke
parents:
diff changeset
558 int state() const { return _state; }
a61af66fc99e Initial load
duke
parents:
diff changeset
559 void set_state(IntervalState s) { _state = s; }
a61af66fc99e Initial load
duke
parents:
diff changeset
560
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // access to split parent and split children
a61af66fc99e Initial load
duke
parents:
diff changeset
562 bool is_split_parent() const { return _split_parent == this; }
a61af66fc99e Initial load
duke
parents:
diff changeset
563 bool is_split_child() const { return _split_parent != this; }
a61af66fc99e Initial load
duke
parents:
diff changeset
564 Interval* split_parent() const { assert(_split_parent->is_split_parent(), "must be"); return _split_parent; }
a61af66fc99e Initial load
duke
parents:
diff changeset
565 Interval* split_child_at_op_id(int op_id, LIR_OpVisitState::OprMode mode);
a61af66fc99e Initial load
duke
parents:
diff changeset
566 Interval* split_child_before_op_id(int op_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
567 bool split_child_covers(int op_id, LIR_OpVisitState::OprMode mode);
a61af66fc99e Initial load
duke
parents:
diff changeset
568 DEBUG_ONLY(void check_split_children();)
a61af66fc99e Initial load
duke
parents:
diff changeset
569
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // information stored in split parent, but available for all children
a61af66fc99e Initial load
duke
parents:
diff changeset
571 int canonical_spill_slot() const { return split_parent()->_canonical_spill_slot; }
a61af66fc99e Initial load
duke
parents:
diff changeset
572 void set_canonical_spill_slot(int slot) { assert(split_parent()->_canonical_spill_slot == -1, "overwriting existing value"); split_parent()->_canonical_spill_slot = slot; }
a61af66fc99e Initial load
duke
parents:
diff changeset
573 Interval* current_split_child() const { return split_parent()->_current_split_child; }
a61af66fc99e Initial load
duke
parents:
diff changeset
574 void make_current_split_child() { split_parent()->_current_split_child = this; }
a61af66fc99e Initial load
duke
parents:
diff changeset
575
a61af66fc99e Initial load
duke
parents:
diff changeset
576 bool insert_move_when_activated() const { return _insert_move_when_activated; }
a61af66fc99e Initial load
duke
parents:
diff changeset
577 void set_insert_move_when_activated(bool b) { _insert_move_when_activated = b; }
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // for spill optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
580 IntervalSpillState spill_state() const { return split_parent()->_spill_state; }
a61af66fc99e Initial load
duke
parents:
diff changeset
581 int spill_definition_pos() const { return split_parent()->_spill_definition_pos; }
a61af66fc99e Initial load
duke
parents:
diff changeset
582 void set_spill_state(IntervalSpillState state) { assert(state >= spill_state(), "state cannot decrease"); split_parent()->_spill_state = state; }
a61af66fc99e Initial load
duke
parents:
diff changeset
583 void set_spill_definition_pos(int pos) { assert(spill_definition_pos() == -1, "cannot set the position twice"); split_parent()->_spill_definition_pos = pos; }
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // returns true if this interval has a shadow copy on the stack that is always correct
a61af66fc99e Initial load
duke
parents:
diff changeset
585 bool always_in_memory() const { return split_parent()->_spill_state == storeAtDefinition || split_parent()->_spill_state == startInMemory; }
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // caching of values that take time to compute and are used multiple times
a61af66fc99e Initial load
duke
parents:
diff changeset
588 LIR_Opr cached_opr() const { return _cached_opr; }
a61af66fc99e Initial load
duke
parents:
diff changeset
589 VMReg cached_vm_reg() const { return _cached_vm_reg; }
a61af66fc99e Initial load
duke
parents:
diff changeset
590 void set_cached_opr(LIR_Opr opr) { _cached_opr = opr; }
a61af66fc99e Initial load
duke
parents:
diff changeset
591 void set_cached_vm_reg(VMReg reg) { _cached_vm_reg = reg; }
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593 // access to use positions
a61af66fc99e Initial load
duke
parents:
diff changeset
594 int first_usage(IntervalUseKind min_use_kind) const; // id of the first operation requiring this interval in a register
a61af66fc99e Initial load
duke
parents:
diff changeset
595 int next_usage(IntervalUseKind min_use_kind, int from) const; // id of next usage seen from the given position
a61af66fc99e Initial load
duke
parents:
diff changeset
596 int next_usage_exact(IntervalUseKind exact_use_kind, int from) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
597 int previous_usage(IntervalUseKind min_use_kind, int from) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 // manipulating intervals
a61af66fc99e Initial load
duke
parents:
diff changeset
600 void add_use_pos(int pos, IntervalUseKind use_kind);
a61af66fc99e Initial load
duke
parents:
diff changeset
601 void add_range(int from, int to);
a61af66fc99e Initial load
duke
parents:
diff changeset
602 Interval* split(int split_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
603 Interval* split_from_start(int split_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
604 void remove_first_use_pos() { _use_pos_and_kinds.truncate(_use_pos_and_kinds.length() - 2); }
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // test intersection
a61af66fc99e Initial load
duke
parents:
diff changeset
607 bool covers(int op_id, LIR_OpVisitState::OprMode mode) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
608 bool has_hole_between(int from, int to);
a61af66fc99e Initial load
duke
parents:
diff changeset
609 bool intersects(Interval* i) const { return _first->intersects(i->_first); }
a61af66fc99e Initial load
duke
parents:
diff changeset
610 int intersects_at(Interval* i) const { return _first->intersects_at(i->_first); }
a61af66fc99e Initial load
duke
parents:
diff changeset
611
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // range iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
613 void rewind_range() { _current = _first; }
a61af66fc99e Initial load
duke
parents:
diff changeset
614 void next_range() { assert(this != _end, "not allowed on sentinel"); _current = _current->next(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
615 int current_from() const { return _current->from(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
616 int current_to() const { return _current->to(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
617 bool current_at_end() const { return _current == Range::end(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
618 bool current_intersects(Interval* it) { return _current->intersects(it->_current); };
a61af66fc99e Initial load
duke
parents:
diff changeset
619 int current_intersects_at(Interval* it) { return _current->intersects_at(it->_current); };
a61af66fc99e Initial load
duke
parents:
diff changeset
620
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // printing
a61af66fc99e Initial load
duke
parents:
diff changeset
622 void print(outputStream* out = tty) const PRODUCT_RETURN;
a61af66fc99e Initial load
duke
parents:
diff changeset
623 };
a61af66fc99e Initial load
duke
parents:
diff changeset
624
a61af66fc99e Initial load
duke
parents:
diff changeset
625
a61af66fc99e Initial load
duke
parents:
diff changeset
626 class IntervalWalker : public CompilationResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
627 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
628 Compilation* _compilation;
a61af66fc99e Initial load
duke
parents:
diff changeset
629 LinearScan* _allocator;
a61af66fc99e Initial load
duke
parents:
diff changeset
630
a61af66fc99e Initial load
duke
parents:
diff changeset
631 Interval* _unhandled_first[nofKinds]; // sorted list of intervals, not life before the current position
a61af66fc99e Initial load
duke
parents:
diff changeset
632 Interval* _active_first [nofKinds]; // sorted list of intervals, life at the current position
a61af66fc99e Initial load
duke
parents:
diff changeset
633 Interval* _inactive_first [nofKinds]; // sorted list of intervals, intervals in a life time hole at the current position
a61af66fc99e Initial load
duke
parents:
diff changeset
634
a61af66fc99e Initial load
duke
parents:
diff changeset
635 Interval* _current; // the current interval coming from unhandled list
a61af66fc99e Initial load
duke
parents:
diff changeset
636 int _current_position; // the current position (intercept point through the intervals)
a61af66fc99e Initial load
duke
parents:
diff changeset
637 IntervalKind _current_kind; // and whether it is fixed_kind or any_kind.
a61af66fc99e Initial load
duke
parents:
diff changeset
638
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640 Compilation* compilation() const { return _compilation; }
a61af66fc99e Initial load
duke
parents:
diff changeset
641 LinearScan* allocator() const { return _allocator; }
a61af66fc99e Initial load
duke
parents:
diff changeset
642
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // unified bailout support
a61af66fc99e Initial load
duke
parents:
diff changeset
644 void bailout(const char* msg) const { compilation()->bailout(msg); }
a61af66fc99e Initial load
duke
parents:
diff changeset
645 bool bailed_out() const { return compilation()->bailed_out(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
646
a61af66fc99e Initial load
duke
parents:
diff changeset
647 void check_bounds(IntervalKind kind) { assert(kind >= fixedKind && kind <= anyKind, "invalid interval_kind"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649 Interval** unhandled_first_addr(IntervalKind kind) { check_bounds(kind); return &_unhandled_first[kind]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
650 Interval** active_first_addr(IntervalKind kind) { check_bounds(kind); return &_active_first[kind]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
651 Interval** inactive_first_addr(IntervalKind kind) { check_bounds(kind); return &_inactive_first[kind]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
652
a61af66fc99e Initial load
duke
parents:
diff changeset
653 void append_unsorted(Interval** first, Interval* interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
654 void append_sorted(Interval** first, Interval* interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
655 void append_to_unhandled(Interval** list, Interval* interval);
a61af66fc99e Initial load
duke
parents:
diff changeset
656
a61af66fc99e Initial load
duke
parents:
diff changeset
657 bool remove_from_list(Interval** list, Interval* i);
a61af66fc99e Initial load
duke
parents:
diff changeset
658 void remove_from_list(Interval* i);
a61af66fc99e Initial load
duke
parents:
diff changeset
659
a61af66fc99e Initial load
duke
parents:
diff changeset
660 void next_interval();
a61af66fc99e Initial load
duke
parents:
diff changeset
661 Interval* current() const { return _current; }
a61af66fc99e Initial load
duke
parents:
diff changeset
662 IntervalKind current_kind() const { return _current_kind; }
a61af66fc99e Initial load
duke
parents:
diff changeset
663
a61af66fc99e Initial load
duke
parents:
diff changeset
664 void walk_to(IntervalState state, int from);
a61af66fc99e Initial load
duke
parents:
diff changeset
665
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // activate_current() is called when an unhandled interval becomes active (in current(), current_kind()).
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // Return false if current() should not be moved the the active interval list.
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // It is safe to append current to any interval list but the unhandled list.
a61af66fc99e Initial load
duke
parents:
diff changeset
669 virtual bool activate_current() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
670
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // interval_moved() is called whenever an interval moves from one interval list to another.
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // In the implementation of this method it is prohibited to move the interval to any list.
a61af66fc99e Initial load
duke
parents:
diff changeset
673 virtual void interval_moved(Interval* interval, IntervalKind kind, IntervalState from, IntervalState to);
a61af66fc99e Initial load
duke
parents:
diff changeset
674
a61af66fc99e Initial load
duke
parents:
diff changeset
675 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
676 IntervalWalker(LinearScan* allocator, Interval* unhandled_fixed_first, Interval* unhandled_any_first);
a61af66fc99e Initial load
duke
parents:
diff changeset
677
a61af66fc99e Initial load
duke
parents:
diff changeset
678 Interval* unhandled_first(IntervalKind kind) { check_bounds(kind); return _unhandled_first[kind]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
679 Interval* active_first(IntervalKind kind) { check_bounds(kind); return _active_first[kind]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
680 Interval* inactive_first(IntervalKind kind) { check_bounds(kind); return _inactive_first[kind]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
681
a61af66fc99e Initial load
duke
parents:
diff changeset
682 // active contains the intervals that are live after the lir_op
a61af66fc99e Initial load
duke
parents:
diff changeset
683 void walk_to(int lir_op_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
684 // active contains the intervals that are live before the lir_op
a61af66fc99e Initial load
duke
parents:
diff changeset
685 void walk_before(int lir_op_id) { walk_to(lir_op_id-1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
686 // walk through all intervals
a61af66fc99e Initial load
duke
parents:
diff changeset
687 void walk() { walk_to(max_jint); }
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689 int current_position() { return _current_position; }
a61af66fc99e Initial load
duke
parents:
diff changeset
690 };
a61af66fc99e Initial load
duke
parents:
diff changeset
691
a61af66fc99e Initial load
duke
parents:
diff changeset
692
a61af66fc99e Initial load
duke
parents:
diff changeset
693 // The actual linear scan register allocator
a61af66fc99e Initial load
duke
parents:
diff changeset
694 class LinearScanWalker : public IntervalWalker {
a61af66fc99e Initial load
duke
parents:
diff changeset
695 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
696 any_reg = LinearScan::any_reg
a61af66fc99e Initial load
duke
parents:
diff changeset
697 };
a61af66fc99e Initial load
duke
parents:
diff changeset
698
a61af66fc99e Initial load
duke
parents:
diff changeset
699 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
700 int _first_reg; // the reg. number of the first phys. register
a61af66fc99e Initial load
duke
parents:
diff changeset
701 int _last_reg; // the reg. nmber of the last phys. register
a61af66fc99e Initial load
duke
parents:
diff changeset
702 int _num_phys_regs; // required by current interval
a61af66fc99e Initial load
duke
parents:
diff changeset
703 bool _adjacent_regs; // have lo/hi words of phys. regs be adjacent
a61af66fc99e Initial load
duke
parents:
diff changeset
704
a61af66fc99e Initial load
duke
parents:
diff changeset
705 int _use_pos[LinearScan::nof_regs];
a61af66fc99e Initial load
duke
parents:
diff changeset
706 int _block_pos[LinearScan::nof_regs];
a61af66fc99e Initial load
duke
parents:
diff changeset
707 IntervalList* _spill_intervals[LinearScan::nof_regs];
a61af66fc99e Initial load
duke
parents:
diff changeset
708
a61af66fc99e Initial load
duke
parents:
diff changeset
709 MoveResolver _move_resolver; // for ordering spill moves
a61af66fc99e Initial load
duke
parents:
diff changeset
710
a61af66fc99e Initial load
duke
parents:
diff changeset
711 // accessors mapped to same functions in class LinearScan
a61af66fc99e Initial load
duke
parents:
diff changeset
712 int block_count() const { return allocator()->block_count(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
713 BlockBegin* block_at(int idx) const { return allocator()->block_at(idx); }
a61af66fc99e Initial load
duke
parents:
diff changeset
714 BlockBegin* block_of_op_with_id(int op_id) const { return allocator()->block_of_op_with_id(op_id); }
a61af66fc99e Initial load
duke
parents:
diff changeset
715
a61af66fc99e Initial load
duke
parents:
diff changeset
716 void init_use_lists(bool only_process_use_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
717 void exclude_from_use(int reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
718 void exclude_from_use(Interval* i);
a61af66fc99e Initial load
duke
parents:
diff changeset
719 void set_use_pos(int reg, Interval* i, int use_pos, bool only_process_use_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
720 void set_use_pos(Interval* i, int use_pos, bool only_process_use_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
721 void set_block_pos(int reg, Interval* i, int block_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
722 void set_block_pos(Interval* i, int block_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724 void free_exclude_active_fixed();
a61af66fc99e Initial load
duke
parents:
diff changeset
725 void free_exclude_active_any();
a61af66fc99e Initial load
duke
parents:
diff changeset
726 void free_collect_inactive_fixed(Interval* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
727 void free_collect_inactive_any(Interval* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
728 void free_collect_unhandled(IntervalKind kind, Interval* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
729 void spill_exclude_active_fixed();
a61af66fc99e Initial load
duke
parents:
diff changeset
730 void spill_block_unhandled_fixed(Interval* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
731 void spill_block_inactive_fixed(Interval* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
732 void spill_collect_active_any();
a61af66fc99e Initial load
duke
parents:
diff changeset
733 void spill_collect_inactive_any(Interval* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
734
a61af66fc99e Initial load
duke
parents:
diff changeset
735 void insert_move(int op_id, Interval* src_it, Interval* dst_it);
a61af66fc99e Initial load
duke
parents:
diff changeset
736 int find_optimal_split_pos(BlockBegin* min_block, BlockBegin* max_block, int max_split_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
737 int find_optimal_split_pos(Interval* it, int min_split_pos, int max_split_pos, bool do_loop_optimization);
a61af66fc99e Initial load
duke
parents:
diff changeset
738 void split_before_usage(Interval* it, int min_split_pos, int max_split_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
739 void split_for_spilling(Interval* it);
a61af66fc99e Initial load
duke
parents:
diff changeset
740 void split_stack_interval(Interval* it);
a61af66fc99e Initial load
duke
parents:
diff changeset
741 void split_when_partial_register_available(Interval* it, int register_available_until);
a61af66fc99e Initial load
duke
parents:
diff changeset
742 void split_and_spill_interval(Interval* it);
a61af66fc99e Initial load
duke
parents:
diff changeset
743
a61af66fc99e Initial load
duke
parents:
diff changeset
744 int find_free_reg(int reg_needed_until, int interval_to, int hint_reg, int ignore_reg, bool* need_split);
a61af66fc99e Initial load
duke
parents:
diff changeset
745 int find_free_double_reg(int reg_needed_until, int interval_to, int hint_reg, bool* need_split);
a61af66fc99e Initial load
duke
parents:
diff changeset
746 bool alloc_free_reg(Interval* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
747
a61af66fc99e Initial load
duke
parents:
diff changeset
748 int find_locked_reg(int reg_needed_until, int interval_to, int hint_reg, int ignore_reg, bool* need_split);
a61af66fc99e Initial load
duke
parents:
diff changeset
749 int find_locked_double_reg(int reg_needed_until, int interval_to, int hint_reg, bool* need_split);
a61af66fc99e Initial load
duke
parents:
diff changeset
750 void split_and_spill_intersecting_intervals(int reg, int regHi);
a61af66fc99e Initial load
duke
parents:
diff changeset
751 void alloc_locked_reg(Interval* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
752
a61af66fc99e Initial load
duke
parents:
diff changeset
753 bool no_allocation_possible(Interval* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
754 void update_phys_reg_range(bool requires_cpu_register);
a61af66fc99e Initial load
duke
parents:
diff changeset
755 void init_vars_for_alloc(Interval* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
756 bool pd_init_regs_for_alloc(Interval* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
757
a61af66fc99e Initial load
duke
parents:
diff changeset
758 void combine_spilled_intervals(Interval* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
759 bool is_move(LIR_Op* op, Interval* from, Interval* to);
a61af66fc99e Initial load
duke
parents:
diff changeset
760
a61af66fc99e Initial load
duke
parents:
diff changeset
761 bool activate_current();
a61af66fc99e Initial load
duke
parents:
diff changeset
762
a61af66fc99e Initial load
duke
parents:
diff changeset
763 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
764 LinearScanWalker(LinearScan* allocator, Interval* unhandled_fixed_first, Interval* unhandled_any_first);
a61af66fc99e Initial load
duke
parents:
diff changeset
765
a61af66fc99e Initial load
duke
parents:
diff changeset
766 // must be called when all intervals are allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
767 void finish_allocation() { _move_resolver.resolve_and_append_moves(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
768 };
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771
a61af66fc99e Initial load
duke
parents:
diff changeset
772 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
773 When a block has more than one predecessor, and all predecessors end with
a61af66fc99e Initial load
duke
parents:
diff changeset
774 the same sequence of move-instructions, than this moves can be placed once
a61af66fc99e Initial load
duke
parents:
diff changeset
775 at the beginning of the block instead of multiple times in the predecessors.
a61af66fc99e Initial load
duke
parents:
diff changeset
776
a61af66fc99e Initial load
duke
parents:
diff changeset
777 Similarly, when a block has more than one successor, then equal sequences of
a61af66fc99e Initial load
duke
parents:
diff changeset
778 moves at the beginning of the successors can be placed once at the end of
a61af66fc99e Initial load
duke
parents:
diff changeset
779 the block. But because the moves must be inserted before all branch
a61af66fc99e Initial load
duke
parents:
diff changeset
780 instructions, this works only when there is exactly one conditional branch
a61af66fc99e Initial load
duke
parents:
diff changeset
781 at the end of the block (because the moves must be inserted before all
a61af66fc99e Initial load
duke
parents:
diff changeset
782 branches, but after all compares).
a61af66fc99e Initial load
duke
parents:
diff changeset
783
a61af66fc99e Initial load
duke
parents:
diff changeset
784 This optimization affects all kind of moves (reg->reg, reg->stack and
a61af66fc99e Initial load
duke
parents:
diff changeset
785 stack->reg). Because this optimization works best when a block contains only
a61af66fc99e Initial load
duke
parents:
diff changeset
786 few moves, it has a huge impact on the number of blocks that are totally
a61af66fc99e Initial load
duke
parents:
diff changeset
787 empty.
a61af66fc99e Initial load
duke
parents:
diff changeset
788 */
a61af66fc99e Initial load
duke
parents:
diff changeset
789 class EdgeMoveOptimizer : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
790 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
791 // the class maintains a list with all lir-instruction-list of the
a61af66fc99e Initial load
duke
parents:
diff changeset
792 // successors (predecessors) and the current index into the lir-lists
a61af66fc99e Initial load
duke
parents:
diff changeset
793 LIR_OpListStack _edge_instructions;
a61af66fc99e Initial load
duke
parents:
diff changeset
794 intStack _edge_instructions_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
795
a61af66fc99e Initial load
duke
parents:
diff changeset
796 void init_instructions();
a61af66fc99e Initial load
duke
parents:
diff changeset
797 void append_instructions(LIR_OpList* instructions, int instructions_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
798 LIR_Op* instruction_at(int edge);
a61af66fc99e Initial load
duke
parents:
diff changeset
799 void remove_cur_instruction(int edge, bool decrement_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
800
a61af66fc99e Initial load
duke
parents:
diff changeset
801 bool operations_different(LIR_Op* op1, LIR_Op* op2);
a61af66fc99e Initial load
duke
parents:
diff changeset
802
a61af66fc99e Initial load
duke
parents:
diff changeset
803 void optimize_moves_at_block_end(BlockBegin* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
804 void optimize_moves_at_block_begin(BlockBegin* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
805
a61af66fc99e Initial load
duke
parents:
diff changeset
806 EdgeMoveOptimizer();
a61af66fc99e Initial load
duke
parents:
diff changeset
807
a61af66fc99e Initial load
duke
parents:
diff changeset
808 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
809 static void optimize(BlockList* code);
a61af66fc99e Initial load
duke
parents:
diff changeset
810 };
a61af66fc99e Initial load
duke
parents:
diff changeset
811
a61af66fc99e Initial load
duke
parents:
diff changeset
812
a61af66fc99e Initial load
duke
parents:
diff changeset
813
a61af66fc99e Initial load
duke
parents:
diff changeset
814 class ControlFlowOptimizer : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
815 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
816 BlockList _original_preds;
a61af66fc99e Initial load
duke
parents:
diff changeset
817
a61af66fc99e Initial load
duke
parents:
diff changeset
818 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
819 ShortLoopSize = 5
a61af66fc99e Initial load
duke
parents:
diff changeset
820 };
a61af66fc99e Initial load
duke
parents:
diff changeset
821 void reorder_short_loop(BlockList* code, BlockBegin* header_block, int header_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
822 void reorder_short_loops(BlockList* code);
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 bool can_delete_block(BlockBegin* cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
825 void substitute_branch_target(BlockBegin* cur, BlockBegin* target_from, BlockBegin* target_to);
a61af66fc99e Initial load
duke
parents:
diff changeset
826 void delete_empty_blocks(BlockList* code);
a61af66fc99e Initial load
duke
parents:
diff changeset
827
a61af66fc99e Initial load
duke
parents:
diff changeset
828 void delete_unnecessary_jumps(BlockList* code);
a61af66fc99e Initial load
duke
parents:
diff changeset
829 void delete_jumps_to_return(BlockList* code);
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831 DEBUG_ONLY(void verify(BlockList* code);)
a61af66fc99e Initial load
duke
parents:
diff changeset
832
a61af66fc99e Initial load
duke
parents:
diff changeset
833 ControlFlowOptimizer();
a61af66fc99e Initial load
duke
parents:
diff changeset
834 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
835 static void optimize(BlockList* code);
a61af66fc99e Initial load
duke
parents:
diff changeset
836 };
a61af66fc99e Initial load
duke
parents:
diff changeset
837
a61af66fc99e Initial load
duke
parents:
diff changeset
838
a61af66fc99e Initial load
duke
parents:
diff changeset
839 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
840
a61af66fc99e Initial load
duke
parents:
diff changeset
841 // Helper class for collecting statistics of LinearScan
a61af66fc99e Initial load
duke
parents:
diff changeset
842 class LinearScanStatistic : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
843 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
844 enum Counter {
a61af66fc99e Initial load
duke
parents:
diff changeset
845 // general counters
a61af66fc99e Initial load
duke
parents:
diff changeset
846 counter_method,
a61af66fc99e Initial load
duke
parents:
diff changeset
847 counter_fpu_method,
a61af66fc99e Initial load
duke
parents:
diff changeset
848 counter_loop_method,
a61af66fc99e Initial load
duke
parents:
diff changeset
849 counter_exception_method,
a61af66fc99e Initial load
duke
parents:
diff changeset
850 counter_loop,
a61af66fc99e Initial load
duke
parents:
diff changeset
851 counter_block,
a61af66fc99e Initial load
duke
parents:
diff changeset
852 counter_loop_block,
a61af66fc99e Initial load
duke
parents:
diff changeset
853 counter_exception_block,
a61af66fc99e Initial load
duke
parents:
diff changeset
854 counter_interval,
a61af66fc99e Initial load
duke
parents:
diff changeset
855 counter_fixed_interval,
a61af66fc99e Initial load
duke
parents:
diff changeset
856 counter_range,
a61af66fc99e Initial load
duke
parents:
diff changeset
857 counter_fixed_range,
a61af66fc99e Initial load
duke
parents:
diff changeset
858 counter_use_pos,
a61af66fc99e Initial load
duke
parents:
diff changeset
859 counter_fixed_use_pos,
a61af66fc99e Initial load
duke
parents:
diff changeset
860 counter_spill_slots,
a61af66fc99e Initial load
duke
parents:
diff changeset
861 blank_line_1,
a61af66fc99e Initial load
duke
parents:
diff changeset
862
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // counter for classes of lir instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
864 counter_instruction,
a61af66fc99e Initial load
duke
parents:
diff changeset
865 counter_label,
a61af66fc99e Initial load
duke
parents:
diff changeset
866 counter_entry,
a61af66fc99e Initial load
duke
parents:
diff changeset
867 counter_return,
a61af66fc99e Initial load
duke
parents:
diff changeset
868 counter_call,
a61af66fc99e Initial load
duke
parents:
diff changeset
869 counter_move,
a61af66fc99e Initial load
duke
parents:
diff changeset
870 counter_cmp,
a61af66fc99e Initial load
duke
parents:
diff changeset
871 counter_cond_branch,
a61af66fc99e Initial load
duke
parents:
diff changeset
872 counter_uncond_branch,
a61af66fc99e Initial load
duke
parents:
diff changeset
873 counter_stub_branch,
a61af66fc99e Initial load
duke
parents:
diff changeset
874 counter_alu,
a61af66fc99e Initial load
duke
parents:
diff changeset
875 counter_alloc,
a61af66fc99e Initial load
duke
parents:
diff changeset
876 counter_sync,
a61af66fc99e Initial load
duke
parents:
diff changeset
877 counter_throw,
a61af66fc99e Initial load
duke
parents:
diff changeset
878 counter_unwind,
a61af66fc99e Initial load
duke
parents:
diff changeset
879 counter_typecheck,
a61af66fc99e Initial load
duke
parents:
diff changeset
880 counter_fpu_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
881 counter_misc_inst,
a61af66fc99e Initial load
duke
parents:
diff changeset
882 counter_other_inst,
a61af66fc99e Initial load
duke
parents:
diff changeset
883 blank_line_2,
a61af66fc99e Initial load
duke
parents:
diff changeset
884
a61af66fc99e Initial load
duke
parents:
diff changeset
885 // counter for different types of moves
a61af66fc99e Initial load
duke
parents:
diff changeset
886 counter_move_total,
a61af66fc99e Initial load
duke
parents:
diff changeset
887 counter_move_reg_reg,
a61af66fc99e Initial load
duke
parents:
diff changeset
888 counter_move_reg_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
889 counter_move_stack_reg,
a61af66fc99e Initial load
duke
parents:
diff changeset
890 counter_move_stack_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
891 counter_move_reg_mem,
a61af66fc99e Initial load
duke
parents:
diff changeset
892 counter_move_mem_reg,
a61af66fc99e Initial load
duke
parents:
diff changeset
893 counter_move_const_any,
a61af66fc99e Initial load
duke
parents:
diff changeset
894
a61af66fc99e Initial load
duke
parents:
diff changeset
895 number_of_counters,
a61af66fc99e Initial load
duke
parents:
diff changeset
896 invalid_counter = -1
a61af66fc99e Initial load
duke
parents:
diff changeset
897 };
a61af66fc99e Initial load
duke
parents:
diff changeset
898
a61af66fc99e Initial load
duke
parents:
diff changeset
899 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
900 int _counters_sum[number_of_counters];
a61af66fc99e Initial load
duke
parents:
diff changeset
901 int _counters_max[number_of_counters];
a61af66fc99e Initial load
duke
parents:
diff changeset
902
a61af66fc99e Initial load
duke
parents:
diff changeset
903 void inc_counter(Counter idx, int value = 1) { _counters_sum[idx] += value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
904
a61af66fc99e Initial load
duke
parents:
diff changeset
905 const char* counter_name(int counter_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
906 Counter base_counter(int counter_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 void sum_up(LinearScanStatistic &method_statistic);
a61af66fc99e Initial load
duke
parents:
diff changeset
909 void collect(LinearScan* allocator);
a61af66fc99e Initial load
duke
parents:
diff changeset
910
a61af66fc99e Initial load
duke
parents:
diff changeset
911 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
912 LinearScanStatistic();
a61af66fc99e Initial load
duke
parents:
diff changeset
913 void print(const char* title);
a61af66fc99e Initial load
duke
parents:
diff changeset
914 static void compute(LinearScan* allocator, LinearScanStatistic &global_statistic);
a61af66fc99e Initial load
duke
parents:
diff changeset
915 };
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 // Helper class for collecting compilation time of LinearScan
a61af66fc99e Initial load
duke
parents:
diff changeset
919 class LinearScanTimers : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
920 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
921 enum Timer {
a61af66fc99e Initial load
duke
parents:
diff changeset
922 timer_do_nothing,
a61af66fc99e Initial load
duke
parents:
diff changeset
923 timer_number_instructions,
a61af66fc99e Initial load
duke
parents:
diff changeset
924 timer_compute_local_live_sets,
a61af66fc99e Initial load
duke
parents:
diff changeset
925 timer_compute_global_live_sets,
a61af66fc99e Initial load
duke
parents:
diff changeset
926 timer_build_intervals,
a61af66fc99e Initial load
duke
parents:
diff changeset
927 timer_sort_intervals_before,
a61af66fc99e Initial load
duke
parents:
diff changeset
928 timer_allocate_registers,
a61af66fc99e Initial load
duke
parents:
diff changeset
929 timer_resolve_data_flow,
a61af66fc99e Initial load
duke
parents:
diff changeset
930 timer_sort_intervals_after,
a61af66fc99e Initial load
duke
parents:
diff changeset
931 timer_eliminate_spill_moves,
a61af66fc99e Initial load
duke
parents:
diff changeset
932 timer_assign_reg_num,
a61af66fc99e Initial load
duke
parents:
diff changeset
933 timer_allocate_fpu_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
934 timer_optimize_lir,
a61af66fc99e Initial load
duke
parents:
diff changeset
935
a61af66fc99e Initial load
duke
parents:
diff changeset
936 number_of_timers
a61af66fc99e Initial load
duke
parents:
diff changeset
937 };
a61af66fc99e Initial load
duke
parents:
diff changeset
938
a61af66fc99e Initial load
duke
parents:
diff changeset
939 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
940 elapsedTimer _timers[number_of_timers];
a61af66fc99e Initial load
duke
parents:
diff changeset
941 const char* timer_name(int idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
942
a61af66fc99e Initial load
duke
parents:
diff changeset
943 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
944 LinearScanTimers();
a61af66fc99e Initial load
duke
parents:
diff changeset
945
a61af66fc99e Initial load
duke
parents:
diff changeset
946 void begin_method(); // called for each method when register allocation starts
a61af66fc99e Initial load
duke
parents:
diff changeset
947 void end_method(LinearScan* allocator); // called for each method when register allocation completed
a61af66fc99e Initial load
duke
parents:
diff changeset
948 void print(double total_time); // called before termination of VM to print global summary
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950 elapsedTimer* timer(int idx) { return &(_timers[idx]); }
a61af66fc99e Initial load
duke
parents:
diff changeset
951 };
a61af66fc99e Initial load
duke
parents:
diff changeset
952
a61af66fc99e Initial load
duke
parents:
diff changeset
953
a61af66fc99e Initial load
duke
parents:
diff changeset
954 #endif // ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
955
a61af66fc99e Initial load
duke
parents:
diff changeset
956
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // Pick up platform-dependent implementation details
a61af66fc99e Initial load
duke
parents:
diff changeset
958 # include "incls/_c1_LinearScan_pd.hpp.incl"