Mercurial > hg > truffle
annotate src/share/vm/c1/c1_LinearScan.cpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | 8a02ca5e5576 |
children | b9a9ed0f8eeb |
rev | line source |
---|---|
0 | 1 /* |
2426
1d1603768966
7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents:
2345
diff
changeset
|
2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1397
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:
1397
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "c1/c1_CFGPrinter.hpp" | |
27 #include "c1/c1_CodeStubs.hpp" | |
28 #include "c1/c1_Compilation.hpp" | |
29 #include "c1/c1_FrameMap.hpp" | |
30 #include "c1/c1_IR.hpp" | |
31 #include "c1/c1_LIRGenerator.hpp" | |
32 #include "c1/c1_LinearScan.hpp" | |
33 #include "c1/c1_ValueStack.hpp" | |
34 #include "utilities/bitMap.inline.hpp" | |
35 #ifdef TARGET_ARCH_x86 | |
36 # include "vmreg_x86.inline.hpp" | |
37 #endif | |
38 #ifdef TARGET_ARCH_sparc | |
39 # include "vmreg_sparc.inline.hpp" | |
40 #endif | |
41 #ifdef TARGET_ARCH_zero | |
42 # include "vmreg_zero.inline.hpp" | |
43 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2081
diff
changeset
|
44 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2081
diff
changeset
|
45 # include "vmreg_arm.inline.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2081
diff
changeset
|
46 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2081
diff
changeset
|
47 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2081
diff
changeset
|
48 # include "vmreg_ppc.inline.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2081
diff
changeset
|
49 #endif |
0 | 50 |
51 | |
52 #ifndef PRODUCT | |
53 | |
54 static LinearScanStatistic _stat_before_alloc; | |
55 static LinearScanStatistic _stat_after_asign; | |
56 static LinearScanStatistic _stat_final; | |
57 | |
58 static LinearScanTimers _total_timer; | |
59 | |
60 // helper macro for short definition of timer | |
61 #define TIME_LINEAR_SCAN(timer_name) TraceTime _block_timer("", _total_timer.timer(LinearScanTimers::timer_name), TimeLinearScan || TimeEachLinearScan, Verbose); | |
62 | |
63 // helper macro for short definition of trace-output inside code | |
64 #define TRACE_LINEAR_SCAN(level, code) \ | |
65 if (TraceLinearScanLevel >= level) { \ | |
66 code; \ | |
67 } | |
68 | |
69 #else | |
70 | |
71 #define TIME_LINEAR_SCAN(timer_name) | |
72 #define TRACE_LINEAR_SCAN(level, code) | |
73 | |
74 #endif | |
75 | |
76 // Map BasicType to spill size in 32-bit words, matching VMReg's notion of words | |
77 #ifdef _LP64 | |
78 static int type2spill_size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 0, 1, -1}; | |
79 #else | |
80 static int type2spill_size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 0, 1, -1}; | |
81 #endif | |
82 | |
83 | |
84 // Implementation of LinearScan | |
85 | |
86 LinearScan::LinearScan(IR* ir, LIRGenerator* gen, FrameMap* frame_map) | |
87 : _compilation(ir->compilation()) | |
88 , _ir(ir) | |
89 , _gen(gen) | |
90 , _frame_map(frame_map) | |
91 , _num_virtual_regs(gen->max_virtual_register_number()) | |
92 , _has_fpu_registers(false) | |
93 , _num_calls(-1) | |
94 , _max_spills(0) | |
95 , _unused_spill_slot(-1) | |
96 , _intervals(0) // initialized later with correct length | |
97 , _new_intervals_from_allocation(new IntervalList()) | |
98 , _sorted_intervals(NULL) | |
2081
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
99 , _needs_full_resort(false) |
0 | 100 , _lir_ops(0) // initialized later with correct length |
101 , _block_of_op(0) // initialized later with correct length | |
102 , _has_info(0) | |
103 , _has_call(0) | |
104 , _scope_value_cache(0) // initialized later with correct length | |
105 , _interval_in_loop(0, 0) // initialized later with correct length | |
106 , _cached_blocks(*ir->linear_scan_order()) | |
304 | 107 #ifdef X86 |
0 | 108 , _fpu_stack_allocator(NULL) |
109 #endif | |
110 { | |
111 assert(this->ir() != NULL, "check if valid"); | |
112 assert(this->compilation() != NULL, "check if valid"); | |
113 assert(this->gen() != NULL, "check if valid"); | |
114 assert(this->frame_map() != NULL, "check if valid"); | |
115 } | |
116 | |
117 | |
118 // ********** functions for converting LIR-Operands to register numbers | |
119 // | |
120 // Emulate a flat register file comprising physical integer registers, | |
121 // physical floating-point registers and virtual registers, in that order. | |
122 // Virtual registers already have appropriate numbers, since V0 is | |
123 // the number of physical registers. | |
124 // Returns -1 for hi word if opr is a single word operand. | |
125 // | |
126 // Note: the inverse operation (calculating an operand for register numbers) | |
127 // is done in calc_operand_for_interval() | |
128 | |
129 int LinearScan::reg_num(LIR_Opr opr) { | |
130 assert(opr->is_register(), "should not call this otherwise"); | |
131 | |
132 if (opr->is_virtual_register()) { | |
133 assert(opr->vreg_number() >= nof_regs, "found a virtual register with a fixed-register number"); | |
134 return opr->vreg_number(); | |
135 } else if (opr->is_single_cpu()) { | |
136 return opr->cpu_regnr(); | |
137 } else if (opr->is_double_cpu()) { | |
138 return opr->cpu_regnrLo(); | |
304 | 139 #ifdef X86 |
0 | 140 } else if (opr->is_single_xmm()) { |
141 return opr->fpu_regnr() + pd_first_xmm_reg; | |
142 } else if (opr->is_double_xmm()) { | |
143 return opr->fpu_regnrLo() + pd_first_xmm_reg; | |
144 #endif | |
145 } else if (opr->is_single_fpu()) { | |
146 return opr->fpu_regnr() + pd_first_fpu_reg; | |
147 } else if (opr->is_double_fpu()) { | |
148 return opr->fpu_regnrLo() + pd_first_fpu_reg; | |
149 } else { | |
150 ShouldNotReachHere(); | |
304 | 151 return -1; |
0 | 152 } |
153 } | |
154 | |
155 int LinearScan::reg_numHi(LIR_Opr opr) { | |
156 assert(opr->is_register(), "should not call this otherwise"); | |
157 | |
158 if (opr->is_virtual_register()) { | |
159 return -1; | |
160 } else if (opr->is_single_cpu()) { | |
161 return -1; | |
162 } else if (opr->is_double_cpu()) { | |
163 return opr->cpu_regnrHi(); | |
304 | 164 #ifdef X86 |
0 | 165 } else if (opr->is_single_xmm()) { |
166 return -1; | |
167 } else if (opr->is_double_xmm()) { | |
168 return -1; | |
169 #endif | |
170 } else if (opr->is_single_fpu()) { | |
171 return -1; | |
172 } else if (opr->is_double_fpu()) { | |
173 return opr->fpu_regnrHi() + pd_first_fpu_reg; | |
174 } else { | |
175 ShouldNotReachHere(); | |
304 | 176 return -1; |
0 | 177 } |
178 } | |
179 | |
180 | |
181 // ********** functions for classification of intervals | |
182 | |
183 bool LinearScan::is_precolored_interval(const Interval* i) { | |
184 return i->reg_num() < LinearScan::nof_regs; | |
185 } | |
186 | |
187 bool LinearScan::is_virtual_interval(const Interval* i) { | |
188 return i->reg_num() >= LIR_OprDesc::vreg_base; | |
189 } | |
190 | |
191 bool LinearScan::is_precolored_cpu_interval(const Interval* i) { | |
192 return i->reg_num() < LinearScan::nof_cpu_regs; | |
193 } | |
194 | |
195 bool LinearScan::is_virtual_cpu_interval(const Interval* i) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
196 #if defined(__SOFTFP__) || defined(E500V2) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
197 return i->reg_num() >= LIR_OprDesc::vreg_base; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
198 #else |
0 | 199 return i->reg_num() >= LIR_OprDesc::vreg_base && (i->type() != T_FLOAT && i->type() != T_DOUBLE); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
200 #endif // __SOFTFP__ or E500V2 |
0 | 201 } |
202 | |
203 bool LinearScan::is_precolored_fpu_interval(const Interval* i) { | |
204 return i->reg_num() >= LinearScan::nof_cpu_regs && i->reg_num() < LinearScan::nof_regs; | |
205 } | |
206 | |
207 bool LinearScan::is_virtual_fpu_interval(const Interval* i) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
208 #if defined(__SOFTFP__) || defined(E500V2) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
209 return false; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
210 #else |
0 | 211 return i->reg_num() >= LIR_OprDesc::vreg_base && (i->type() == T_FLOAT || i->type() == T_DOUBLE); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
212 #endif // __SOFTFP__ or E500V2 |
0 | 213 } |
214 | |
215 bool LinearScan::is_in_fpu_register(const Interval* i) { | |
216 // fixed intervals not needed for FPU stack allocation | |
217 return i->reg_num() >= nof_regs && pd_first_fpu_reg <= i->assigned_reg() && i->assigned_reg() <= pd_last_fpu_reg; | |
218 } | |
219 | |
220 bool LinearScan::is_oop_interval(const Interval* i) { | |
221 // fixed intervals never contain oops | |
222 return i->reg_num() >= nof_regs && i->type() == T_OBJECT; | |
223 } | |
224 | |
225 | |
226 // ********** General helper functions | |
227 | |
228 // compute next unused stack index that can be used for spilling | |
229 int LinearScan::allocate_spill_slot(bool double_word) { | |
230 int spill_slot; | |
231 if (double_word) { | |
232 if ((_max_spills & 1) == 1) { | |
233 // alignment of double-word values | |
234 // the hole because of the alignment is filled with the next single-word value | |
235 assert(_unused_spill_slot == -1, "wasting a spill slot"); | |
236 _unused_spill_slot = _max_spills; | |
237 _max_spills++; | |
238 } | |
239 spill_slot = _max_spills; | |
240 _max_spills += 2; | |
241 | |
242 } else if (_unused_spill_slot != -1) { | |
243 // re-use hole that was the result of a previous double-word alignment | |
244 spill_slot = _unused_spill_slot; | |
245 _unused_spill_slot = -1; | |
246 | |
247 } else { | |
248 spill_slot = _max_spills; | |
249 _max_spills++; | |
250 } | |
251 | |
252 int result = spill_slot + LinearScan::nof_regs + frame_map()->argcount(); | |
253 | |
254 // the class OopMapValue uses only 11 bits for storing the name of the | |
255 // oop location. So a stack slot bigger than 2^11 leads to an overflow | |
256 // that is not reported in product builds. Prevent this by checking the | |
257 // spill slot here (altough this value and the later used location name | |
258 // are slightly different) | |
259 if (result > 2000) { | |
260 bailout("too many stack slots used"); | |
261 } | |
262 | |
263 return result; | |
264 } | |
265 | |
266 void LinearScan::assign_spill_slot(Interval* it) { | |
267 // assign the canonical spill slot of the parent (if a part of the interval | |
268 // is already spilled) or allocate a new spill slot | |
269 if (it->canonical_spill_slot() >= 0) { | |
270 it->assign_reg(it->canonical_spill_slot()); | |
271 } else { | |
272 int spill = allocate_spill_slot(type2spill_size[it->type()] == 2); | |
273 it->set_canonical_spill_slot(spill); | |
274 it->assign_reg(spill); | |
275 } | |
276 } | |
277 | |
278 void LinearScan::propagate_spill_slots() { | |
279 if (!frame_map()->finalize_frame(max_spills())) { | |
280 bailout("frame too large"); | |
281 } | |
282 } | |
283 | |
284 // create a new interval with a predefined reg_num | |
285 // (only used for parent intervals that are created during the building phase) | |
286 Interval* LinearScan::create_interval(int reg_num) { | |
287 assert(_intervals.at(reg_num) == NULL, "overwriting exisiting interval"); | |
288 | |
289 Interval* interval = new Interval(reg_num); | |
290 _intervals.at_put(reg_num, interval); | |
291 | |
292 // assign register number for precolored intervals | |
293 if (reg_num < LIR_OprDesc::vreg_base) { | |
294 interval->assign_reg(reg_num); | |
295 } | |
296 return interval; | |
297 } | |
298 | |
299 // assign a new reg_num to the interval and append it to the list of intervals | |
300 // (only used for child intervals that are created during register allocation) | |
301 void LinearScan::append_interval(Interval* it) { | |
302 it->set_reg_num(_intervals.length()); | |
303 _intervals.append(it); | |
304 _new_intervals_from_allocation->append(it); | |
305 } | |
306 | |
307 // copy the vreg-flags if an interval is split | |
308 void LinearScan::copy_register_flags(Interval* from, Interval* to) { | |
309 if (gen()->is_vreg_flag_set(from->reg_num(), LIRGenerator::byte_reg)) { | |
310 gen()->set_vreg_flag(to->reg_num(), LIRGenerator::byte_reg); | |
311 } | |
312 if (gen()->is_vreg_flag_set(from->reg_num(), LIRGenerator::callee_saved)) { | |
313 gen()->set_vreg_flag(to->reg_num(), LIRGenerator::callee_saved); | |
314 } | |
315 | |
316 // Note: do not copy the must_start_in_memory flag because it is not necessary for child | |
317 // intervals (only the very beginning of the interval must be in memory) | |
318 } | |
319 | |
320 | |
321 // ********** spill move optimization | |
322 // eliminate moves from register to stack if stack slot is known to be correct | |
323 | |
324 // called during building of intervals | |
325 void LinearScan::change_spill_definition_pos(Interval* interval, int def_pos) { | |
326 assert(interval->is_split_parent(), "can only be called for split parents"); | |
327 | |
328 switch (interval->spill_state()) { | |
329 case noDefinitionFound: | |
330 assert(interval->spill_definition_pos() == -1, "must no be set before"); | |
331 interval->set_spill_definition_pos(def_pos); | |
332 interval->set_spill_state(oneDefinitionFound); | |
333 break; | |
334 | |
335 case oneDefinitionFound: | |
336 assert(def_pos <= interval->spill_definition_pos(), "positions are processed in reverse order when intervals are created"); | |
337 if (def_pos < interval->spill_definition_pos() - 2) { | |
338 // second definition found, so no spill optimization possible for this interval | |
339 interval->set_spill_state(noOptimization); | |
340 } else { | |
341 // two consecutive definitions (because of two-operand LIR form) | |
342 assert(block_of_op_with_id(def_pos) == block_of_op_with_id(interval->spill_definition_pos()), "block must be equal"); | |
343 } | |
344 break; | |
345 | |
346 case noOptimization: | |
347 // nothing to do | |
348 break; | |
349 | |
350 default: | |
351 assert(false, "other states not allowed at this time"); | |
352 } | |
353 } | |
354 | |
355 // called during register allocation | |
356 void LinearScan::change_spill_state(Interval* interval, int spill_pos) { | |
357 switch (interval->spill_state()) { | |
358 case oneDefinitionFound: { | |
359 int def_loop_depth = block_of_op_with_id(interval->spill_definition_pos())->loop_depth(); | |
360 int spill_loop_depth = block_of_op_with_id(spill_pos)->loop_depth(); | |
361 | |
362 if (def_loop_depth < spill_loop_depth) { | |
363 // the loop depth of the spilling position is higher then the loop depth | |
364 // at the definition of the interval -> move write to memory out of loop | |
365 // by storing at definitin of the interval | |
366 interval->set_spill_state(storeAtDefinition); | |
367 } else { | |
368 // the interval is currently spilled only once, so for now there is no | |
369 // reason to store the interval at the definition | |
370 interval->set_spill_state(oneMoveInserted); | |
371 } | |
372 break; | |
373 } | |
374 | |
375 case oneMoveInserted: { | |
376 // the interval is spilled more then once, so it is better to store it to | |
377 // memory at the definition | |
378 interval->set_spill_state(storeAtDefinition); | |
379 break; | |
380 } | |
381 | |
382 case storeAtDefinition: | |
383 case startInMemory: | |
384 case noOptimization: | |
385 case noDefinitionFound: | |
386 // nothing to do | |
387 break; | |
388 | |
389 default: | |
390 assert(false, "other states not allowed at this time"); | |
391 } | |
392 } | |
393 | |
394 | |
395 bool LinearScan::must_store_at_definition(const Interval* i) { | |
396 return i->is_split_parent() && i->spill_state() == storeAtDefinition; | |
397 } | |
398 | |
399 // called once before asignment of register numbers | |
400 void LinearScan::eliminate_spill_moves() { | |
401 TIME_LINEAR_SCAN(timer_eliminate_spill_moves); | |
402 TRACE_LINEAR_SCAN(3, tty->print_cr("***** Eliminating unnecessary spill moves")); | |
403 | |
404 // collect all intervals that must be stored after their definion. | |
405 // the list is sorted by Interval::spill_definition_pos | |
406 Interval* interval; | |
407 Interval* temp_list; | |
408 create_unhandled_lists(&interval, &temp_list, must_store_at_definition, NULL); | |
409 | |
410 #ifdef ASSERT | |
411 Interval* prev = NULL; | |
412 Interval* temp = interval; | |
413 while (temp != Interval::end()) { | |
414 assert(temp->spill_definition_pos() > 0, "invalid spill definition pos"); | |
415 if (prev != NULL) { | |
416 assert(temp->from() >= prev->from(), "intervals not sorted"); | |
417 assert(temp->spill_definition_pos() >= prev->spill_definition_pos(), "when intervals are sorted by from, then they must also be sorted by spill_definition_pos"); | |
418 } | |
419 | |
420 assert(temp->canonical_spill_slot() >= LinearScan::nof_regs, "interval has no spill slot assigned"); | |
421 assert(temp->spill_definition_pos() >= temp->from(), "invalid order"); | |
422 assert(temp->spill_definition_pos() <= temp->from() + 2, "only intervals defined once at their start-pos can be optimized"); | |
423 | |
424 TRACE_LINEAR_SCAN(4, tty->print_cr("interval %d (from %d to %d) must be stored at %d", temp->reg_num(), temp->from(), temp->to(), temp->spill_definition_pos())); | |
425 | |
426 temp = temp->next(); | |
427 } | |
428 #endif | |
429 | |
430 LIR_InsertionBuffer insertion_buffer; | |
431 int num_blocks = block_count(); | |
432 for (int i = 0; i < num_blocks; i++) { | |
433 BlockBegin* block = block_at(i); | |
434 LIR_OpList* instructions = block->lir()->instructions_list(); | |
435 int num_inst = instructions->length(); | |
436 bool has_new = false; | |
437 | |
438 // iterate all instructions of the block. skip the first because it is always a label | |
439 for (int j = 1; j < num_inst; j++) { | |
440 LIR_Op* op = instructions->at(j); | |
441 int op_id = op->id(); | |
442 | |
443 if (op_id == -1) { | |
444 // remove move from register to stack if the stack slot is guaranteed to be correct. | |
445 // only moves that have been inserted by LinearScan can be removed. | |
446 assert(op->code() == lir_move, "only moves can have a op_id of -1"); | |
447 assert(op->as_Op1() != NULL, "move must be LIR_Op1"); | |
448 assert(op->as_Op1()->result_opr()->is_virtual(), "LinearScan inserts only moves to virtual registers"); | |
449 | |
450 LIR_Op1* op1 = (LIR_Op1*)op; | |
451 Interval* interval = interval_at(op1->result_opr()->vreg_number()); | |
452 | |
453 if (interval->assigned_reg() >= LinearScan::nof_regs && interval->always_in_memory()) { | |
454 // move target is a stack slot that is always correct, so eliminate instruction | |
455 TRACE_LINEAR_SCAN(4, tty->print_cr("eliminating move from interval %d to %d", op1->in_opr()->vreg_number(), op1->result_opr()->vreg_number())); | |
456 instructions->at_put(j, NULL); // NULL-instructions are deleted by assign_reg_num | |
457 } | |
458 | |
459 } else { | |
460 // insert move from register to stack just after the beginning of the interval | |
461 assert(interval == Interval::end() || interval->spill_definition_pos() >= op_id, "invalid order"); | |
462 assert(interval == Interval::end() || (interval->is_split_parent() && interval->spill_state() == storeAtDefinition), "invalid interval"); | |
463 | |
464 while (interval != Interval::end() && interval->spill_definition_pos() == op_id) { | |
465 if (!has_new) { | |
466 // prepare insertion buffer (appended when all instructions of the block are processed) | |
467 insertion_buffer.init(block->lir()); | |
468 has_new = true; | |
469 } | |
470 | |
471 LIR_Opr from_opr = operand_for_interval(interval); | |
472 LIR_Opr to_opr = canonical_spill_opr(interval); | |
473 assert(from_opr->is_fixed_cpu() || from_opr->is_fixed_fpu(), "from operand must be a register"); | |
474 assert(to_opr->is_stack(), "to operand must be a stack slot"); | |
475 | |
476 insertion_buffer.move(j, from_opr, to_opr); | |
477 TRACE_LINEAR_SCAN(4, tty->print_cr("inserting move after definition of interval %d to stack slot %d at op_id %d", interval->reg_num(), interval->canonical_spill_slot() - LinearScan::nof_regs, op_id)); | |
478 | |
479 interval = interval->next(); | |
480 } | |
481 } | |
482 } // end of instruction iteration | |
483 | |
484 if (has_new) { | |
485 block->lir()->append(&insertion_buffer); | |
486 } | |
487 } // end of block iteration | |
488 | |
489 assert(interval == Interval::end(), "missed an interval"); | |
490 } | |
491 | |
492 | |
493 // ********** Phase 1: number all instructions in all blocks | |
494 // Compute depth-first and linear scan block orders, and number LIR_Op nodes for linear scan. | |
495 | |
496 void LinearScan::number_instructions() { | |
497 { | |
498 // dummy-timer to measure the cost of the timer itself | |
499 // (this time is then subtracted from all other timers to get the real value) | |
500 TIME_LINEAR_SCAN(timer_do_nothing); | |
501 } | |
502 TIME_LINEAR_SCAN(timer_number_instructions); | |
503 | |
504 // Assign IDs to LIR nodes and build a mapping, lir_ops, from ID to LIR_Op node. | |
505 int num_blocks = block_count(); | |
506 int num_instructions = 0; | |
507 int i; | |
508 for (i = 0; i < num_blocks; i++) { | |
509 num_instructions += block_at(i)->lir()->instructions_list()->length(); | |
510 } | |
511 | |
512 // initialize with correct length | |
513 _lir_ops = LIR_OpArray(num_instructions); | |
514 _block_of_op = BlockBeginArray(num_instructions); | |
515 | |
516 int op_id = 0; | |
517 int idx = 0; | |
518 | |
519 for (i = 0; i < num_blocks; i++) { | |
520 BlockBegin* block = block_at(i); | |
521 block->set_first_lir_instruction_id(op_id); | |
522 LIR_OpList* instructions = block->lir()->instructions_list(); | |
523 | |
524 int num_inst = instructions->length(); | |
525 for (int j = 0; j < num_inst; j++) { | |
526 LIR_Op* op = instructions->at(j); | |
527 op->set_id(op_id); | |
528 | |
529 _lir_ops.at_put(idx, op); | |
530 _block_of_op.at_put(idx, block); | |
531 assert(lir_op_with_id(op_id) == op, "must match"); | |
532 | |
533 idx++; | |
534 op_id += 2; // numbering of lir_ops by two | |
535 } | |
536 block->set_last_lir_instruction_id(op_id - 2); | |
537 } | |
538 assert(idx == num_instructions, "must match"); | |
539 assert(idx * 2 == op_id, "must match"); | |
540 | |
541 _has_call = BitMap(num_instructions); _has_call.clear(); | |
542 _has_info = BitMap(num_instructions); _has_info.clear(); | |
543 } | |
544 | |
545 | |
546 // ********** Phase 2: compute local live sets separately for each block | |
547 // (sets live_gen and live_kill for each block) | |
548 | |
549 void LinearScan::set_live_gen_kill(Value value, LIR_Op* op, BitMap& live_gen, BitMap& live_kill) { | |
550 LIR_Opr opr = value->operand(); | |
551 Constant* con = value->as_Constant(); | |
552 | |
553 // check some asumptions about debug information | |
554 assert(!value->type()->is_illegal(), "if this local is used by the interpreter it shouldn't be of indeterminate type"); | |
555 assert(con == NULL || opr->is_virtual() || opr->is_constant() || opr->is_illegal(), "asumption: Constant instructions have only constant operands"); | |
556 assert(con != NULL || opr->is_virtual(), "asumption: non-Constant instructions have only virtual operands"); | |
557 | |
558 if ((con == NULL || con->is_pinned()) && opr->is_register()) { | |
559 assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below"); | |
560 int reg = opr->vreg_number(); | |
561 if (!live_kill.at(reg)) { | |
562 live_gen.set_bit(reg); | |
563 TRACE_LINEAR_SCAN(4, tty->print_cr(" Setting live_gen for value %c%d, LIR op_id %d, register number %d", value->type()->tchar(), value->id(), op->id(), reg)); | |
564 } | |
565 } | |
566 } | |
567 | |
568 | |
569 void LinearScan::compute_local_live_sets() { | |
570 TIME_LINEAR_SCAN(timer_compute_local_live_sets); | |
571 | |
572 int num_blocks = block_count(); | |
573 int live_size = live_set_size(); | |
574 bool local_has_fpu_registers = false; | |
575 int local_num_calls = 0; | |
576 LIR_OpVisitState visitor; | |
577 | |
578 BitMap2D local_interval_in_loop = BitMap2D(_num_virtual_regs, num_loops()); | |
579 local_interval_in_loop.clear(); | |
580 | |
581 // iterate all blocks | |
582 for (int i = 0; i < num_blocks; i++) { | |
583 BlockBegin* block = block_at(i); | |
584 | |
585 BitMap live_gen(live_size); live_gen.clear(); | |
586 BitMap live_kill(live_size); live_kill.clear(); | |
587 | |
588 if (block->is_set(BlockBegin::exception_entry_flag)) { | |
589 // Phi functions at the begin of an exception handler are | |
590 // implicitly defined (= killed) at the beginning of the block. | |
591 for_each_phi_fun(block, phi, | |
592 live_kill.set_bit(phi->operand()->vreg_number()) | |
593 ); | |
594 } | |
595 | |
596 LIR_OpList* instructions = block->lir()->instructions_list(); | |
597 int num_inst = instructions->length(); | |
598 | |
599 // iterate all instructions of the block. skip the first because it is always a label | |
600 assert(visitor.no_operands(instructions->at(0)), "first operation must always be a label"); | |
601 for (int j = 1; j < num_inst; j++) { | |
602 LIR_Op* op = instructions->at(j); | |
603 | |
604 // visit operation to collect all operands | |
605 visitor.visit(op); | |
606 | |
607 if (visitor.has_call()) { | |
608 _has_call.set_bit(op->id() >> 1); | |
609 local_num_calls++; | |
610 } | |
611 if (visitor.info_count() > 0) { | |
612 _has_info.set_bit(op->id() >> 1); | |
613 } | |
614 | |
615 // iterate input operands of instruction | |
616 int k, n, reg; | |
617 n = visitor.opr_count(LIR_OpVisitState::inputMode); | |
618 for (k = 0; k < n; k++) { | |
619 LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::inputMode, k); | |
620 assert(opr->is_register(), "visitor should only return register operands"); | |
621 | |
622 if (opr->is_virtual_register()) { | |
623 assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below"); | |
624 reg = opr->vreg_number(); | |
625 if (!live_kill.at(reg)) { | |
626 live_gen.set_bit(reg); | |
627 TRACE_LINEAR_SCAN(4, tty->print_cr(" Setting live_gen for register %d at instruction %d", reg, op->id())); | |
628 } | |
629 if (block->loop_index() >= 0) { | |
630 local_interval_in_loop.set_bit(reg, block->loop_index()); | |
631 } | |
632 local_has_fpu_registers = local_has_fpu_registers || opr->is_virtual_fpu(); | |
633 } | |
634 | |
635 #ifdef ASSERT | |
636 // fixed intervals are never live at block boundaries, so | |
637 // they need not be processed in live sets. | |
638 // this is checked by these assertions to be sure about it. | |
639 // the entry block may have incoming values in registers, which is ok. | |
640 if (!opr->is_virtual_register() && block != ir()->start()) { | |
641 reg = reg_num(opr); | |
642 if (is_processed_reg_num(reg)) { | |
643 assert(live_kill.at(reg), "using fixed register that is not defined in this block"); | |
644 } | |
645 reg = reg_numHi(opr); | |
646 if (is_valid_reg_num(reg) && is_processed_reg_num(reg)) { | |
647 assert(live_kill.at(reg), "using fixed register that is not defined in this block"); | |
648 } | |
649 } | |
650 #endif | |
651 } | |
652 | |
653 // Add uses of live locals from interpreter's point of view for proper debug information generation | |
654 n = visitor.info_count(); | |
655 for (k = 0; k < n; k++) { | |
656 CodeEmitInfo* info = visitor.info_at(k); | |
657 ValueStack* stack = info->stack(); | |
658 for_each_state_value(stack, value, | |
659 set_live_gen_kill(value, op, live_gen, live_kill) | |
660 ); | |
661 } | |
662 | |
663 // iterate temp operands of instruction | |
664 n = visitor.opr_count(LIR_OpVisitState::tempMode); | |
665 for (k = 0; k < n; k++) { | |
666 LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::tempMode, k); | |
667 assert(opr->is_register(), "visitor should only return register operands"); | |
668 | |
669 if (opr->is_virtual_register()) { | |
670 assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below"); | |
671 reg = opr->vreg_number(); | |
672 live_kill.set_bit(reg); | |
673 if (block->loop_index() >= 0) { | |
674 local_interval_in_loop.set_bit(reg, block->loop_index()); | |
675 } | |
676 local_has_fpu_registers = local_has_fpu_registers || opr->is_virtual_fpu(); | |
677 } | |
678 | |
679 #ifdef ASSERT | |
680 // fixed intervals are never live at block boundaries, so | |
681 // they need not be processed in live sets | |
682 // process them only in debug mode so that this can be checked | |
683 if (!opr->is_virtual_register()) { | |
684 reg = reg_num(opr); | |
685 if (is_processed_reg_num(reg)) { | |
686 live_kill.set_bit(reg_num(opr)); | |
687 } | |
688 reg = reg_numHi(opr); | |
689 if (is_valid_reg_num(reg) && is_processed_reg_num(reg)) { | |
690 live_kill.set_bit(reg); | |
691 } | |
692 } | |
693 #endif | |
694 } | |
695 | |
696 // iterate output operands of instruction | |
697 n = visitor.opr_count(LIR_OpVisitState::outputMode); | |
698 for (k = 0; k < n; k++) { | |
699 LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::outputMode, k); | |
700 assert(opr->is_register(), "visitor should only return register operands"); | |
701 | |
702 if (opr->is_virtual_register()) { | |
703 assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below"); | |
704 reg = opr->vreg_number(); | |
705 live_kill.set_bit(reg); | |
706 if (block->loop_index() >= 0) { | |
707 local_interval_in_loop.set_bit(reg, block->loop_index()); | |
708 } | |
709 local_has_fpu_registers = local_has_fpu_registers || opr->is_virtual_fpu(); | |
710 } | |
711 | |
712 #ifdef ASSERT | |
713 // fixed intervals are never live at block boundaries, so | |
714 // they need not be processed in live sets | |
715 // process them only in debug mode so that this can be checked | |
716 if (!opr->is_virtual_register()) { | |
717 reg = reg_num(opr); | |
718 if (is_processed_reg_num(reg)) { | |
719 live_kill.set_bit(reg_num(opr)); | |
720 } | |
721 reg = reg_numHi(opr); | |
722 if (is_valid_reg_num(reg) && is_processed_reg_num(reg)) { | |
723 live_kill.set_bit(reg); | |
724 } | |
725 } | |
726 #endif | |
727 } | |
728 } // end of instruction iteration | |
729 | |
730 block->set_live_gen (live_gen); | |
731 block->set_live_kill(live_kill); | |
732 block->set_live_in (BitMap(live_size)); block->live_in().clear(); | |
733 block->set_live_out (BitMap(live_size)); block->live_out().clear(); | |
734 | |
735 TRACE_LINEAR_SCAN(4, tty->print("live_gen B%d ", block->block_id()); print_bitmap(block->live_gen())); | |
736 TRACE_LINEAR_SCAN(4, tty->print("live_kill B%d ", block->block_id()); print_bitmap(block->live_kill())); | |
737 } // end of block iteration | |
738 | |
739 // propagate local calculated information into LinearScan object | |
740 _has_fpu_registers = local_has_fpu_registers; | |
741 compilation()->set_has_fpu_code(local_has_fpu_registers); | |
742 | |
743 _num_calls = local_num_calls; | |
744 _interval_in_loop = local_interval_in_loop; | |
745 } | |
746 | |
747 | |
748 // ********** Phase 3: perform a backward dataflow analysis to compute global live sets | |
749 // (sets live_in and live_out for each block) | |
750 | |
751 void LinearScan::compute_global_live_sets() { | |
752 TIME_LINEAR_SCAN(timer_compute_global_live_sets); | |
753 | |
754 int num_blocks = block_count(); | |
755 bool change_occurred; | |
756 bool change_occurred_in_block; | |
757 int iteration_count = 0; | |
758 BitMap live_out(live_set_size()); live_out.clear(); // scratch set for calculations | |
759 | |
760 // Perform a backward dataflow analysis to compute live_out and live_in for each block. | |
761 // The loop is executed until a fixpoint is reached (no changes in an iteration) | |
762 // Exception handlers must be processed because not all live values are | |
763 // present in the state array, e.g. because of global value numbering | |
764 do { | |
765 change_occurred = false; | |
766 | |
767 // iterate all blocks in reverse order | |
768 for (int i = num_blocks - 1; i >= 0; i--) { | |
769 BlockBegin* block = block_at(i); | |
770 | |
771 change_occurred_in_block = false; | |
772 | |
773 // live_out(block) is the union of live_in(sux), for successors sux of block | |
774 int n = block->number_of_sux(); | |
775 int e = block->number_of_exception_handlers(); | |
776 if (n + e > 0) { | |
777 // block has successors | |
778 if (n > 0) { | |
779 live_out.set_from(block->sux_at(0)->live_in()); | |
780 for (int j = 1; j < n; j++) { | |
781 live_out.set_union(block->sux_at(j)->live_in()); | |
782 } | |
783 } else { | |
784 live_out.clear(); | |
785 } | |
786 for (int j = 0; j < e; j++) { | |
787 live_out.set_union(block->exception_handler_at(j)->live_in()); | |
788 } | |
789 | |
790 if (!block->live_out().is_same(live_out)) { | |
791 // A change occurred. Swap the old and new live out sets to avoid copying. | |
792 BitMap temp = block->live_out(); | |
793 block->set_live_out(live_out); | |
794 live_out = temp; | |
795 | |
796 change_occurred = true; | |
797 change_occurred_in_block = true; | |
798 } | |
799 } | |
800 | |
801 if (iteration_count == 0 || change_occurred_in_block) { | |
802 // live_in(block) is the union of live_gen(block) with (live_out(block) & !live_kill(block)) | |
803 // note: live_in has to be computed only in first iteration or if live_out has changed! | |
804 BitMap live_in = block->live_in(); | |
805 live_in.set_from(block->live_out()); | |
806 live_in.set_difference(block->live_kill()); | |
807 live_in.set_union(block->live_gen()); | |
808 } | |
809 | |
810 #ifndef PRODUCT | |
811 if (TraceLinearScanLevel >= 4) { | |
812 char c = ' '; | |
813 if (iteration_count == 0 || change_occurred_in_block) { | |
814 c = '*'; | |
815 } | |
816 tty->print("(%d) live_in%c B%d ", iteration_count, c, block->block_id()); print_bitmap(block->live_in()); | |
817 tty->print("(%d) live_out%c B%d ", iteration_count, c, block->block_id()); print_bitmap(block->live_out()); | |
818 } | |
819 #endif | |
820 } | |
821 iteration_count++; | |
822 | |
823 if (change_occurred && iteration_count > 50) { | |
824 BAILOUT("too many iterations in compute_global_live_sets"); | |
825 } | |
826 } while (change_occurred); | |
827 | |
828 | |
829 #ifdef ASSERT | |
830 // check that fixed intervals are not live at block boundaries | |
831 // (live set must be empty at fixed intervals) | |
832 for (int i = 0; i < num_blocks; i++) { | |
833 BlockBegin* block = block_at(i); | |
834 for (int j = 0; j < LIR_OprDesc::vreg_base; j++) { | |
835 assert(block->live_in().at(j) == false, "live_in set of fixed register must be empty"); | |
836 assert(block->live_out().at(j) == false, "live_out set of fixed register must be empty"); | |
837 assert(block->live_gen().at(j) == false, "live_gen set of fixed register must be empty"); | |
838 } | |
839 } | |
840 #endif | |
841 | |
842 // check that the live_in set of the first block is empty | |
843 BitMap live_in_args(ir()->start()->live_in().size()); | |
844 live_in_args.clear(); | |
845 if (!ir()->start()->live_in().is_same(live_in_args)) { | |
846 #ifdef ASSERT | |
847 tty->print_cr("Error: live_in set of first block must be empty (when this fails, virtual registers are used before they are defined)"); | |
848 tty->print_cr("affected registers:"); | |
849 print_bitmap(ir()->start()->live_in()); | |
850 | |
851 // print some additional information to simplify debugging | |
852 for (unsigned int i = 0; i < ir()->start()->live_in().size(); i++) { | |
853 if (ir()->start()->live_in().at(i)) { | |
854 Instruction* instr = gen()->instruction_for_vreg(i); | |
855 tty->print_cr("* vreg %d (HIR instruction %c%d)", i, instr == NULL ? ' ' : instr->type()->tchar(), instr == NULL ? 0 : instr->id()); | |
856 | |
857 for (int j = 0; j < num_blocks; j++) { | |
858 BlockBegin* block = block_at(j); | |
859 if (block->live_gen().at(i)) { | |
860 tty->print_cr(" used in block B%d", block->block_id()); | |
861 } | |
862 if (block->live_kill().at(i)) { | |
863 tty->print_cr(" defined in block B%d", block->block_id()); | |
864 } | |
865 } | |
866 } | |
867 } | |
868 | |
869 #endif | |
870 // when this fails, virtual registers are used before they are defined. | |
871 assert(false, "live_in set of first block must be empty"); | |
872 // bailout of if this occurs in product mode. | |
873 bailout("live_in set of first block not empty"); | |
874 } | |
875 } | |
876 | |
877 | |
878 // ********** Phase 4: build intervals | |
879 // (fills the list _intervals) | |
880 | |
881 void LinearScan::add_use(Value value, int from, int to, IntervalUseKind use_kind) { | |
882 assert(!value->type()->is_illegal(), "if this value is used by the interpreter it shouldn't be of indeterminate type"); | |
883 LIR_Opr opr = value->operand(); | |
884 Constant* con = value->as_Constant(); | |
885 | |
886 if ((con == NULL || con->is_pinned()) && opr->is_register()) { | |
887 assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below"); | |
888 add_use(opr, from, to, use_kind); | |
889 } | |
890 } | |
891 | |
892 | |
893 void LinearScan::add_def(LIR_Opr opr, int def_pos, IntervalUseKind use_kind) { | |
894 TRACE_LINEAR_SCAN(2, tty->print(" def "); opr->print(tty); tty->print_cr(" def_pos %d (%d)", def_pos, use_kind)); | |
895 assert(opr->is_register(), "should not be called otherwise"); | |
896 | |
897 if (opr->is_virtual_register()) { | |
898 assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below"); | |
899 add_def(opr->vreg_number(), def_pos, use_kind, opr->type_register()); | |
900 | |
901 } else { | |
902 int reg = reg_num(opr); | |
903 if (is_processed_reg_num(reg)) { | |
904 add_def(reg, def_pos, use_kind, opr->type_register()); | |
905 } | |
906 reg = reg_numHi(opr); | |
907 if (is_valid_reg_num(reg) && is_processed_reg_num(reg)) { | |
908 add_def(reg, def_pos, use_kind, opr->type_register()); | |
909 } | |
910 } | |
911 } | |
912 | |
913 void LinearScan::add_use(LIR_Opr opr, int from, int to, IntervalUseKind use_kind) { | |
914 TRACE_LINEAR_SCAN(2, tty->print(" use "); opr->print(tty); tty->print_cr(" from %d to %d (%d)", from, to, use_kind)); | |
915 assert(opr->is_register(), "should not be called otherwise"); | |
916 | |
917 if (opr->is_virtual_register()) { | |
918 assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below"); | |
919 add_use(opr->vreg_number(), from, to, use_kind, opr->type_register()); | |
920 | |
921 } else { | |
922 int reg = reg_num(opr); | |
923 if (is_processed_reg_num(reg)) { | |
924 add_use(reg, from, to, use_kind, opr->type_register()); | |
925 } | |
926 reg = reg_numHi(opr); | |
927 if (is_valid_reg_num(reg) && is_processed_reg_num(reg)) { | |
928 add_use(reg, from, to, use_kind, opr->type_register()); | |
929 } | |
930 } | |
931 } | |
932 | |
933 void LinearScan::add_temp(LIR_Opr opr, int temp_pos, IntervalUseKind use_kind) { | |
934 TRACE_LINEAR_SCAN(2, tty->print(" temp "); opr->print(tty); tty->print_cr(" temp_pos %d (%d)", temp_pos, use_kind)); | |
935 assert(opr->is_register(), "should not be called otherwise"); | |
936 | |
937 if (opr->is_virtual_register()) { | |
938 assert(reg_num(opr) == opr->vreg_number() && !is_valid_reg_num(reg_numHi(opr)), "invalid optimization below"); | |
939 add_temp(opr->vreg_number(), temp_pos, use_kind, opr->type_register()); | |
940 | |
941 } else { | |
942 int reg = reg_num(opr); | |
943 if (is_processed_reg_num(reg)) { | |
944 add_temp(reg, temp_pos, use_kind, opr->type_register()); | |
945 } | |
946 reg = reg_numHi(opr); | |
947 if (is_valid_reg_num(reg) && is_processed_reg_num(reg)) { | |
948 add_temp(reg, temp_pos, use_kind, opr->type_register()); | |
949 } | |
950 } | |
951 } | |
952 | |
953 | |
954 void LinearScan::add_def(int reg_num, int def_pos, IntervalUseKind use_kind, BasicType type) { | |
955 Interval* interval = interval_at(reg_num); | |
956 if (interval != NULL) { | |
957 assert(interval->reg_num() == reg_num, "wrong interval"); | |
958 | |
959 if (type != T_ILLEGAL) { | |
960 interval->set_type(type); | |
961 } | |
962 | |
963 Range* r = interval->first(); | |
964 if (r->from() <= def_pos) { | |
965 // Update the starting point (when a range is first created for a use, its | |
966 // start is the beginning of the current block until a def is encountered.) | |
967 r->set_from(def_pos); | |
968 interval->add_use_pos(def_pos, use_kind); | |
969 | |
970 } else { | |
971 // Dead value - make vacuous interval | |
972 // also add use_kind for dead intervals | |
973 interval->add_range(def_pos, def_pos + 1); | |
974 interval->add_use_pos(def_pos, use_kind); | |
975 TRACE_LINEAR_SCAN(2, tty->print_cr("Warning: def of reg %d at %d occurs without use", reg_num, def_pos)); | |
976 } | |
977 | |
978 } else { | |
979 // Dead value - make vacuous interval | |
980 // also add use_kind for dead intervals | |
981 interval = create_interval(reg_num); | |
982 if (type != T_ILLEGAL) { | |
983 interval->set_type(type); | |
984 } | |
985 | |
986 interval->add_range(def_pos, def_pos + 1); | |
987 interval->add_use_pos(def_pos, use_kind); | |
988 TRACE_LINEAR_SCAN(2, tty->print_cr("Warning: dead value %d at %d in live intervals", reg_num, def_pos)); | |
989 } | |
990 | |
991 change_spill_definition_pos(interval, def_pos); | |
992 if (use_kind == noUse && interval->spill_state() <= startInMemory) { | |
993 // detection of method-parameters and roundfp-results | |
994 // TODO: move this directly to position where use-kind is computed | |
995 interval->set_spill_state(startInMemory); | |
996 } | |
997 } | |
998 | |
999 void LinearScan::add_use(int reg_num, int from, int to, IntervalUseKind use_kind, BasicType type) { | |
1000 Interval* interval = interval_at(reg_num); | |
1001 if (interval == NULL) { | |
1002 interval = create_interval(reg_num); | |
1003 } | |
1004 assert(interval->reg_num() == reg_num, "wrong interval"); | |
1005 | |
1006 if (type != T_ILLEGAL) { | |
1007 interval->set_type(type); | |
1008 } | |
1009 | |
1010 interval->add_range(from, to); | |
1011 interval->add_use_pos(to, use_kind); | |
1012 } | |
1013 | |
1014 void LinearScan::add_temp(int reg_num, int temp_pos, IntervalUseKind use_kind, BasicType type) { | |
1015 Interval* interval = interval_at(reg_num); | |
1016 if (interval == NULL) { | |
1017 interval = create_interval(reg_num); | |
1018 } | |
1019 assert(interval->reg_num() == reg_num, "wrong interval"); | |
1020 | |
1021 if (type != T_ILLEGAL) { | |
1022 interval->set_type(type); | |
1023 } | |
1024 | |
1025 interval->add_range(temp_pos, temp_pos + 1); | |
1026 interval->add_use_pos(temp_pos, use_kind); | |
1027 } | |
1028 | |
1029 | |
1030 // the results of this functions are used for optimizing spilling and reloading | |
1031 // if the functions return shouldHaveRegister and the interval is spilled, | |
1032 // it is not reloaded to a register. | |
1033 IntervalUseKind LinearScan::use_kind_of_output_operand(LIR_Op* op, LIR_Opr opr) { | |
1034 if (op->code() == lir_move) { | |
1035 assert(op->as_Op1() != NULL, "lir_move must be LIR_Op1"); | |
1036 LIR_Op1* move = (LIR_Op1*)op; | |
1037 LIR_Opr res = move->result_opr(); | |
1038 bool result_in_memory = res->is_virtual() && gen()->is_vreg_flag_set(res->vreg_number(), LIRGenerator::must_start_in_memory); | |
1039 | |
1040 if (result_in_memory) { | |
1041 // Begin of an interval with must_start_in_memory set. | |
1042 // This interval will always get a stack slot first, so return noUse. | |
1043 return noUse; | |
1044 | |
1045 } else if (move->in_opr()->is_stack()) { | |
1046 // method argument (condition must be equal to handle_method_arguments) | |
1047 return noUse; | |
1048 | |
1049 } else if (move->in_opr()->is_register() && move->result_opr()->is_register()) { | |
1050 // Move from register to register | |
1051 if (block_of_op_with_id(op->id())->is_set(BlockBegin::osr_entry_flag)) { | |
1052 // special handling of phi-function moves inside osr-entry blocks | |
1053 // input operand must have a register instead of output operand (leads to better register allocation) | |
1054 return shouldHaveRegister; | |
1055 } | |
1056 } | |
1057 } | |
1058 | |
1059 if (opr->is_virtual() && | |
1060 gen()->is_vreg_flag_set(opr->vreg_number(), LIRGenerator::must_start_in_memory)) { | |
1061 // result is a stack-slot, so prevent immediate reloading | |
1062 return noUse; | |
1063 } | |
1064 | |
1065 // all other operands require a register | |
1066 return mustHaveRegister; | |
1067 } | |
1068 | |
1069 IntervalUseKind LinearScan::use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr) { | |
1070 if (op->code() == lir_move) { | |
1071 assert(op->as_Op1() != NULL, "lir_move must be LIR_Op1"); | |
1072 LIR_Op1* move = (LIR_Op1*)op; | |
1073 LIR_Opr res = move->result_opr(); | |
1074 bool result_in_memory = res->is_virtual() && gen()->is_vreg_flag_set(res->vreg_number(), LIRGenerator::must_start_in_memory); | |
1075 | |
1076 if (result_in_memory) { | |
1077 // Move to an interval with must_start_in_memory set. | |
1078 // To avoid moves from stack to stack (not allowed) force the input operand to a register | |
1079 return mustHaveRegister; | |
1080 | |
1081 } else if (move->in_opr()->is_register() && move->result_opr()->is_register()) { | |
1082 // Move from register to register | |
1083 if (block_of_op_with_id(op->id())->is_set(BlockBegin::osr_entry_flag)) { | |
1084 // special handling of phi-function moves inside osr-entry blocks | |
1085 // input operand must have a register instead of output operand (leads to better register allocation) | |
1086 return mustHaveRegister; | |
1087 } | |
1088 | |
1089 // The input operand is not forced to a register (moves from stack to register are allowed), | |
1090 // but it is faster if the input operand is in a register | |
1091 return shouldHaveRegister; | |
1092 } | |
1093 } | |
1094 | |
1095 | |
304 | 1096 #ifdef X86 |
0 | 1097 if (op->code() == lir_cmove) { |
1098 // conditional moves can handle stack operands | |
1099 assert(op->result_opr()->is_register(), "result must always be in a register"); | |
1100 return shouldHaveRegister; | |
1101 } | |
1102 | |
1103 // optimizations for second input operand of arithmehtic operations on Intel | |
1104 // this operand is allowed to be on the stack in some cases | |
1105 BasicType opr_type = opr->type_register(); | |
1106 if (opr_type == T_FLOAT || opr_type == T_DOUBLE) { | |
1107 if ((UseSSE == 1 && opr_type == T_FLOAT) || UseSSE >= 2) { | |
1108 // SSE float instruction (T_DOUBLE only supported with SSE2) | |
1109 switch (op->code()) { | |
1110 case lir_cmp: | |
1111 case lir_add: | |
1112 case lir_sub: | |
1113 case lir_mul: | |
1114 case lir_div: | |
1115 { | |
1116 assert(op->as_Op2() != NULL, "must be LIR_Op2"); | |
1117 LIR_Op2* op2 = (LIR_Op2*)op; | |
1118 if (op2->in_opr1() != op2->in_opr2() && op2->in_opr2() == opr) { | |
1119 assert((op2->result_opr()->is_register() || op->code() == lir_cmp) && op2->in_opr1()->is_register(), "cannot mark second operand as stack if others are not in register"); | |
1120 return shouldHaveRegister; | |
1121 } | |
1122 } | |
1123 } | |
1124 } else { | |
1125 // FPU stack float instruction | |
1126 switch (op->code()) { | |
1127 case lir_add: | |
1128 case lir_sub: | |
1129 case lir_mul: | |
1130 case lir_div: | |
1131 { | |
1132 assert(op->as_Op2() != NULL, "must be LIR_Op2"); | |
1133 LIR_Op2* op2 = (LIR_Op2*)op; | |
1134 if (op2->in_opr1() != op2->in_opr2() && op2->in_opr2() == opr) { | |
1135 assert((op2->result_opr()->is_register() || op->code() == lir_cmp) && op2->in_opr1()->is_register(), "cannot mark second operand as stack if others are not in register"); | |
1136 return shouldHaveRegister; | |
1137 } | |
1138 } | |
1139 } | |
1140 } | |
1141 | |
1142 } else if (opr_type != T_LONG) { | |
1143 // integer instruction (note: long operands must always be in register) | |
1144 switch (op->code()) { | |
1145 case lir_cmp: | |
1146 case lir_add: | |
1147 case lir_sub: | |
1148 case lir_logic_and: | |
1149 case lir_logic_or: | |
1150 case lir_logic_xor: | |
1151 { | |
1152 assert(op->as_Op2() != NULL, "must be LIR_Op2"); | |
1153 LIR_Op2* op2 = (LIR_Op2*)op; | |
1154 if (op2->in_opr1() != op2->in_opr2() && op2->in_opr2() == opr) { | |
1155 assert((op2->result_opr()->is_register() || op->code() == lir_cmp) && op2->in_opr1()->is_register(), "cannot mark second operand as stack if others are not in register"); | |
1156 return shouldHaveRegister; | |
1157 } | |
1158 } | |
1159 } | |
1160 } | |
304 | 1161 #endif // X86 |
0 | 1162 |
1163 // all other operands require a register | |
1164 return mustHaveRegister; | |
1165 } | |
1166 | |
1167 | |
1168 void LinearScan::handle_method_arguments(LIR_Op* op) { | |
1169 // special handling for method arguments (moves from stack to virtual register): | |
1170 // the interval gets no register assigned, but the stack slot. | |
1171 // it is split before the first use by the register allocator. | |
1172 | |
1173 if (op->code() == lir_move) { | |
1174 assert(op->as_Op1() != NULL, "must be LIR_Op1"); | |
1175 LIR_Op1* move = (LIR_Op1*)op; | |
1176 | |
1177 if (move->in_opr()->is_stack()) { | |
1178 #ifdef ASSERT | |
1179 int arg_size = compilation()->method()->arg_size(); | |
1180 LIR_Opr o = move->in_opr(); | |
1181 if (o->is_single_stack()) { | |
1182 assert(o->single_stack_ix() >= 0 && o->single_stack_ix() < arg_size, "out of range"); | |
1183 } else if (o->is_double_stack()) { | |
1184 assert(o->double_stack_ix() >= 0 && o->double_stack_ix() < arg_size, "out of range"); | |
1185 } else { | |
1186 ShouldNotReachHere(); | |
1187 } | |
1188 | |
1189 assert(move->id() > 0, "invalid id"); | |
1190 assert(block_of_op_with_id(move->id())->number_of_preds() == 0, "move from stack must be in first block"); | |
1191 assert(move->result_opr()->is_virtual(), "result of move must be a virtual register"); | |
1192 | |
1193 TRACE_LINEAR_SCAN(4, tty->print_cr("found move from stack slot %d to vreg %d", o->is_single_stack() ? o->single_stack_ix() : o->double_stack_ix(), reg_num(move->result_opr()))); | |
1194 #endif | |
1195 | |
1196 Interval* interval = interval_at(reg_num(move->result_opr())); | |
1197 | |
1198 int stack_slot = LinearScan::nof_regs + (move->in_opr()->is_single_stack() ? move->in_opr()->single_stack_ix() : move->in_opr()->double_stack_ix()); | |
1199 interval->set_canonical_spill_slot(stack_slot); | |
1200 interval->assign_reg(stack_slot); | |
1201 } | |
1202 } | |
1203 } | |
1204 | |
1205 void LinearScan::handle_doubleword_moves(LIR_Op* op) { | |
1206 // special handling for doubleword move from memory to register: | |
1207 // in this case the registers of the input address and the result | |
1208 // registers must not overlap -> add a temp range for the input registers | |
1209 if (op->code() == lir_move) { | |
1210 assert(op->as_Op1() != NULL, "must be LIR_Op1"); | |
1211 LIR_Op1* move = (LIR_Op1*)op; | |
1212 | |
1213 if (move->result_opr()->is_double_cpu() && move->in_opr()->is_pointer()) { | |
1214 LIR_Address* address = move->in_opr()->as_address_ptr(); | |
1215 if (address != NULL) { | |
1216 if (address->base()->is_valid()) { | |
1217 add_temp(address->base(), op->id(), noUse); | |
1218 } | |
1219 if (address->index()->is_valid()) { | |
1220 add_temp(address->index(), op->id(), noUse); | |
1221 } | |
1222 } | |
1223 } | |
1224 } | |
1225 } | |
1226 | |
1227 void LinearScan::add_register_hints(LIR_Op* op) { | |
1228 switch (op->code()) { | |
1229 case lir_move: // fall through | |
1230 case lir_convert: { | |
1231 assert(op->as_Op1() != NULL, "lir_move, lir_convert must be LIR_Op1"); | |
1232 LIR_Op1* move = (LIR_Op1*)op; | |
1233 | |
1234 LIR_Opr move_from = move->in_opr(); | |
1235 LIR_Opr move_to = move->result_opr(); | |
1236 | |
1237 if (move_to->is_register() && move_from->is_register()) { | |
1238 Interval* from = interval_at(reg_num(move_from)); | |
1239 Interval* to = interval_at(reg_num(move_to)); | |
1240 if (from != NULL && to != NULL) { | |
1241 to->set_register_hint(from); | |
1242 TRACE_LINEAR_SCAN(4, tty->print_cr("operation at op_id %d: added hint from interval %d to %d", move->id(), from->reg_num(), to->reg_num())); | |
1243 } | |
1244 } | |
1245 break; | |
1246 } | |
1247 case lir_cmove: { | |
1248 assert(op->as_Op2() != NULL, "lir_cmove must be LIR_Op2"); | |
1249 LIR_Op2* cmove = (LIR_Op2*)op; | |
1250 | |
1251 LIR_Opr move_from = cmove->in_opr1(); | |
1252 LIR_Opr move_to = cmove->result_opr(); | |
1253 | |
1254 if (move_to->is_register() && move_from->is_register()) { | |
1255 Interval* from = interval_at(reg_num(move_from)); | |
1256 Interval* to = interval_at(reg_num(move_to)); | |
1257 if (from != NULL && to != NULL) { | |
1258 to->set_register_hint(from); | |
1259 TRACE_LINEAR_SCAN(4, tty->print_cr("operation at op_id %d: added hint from interval %d to %d", cmove->id(), from->reg_num(), to->reg_num())); | |
1260 } | |
1261 } | |
1262 break; | |
1263 } | |
1264 } | |
1265 } | |
1266 | |
1267 | |
1268 void LinearScan::build_intervals() { | |
1269 TIME_LINEAR_SCAN(timer_build_intervals); | |
1270 | |
1271 // initialize interval list with expected number of intervals | |
1272 // (32 is added to have some space for split children without having to resize the list) | |
1273 _intervals = IntervalList(num_virtual_regs() + 32); | |
1274 // initialize all slots that are used by build_intervals | |
1275 _intervals.at_put_grow(num_virtual_regs() - 1, NULL, NULL); | |
1276 | |
1277 // create a list with all caller-save registers (cpu, fpu, xmm) | |
1278 // when an instruction is a call, a temp range is created for all these registers | |
1279 int num_caller_save_registers = 0; | |
1280 int caller_save_registers[LinearScan::nof_regs]; | |
1281 | |
1282 int i; | |
2002 | 1283 for (i = 0; i < FrameMap::nof_caller_save_cpu_regs(); i++) { |
0 | 1284 LIR_Opr opr = FrameMap::caller_save_cpu_reg_at(i); |
1285 assert(opr->is_valid() && opr->is_register(), "FrameMap should not return invalid operands"); | |
1286 assert(reg_numHi(opr) == -1, "missing addition of range for hi-register"); | |
1287 caller_save_registers[num_caller_save_registers++] = reg_num(opr); | |
1288 } | |
1289 | |
1290 // temp ranges for fpu registers are only created when the method has | |
1291 // virtual fpu operands. Otherwise no allocation for fpu registers is | |
1292 // perfomed and so the temp ranges would be useless | |
1293 if (has_fpu_registers()) { | |
304 | 1294 #ifdef X86 |
0 | 1295 if (UseSSE < 2) { |
1296 #endif | |
1297 for (i = 0; i < FrameMap::nof_caller_save_fpu_regs; i++) { | |
1298 LIR_Opr opr = FrameMap::caller_save_fpu_reg_at(i); | |
1299 assert(opr->is_valid() && opr->is_register(), "FrameMap should not return invalid operands"); | |
1300 assert(reg_numHi(opr) == -1, "missing addition of range for hi-register"); | |
1301 caller_save_registers[num_caller_save_registers++] = reg_num(opr); | |
1302 } | |
304 | 1303 #ifdef X86 |
0 | 1304 } |
1305 if (UseSSE > 0) { | |
1306 for (i = 0; i < FrameMap::nof_caller_save_xmm_regs; i++) { | |
1307 LIR_Opr opr = FrameMap::caller_save_xmm_reg_at(i); | |
1308 assert(opr->is_valid() && opr->is_register(), "FrameMap should not return invalid operands"); | |
1309 assert(reg_numHi(opr) == -1, "missing addition of range for hi-register"); | |
1310 caller_save_registers[num_caller_save_registers++] = reg_num(opr); | |
1311 } | |
1312 } | |
1313 #endif | |
1314 } | |
1315 assert(num_caller_save_registers <= LinearScan::nof_regs, "out of bounds"); | |
1316 | |
1317 | |
1318 LIR_OpVisitState visitor; | |
1319 | |
1320 // iterate all blocks in reverse order | |
1321 for (i = block_count() - 1; i >= 0; i--) { | |
1322 BlockBegin* block = block_at(i); | |
1323 LIR_OpList* instructions = block->lir()->instructions_list(); | |
1324 int block_from = block->first_lir_instruction_id(); | |
1325 int block_to = block->last_lir_instruction_id(); | |
1326 | |
1327 assert(block_from == instructions->at(0)->id(), "must be"); | |
1328 assert(block_to == instructions->at(instructions->length() - 1)->id(), "must be"); | |
1329 | |
1330 // Update intervals for registers live at the end of this block; | |
1331 BitMap live = block->live_out(); | |
304 | 1332 int size = (int)live.size(); |
1333 for (int number = (int)live.get_next_one_offset(0, size); number < size; number = (int)live.get_next_one_offset(number + 1, size)) { | |
0 | 1334 assert(live.at(number), "should not stop here otherwise"); |
1335 assert(number >= LIR_OprDesc::vreg_base, "fixed intervals must not be live on block bounds"); | |
1336 TRACE_LINEAR_SCAN(2, tty->print_cr("live in %d to %d", number, block_to + 2)); | |
1337 | |
1338 add_use(number, block_from, block_to + 2, noUse, T_ILLEGAL); | |
1339 | |
1340 // add special use positions for loop-end blocks when the | |
1341 // interval is used anywhere inside this loop. It's possible | |
1342 // that the block was part of a non-natural loop, so it might | |
1343 // have an invalid loop index. | |
1344 if (block->is_set(BlockBegin::linear_scan_loop_end_flag) && | |
1345 block->loop_index() != -1 && | |
1346 is_interval_in_loop(number, block->loop_index())) { | |
1347 interval_at(number)->add_use_pos(block_to + 1, loopEndMarker); | |
1348 } | |
1349 } | |
1350 | |
1351 // iterate all instructions of the block in reverse order. | |
1352 // skip the first instruction because it is always a label | |
1353 // definitions of intervals are processed before uses | |
1354 assert(visitor.no_operands(instructions->at(0)), "first operation must always be a label"); | |
1355 for (int j = instructions->length() - 1; j >= 1; j--) { | |
1356 LIR_Op* op = instructions->at(j); | |
1357 int op_id = op->id(); | |
1358 | |
1359 // visit operation to collect all operands | |
1360 visitor.visit(op); | |
1361 | |
1362 // add a temp range for each register if operation destroys caller-save registers | |
1363 if (visitor.has_call()) { | |
1364 for (int k = 0; k < num_caller_save_registers; k++) { | |
1365 add_temp(caller_save_registers[k], op_id, noUse, T_ILLEGAL); | |
1366 } | |
1367 TRACE_LINEAR_SCAN(4, tty->print_cr("operation destroys all caller-save registers")); | |
1368 } | |
1369 | |
1370 // Add any platform dependent temps | |
1371 pd_add_temps(op); | |
1372 | |
1373 // visit definitions (output and temp operands) | |
1374 int k, n; | |
1375 n = visitor.opr_count(LIR_OpVisitState::outputMode); | |
1376 for (k = 0; k < n; k++) { | |
1377 LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::outputMode, k); | |
1378 assert(opr->is_register(), "visitor should only return register operands"); | |
1379 add_def(opr, op_id, use_kind_of_output_operand(op, opr)); | |
1380 } | |
1381 | |
1382 n = visitor.opr_count(LIR_OpVisitState::tempMode); | |
1383 for (k = 0; k < n; k++) { | |
1384 LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::tempMode, k); | |
1385 assert(opr->is_register(), "visitor should only return register operands"); | |
1386 add_temp(opr, op_id, mustHaveRegister); | |
1387 } | |
1388 | |
1389 // visit uses (input operands) | |
1390 n = visitor.opr_count(LIR_OpVisitState::inputMode); | |
1391 for (k = 0; k < n; k++) { | |
1392 LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::inputMode, k); | |
1393 assert(opr->is_register(), "visitor should only return register operands"); | |
1394 add_use(opr, block_from, op_id, use_kind_of_input_operand(op, opr)); | |
1395 } | |
1396 | |
1397 // Add uses of live locals from interpreter's point of view for proper | |
1398 // debug information generation | |
1399 // Treat these operands as temp values (if the life range is extended | |
1400 // to a call site, the value would be in a register at the call otherwise) | |
1401 n = visitor.info_count(); | |
1402 for (k = 0; k < n; k++) { | |
1403 CodeEmitInfo* info = visitor.info_at(k); | |
1404 ValueStack* stack = info->stack(); | |
1405 for_each_state_value(stack, value, | |
1406 add_use(value, block_from, op_id + 1, noUse); | |
1407 ); | |
1408 } | |
1409 | |
1410 // special steps for some instructions (especially moves) | |
1411 handle_method_arguments(op); | |
1412 handle_doubleword_moves(op); | |
1413 add_register_hints(op); | |
1414 | |
1415 } // end of instruction iteration | |
1416 } // end of block iteration | |
1417 | |
1418 | |
1419 // add the range [0, 1[ to all fixed intervals | |
1420 // -> the register allocator need not handle unhandled fixed intervals | |
1421 for (int n = 0; n < LinearScan::nof_regs; n++) { | |
1422 Interval* interval = interval_at(n); | |
1423 if (interval != NULL) { | |
1424 interval->add_range(0, 1); | |
1425 } | |
1426 } | |
1427 } | |
1428 | |
1429 | |
1430 // ********** Phase 5: actual register allocation | |
1431 | |
1432 int LinearScan::interval_cmp(Interval** a, Interval** b) { | |
1433 if (*a != NULL) { | |
1434 if (*b != NULL) { | |
1435 return (*a)->from() - (*b)->from(); | |
1436 } else { | |
1437 return -1; | |
1438 } | |
1439 } else { | |
1440 if (*b != NULL) { | |
1441 return 1; | |
1442 } else { | |
1443 return 0; | |
1444 } | |
1445 } | |
1446 } | |
1447 | |
1448 #ifndef PRODUCT | |
1449 bool LinearScan::is_sorted(IntervalArray* intervals) { | |
1450 int from = -1; | |
1451 int i, j; | |
1452 for (i = 0; i < intervals->length(); i ++) { | |
1453 Interval* it = intervals->at(i); | |
1454 if (it != NULL) { | |
1455 if (from > it->from()) { | |
1456 assert(false, ""); | |
1457 return false; | |
1458 } | |
1459 from = it->from(); | |
1460 } | |
1461 } | |
1462 | |
1463 // check in both directions if sorted list and unsorted list contain same intervals | |
1464 for (i = 0; i < interval_count(); i++) { | |
1465 if (interval_at(i) != NULL) { | |
1466 int num_found = 0; | |
1467 for (j = 0; j < intervals->length(); j++) { | |
1468 if (interval_at(i) == intervals->at(j)) { | |
1469 num_found++; | |
1470 } | |
1471 } | |
1472 assert(num_found == 1, "lists do not contain same intervals"); | |
1473 } | |
1474 } | |
1475 for (j = 0; j < intervals->length(); j++) { | |
1476 int num_found = 0; | |
1477 for (i = 0; i < interval_count(); i++) { | |
1478 if (interval_at(i) == intervals->at(j)) { | |
1479 num_found++; | |
1480 } | |
1481 } | |
1482 assert(num_found == 1, "lists do not contain same intervals"); | |
1483 } | |
1484 | |
1485 return true; | |
1486 } | |
1487 #endif | |
1488 | |
1489 void LinearScan::add_to_list(Interval** first, Interval** prev, Interval* interval) { | |
1490 if (*prev != NULL) { | |
1491 (*prev)->set_next(interval); | |
1492 } else { | |
1493 *first = interval; | |
1494 } | |
1495 *prev = interval; | |
1496 } | |
1497 | |
1498 void LinearScan::create_unhandled_lists(Interval** list1, Interval** list2, bool (is_list1)(const Interval* i), bool (is_list2)(const Interval* i)) { | |
1499 assert(is_sorted(_sorted_intervals), "interval list is not sorted"); | |
1500 | |
1501 *list1 = *list2 = Interval::end(); | |
1502 | |
1503 Interval* list1_prev = NULL; | |
1504 Interval* list2_prev = NULL; | |
1505 Interval* v; | |
1506 | |
1507 const int n = _sorted_intervals->length(); | |
1508 for (int i = 0; i < n; i++) { | |
1509 v = _sorted_intervals->at(i); | |
1510 if (v == NULL) continue; | |
1511 | |
1512 if (is_list1(v)) { | |
1513 add_to_list(list1, &list1_prev, v); | |
1514 } else if (is_list2 == NULL || is_list2(v)) { | |
1515 add_to_list(list2, &list2_prev, v); | |
1516 } | |
1517 } | |
1518 | |
1519 if (list1_prev != NULL) list1_prev->set_next(Interval::end()); | |
1520 if (list2_prev != NULL) list2_prev->set_next(Interval::end()); | |
1521 | |
1522 assert(list1_prev == NULL || list1_prev->next() == Interval::end(), "linear list ends not with sentinel"); | |
1523 assert(list2_prev == NULL || list2_prev->next() == Interval::end(), "linear list ends not with sentinel"); | |
1524 } | |
1525 | |
1526 | |
1527 void LinearScan::sort_intervals_before_allocation() { | |
1528 TIME_LINEAR_SCAN(timer_sort_intervals_before); | |
1529 | |
2081
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1530 if (_needs_full_resort) { |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1531 // There is no known reason why this should occur but just in case... |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1532 assert(false, "should never occur"); |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1533 // Re-sort existing interval list because an Interval::from() has changed |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1534 _sorted_intervals->sort(interval_cmp); |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1535 _needs_full_resort = false; |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1536 } |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1537 |
0 | 1538 IntervalList* unsorted_list = &_intervals; |
1539 int unsorted_len = unsorted_list->length(); | |
1540 int sorted_len = 0; | |
1541 int unsorted_idx; | |
1542 int sorted_idx = 0; | |
1543 int sorted_from_max = -1; | |
1544 | |
1545 // calc number of items for sorted list (sorted list must not contain NULL values) | |
1546 for (unsorted_idx = 0; unsorted_idx < unsorted_len; unsorted_idx++) { | |
1547 if (unsorted_list->at(unsorted_idx) != NULL) { | |
1548 sorted_len++; | |
1549 } | |
1550 } | |
1551 IntervalArray* sorted_list = new IntervalArray(sorted_len); | |
1552 | |
1553 // special sorting algorithm: the original interval-list is almost sorted, | |
1554 // only some intervals are swapped. So this is much faster than a complete QuickSort | |
1555 for (unsorted_idx = 0; unsorted_idx < unsorted_len; unsorted_idx++) { | |
1556 Interval* cur_interval = unsorted_list->at(unsorted_idx); | |
1557 | |
1558 if (cur_interval != NULL) { | |
1559 int cur_from = cur_interval->from(); | |
1560 | |
1561 if (sorted_from_max <= cur_from) { | |
1562 sorted_list->at_put(sorted_idx++, cur_interval); | |
1563 sorted_from_max = cur_interval->from(); | |
1564 } else { | |
1565 // the asumption that the intervals are already sorted failed, | |
1566 // so this interval must be sorted in manually | |
1567 int j; | |
1568 for (j = sorted_idx - 1; j >= 0 && cur_from < sorted_list->at(j)->from(); j--) { | |
1569 sorted_list->at_put(j + 1, sorted_list->at(j)); | |
1570 } | |
1571 sorted_list->at_put(j + 1, cur_interval); | |
1572 sorted_idx++; | |
1573 } | |
1574 } | |
1575 } | |
1576 _sorted_intervals = sorted_list; | |
2081
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1577 assert(is_sorted(_sorted_intervals), "intervals unsorted"); |
0 | 1578 } |
1579 | |
1580 void LinearScan::sort_intervals_after_allocation() { | |
1581 TIME_LINEAR_SCAN(timer_sort_intervals_after); | |
1582 | |
2081
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1583 if (_needs_full_resort) { |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1584 // Re-sort existing interval list because an Interval::from() has changed |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1585 _sorted_intervals->sort(interval_cmp); |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1586 _needs_full_resort = false; |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1587 } |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1588 |
0 | 1589 IntervalArray* old_list = _sorted_intervals; |
1590 IntervalList* new_list = _new_intervals_from_allocation; | |
1591 int old_len = old_list->length(); | |
1592 int new_len = new_list->length(); | |
1593 | |
1594 if (new_len == 0) { | |
1595 // no intervals have been added during allocation, so sorted list is already up to date | |
2081
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1596 assert(is_sorted(_sorted_intervals), "intervals unsorted"); |
0 | 1597 return; |
1598 } | |
1599 | |
1600 // conventional sort-algorithm for new intervals | |
1601 new_list->sort(interval_cmp); | |
1602 | |
1603 // merge old and new list (both already sorted) into one combined list | |
1604 IntervalArray* combined_list = new IntervalArray(old_len + new_len); | |
1605 int old_idx = 0; | |
1606 int new_idx = 0; | |
1607 | |
1608 while (old_idx + new_idx < old_len + new_len) { | |
1609 if (new_idx >= new_len || (old_idx < old_len && old_list->at(old_idx)->from() <= new_list->at(new_idx)->from())) { | |
1610 combined_list->at_put(old_idx + new_idx, old_list->at(old_idx)); | |
1611 old_idx++; | |
1612 } else { | |
1613 combined_list->at_put(old_idx + new_idx, new_list->at(new_idx)); | |
1614 new_idx++; | |
1615 } | |
1616 } | |
1617 | |
1618 _sorted_intervals = combined_list; | |
2081
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1619 assert(is_sorted(_sorted_intervals), "intervals unsorted"); |
0 | 1620 } |
1621 | |
1622 | |
1623 void LinearScan::allocate_registers() { | |
1624 TIME_LINEAR_SCAN(timer_allocate_registers); | |
1625 | |
1626 Interval* precolored_cpu_intervals, *not_precolored_cpu_intervals; | |
1627 Interval* precolored_fpu_intervals, *not_precolored_fpu_intervals; | |
1628 | |
1629 create_unhandled_lists(&precolored_cpu_intervals, ¬_precolored_cpu_intervals, is_precolored_cpu_interval, is_virtual_cpu_interval); | |
1630 if (has_fpu_registers()) { | |
1631 create_unhandled_lists(&precolored_fpu_intervals, ¬_precolored_fpu_intervals, is_precolored_fpu_interval, is_virtual_fpu_interval); | |
1632 #ifdef ASSERT | |
1633 } else { | |
1634 // fpu register allocation is omitted because no virtual fpu registers are present | |
1635 // just check this again... | |
1636 create_unhandled_lists(&precolored_fpu_intervals, ¬_precolored_fpu_intervals, is_precolored_fpu_interval, is_virtual_fpu_interval); | |
1637 assert(not_precolored_fpu_intervals == Interval::end(), "missed an uncolored fpu interval"); | |
1638 #endif | |
1639 } | |
1640 | |
1641 // allocate cpu registers | |
1642 LinearScanWalker cpu_lsw(this, precolored_cpu_intervals, not_precolored_cpu_intervals); | |
1643 cpu_lsw.walk(); | |
1644 cpu_lsw.finish_allocation(); | |
1645 | |
1646 if (has_fpu_registers()) { | |
1647 // allocate fpu registers | |
1648 LinearScanWalker fpu_lsw(this, precolored_fpu_intervals, not_precolored_fpu_intervals); | |
1649 fpu_lsw.walk(); | |
1650 fpu_lsw.finish_allocation(); | |
1651 } | |
1652 } | |
1653 | |
1654 | |
1655 // ********** Phase 6: resolve data flow | |
1656 // (insert moves at edges between blocks if intervals have been split) | |
1657 | |
1658 // wrapper for Interval::split_child_at_op_id that performs a bailout in product mode | |
1659 // instead of returning NULL | |
1660 Interval* LinearScan::split_child_at_op_id(Interval* interval, int op_id, LIR_OpVisitState::OprMode mode) { | |
1661 Interval* result = interval->split_child_at_op_id(op_id, mode); | |
1662 if (result != NULL) { | |
1663 return result; | |
1664 } | |
1665 | |
1666 assert(false, "must find an interval, but do a clean bailout in product mode"); | |
1667 result = new Interval(LIR_OprDesc::vreg_base); | |
1668 result->assign_reg(0); | |
1669 result->set_type(T_INT); | |
1670 BAILOUT_("LinearScan: interval is NULL", result); | |
1671 } | |
1672 | |
1673 | |
1674 Interval* LinearScan::interval_at_block_begin(BlockBegin* block, int reg_num) { | |
1675 assert(LinearScan::nof_regs <= reg_num && reg_num < num_virtual_regs(), "register number out of bounds"); | |
1676 assert(interval_at(reg_num) != NULL, "no interval found"); | |
1677 | |
1678 return split_child_at_op_id(interval_at(reg_num), block->first_lir_instruction_id(), LIR_OpVisitState::outputMode); | |
1679 } | |
1680 | |
1681 Interval* LinearScan::interval_at_block_end(BlockBegin* block, int reg_num) { | |
1682 assert(LinearScan::nof_regs <= reg_num && reg_num < num_virtual_regs(), "register number out of bounds"); | |
1683 assert(interval_at(reg_num) != NULL, "no interval found"); | |
1684 | |
1685 return split_child_at_op_id(interval_at(reg_num), block->last_lir_instruction_id() + 1, LIR_OpVisitState::outputMode); | |
1686 } | |
1687 | |
1688 Interval* LinearScan::interval_at_op_id(int reg_num, int op_id) { | |
1689 assert(LinearScan::nof_regs <= reg_num && reg_num < num_virtual_regs(), "register number out of bounds"); | |
1690 assert(interval_at(reg_num) != NULL, "no interval found"); | |
1691 | |
1692 return split_child_at_op_id(interval_at(reg_num), op_id, LIR_OpVisitState::inputMode); | |
1693 } | |
1694 | |
1695 | |
1696 void LinearScan::resolve_collect_mappings(BlockBegin* from_block, BlockBegin* to_block, MoveResolver &move_resolver) { | |
1697 DEBUG_ONLY(move_resolver.check_empty()); | |
1698 | |
1699 const int num_regs = num_virtual_regs(); | |
1700 const int size = live_set_size(); | |
1701 const BitMap live_at_edge = to_block->live_in(); | |
1702 | |
1703 // visit all registers where the live_at_edge bit is set | |
304 | 1704 for (int r = (int)live_at_edge.get_next_one_offset(0, size); r < size; r = (int)live_at_edge.get_next_one_offset(r + 1, size)) { |
0 | 1705 assert(r < num_regs, "live information set for not exisiting interval"); |
1706 assert(from_block->live_out().at(r) && to_block->live_in().at(r), "interval not live at this edge"); | |
1707 | |
1708 Interval* from_interval = interval_at_block_end(from_block, r); | |
1709 Interval* to_interval = interval_at_block_begin(to_block, r); | |
1710 | |
1711 if (from_interval != to_interval && (from_interval->assigned_reg() != to_interval->assigned_reg() || from_interval->assigned_regHi() != to_interval->assigned_regHi())) { | |
1712 // need to insert move instruction | |
1713 move_resolver.add_mapping(from_interval, to_interval); | |
1714 } | |
1715 } | |
1716 } | |
1717 | |
1718 | |
1719 void LinearScan::resolve_find_insert_pos(BlockBegin* from_block, BlockBegin* to_block, MoveResolver &move_resolver) { | |
1720 if (from_block->number_of_sux() <= 1) { | |
1721 TRACE_LINEAR_SCAN(4, tty->print_cr("inserting moves at end of from_block B%d", from_block->block_id())); | |
1722 | |
1723 LIR_OpList* instructions = from_block->lir()->instructions_list(); | |
1724 LIR_OpBranch* branch = instructions->last()->as_OpBranch(); | |
1725 if (branch != NULL) { | |
1726 // insert moves before branch | |
1727 assert(branch->cond() == lir_cond_always, "block does not end with an unconditional jump"); | |
1728 move_resolver.set_insert_position(from_block->lir(), instructions->length() - 2); | |
1729 } else { | |
1730 move_resolver.set_insert_position(from_block->lir(), instructions->length() - 1); | |
1731 } | |
1732 | |
1733 } else { | |
1734 TRACE_LINEAR_SCAN(4, tty->print_cr("inserting moves at beginning of to_block B%d", to_block->block_id())); | |
1735 #ifdef ASSERT | |
1736 assert(from_block->lir()->instructions_list()->at(0)->as_OpLabel() != NULL, "block does not start with a label"); | |
1737 | |
1738 // because the number of predecessor edges matches the number of | |
1739 // successor edges, blocks which are reached by switch statements | |
1740 // may have be more than one predecessor but it will be guaranteed | |
1741 // that all predecessors will be the same. | |
1742 for (int i = 0; i < to_block->number_of_preds(); i++) { | |
1743 assert(from_block == to_block->pred_at(i), "all critical edges must be broken"); | |
1744 } | |
1745 #endif | |
1746 | |
1747 move_resolver.set_insert_position(to_block->lir(), 0); | |
1748 } | |
1749 } | |
1750 | |
1751 | |
1752 // insert necessary moves (spilling or reloading) at edges between blocks if interval has been split | |
1753 void LinearScan::resolve_data_flow() { | |
1754 TIME_LINEAR_SCAN(timer_resolve_data_flow); | |
1755 | |
1756 int num_blocks = block_count(); | |
1757 MoveResolver move_resolver(this); | |
1758 BitMap block_completed(num_blocks); block_completed.clear(); | |
1759 BitMap already_resolved(num_blocks); already_resolved.clear(); | |
1760 | |
1761 int i; | |
1762 for (i = 0; i < num_blocks; i++) { | |
1763 BlockBegin* block = block_at(i); | |
1764 | |
1765 // check if block has only one predecessor and only one successor | |
1766 if (block->number_of_preds() == 1 && block->number_of_sux() == 1 && block->number_of_exception_handlers() == 0) { | |
1767 LIR_OpList* instructions = block->lir()->instructions_list(); | |
1768 assert(instructions->at(0)->code() == lir_label, "block must start with label"); | |
1769 assert(instructions->last()->code() == lir_branch, "block with successors must end with branch"); | |
1770 assert(instructions->last()->as_OpBranch()->cond() == lir_cond_always, "block with successor must end with unconditional branch"); | |
1771 | |
1772 // check if block is empty (only label and branch) | |
1773 if (instructions->length() == 2) { | |
1774 BlockBegin* pred = block->pred_at(0); | |
1775 BlockBegin* sux = block->sux_at(0); | |
1776 | |
1777 // prevent optimization of two consecutive blocks | |
1778 if (!block_completed.at(pred->linear_scan_number()) && !block_completed.at(sux->linear_scan_number())) { | |
1779 TRACE_LINEAR_SCAN(3, tty->print_cr("**** optimizing empty block B%d (pred: B%d, sux: B%d)", block->block_id(), pred->block_id(), sux->block_id())); | |
1780 block_completed.set_bit(block->linear_scan_number()); | |
1781 | |
1782 // directly resolve between pred and sux (without looking at the empty block between) | |
1783 resolve_collect_mappings(pred, sux, move_resolver); | |
1784 if (move_resolver.has_mappings()) { | |
1785 move_resolver.set_insert_position(block->lir(), 0); | |
1786 move_resolver.resolve_and_append_moves(); | |
1787 } | |
1788 } | |
1789 } | |
1790 } | |
1791 } | |
1792 | |
1793 | |
1794 for (i = 0; i < num_blocks; i++) { | |
1795 if (!block_completed.at(i)) { | |
1796 BlockBegin* from_block = block_at(i); | |
1797 already_resolved.set_from(block_completed); | |
1798 | |
1799 int num_sux = from_block->number_of_sux(); | |
1800 for (int s = 0; s < num_sux; s++) { | |
1801 BlockBegin* to_block = from_block->sux_at(s); | |
1802 | |
1803 // check for duplicate edges between the same blocks (can happen with switch blocks) | |
1804 if (!already_resolved.at(to_block->linear_scan_number())) { | |
1805 TRACE_LINEAR_SCAN(3, tty->print_cr("**** processing edge between B%d and B%d", from_block->block_id(), to_block->block_id())); | |
1806 already_resolved.set_bit(to_block->linear_scan_number()); | |
1807 | |
1808 // collect all intervals that have been split between from_block and to_block | |
1809 resolve_collect_mappings(from_block, to_block, move_resolver); | |
1810 if (move_resolver.has_mappings()) { | |
1811 resolve_find_insert_pos(from_block, to_block, move_resolver); | |
1812 move_resolver.resolve_and_append_moves(); | |
1813 } | |
1814 } | |
1815 } | |
1816 } | |
1817 } | |
1818 } | |
1819 | |
1820 | |
1821 void LinearScan::resolve_exception_entry(BlockBegin* block, int reg_num, MoveResolver &move_resolver) { | |
1822 if (interval_at(reg_num) == NULL) { | |
1823 // if a phi function is never used, no interval is created -> ignore this | |
1824 return; | |
1825 } | |
1826 | |
1827 Interval* interval = interval_at_block_begin(block, reg_num); | |
1828 int reg = interval->assigned_reg(); | |
1829 int regHi = interval->assigned_regHi(); | |
1830 | |
1831 if ((reg < nof_regs && interval->always_in_memory()) || | |
1832 (use_fpu_stack_allocation() && reg >= pd_first_fpu_reg && reg <= pd_last_fpu_reg)) { | |
1833 // the interval is split to get a short range that is located on the stack | |
1834 // in the following two cases: | |
1835 // * the interval started in memory (e.g. method parameter), but is currently in a register | |
1836 // this is an optimization for exception handling that reduces the number of moves that | |
1837 // are necessary for resolving the states when an exception uses this exception handler | |
1838 // * the interval would be on the fpu stack at the begin of the exception handler | |
1839 // this is not allowed because of the complicated fpu stack handling on Intel | |
1840 | |
1841 // range that will be spilled to memory | |
1842 int from_op_id = block->first_lir_instruction_id(); | |
1843 int to_op_id = from_op_id + 1; // short live range of length 1 | |
1844 assert(interval->from() <= from_op_id && interval->to() >= to_op_id, | |
1845 "no split allowed between exception entry and first instruction"); | |
1846 | |
1847 if (interval->from() != from_op_id) { | |
1848 // the part before from_op_id is unchanged | |
1849 interval = interval->split(from_op_id); | |
1850 interval->assign_reg(reg, regHi); | |
1851 append_interval(interval); | |
2081
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1852 } else { |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
1853 _needs_full_resort = true; |
0 | 1854 } |
1855 assert(interval->from() == from_op_id, "must be true now"); | |
1856 | |
1857 Interval* spilled_part = interval; | |
1858 if (interval->to() != to_op_id) { | |
1859 // the part after to_op_id is unchanged | |
1860 spilled_part = interval->split_from_start(to_op_id); | |
1861 append_interval(spilled_part); | |
1862 move_resolver.add_mapping(spilled_part, interval); | |
1863 } | |
1864 assign_spill_slot(spilled_part); | |
1865 | |
1866 assert(spilled_part->from() == from_op_id && spilled_part->to() == to_op_id, "just checking"); | |
1867 } | |
1868 } | |
1869 | |
1870 void LinearScan::resolve_exception_entry(BlockBegin* block, MoveResolver &move_resolver) { | |
1871 assert(block->is_set(BlockBegin::exception_entry_flag), "should not call otherwise"); | |
1872 DEBUG_ONLY(move_resolver.check_empty()); | |
1873 | |
1874 // visit all registers where the live_in bit is set | |
1875 int size = live_set_size(); | |
304 | 1876 for (int r = (int)block->live_in().get_next_one_offset(0, size); r < size; r = (int)block->live_in().get_next_one_offset(r + 1, size)) { |
0 | 1877 resolve_exception_entry(block, r, move_resolver); |
1878 } | |
1879 | |
1880 // the live_in bits are not set for phi functions of the xhandler entry, so iterate them separately | |
1881 for_each_phi_fun(block, phi, | |
1882 resolve_exception_entry(block, phi->operand()->vreg_number(), move_resolver) | |
1883 ); | |
1884 | |
1885 if (move_resolver.has_mappings()) { | |
1886 // insert moves after first instruction | |
5906
b279f99d7143
6910461: Register allocator may insert spill code at wrong insertion index
roland
parents:
4948
diff
changeset
|
1887 move_resolver.set_insert_position(block->lir(), 0); |
0 | 1888 move_resolver.resolve_and_append_moves(); |
1889 } | |
1890 } | |
1891 | |
1892 | |
1893 void LinearScan::resolve_exception_edge(XHandler* handler, int throwing_op_id, int reg_num, Phi* phi, MoveResolver &move_resolver) { | |
1894 if (interval_at(reg_num) == NULL) { | |
1895 // if a phi function is never used, no interval is created -> ignore this | |
1896 return; | |
1897 } | |
1898 | |
1899 // the computation of to_interval is equal to resolve_collect_mappings, | |
1900 // but from_interval is more complicated because of phi functions | |
1901 BlockBegin* to_block = handler->entry_block(); | |
1902 Interval* to_interval = interval_at_block_begin(to_block, reg_num); | |
1903 | |
1904 if (phi != NULL) { | |
1905 // phi function of the exception entry block | |
1906 // no moves are created for this phi function in the LIR_Generator, so the | |
1907 // interval at the throwing instruction must be searched using the operands | |
1908 // of the phi function | |
1909 Value from_value = phi->operand_at(handler->phi_operand()); | |
1910 | |
1911 // with phi functions it can happen that the same from_value is used in | |
1912 // multiple mappings, so notify move-resolver that this is allowed | |
1913 move_resolver.set_multiple_reads_allowed(); | |
1914 | |
1915 Constant* con = from_value->as_Constant(); | |
1916 if (con != NULL && !con->is_pinned()) { | |
1917 // unpinned constants may have no register, so add mapping from constant to interval | |
1918 move_resolver.add_mapping(LIR_OprFact::value_type(con->type()), to_interval); | |
1919 } else { | |
1920 // search split child at the throwing op_id | |
1921 Interval* from_interval = interval_at_op_id(from_value->operand()->vreg_number(), throwing_op_id); | |
1922 move_resolver.add_mapping(from_interval, to_interval); | |
1923 } | |
1924 | |
1925 } else { | |
1926 // no phi function, so use reg_num also for from_interval | |
1927 // search split child at the throwing op_id | |
1928 Interval* from_interval = interval_at_op_id(reg_num, throwing_op_id); | |
1929 if (from_interval != to_interval) { | |
1930 // optimization to reduce number of moves: when to_interval is on stack and | |
1931 // the stack slot is known to be always correct, then no move is necessary | |
1932 if (!from_interval->always_in_memory() || from_interval->canonical_spill_slot() != to_interval->assigned_reg()) { | |
1933 move_resolver.add_mapping(from_interval, to_interval); | |
1934 } | |
1935 } | |
1936 } | |
1937 } | |
1938 | |
1939 void LinearScan::resolve_exception_edge(XHandler* handler, int throwing_op_id, MoveResolver &move_resolver) { | |
1940 TRACE_LINEAR_SCAN(4, tty->print_cr("resolving exception handler B%d: throwing_op_id=%d", handler->entry_block()->block_id(), throwing_op_id)); | |
1941 | |
1942 DEBUG_ONLY(move_resolver.check_empty()); | |
1943 assert(handler->lir_op_id() == -1, "already processed this xhandler"); | |
1944 DEBUG_ONLY(handler->set_lir_op_id(throwing_op_id)); | |
1945 assert(handler->entry_code() == NULL, "code already present"); | |
1946 | |
1947 // visit all registers where the live_in bit is set | |
1948 BlockBegin* block = handler->entry_block(); | |
1949 int size = live_set_size(); | |
304 | 1950 for (int r = (int)block->live_in().get_next_one_offset(0, size); r < size; r = (int)block->live_in().get_next_one_offset(r + 1, size)) { |
0 | 1951 resolve_exception_edge(handler, throwing_op_id, r, NULL, move_resolver); |
1952 } | |
1953 | |
1954 // the live_in bits are not set for phi functions of the xhandler entry, so iterate them separately | |
1955 for_each_phi_fun(block, phi, | |
1956 resolve_exception_edge(handler, throwing_op_id, phi->operand()->vreg_number(), phi, move_resolver) | |
1957 ); | |
1958 | |
1959 if (move_resolver.has_mappings()) { | |
1960 LIR_List* entry_code = new LIR_List(compilation()); | |
1961 move_resolver.set_insert_position(entry_code, 0); | |
1962 move_resolver.resolve_and_append_moves(); | |
1963 | |
1964 entry_code->jump(handler->entry_block()); | |
1965 handler->set_entry_code(entry_code); | |
1966 } | |
1967 } | |
1968 | |
1969 | |
1970 void LinearScan::resolve_exception_handlers() { | |
1971 MoveResolver move_resolver(this); | |
1972 LIR_OpVisitState visitor; | |
1973 int num_blocks = block_count(); | |
1974 | |
1975 int i; | |
1976 for (i = 0; i < num_blocks; i++) { | |
1977 BlockBegin* block = block_at(i); | |
1978 if (block->is_set(BlockBegin::exception_entry_flag)) { | |
1979 resolve_exception_entry(block, move_resolver); | |
1980 } | |
1981 } | |
1982 | |
1983 for (i = 0; i < num_blocks; i++) { | |
1984 BlockBegin* block = block_at(i); | |
1985 LIR_List* ops = block->lir(); | |
1986 int num_ops = ops->length(); | |
1987 | |
1988 // iterate all instructions of the block. skip the first because it is always a label | |
1989 assert(visitor.no_operands(ops->at(0)), "first operation must always be a label"); | |
1990 for (int j = 1; j < num_ops; j++) { | |
1991 LIR_Op* op = ops->at(j); | |
1992 int op_id = op->id(); | |
1993 | |
1994 if (op_id != -1 && has_info(op_id)) { | |
1995 // visit operation to collect all operands | |
1996 visitor.visit(op); | |
1997 assert(visitor.info_count() > 0, "should not visit otherwise"); | |
1998 | |
1999 XHandlers* xhandlers = visitor.all_xhandler(); | |
2000 int n = xhandlers->length(); | |
2001 for (int k = 0; k < n; k++) { | |
2002 resolve_exception_edge(xhandlers->handler_at(k), op_id, move_resolver); | |
2003 } | |
2004 | |
2005 #ifdef ASSERT | |
2006 } else { | |
2007 visitor.visit(op); | |
2008 assert(visitor.all_xhandler()->length() == 0, "missed exception handler"); | |
2009 #endif | |
2010 } | |
2011 } | |
2012 } | |
2013 } | |
2014 | |
2015 | |
2016 // ********** Phase 7: assign register numbers back to LIR | |
2017 // (includes computation of debug information and oop maps) | |
2018 | |
2019 VMReg LinearScan::vm_reg_for_interval(Interval* interval) { | |
2020 VMReg reg = interval->cached_vm_reg(); | |
2021 if (!reg->is_valid() ) { | |
2022 reg = vm_reg_for_operand(operand_for_interval(interval)); | |
2023 interval->set_cached_vm_reg(reg); | |
2024 } | |
2025 assert(reg == vm_reg_for_operand(operand_for_interval(interval)), "wrong cached value"); | |
2026 return reg; | |
2027 } | |
2028 | |
2029 VMReg LinearScan::vm_reg_for_operand(LIR_Opr opr) { | |
2030 assert(opr->is_oop(), "currently only implemented for oop operands"); | |
2031 return frame_map()->regname(opr); | |
2032 } | |
2033 | |
2034 | |
2035 LIR_Opr LinearScan::operand_for_interval(Interval* interval) { | |
2036 LIR_Opr opr = interval->cached_opr(); | |
2037 if (opr->is_illegal()) { | |
2038 opr = calc_operand_for_interval(interval); | |
2039 interval->set_cached_opr(opr); | |
2040 } | |
2041 | |
2042 assert(opr == calc_operand_for_interval(interval), "wrong cached value"); | |
2043 return opr; | |
2044 } | |
2045 | |
2046 LIR_Opr LinearScan::calc_operand_for_interval(const Interval* interval) { | |
2047 int assigned_reg = interval->assigned_reg(); | |
2048 BasicType type = interval->type(); | |
2049 | |
2050 if (assigned_reg >= nof_regs) { | |
2051 // stack slot | |
2052 assert(interval->assigned_regHi() == any_reg, "must not have hi register"); | |
2053 return LIR_OprFact::stack(assigned_reg - nof_regs, type); | |
2054 | |
2055 } else { | |
2056 // register | |
2057 switch (type) { | |
2058 case T_OBJECT: { | |
2059 assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register"); | |
2060 assert(interval->assigned_regHi() == any_reg, "must not have hi register"); | |
2061 return LIR_OprFact::single_cpu_oop(assigned_reg); | |
2062 } | |
2063 | |
1816
87b64980e2f1
6972540: sun/nio/ch/SocketChannelImpl compilation crashed when executing CompileTheWorld
never
parents:
1681
diff
changeset
|
2064 case T_ADDRESS: { |
87b64980e2f1
6972540: sun/nio/ch/SocketChannelImpl compilation crashed when executing CompileTheWorld
never
parents:
1681
diff
changeset
|
2065 assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register"); |
87b64980e2f1
6972540: sun/nio/ch/SocketChannelImpl compilation crashed when executing CompileTheWorld
never
parents:
1681
diff
changeset
|
2066 assert(interval->assigned_regHi() == any_reg, "must not have hi register"); |
87b64980e2f1
6972540: sun/nio/ch/SocketChannelImpl compilation crashed when executing CompileTheWorld
never
parents:
1681
diff
changeset
|
2067 return LIR_OprFact::single_cpu_address(assigned_reg); |
87b64980e2f1
6972540: sun/nio/ch/SocketChannelImpl compilation crashed when executing CompileTheWorld
never
parents:
1681
diff
changeset
|
2068 } |
87b64980e2f1
6972540: sun/nio/ch/SocketChannelImpl compilation crashed when executing CompileTheWorld
never
parents:
1681
diff
changeset
|
2069 |
6739
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6197
diff
changeset
|
2070 case T_METADATA: { |
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6197
diff
changeset
|
2071 assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register"); |
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6197
diff
changeset
|
2072 assert(interval->assigned_regHi() == any_reg, "must not have hi register"); |
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6197
diff
changeset
|
2073 return LIR_OprFact::single_cpu_metadata(assigned_reg); |
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6197
diff
changeset
|
2074 } |
8a02ca5e5576
7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents:
6197
diff
changeset
|
2075 |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2076 #ifdef __SOFTFP__ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2077 case T_FLOAT: // fall through |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2078 #endif // __SOFTFP__ |
0 | 2079 case T_INT: { |
2080 assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register"); | |
2081 assert(interval->assigned_regHi() == any_reg, "must not have hi register"); | |
2082 return LIR_OprFact::single_cpu(assigned_reg); | |
2083 } | |
2084 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2085 #ifdef __SOFTFP__ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2086 case T_DOUBLE: // fall through |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2087 #endif // __SOFTFP__ |
0 | 2088 case T_LONG: { |
2089 int assigned_regHi = interval->assigned_regHi(); | |
2090 assert(assigned_reg >= pd_first_cpu_reg && assigned_reg <= pd_last_cpu_reg, "no cpu register"); | |
2091 assert(num_physical_regs(T_LONG) == 1 || | |
2092 (assigned_regHi >= pd_first_cpu_reg && assigned_regHi <= pd_last_cpu_reg), "no cpu register"); | |
2093 | |
2094 assert(assigned_reg != assigned_regHi, "invalid allocation"); | |
2095 assert(num_physical_regs(T_LONG) == 1 || assigned_reg < assigned_regHi, | |
2096 "register numbers must be sorted (ensure that e.g. a move from eax,ebx to ebx,eax can not occur)"); | |
2097 assert((assigned_regHi != any_reg) ^ (num_physical_regs(T_LONG) == 1), "must be match"); | |
2098 if (requires_adjacent_regs(T_LONG)) { | |
2099 assert(assigned_reg % 2 == 0 && assigned_reg + 1 == assigned_regHi, "must be sequential and even"); | |
2100 } | |
2101 | |
2102 #ifdef _LP64 | |
2103 return LIR_OprFact::double_cpu(assigned_reg, assigned_reg); | |
2104 #else | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2105 #if defined(SPARC) || defined(PPC) |
0 | 2106 return LIR_OprFact::double_cpu(assigned_regHi, assigned_reg); |
2107 #else | |
2108 return LIR_OprFact::double_cpu(assigned_reg, assigned_regHi); | |
304 | 2109 #endif // SPARC |
2110 #endif // LP64 | |
0 | 2111 } |
2112 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2113 #ifndef __SOFTFP__ |
0 | 2114 case T_FLOAT: { |
304 | 2115 #ifdef X86 |
0 | 2116 if (UseSSE >= 1) { |
2117 assert(assigned_reg >= pd_first_xmm_reg && assigned_reg <= pd_last_xmm_reg, "no xmm register"); | |
2118 assert(interval->assigned_regHi() == any_reg, "must not have hi register"); | |
2119 return LIR_OprFact::single_xmm(assigned_reg - pd_first_xmm_reg); | |
2120 } | |
2121 #endif | |
2122 | |
2123 assert(assigned_reg >= pd_first_fpu_reg && assigned_reg <= pd_last_fpu_reg, "no fpu register"); | |
2124 assert(interval->assigned_regHi() == any_reg, "must not have hi register"); | |
2125 return LIR_OprFact::single_fpu(assigned_reg - pd_first_fpu_reg); | |
2126 } | |
2127 | |
2128 case T_DOUBLE: { | |
304 | 2129 #ifdef X86 |
0 | 2130 if (UseSSE >= 2) { |
2131 assert(assigned_reg >= pd_first_xmm_reg && assigned_reg <= pd_last_xmm_reg, "no xmm register"); | |
2132 assert(interval->assigned_regHi() == any_reg, "must not have hi register (double xmm values are stored in one register)"); | |
2133 return LIR_OprFact::double_xmm(assigned_reg - pd_first_xmm_reg); | |
2134 } | |
2135 #endif | |
2136 | |
2137 #ifdef SPARC | |
2138 assert(assigned_reg >= pd_first_fpu_reg && assigned_reg <= pd_last_fpu_reg, "no fpu register"); | |
2139 assert(interval->assigned_regHi() >= pd_first_fpu_reg && interval->assigned_regHi() <= pd_last_fpu_reg, "no fpu register"); | |
2140 assert(assigned_reg % 2 == 0 && assigned_reg + 1 == interval->assigned_regHi(), "must be sequential and even"); | |
2141 LIR_Opr result = LIR_OprFact::double_fpu(interval->assigned_regHi() - pd_first_fpu_reg, assigned_reg - pd_first_fpu_reg); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2142 #elif defined(ARM) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2143 assert(assigned_reg >= pd_first_fpu_reg && assigned_reg <= pd_last_fpu_reg, "no fpu register"); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2144 assert(interval->assigned_regHi() >= pd_first_fpu_reg && interval->assigned_regHi() <= pd_last_fpu_reg, "no fpu register"); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2145 assert(assigned_reg % 2 == 0 && assigned_reg + 1 == interval->assigned_regHi(), "must be sequential and even"); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2146 LIR_Opr result = LIR_OprFact::double_fpu(assigned_reg - pd_first_fpu_reg, interval->assigned_regHi() - pd_first_fpu_reg); |
0 | 2147 #else |
2148 assert(assigned_reg >= pd_first_fpu_reg && assigned_reg <= pd_last_fpu_reg, "no fpu register"); | |
2149 assert(interval->assigned_regHi() == any_reg, "must not have hi register (double fpu values are stored in one register on Intel)"); | |
2150 LIR_Opr result = LIR_OprFact::double_fpu(assigned_reg - pd_first_fpu_reg); | |
2151 #endif | |
2152 return result; | |
2153 } | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2154 #endif // __SOFTFP__ |
0 | 2155 |
2156 default: { | |
2157 ShouldNotReachHere(); | |
2158 return LIR_OprFact::illegalOpr; | |
2159 } | |
2160 } | |
2161 } | |
2162 } | |
2163 | |
2164 LIR_Opr LinearScan::canonical_spill_opr(Interval* interval) { | |
2165 assert(interval->canonical_spill_slot() >= nof_regs, "canonical spill slot not set"); | |
2166 return LIR_OprFact::stack(interval->canonical_spill_slot() - nof_regs, interval->type()); | |
2167 } | |
2168 | |
2169 LIR_Opr LinearScan::color_lir_opr(LIR_Opr opr, int op_id, LIR_OpVisitState::OprMode mode) { | |
2170 assert(opr->is_virtual(), "should not call this otherwise"); | |
2171 | |
2172 Interval* interval = interval_at(opr->vreg_number()); | |
2173 assert(interval != NULL, "interval must exist"); | |
2174 | |
2175 if (op_id != -1) { | |
2176 #ifdef ASSERT | |
2177 BlockBegin* block = block_of_op_with_id(op_id); | |
2178 if (block->number_of_sux() <= 1 && op_id == block->last_lir_instruction_id()) { | |
2179 // check if spill moves could have been appended at the end of this block, but | |
2180 // before the branch instruction. So the split child information for this branch would | |
2181 // be incorrect. | |
2182 LIR_OpBranch* branch = block->lir()->instructions_list()->last()->as_OpBranch(); | |
2183 if (branch != NULL) { | |
2184 if (block->live_out().at(opr->vreg_number())) { | |
2185 assert(branch->cond() == lir_cond_always, "block does not end with an unconditional jump"); | |
2186 assert(false, "can't get split child for the last branch of a block because the information would be incorrect (moves are inserted before the branch in resolve_data_flow)"); | |
2187 } | |
2188 } | |
2189 } | |
2190 #endif | |
2191 | |
2192 // operands are not changed when an interval is split during allocation, | |
2193 // so search the right interval here | |
2194 interval = split_child_at_op_id(interval, op_id, mode); | |
2195 } | |
2196 | |
2197 LIR_Opr res = operand_for_interval(interval); | |
2198 | |
304 | 2199 #ifdef X86 |
0 | 2200 // new semantic for is_last_use: not only set on definite end of interval, |
2201 // but also before hole | |
2202 // This may still miss some cases (e.g. for dead values), but it is not necessary that the | |
2203 // last use information is completely correct | |
2204 // information is only needed for fpu stack allocation | |
2205 if (res->is_fpu_register()) { | |
2206 if (opr->is_last_use() || op_id == interval->to() || (op_id != -1 && interval->has_hole_between(op_id, op_id + 1))) { | |
2207 assert(op_id == -1 || !is_block_begin(op_id), "holes at begin of block may also result from control flow"); | |
2208 res = res->make_last_use(); | |
2209 } | |
2210 } | |
2211 #endif | |
2212 | |
2213 assert(!gen()->is_vreg_flag_set(opr->vreg_number(), LIRGenerator::callee_saved) || !FrameMap::is_caller_save_register(res), "bad allocation"); | |
2214 | |
2215 return res; | |
2216 } | |
2217 | |
2218 | |
2219 #ifdef ASSERT | |
2220 // some methods used to check correctness of debug information | |
2221 | |
2222 void assert_no_register_values(GrowableArray<ScopeValue*>* values) { | |
2223 if (values == NULL) { | |
2224 return; | |
2225 } | |
2226 | |
2227 for (int i = 0; i < values->length(); i++) { | |
2228 ScopeValue* value = values->at(i); | |
2229 | |
2230 if (value->is_location()) { | |
2231 Location location = ((LocationValue*)value)->location(); | |
2232 assert(location.where() == Location::on_stack, "value is in register"); | |
2233 } | |
2234 } | |
2235 } | |
2236 | |
2237 void assert_no_register_values(GrowableArray<MonitorValue*>* values) { | |
2238 if (values == NULL) { | |
2239 return; | |
2240 } | |
2241 | |
2242 for (int i = 0; i < values->length(); i++) { | |
2243 MonitorValue* value = values->at(i); | |
2244 | |
2245 if (value->owner()->is_location()) { | |
2246 Location location = ((LocationValue*)value->owner())->location(); | |
2247 assert(location.where() == Location::on_stack, "owner is in register"); | |
2248 } | |
2249 assert(value->basic_lock().where() == Location::on_stack, "basic_lock is in register"); | |
2250 } | |
2251 } | |
2252 | |
2253 void assert_equal(Location l1, Location l2) { | |
2254 assert(l1.where() == l2.where() && l1.type() == l2.type() && l1.offset() == l2.offset(), ""); | |
2255 } | |
2256 | |
2257 void assert_equal(ScopeValue* v1, ScopeValue* v2) { | |
2258 if (v1->is_location()) { | |
2259 assert(v2->is_location(), ""); | |
2260 assert_equal(((LocationValue*)v1)->location(), ((LocationValue*)v2)->location()); | |
2261 } else if (v1->is_constant_int()) { | |
2262 assert(v2->is_constant_int(), ""); | |
2263 assert(((ConstantIntValue*)v1)->value() == ((ConstantIntValue*)v2)->value(), ""); | |
2264 } else if (v1->is_constant_double()) { | |
2265 assert(v2->is_constant_double(), ""); | |
2266 assert(((ConstantDoubleValue*)v1)->value() == ((ConstantDoubleValue*)v2)->value(), ""); | |
2267 } else if (v1->is_constant_long()) { | |
2268 assert(v2->is_constant_long(), ""); | |
2269 assert(((ConstantLongValue*)v1)->value() == ((ConstantLongValue*)v2)->value(), ""); | |
2270 } else if (v1->is_constant_oop()) { | |
2271 assert(v2->is_constant_oop(), ""); | |
2272 assert(((ConstantOopWriteValue*)v1)->value() == ((ConstantOopWriteValue*)v2)->value(), ""); | |
2273 } else { | |
2274 ShouldNotReachHere(); | |
2275 } | |
2276 } | |
2277 | |
2278 void assert_equal(MonitorValue* m1, MonitorValue* m2) { | |
2279 assert_equal(m1->owner(), m2->owner()); | |
2280 assert_equal(m1->basic_lock(), m2->basic_lock()); | |
2281 } | |
2282 | |
2283 void assert_equal(IRScopeDebugInfo* d1, IRScopeDebugInfo* d2) { | |
2284 assert(d1->scope() == d2->scope(), "not equal"); | |
2285 assert(d1->bci() == d2->bci(), "not equal"); | |
2286 | |
2287 if (d1->locals() != NULL) { | |
2288 assert(d1->locals() != NULL && d2->locals() != NULL, "not equal"); | |
2289 assert(d1->locals()->length() == d2->locals()->length(), "not equal"); | |
2290 for (int i = 0; i < d1->locals()->length(); i++) { | |
2291 assert_equal(d1->locals()->at(i), d2->locals()->at(i)); | |
2292 } | |
2293 } else { | |
2294 assert(d1->locals() == NULL && d2->locals() == NULL, "not equal"); | |
2295 } | |
2296 | |
2297 if (d1->expressions() != NULL) { | |
2298 assert(d1->expressions() != NULL && d2->expressions() != NULL, "not equal"); | |
2299 assert(d1->expressions()->length() == d2->expressions()->length(), "not equal"); | |
2300 for (int i = 0; i < d1->expressions()->length(); i++) { | |
2301 assert_equal(d1->expressions()->at(i), d2->expressions()->at(i)); | |
2302 } | |
2303 } else { | |
2304 assert(d1->expressions() == NULL && d2->expressions() == NULL, "not equal"); | |
2305 } | |
2306 | |
2307 if (d1->monitors() != NULL) { | |
2308 assert(d1->monitors() != NULL && d2->monitors() != NULL, "not equal"); | |
2309 assert(d1->monitors()->length() == d2->monitors()->length(), "not equal"); | |
2310 for (int i = 0; i < d1->monitors()->length(); i++) { | |
2311 assert_equal(d1->monitors()->at(i), d2->monitors()->at(i)); | |
2312 } | |
2313 } else { | |
2314 assert(d1->monitors() == NULL && d2->monitors() == NULL, "not equal"); | |
2315 } | |
2316 | |
2317 if (d1->caller() != NULL) { | |
2318 assert(d1->caller() != NULL && d2->caller() != NULL, "not equal"); | |
2319 assert_equal(d1->caller(), d2->caller()); | |
2320 } else { | |
2321 assert(d1->caller() == NULL && d2->caller() == NULL, "not equal"); | |
2322 } | |
2323 } | |
2324 | |
2325 void check_stack_depth(CodeEmitInfo* info, int stack_end) { | |
1819 | 2326 if (info->stack()->bci() != SynchronizationEntryBCI && !info->scope()->method()->is_native()) { |
2327 Bytecodes::Code code = info->scope()->method()->java_code_at_bci(info->stack()->bci()); | |
0 | 2328 switch (code) { |
2329 case Bytecodes::_ifnull : // fall through | |
2330 case Bytecodes::_ifnonnull : // fall through | |
2331 case Bytecodes::_ifeq : // fall through | |
2332 case Bytecodes::_ifne : // fall through | |
2333 case Bytecodes::_iflt : // fall through | |
2334 case Bytecodes::_ifge : // fall through | |
2335 case Bytecodes::_ifgt : // fall through | |
2336 case Bytecodes::_ifle : // fall through | |
2337 case Bytecodes::_if_icmpeq : // fall through | |
2338 case Bytecodes::_if_icmpne : // fall through | |
2339 case Bytecodes::_if_icmplt : // fall through | |
2340 case Bytecodes::_if_icmpge : // fall through | |
2341 case Bytecodes::_if_icmpgt : // fall through | |
2342 case Bytecodes::_if_icmple : // fall through | |
2343 case Bytecodes::_if_acmpeq : // fall through | |
2344 case Bytecodes::_if_acmpne : | |
2345 assert(stack_end >= -Bytecodes::depth(code), "must have non-empty expression stack at if bytecode"); | |
2346 break; | |
2347 } | |
2348 } | |
2349 } | |
2350 | |
2351 #endif // ASSERT | |
2352 | |
2353 | |
2354 IntervalWalker* LinearScan::init_compute_oop_maps() { | |
2355 // setup lists of potential oops for walking | |
2356 Interval* oop_intervals; | |
2357 Interval* non_oop_intervals; | |
2358 | |
2359 create_unhandled_lists(&oop_intervals, &non_oop_intervals, is_oop_interval, NULL); | |
2360 | |
2361 // intervals that have no oops inside need not to be processed | |
2362 // to ensure a walking until the last instruction id, add a dummy interval | |
2363 // with a high operation id | |
2364 non_oop_intervals = new Interval(any_reg); | |
2365 non_oop_intervals->add_range(max_jint - 2, max_jint - 1); | |
2366 | |
2367 return new IntervalWalker(this, oop_intervals, non_oop_intervals); | |
2368 } | |
2369 | |
2370 | |
2371 OopMap* LinearScan::compute_oop_map(IntervalWalker* iw, LIR_Op* op, CodeEmitInfo* info, bool is_call_site) { | |
2372 TRACE_LINEAR_SCAN(3, tty->print_cr("creating oop map at op_id %d", op->id())); | |
2373 | |
2374 // walk before the current operation -> intervals that start at | |
2375 // the operation (= output operands of the operation) are not | |
2376 // included in the oop map | |
2377 iw->walk_before(op->id()); | |
2378 | |
2379 int frame_size = frame_map()->framesize(); | |
2380 int arg_count = frame_map()->oop_map_arg_count(); | |
2381 OopMap* map = new OopMap(frame_size, arg_count); | |
2382 | |
2383 // Check if this is a patch site. | |
2384 bool is_patch_info = false; | |
2385 if (op->code() == lir_move) { | |
2386 assert(!is_call_site, "move must not be a call site"); | |
2387 assert(op->as_Op1() != NULL, "move must be LIR_Op1"); | |
2388 LIR_Op1* move = (LIR_Op1*)op; | |
2389 | |
2390 is_patch_info = move->patch_code() != lir_patch_none; | |
2391 } | |
2392 | |
2393 // Iterate through active intervals | |
2394 for (Interval* interval = iw->active_first(fixedKind); interval != Interval::end(); interval = interval->next()) { | |
2395 int assigned_reg = interval->assigned_reg(); | |
2396 | |
2397 assert(interval->current_from() <= op->id() && op->id() <= interval->current_to(), "interval should not be active otherwise"); | |
2398 assert(interval->assigned_regHi() == any_reg, "oop must be single word"); | |
2399 assert(interval->reg_num() >= LIR_OprDesc::vreg_base, "fixed interval found"); | |
2400 | |
2401 // Check if this range covers the instruction. Intervals that | |
2402 // start or end at the current operation are not included in the | |
2403 // oop map, except in the case of patching moves. For patching | |
2404 // moves, any intervals which end at this instruction are included | |
2405 // in the oop map since we may safepoint while doing the patch | |
2406 // before we've consumed the inputs. | |
2407 if (is_patch_info || op->id() < interval->current_to()) { | |
2408 | |
2409 // caller-save registers must not be included into oop-maps at calls | |
2410 assert(!is_call_site || assigned_reg >= nof_regs || !is_caller_save(assigned_reg), "interval is in a caller-save register at a call -> register will be overwritten"); | |
2411 | |
2412 VMReg name = vm_reg_for_interval(interval); | |
3908
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
2426
diff
changeset
|
2413 set_oop(map, name); |
0 | 2414 |
2415 // Spill optimization: when the stack value is guaranteed to be always correct, | |
2416 // then it must be added to the oop map even if the interval is currently in a register | |
2417 if (interval->always_in_memory() && | |
2418 op->id() > interval->spill_definition_pos() && | |
2419 interval->assigned_reg() != interval->canonical_spill_slot()) { | |
2420 assert(interval->spill_definition_pos() > 0, "position not set correctly"); | |
2421 assert(interval->canonical_spill_slot() >= LinearScan::nof_regs, "no spill slot assigned"); | |
2422 assert(interval->assigned_reg() < LinearScan::nof_regs, "interval is on stack, so stack slot is registered twice"); | |
2423 | |
3908
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
2426
diff
changeset
|
2424 set_oop(map, frame_map()->slot_regname(interval->canonical_spill_slot() - LinearScan::nof_regs)); |
0 | 2425 } |
2426 } | |
2427 } | |
2428 | |
2429 // add oops from lock stack | |
2430 assert(info->stack() != NULL, "CodeEmitInfo must always have a stack"); | |
1819 | 2431 int locks_count = info->stack()->total_locks_size(); |
0 | 2432 for (int i = 0; i < locks_count; i++) { |
3908
7588156f5cf9
7051798: SA-JDI: NPE in Frame.addressOfStackSlot(Frame.java:244)
never
parents:
2426
diff
changeset
|
2433 set_oop(map, frame_map()->monitor_object_regname(i)); |
0 | 2434 } |
2435 | |
2436 return map; | |
2437 } | |
2438 | |
2439 | |
2440 void LinearScan::compute_oop_map(IntervalWalker* iw, const LIR_OpVisitState &visitor, LIR_Op* op) { | |
2441 assert(visitor.info_count() > 0, "no oop map needed"); | |
2442 | |
2443 // compute oop_map only for first CodeEmitInfo | |
2444 // because it is (in most cases) equal for all other infos of the same operation | |
2445 CodeEmitInfo* first_info = visitor.info_at(0); | |
2446 OopMap* first_oop_map = compute_oop_map(iw, op, first_info, visitor.has_call()); | |
2447 | |
2448 for (int i = 0; i < visitor.info_count(); i++) { | |
2449 CodeEmitInfo* info = visitor.info_at(i); | |
2450 OopMap* oop_map = first_oop_map; | |
2451 | |
2452 if (info->stack()->locks_size() != first_info->stack()->locks_size()) { | |
2453 // this info has a different number of locks then the precomputed oop map | |
2454 // (possible for lock and unlock instructions) -> compute oop map with | |
2455 // correct lock information | |
2456 oop_map = compute_oop_map(iw, op, info, visitor.has_call()); | |
2457 } | |
2458 | |
2459 if (info->_oop_map == NULL) { | |
2460 info->_oop_map = oop_map; | |
2461 } else { | |
2462 // a CodeEmitInfo can not be shared between different LIR-instructions | |
2463 // because interval splitting can occur anywhere between two instructions | |
2464 // and so the oop maps must be different | |
2465 // -> check if the already set oop_map is exactly the one calculated for this operation | |
2466 assert(info->_oop_map == oop_map, "same CodeEmitInfo used for multiple LIR instructions"); | |
2467 } | |
2468 } | |
2469 } | |
2470 | |
2471 | |
2472 // frequently used constants | |
4948
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2473 // Allocate them with new so they are never destroyed (otherwise, a |
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2474 // forced exit could destroy these objects while they are still in |
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2475 // use). |
6197 | 2476 ConstantOopWriteValue* LinearScan::_oop_null_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantOopWriteValue(NULL); |
2477 ConstantIntValue* LinearScan::_int_m1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(-1); | |
2478 ConstantIntValue* LinearScan::_int_0_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(0); | |
2479 ConstantIntValue* LinearScan::_int_1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(1); | |
2480 ConstantIntValue* LinearScan::_int_2_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(2); | |
2481 LocationValue* _illegal_value = new (ResourceObj::C_HEAP, mtCompiler) LocationValue(Location()); | |
0 | 2482 |
2483 void LinearScan::init_compute_debug_info() { | |
2484 // cache for frequently used scope values | |
2485 // (cpu registers and stack slots) | |
2486 _scope_value_cache = ScopeValueArray((LinearScan::nof_cpu_regs + frame_map()->argcount() + max_spills()) * 2, NULL); | |
2487 } | |
2488 | |
2489 MonitorValue* LinearScan::location_for_monitor_index(int monitor_index) { | |
2490 Location loc; | |
2491 if (!frame_map()->location_for_monitor_object(monitor_index, &loc)) { | |
2492 bailout("too large frame"); | |
2493 } | |
2494 ScopeValue* object_scope_value = new LocationValue(loc); | |
2495 | |
2496 if (!frame_map()->location_for_monitor_lock(monitor_index, &loc)) { | |
2497 bailout("too large frame"); | |
2498 } | |
2499 return new MonitorValue(object_scope_value, loc); | |
2500 } | |
2501 | |
2502 LocationValue* LinearScan::location_for_name(int name, Location::Type loc_type) { | |
2503 Location loc; | |
2504 if (!frame_map()->locations_for_slot(name, loc_type, &loc)) { | |
2505 bailout("too large frame"); | |
2506 } | |
2507 return new LocationValue(loc); | |
2508 } | |
2509 | |
2510 | |
2511 int LinearScan::append_scope_value_for_constant(LIR_Opr opr, GrowableArray<ScopeValue*>* scope_values) { | |
2512 assert(opr->is_constant(), "should not be called otherwise"); | |
2513 | |
2514 LIR_Const* c = opr->as_constant_ptr(); | |
2515 BasicType t = c->type(); | |
2516 switch (t) { | |
2517 case T_OBJECT: { | |
2518 jobject value = c->as_jobject(); | |
2519 if (value == NULL) { | |
4948
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2520 scope_values->append(_oop_null_scope_value); |
0 | 2521 } else { |
2522 scope_values->append(new ConstantOopWriteValue(c->as_jobject())); | |
2523 } | |
2524 return 1; | |
2525 } | |
2526 | |
2527 case T_INT: // fall through | |
2528 case T_FLOAT: { | |
2529 int value = c->as_jint_bits(); | |
2530 switch (value) { | |
4948
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2531 case -1: scope_values->append(_int_m1_scope_value); break; |
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2532 case 0: scope_values->append(_int_0_scope_value); break; |
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2533 case 1: scope_values->append(_int_1_scope_value); break; |
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2534 case 2: scope_values->append(_int_2_scope_value); break; |
0 | 2535 default: scope_values->append(new ConstantIntValue(c->as_jint_bits())); break; |
2536 } | |
2537 return 1; | |
2538 } | |
2539 | |
2540 case T_LONG: // fall through | |
2541 case T_DOUBLE: { | |
1060 | 2542 #ifdef _LP64 |
4948
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2543 scope_values->append(_int_0_scope_value); |
1060 | 2544 scope_values->append(new ConstantLongValue(c->as_jlong_bits())); |
2545 #else | |
0 | 2546 if (hi_word_offset_in_bytes > lo_word_offset_in_bytes) { |
2547 scope_values->append(new ConstantIntValue(c->as_jint_hi_bits())); | |
2548 scope_values->append(new ConstantIntValue(c->as_jint_lo_bits())); | |
2549 } else { | |
2550 scope_values->append(new ConstantIntValue(c->as_jint_lo_bits())); | |
2551 scope_values->append(new ConstantIntValue(c->as_jint_hi_bits())); | |
2552 } | |
1060 | 2553 #endif |
0 | 2554 return 2; |
2555 } | |
2556 | |
1297
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1060
diff
changeset
|
2557 case T_ADDRESS: { |
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1060
diff
changeset
|
2558 #ifdef _LP64 |
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1060
diff
changeset
|
2559 scope_values->append(new ConstantLongValue(c->as_jint())); |
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1060
diff
changeset
|
2560 #else |
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1060
diff
changeset
|
2561 scope_values->append(new ConstantIntValue(c->as_jint())); |
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1060
diff
changeset
|
2562 #endif |
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1060
diff
changeset
|
2563 return 1; |
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1060
diff
changeset
|
2564 } |
c466efa608d5
6932496: c1: deoptimization of jsr subroutine fails on sparcv9
roland
parents:
1060
diff
changeset
|
2565 |
0 | 2566 default: |
2567 ShouldNotReachHere(); | |
304 | 2568 return -1; |
0 | 2569 } |
2570 } | |
2571 | |
2572 int LinearScan::append_scope_value_for_operand(LIR_Opr opr, GrowableArray<ScopeValue*>* scope_values) { | |
2573 if (opr->is_single_stack()) { | |
2574 int stack_idx = opr->single_stack_ix(); | |
2575 bool is_oop = opr->is_oop_register(); | |
2576 int cache_idx = (stack_idx + LinearScan::nof_cpu_regs) * 2 + (is_oop ? 1 : 0); | |
2577 | |
2578 ScopeValue* sv = _scope_value_cache.at(cache_idx); | |
2579 if (sv == NULL) { | |
2580 Location::Type loc_type = is_oop ? Location::oop : Location::normal; | |
2581 sv = location_for_name(stack_idx, loc_type); | |
2582 _scope_value_cache.at_put(cache_idx, sv); | |
2583 } | |
2584 | |
2585 // check if cached value is correct | |
2586 DEBUG_ONLY(assert_equal(sv, location_for_name(stack_idx, is_oop ? Location::oop : Location::normal))); | |
2587 | |
2588 scope_values->append(sv); | |
2589 return 1; | |
2590 | |
2591 } else if (opr->is_single_cpu()) { | |
2592 bool is_oop = opr->is_oop_register(); | |
2593 int cache_idx = opr->cpu_regnr() * 2 + (is_oop ? 1 : 0); | |
1060 | 2594 Location::Type int_loc_type = NOT_LP64(Location::normal) LP64_ONLY(Location::int_in_long); |
0 | 2595 |
2596 ScopeValue* sv = _scope_value_cache.at(cache_idx); | |
2597 if (sv == NULL) { | |
1060 | 2598 Location::Type loc_type = is_oop ? Location::oop : int_loc_type; |
0 | 2599 VMReg rname = frame_map()->regname(opr); |
2600 sv = new LocationValue(Location::new_reg_loc(loc_type, rname)); | |
2601 _scope_value_cache.at_put(cache_idx, sv); | |
2602 } | |
2603 | |
2604 // check if cached value is correct | |
1060 | 2605 DEBUG_ONLY(assert_equal(sv, new LocationValue(Location::new_reg_loc(is_oop ? Location::oop : int_loc_type, frame_map()->regname(opr))))); |
0 | 2606 |
2607 scope_values->append(sv); | |
2608 return 1; | |
2609 | |
304 | 2610 #ifdef X86 |
0 | 2611 } else if (opr->is_single_xmm()) { |
2612 VMReg rname = opr->as_xmm_float_reg()->as_VMReg(); | |
2613 LocationValue* sv = new LocationValue(Location::new_reg_loc(Location::normal, rname)); | |
2614 | |
2615 scope_values->append(sv); | |
2616 return 1; | |
2617 #endif | |
2618 | |
2619 } else if (opr->is_single_fpu()) { | |
304 | 2620 #ifdef X86 |
0 | 2621 // the exact location of fpu stack values is only known |
2622 // during fpu stack allocation, so the stack allocator object | |
2623 // must be present | |
2624 assert(use_fpu_stack_allocation(), "should not have float stack values without fpu stack allocation (all floats must be SSE2)"); | |
2625 assert(_fpu_stack_allocator != NULL, "must be present"); | |
2626 opr = _fpu_stack_allocator->to_fpu_stack(opr); | |
2627 #endif | |
2628 | |
2629 Location::Type loc_type = float_saved_as_double ? Location::float_in_dbl : Location::normal; | |
2630 VMReg rname = frame_map()->fpu_regname(opr->fpu_regnr()); | |
3999
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2631 #ifndef __SOFTFP__ |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2632 #ifndef VM_LITTLE_ENDIAN |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2633 if (! float_saved_as_double) { |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2634 // On big endian system, we may have an issue if float registers use only |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2635 // the low half of the (same) double registers. |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2636 // Both the float and the double could have the same regnr but would correspond |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2637 // to two different addresses once saved. |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2638 |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2639 // get next safely (no assertion checks) |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2640 VMReg next = VMRegImpl::as_VMReg(1+rname->value()); |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2641 if (next->is_reg() && |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2642 (next->as_FloatRegister() == rname->as_FloatRegister())) { |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2643 // the back-end does use the same numbering for the double and the float |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2644 rname = next; // VMReg for the low bits, e.g. the real VMReg for the float |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2645 } |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2646 } |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2647 #endif |
eba73e0c7780
7096366: PPC: corruption of floating-point values with DeoptimizeALot
bdelsart
parents:
3908
diff
changeset
|
2648 #endif |
0 | 2649 LocationValue* sv = new LocationValue(Location::new_reg_loc(loc_type, rname)); |
2650 | |
2651 scope_values->append(sv); | |
2652 return 1; | |
2653 | |
2654 } else { | |
2655 // double-size operands | |
2656 | |
2657 ScopeValue* first; | |
2658 ScopeValue* second; | |
2659 | |
2660 if (opr->is_double_stack()) { | |
304 | 2661 #ifdef _LP64 |
2662 Location loc1; | |
2663 Location::Type loc_type = opr->type() == T_LONG ? Location::lng : Location::dbl; | |
2664 if (!frame_map()->locations_for_slot(opr->double_stack_ix(), loc_type, &loc1, NULL)) { | |
2665 bailout("too large frame"); | |
2666 } | |
2667 // Does this reverse on x86 vs. sparc? | |
2668 first = new LocationValue(loc1); | |
4948
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2669 second = _int_0_scope_value; |
304 | 2670 #else |
0 | 2671 Location loc1, loc2; |
2672 if (!frame_map()->locations_for_slot(opr->double_stack_ix(), Location::normal, &loc1, &loc2)) { | |
2673 bailout("too large frame"); | |
2674 } | |
2675 first = new LocationValue(loc1); | |
2676 second = new LocationValue(loc2); | |
304 | 2677 #endif // _LP64 |
0 | 2678 |
2679 } else if (opr->is_double_cpu()) { | |
2680 #ifdef _LP64 | |
2681 VMReg rname_first = opr->as_register_lo()->as_VMReg(); | |
2682 first = new LocationValue(Location::new_reg_loc(Location::lng, rname_first)); | |
4948
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2683 second = _int_0_scope_value; |
0 | 2684 #else |
2685 VMReg rname_first = opr->as_register_lo()->as_VMReg(); | |
2686 VMReg rname_second = opr->as_register_hi()->as_VMReg(); | |
2687 | |
2688 if (hi_word_offset_in_bytes < lo_word_offset_in_bytes) { | |
2689 // lo/hi and swapped relative to first and second, so swap them | |
2690 VMReg tmp = rname_first; | |
2691 rname_first = rname_second; | |
2692 rname_second = tmp; | |
2693 } | |
2694 | |
2695 first = new LocationValue(Location::new_reg_loc(Location::normal, rname_first)); | |
2696 second = new LocationValue(Location::new_reg_loc(Location::normal, rname_second)); | |
304 | 2697 #endif //_LP64 |
2698 | |
2699 | |
2700 #ifdef X86 | |
0 | 2701 } else if (opr->is_double_xmm()) { |
2702 assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation"); | |
2703 VMReg rname_first = opr->as_xmm_double_reg()->as_VMReg(); | |
1369 | 2704 # ifdef _LP64 |
2705 first = new LocationValue(Location::new_reg_loc(Location::dbl, rname_first)); | |
4948
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2706 second = _int_0_scope_value; |
1369 | 2707 # else |
0 | 2708 first = new LocationValue(Location::new_reg_loc(Location::normal, rname_first)); |
2709 // %%% This is probably a waste but we'll keep things as they were for now | |
2710 if (true) { | |
2711 VMReg rname_second = rname_first->next(); | |
2712 second = new LocationValue(Location::new_reg_loc(Location::normal, rname_second)); | |
2713 } | |
1369 | 2714 # endif |
0 | 2715 #endif |
2716 | |
2717 } else if (opr->is_double_fpu()) { | |
2718 // On SPARC, fpu_regnrLo/fpu_regnrHi represents the two halves of | |
304 | 2719 // the double as float registers in the native ordering. On X86, |
0 | 2720 // fpu_regnrLo is a FPU stack slot whose VMReg represents |
2721 // the low-order word of the double and fpu_regnrLo + 1 is the | |
2722 // name for the other half. *first and *second must represent the | |
2723 // least and most significant words, respectively. | |
2724 | |
304 | 2725 #ifdef X86 |
0 | 2726 // the exact location of fpu stack values is only known |
2727 // during fpu stack allocation, so the stack allocator object | |
2728 // must be present | |
2729 assert(use_fpu_stack_allocation(), "should not have float stack values without fpu stack allocation (all floats must be SSE2)"); | |
2730 assert(_fpu_stack_allocator != NULL, "must be present"); | |
2731 opr = _fpu_stack_allocator->to_fpu_stack(opr); | |
2732 | |
2345
b9684d5ccb52
7011490: Wrong computation results in Test6880034
vladidan
parents:
2192
diff
changeset
|
2733 assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation (only fpu_regnrLo is used)"); |
0 | 2734 #endif |
2735 #ifdef SPARC | |
2736 assert(opr->fpu_regnrLo() == opr->fpu_regnrHi() + 1, "assumed in calculation (only fpu_regnrHi is used)"); | |
2737 #endif | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2738 #ifdef ARM |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2739 assert(opr->fpu_regnrHi() == opr->fpu_regnrLo() + 1, "assumed in calculation (only fpu_regnrLo is used)"); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2740 #endif |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2741 #ifdef PPC |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2742 assert(opr->fpu_regnrLo() == opr->fpu_regnrHi(), "assumed in calculation (only fpu_regnrHi is used)"); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
2743 #endif |
0 | 2744 |
2345
b9684d5ccb52
7011490: Wrong computation results in Test6880034
vladidan
parents:
2192
diff
changeset
|
2745 #ifdef VM_LITTLE_ENDIAN |
b9684d5ccb52
7011490: Wrong computation results in Test6880034
vladidan
parents:
2192
diff
changeset
|
2746 VMReg rname_first = frame_map()->fpu_regname(opr->fpu_regnrLo()); |
b9684d5ccb52
7011490: Wrong computation results in Test6880034
vladidan
parents:
2192
diff
changeset
|
2747 #else |
0 | 2748 VMReg rname_first = frame_map()->fpu_regname(opr->fpu_regnrHi()); |
2345
b9684d5ccb52
7011490: Wrong computation results in Test6880034
vladidan
parents:
2192
diff
changeset
|
2749 #endif |
b9684d5ccb52
7011490: Wrong computation results in Test6880034
vladidan
parents:
2192
diff
changeset
|
2750 |
1369 | 2751 #ifdef _LP64 |
2752 first = new LocationValue(Location::new_reg_loc(Location::dbl, rname_first)); | |
4948
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2753 second = _int_0_scope_value; |
1369 | 2754 #else |
0 | 2755 first = new LocationValue(Location::new_reg_loc(Location::normal, rname_first)); |
2756 // %%% This is probably a waste but we'll keep things as they were for now | |
2757 if (true) { | |
2758 VMReg rname_second = rname_first->next(); | |
2759 second = new LocationValue(Location::new_reg_loc(Location::normal, rname_second)); | |
2760 } | |
1369 | 2761 #endif |
0 | 2762 |
2763 } else { | |
2764 ShouldNotReachHere(); | |
2765 first = NULL; | |
2766 second = NULL; | |
2767 } | |
2768 | |
2769 assert(first != NULL && second != NULL, "must be set"); | |
2770 // The convention the interpreter uses is that the second local | |
2771 // holds the first raw word of the native double representation. | |
2772 // This is actually reasonable, since locals and stack arrays | |
2773 // grow downwards in all implementations. | |
2774 // (If, on some machine, the interpreter's Java locals or stack | |
2775 // were to grow upwards, the embedded doubles would be word-swapped.) | |
2776 scope_values->append(second); | |
2777 scope_values->append(first); | |
2778 return 2; | |
2779 } | |
2780 } | |
2781 | |
2782 | |
2783 int LinearScan::append_scope_value(int op_id, Value value, GrowableArray<ScopeValue*>* scope_values) { | |
2784 if (value != NULL) { | |
2785 LIR_Opr opr = value->operand(); | |
2786 Constant* con = value->as_Constant(); | |
2787 | |
2788 assert(con == NULL || opr->is_virtual() || opr->is_constant() || opr->is_illegal(), "asumption: Constant instructions have only constant operands (or illegal if constant is optimized away)"); | |
2789 assert(con != NULL || opr->is_virtual(), "asumption: non-Constant instructions have only virtual operands"); | |
2790 | |
2791 if (con != NULL && !con->is_pinned() && !opr->is_constant()) { | |
2792 // Unpinned constants may have a virtual operand for a part of the lifetime | |
2793 // or may be illegal when it was optimized away, | |
2794 // so always use a constant operand | |
2795 opr = LIR_OprFact::value_type(con->type()); | |
2796 } | |
2797 assert(opr->is_virtual() || opr->is_constant(), "other cases not allowed here"); | |
2798 | |
2799 if (opr->is_virtual()) { | |
2800 LIR_OpVisitState::OprMode mode = LIR_OpVisitState::inputMode; | |
2801 | |
2802 BlockBegin* block = block_of_op_with_id(op_id); | |
2803 if (block->number_of_sux() == 1 && op_id == block->last_lir_instruction_id()) { | |
2804 // generating debug information for the last instruction of a block. | |
2805 // if this instruction is a branch, spill moves are inserted before this branch | |
2806 // and so the wrong operand would be returned (spill moves at block boundaries are not | |
2807 // considered in the live ranges of intervals) | |
2808 // Solution: use the first op_id of the branch target block instead. | |
2809 if (block->lir()->instructions_list()->last()->as_OpBranch() != NULL) { | |
2810 if (block->live_out().at(opr->vreg_number())) { | |
2811 op_id = block->sux_at(0)->first_lir_instruction_id(); | |
2812 mode = LIR_OpVisitState::outputMode; | |
2813 } | |
2814 } | |
2815 } | |
2816 | |
2817 // Get current location of operand | |
2818 // The operand must be live because debug information is considered when building the intervals | |
2819 // if the interval is not live, color_lir_opr will cause an assertion failure | |
2820 opr = color_lir_opr(opr, op_id, mode); | |
2821 assert(!has_call(op_id) || opr->is_stack() || !is_caller_save(reg_num(opr)), "can not have caller-save register operands at calls"); | |
2822 | |
2823 // Append to ScopeValue array | |
2824 return append_scope_value_for_operand(opr, scope_values); | |
2825 | |
2826 } else { | |
2827 assert(value->as_Constant() != NULL, "all other instructions have only virtual operands"); | |
2828 assert(opr->is_constant(), "operand must be constant"); | |
2829 | |
2830 return append_scope_value_for_constant(opr, scope_values); | |
2831 } | |
2832 } else { | |
2833 // append a dummy value because real value not needed | |
4948
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2834 scope_values->append(_illegal_value); |
0 | 2835 return 1; |
2836 } | |
2837 } | |
2838 | |
2839 | |
1819 | 2840 IRScopeDebugInfo* LinearScan::compute_debug_info_for_scope(int op_id, IRScope* cur_scope, ValueStack* cur_state, ValueStack* innermost_state) { |
0 | 2841 IRScopeDebugInfo* caller_debug_info = NULL; |
1819 | 2842 |
2843 ValueStack* caller_state = cur_state->caller_state(); | |
0 | 2844 if (caller_state != NULL) { |
2845 // process recursively to compute outermost scope first | |
1819 | 2846 caller_debug_info = compute_debug_info_for_scope(op_id, cur_scope->caller(), caller_state, innermost_state); |
0 | 2847 } |
2848 | |
2849 // initialize these to null. | |
2850 // If we don't need deopt info or there are no locals, expressions or monitors, | |
2851 // then these get recorded as no information and avoids the allocation of 0 length arrays. | |
2852 GrowableArray<ScopeValue*>* locals = NULL; | |
2853 GrowableArray<ScopeValue*>* expressions = NULL; | |
2854 GrowableArray<MonitorValue*>* monitors = NULL; | |
2855 | |
2856 // describe local variable values | |
1819 | 2857 int nof_locals = cur_state->locals_size(); |
0 | 2858 if (nof_locals > 0) { |
2859 locals = new GrowableArray<ScopeValue*>(nof_locals); | |
2860 | |
2861 int pos = 0; | |
2862 while (pos < nof_locals) { | |
2863 assert(pos < cur_state->locals_size(), "why not?"); | |
2864 | |
2865 Value local = cur_state->local_at(pos); | |
2866 pos += append_scope_value(op_id, local, locals); | |
2867 | |
2868 assert(locals->length() == pos, "must match"); | |
2869 } | |
2870 assert(locals->length() == cur_scope->method()->max_locals(), "wrong number of locals"); | |
2871 assert(locals->length() == cur_state->locals_size(), "wrong number of locals"); | |
1819 | 2872 } else if (cur_scope->method()->max_locals() > 0) { |
2873 assert(cur_state->kind() == ValueStack::EmptyExceptionState, "should be"); | |
2874 nof_locals = cur_scope->method()->max_locals(); | |
2875 locals = new GrowableArray<ScopeValue*>(nof_locals); | |
2876 for(int i = 0; i < nof_locals; i++) { | |
4948
c7401dcad8bf
7143038: SIGSEGV in assert_equal / LinearScan::assign_reg_num
roland
parents:
3999
diff
changeset
|
2877 locals->append(_illegal_value); |
1819 | 2878 } |
2879 } | |
0 | 2880 |
2881 // describe expression stack | |
1819 | 2882 int nof_stack = cur_state->stack_size(); |
0 | 2883 if (nof_stack > 0) { |
2884 expressions = new GrowableArray<ScopeValue*>(nof_stack); | |
2885 | |
1819 | 2886 int pos = 0; |
2887 while (pos < nof_stack) { | |
2888 Value expression = cur_state->stack_at_inc(pos); | |
0 | 2889 append_scope_value(op_id, expression, expressions); |
2890 | |
1819 | 2891 assert(expressions->length() == pos, "must match"); |
2892 } | |
2893 assert(expressions->length() == cur_state->stack_size(), "wrong number of stack entries"); | |
0 | 2894 } |
2895 | |
2896 // describe monitors | |
1819 | 2897 int nof_locks = cur_state->locks_size(); |
0 | 2898 if (nof_locks > 0) { |
1819 | 2899 int lock_offset = cur_state->caller_state() != NULL ? cur_state->caller_state()->total_locks_size() : 0; |
0 | 2900 monitors = new GrowableArray<MonitorValue*>(nof_locks); |
1819 | 2901 for (int i = 0; i < nof_locks; i++) { |
2902 monitors->append(location_for_monitor_index(lock_offset + i)); | |
2903 } | |
2904 } | |
2905 | |
2906 return new IRScopeDebugInfo(cur_scope, cur_state->bci(), locals, expressions, monitors, caller_debug_info); | |
0 | 2907 } |
2908 | |
2909 | |
2910 void LinearScan::compute_debug_info(CodeEmitInfo* info, int op_id) { | |
2911 TRACE_LINEAR_SCAN(3, tty->print_cr("creating debug information at op_id %d", op_id)); | |
2912 | |
2913 IRScope* innermost_scope = info->scope(); | |
2914 ValueStack* innermost_state = info->stack(); | |
2915 | |
2916 assert(innermost_scope != NULL && innermost_state != NULL, "why is it missing?"); | |
2917 | |
1819 | 2918 DEBUG_ONLY(check_stack_depth(info, innermost_state->stack_size())); |
0 | 2919 |
2920 if (info->_scope_debug_info == NULL) { | |
2921 // compute debug information | |
1819 | 2922 info->_scope_debug_info = compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state); |
0 | 2923 } else { |
2924 // debug information already set. Check that it is correct from the current point of view | |
1819 | 2925 DEBUG_ONLY(assert_equal(info->_scope_debug_info, compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state))); |
0 | 2926 } |
2927 } | |
2928 | |
2929 | |
2930 void LinearScan::assign_reg_num(LIR_OpList* instructions, IntervalWalker* iw) { | |
2931 LIR_OpVisitState visitor; | |
2932 int num_inst = instructions->length(); | |
2933 bool has_dead = false; | |
2934 | |
2935 for (int j = 0; j < num_inst; j++) { | |
2936 LIR_Op* op = instructions->at(j); | |
2937 if (op == NULL) { // this can happen when spill-moves are removed in eliminate_spill_moves | |
2938 has_dead = true; | |
2939 continue; | |
2940 } | |
2941 int op_id = op->id(); | |
2942 | |
2943 // visit instruction to get list of operands | |
2944 visitor.visit(op); | |
2945 | |
2946 // iterate all modes of the visitor and process all virtual operands | |
2947 for_each_visitor_mode(mode) { | |
2948 int n = visitor.opr_count(mode); | |
2949 for (int k = 0; k < n; k++) { | |
2950 LIR_Opr opr = visitor.opr_at(mode, k); | |
2951 if (opr->is_virtual_register()) { | |
2952 visitor.set_opr_at(mode, k, color_lir_opr(opr, op_id, mode)); | |
2953 } | |
2954 } | |
2955 } | |
2956 | |
2957 if (visitor.info_count() > 0) { | |
2958 // exception handling | |
2959 if (compilation()->has_exception_handlers()) { | |
2960 XHandlers* xhandlers = visitor.all_xhandler(); | |
2961 int n = xhandlers->length(); | |
2962 for (int k = 0; k < n; k++) { | |
2963 XHandler* handler = xhandlers->handler_at(k); | |
2964 if (handler->entry_code() != NULL) { | |
2965 assign_reg_num(handler->entry_code()->instructions_list(), NULL); | |
2966 } | |
2967 } | |
2968 } else { | |
2969 assert(visitor.all_xhandler()->length() == 0, "missed exception handler"); | |
2970 } | |
2971 | |
2972 // compute oop map | |
2973 assert(iw != NULL, "needed for compute_oop_map"); | |
2974 compute_oop_map(iw, visitor, op); | |
2975 | |
2976 // compute debug information | |
2977 if (!use_fpu_stack_allocation()) { | |
2978 // compute debug information if fpu stack allocation is not needed. | |
2979 // when fpu stack allocation is needed, the debug information can not | |
2980 // be computed here because the exact location of fpu operands is not known | |
2981 // -> debug information is created inside the fpu stack allocator | |
2982 int n = visitor.info_count(); | |
2983 for (int k = 0; k < n; k++) { | |
2984 compute_debug_info(visitor.info_at(k), op_id); | |
2985 } | |
2986 } | |
2987 } | |
2988 | |
2989 #ifdef ASSERT | |
2990 // make sure we haven't made the op invalid. | |
2991 op->verify(); | |
2992 #endif | |
2993 | |
2994 // remove useless moves | |
2995 if (op->code() == lir_move) { | |
2996 assert(op->as_Op1() != NULL, "move must be LIR_Op1"); | |
2997 LIR_Op1* move = (LIR_Op1*)op; | |
2998 LIR_Opr src = move->in_opr(); | |
2999 LIR_Opr dst = move->result_opr(); | |
3000 if (dst == src || | |
3001 !dst->is_pointer() && !src->is_pointer() && | |
3002 src->is_same_register(dst)) { | |
3003 instructions->at_put(j, NULL); | |
3004 has_dead = true; | |
3005 } | |
3006 } | |
3007 } | |
3008 | |
3009 if (has_dead) { | |
3010 // iterate all instructions of the block and remove all null-values. | |
3011 int insert_point = 0; | |
3012 for (int j = 0; j < num_inst; j++) { | |
3013 LIR_Op* op = instructions->at(j); | |
3014 if (op != NULL) { | |
3015 if (insert_point != j) { | |
3016 instructions->at_put(insert_point, op); | |
3017 } | |
3018 insert_point++; | |
3019 } | |
3020 } | |
3021 instructions->truncate(insert_point); | |
3022 } | |
3023 } | |
3024 | |
3025 void LinearScan::assign_reg_num() { | |
3026 TIME_LINEAR_SCAN(timer_assign_reg_num); | |
3027 | |
3028 init_compute_debug_info(); | |
3029 IntervalWalker* iw = init_compute_oop_maps(); | |
3030 | |
3031 int num_blocks = block_count(); | |
3032 for (int i = 0; i < num_blocks; i++) { | |
3033 BlockBegin* block = block_at(i); | |
3034 assign_reg_num(block->lir()->instructions_list(), iw); | |
3035 } | |
3036 } | |
3037 | |
3038 | |
3039 void LinearScan::do_linear_scan() { | |
3040 NOT_PRODUCT(_total_timer.begin_method()); | |
3041 | |
3042 number_instructions(); | |
3043 | |
3044 NOT_PRODUCT(print_lir(1, "Before Register Allocation")); | |
3045 | |
3046 compute_local_live_sets(); | |
3047 compute_global_live_sets(); | |
3048 CHECK_BAILOUT(); | |
3049 | |
3050 build_intervals(); | |
3051 CHECK_BAILOUT(); | |
3052 sort_intervals_before_allocation(); | |
3053 | |
3054 NOT_PRODUCT(print_intervals("Before Register Allocation")); | |
3055 NOT_PRODUCT(LinearScanStatistic::compute(this, _stat_before_alloc)); | |
3056 | |
3057 allocate_registers(); | |
3058 CHECK_BAILOUT(); | |
3059 | |
3060 resolve_data_flow(); | |
3061 if (compilation()->has_exception_handlers()) { | |
3062 resolve_exception_handlers(); | |
3063 } | |
3064 // fill in number of spill slots into frame_map | |
3065 propagate_spill_slots(); | |
3066 CHECK_BAILOUT(); | |
3067 | |
3068 NOT_PRODUCT(print_intervals("After Register Allocation")); | |
3069 NOT_PRODUCT(print_lir(2, "LIR after register allocation:")); | |
3070 | |
3071 sort_intervals_after_allocation(); | |
722
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3072 |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3073 DEBUG_ONLY(verify()); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3074 |
0 | 3075 eliminate_spill_moves(); |
3076 assign_reg_num(); | |
3077 CHECK_BAILOUT(); | |
3078 | |
3079 NOT_PRODUCT(print_lir(2, "LIR after assignment of register numbers:")); | |
3080 NOT_PRODUCT(LinearScanStatistic::compute(this, _stat_after_asign)); | |
3081 | |
3082 { TIME_LINEAR_SCAN(timer_allocate_fpu_stack); | |
3083 | |
3084 if (use_fpu_stack_allocation()) { | |
3085 allocate_fpu_stack(); // Only has effect on Intel | |
3086 NOT_PRODUCT(print_lir(2, "LIR after FPU stack allocation:")); | |
3087 } | |
3088 } | |
3089 | |
3090 { TIME_LINEAR_SCAN(timer_optimize_lir); | |
3091 | |
3092 EdgeMoveOptimizer::optimize(ir()->code()); | |
3093 ControlFlowOptimizer::optimize(ir()->code()); | |
3094 // check that cfg is still correct after optimizations | |
3095 ir()->verify(); | |
3096 } | |
3097 | |
3098 NOT_PRODUCT(print_lir(1, "Before Code Generation", false)); | |
3099 NOT_PRODUCT(LinearScanStatistic::compute(this, _stat_final)); | |
3100 NOT_PRODUCT(_total_timer.end_method(this)); | |
3101 } | |
3102 | |
3103 | |
3104 // ********** Printing functions | |
3105 | |
3106 #ifndef PRODUCT | |
3107 | |
3108 void LinearScan::print_timers(double total) { | |
3109 _total_timer.print(total); | |
3110 } | |
3111 | |
3112 void LinearScan::print_statistics() { | |
3113 _stat_before_alloc.print("before allocation"); | |
3114 _stat_after_asign.print("after assignment of register"); | |
3115 _stat_final.print("after optimization"); | |
3116 } | |
3117 | |
3118 void LinearScan::print_bitmap(BitMap& b) { | |
3119 for (unsigned int i = 0; i < b.size(); i++) { | |
3120 if (b.at(i)) tty->print("%d ", i); | |
3121 } | |
3122 tty->cr(); | |
3123 } | |
3124 | |
3125 void LinearScan::print_intervals(const char* label) { | |
3126 if (TraceLinearScanLevel >= 1) { | |
3127 int i; | |
3128 tty->cr(); | |
3129 tty->print_cr("%s", label); | |
3130 | |
3131 for (i = 0; i < interval_count(); i++) { | |
3132 Interval* interval = interval_at(i); | |
3133 if (interval != NULL) { | |
3134 interval->print(); | |
3135 } | |
3136 } | |
3137 | |
3138 tty->cr(); | |
3139 tty->print_cr("--- Basic Blocks ---"); | |
3140 for (i = 0; i < block_count(); i++) { | |
3141 BlockBegin* block = block_at(i); | |
3142 tty->print("B%d [%d, %d, %d, %d] ", block->block_id(), block->first_lir_instruction_id(), block->last_lir_instruction_id(), block->loop_index(), block->loop_depth()); | |
3143 } | |
3144 tty->cr(); | |
3145 tty->cr(); | |
3146 } | |
3147 | |
3148 if (PrintCFGToFile) { | |
3149 CFGPrinter::print_intervals(&_intervals, label); | |
3150 } | |
3151 } | |
3152 | |
3153 void LinearScan::print_lir(int level, const char* label, bool hir_valid) { | |
3154 if (TraceLinearScanLevel >= level) { | |
3155 tty->cr(); | |
3156 tty->print_cr("%s", label); | |
3157 print_LIR(ir()->linear_scan_order()); | |
3158 tty->cr(); | |
3159 } | |
3160 | |
3161 if (level == 1 && PrintCFGToFile) { | |
3162 CFGPrinter::print_cfg(ir()->linear_scan_order(), label, hir_valid, true); | |
3163 } | |
3164 } | |
3165 | |
3166 #endif //PRODUCT | |
3167 | |
3168 | |
3169 // ********** verification functions for allocation | |
3170 // (check that all intervals have a correct register and that no registers are overwritten) | |
3171 #ifdef ASSERT | |
3172 | |
3173 void LinearScan::verify() { | |
3174 TRACE_LINEAR_SCAN(2, tty->print_cr("********* verifying intervals ******************************************")); | |
3175 verify_intervals(); | |
3176 | |
3177 TRACE_LINEAR_SCAN(2, tty->print_cr("********* verifying that no oops are in fixed intervals ****************")); | |
3178 verify_no_oops_in_fixed_intervals(); | |
3179 | |
3180 TRACE_LINEAR_SCAN(2, tty->print_cr("********* verifying that unpinned constants are not alive across block boundaries")); | |
3181 verify_constants(); | |
3182 | |
3183 TRACE_LINEAR_SCAN(2, tty->print_cr("********* verifying register allocation ********************************")); | |
3184 verify_registers(); | |
3185 | |
3186 TRACE_LINEAR_SCAN(2, tty->print_cr("********* no errors found **********************************************")); | |
3187 } | |
3188 | |
3189 void LinearScan::verify_intervals() { | |
3190 int len = interval_count(); | |
3191 bool has_error = false; | |
3192 | |
3193 for (int i = 0; i < len; i++) { | |
3194 Interval* i1 = interval_at(i); | |
3195 if (i1 == NULL) continue; | |
3196 | |
3197 i1->check_split_children(); | |
3198 | |
3199 if (i1->reg_num() != i) { | |
3200 tty->print_cr("Interval %d is on position %d in list", i1->reg_num(), i); i1->print(); tty->cr(); | |
3201 has_error = true; | |
3202 } | |
3203 | |
3204 if (i1->reg_num() >= LIR_OprDesc::vreg_base && i1->type() == T_ILLEGAL) { | |
3205 tty->print_cr("Interval %d has no type assigned", i1->reg_num()); i1->print(); tty->cr(); | |
3206 has_error = true; | |
3207 } | |
3208 | |
3209 if (i1->assigned_reg() == any_reg) { | |
3210 tty->print_cr("Interval %d has no register assigned", i1->reg_num()); i1->print(); tty->cr(); | |
3211 has_error = true; | |
3212 } | |
3213 | |
3214 if (i1->assigned_reg() == i1->assigned_regHi()) { | |
3215 tty->print_cr("Interval %d: low and high register equal", i1->reg_num()); i1->print(); tty->cr(); | |
3216 has_error = true; | |
3217 } | |
3218 | |
3219 if (!is_processed_reg_num(i1->assigned_reg())) { | |
3220 tty->print_cr("Can not have an Interval for an ignored register"); i1->print(); tty->cr(); | |
3221 has_error = true; | |
3222 } | |
3223 | |
3224 if (i1->first() == Range::end()) { | |
3225 tty->print_cr("Interval %d has no Range", i1->reg_num()); i1->print(); tty->cr(); | |
3226 has_error = true; | |
3227 } | |
3228 | |
3229 for (Range* r = i1->first(); r != Range::end(); r = r->next()) { | |
3230 if (r->from() >= r->to()) { | |
3231 tty->print_cr("Interval %d has zero length range", i1->reg_num()); i1->print(); tty->cr(); | |
3232 has_error = true; | |
3233 } | |
3234 } | |
3235 | |
3236 for (int j = i + 1; j < len; j++) { | |
3237 Interval* i2 = interval_at(j); | |
3238 if (i2 == NULL) continue; | |
3239 | |
3240 // special intervals that are created in MoveResolver | |
3241 // -> ignore them because the range information has no meaning there | |
3242 if (i1->from() == 1 && i1->to() == 2) continue; | |
3243 if (i2->from() == 1 && i2->to() == 2) continue; | |
3244 | |
3245 int r1 = i1->assigned_reg(); | |
3246 int r1Hi = i1->assigned_regHi(); | |
3247 int r2 = i2->assigned_reg(); | |
3248 int r2Hi = i2->assigned_regHi(); | |
3249 if (i1->intersects(i2) && (r1 == r2 || r1 == r2Hi || (r1Hi != any_reg && (r1Hi == r2 || r1Hi == r2Hi)))) { | |
3250 tty->print_cr("Intervals %d and %d overlap and have the same register assigned", i1->reg_num(), i2->reg_num()); | |
3251 i1->print(); tty->cr(); | |
3252 i2->print(); tty->cr(); | |
3253 has_error = true; | |
3254 } | |
3255 } | |
3256 } | |
3257 | |
3258 assert(has_error == false, "register allocation invalid"); | |
3259 } | |
3260 | |
3261 | |
3262 void LinearScan::verify_no_oops_in_fixed_intervals() { | |
722
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3263 Interval* fixed_intervals; |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3264 Interval* other_intervals; |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3265 create_unhandled_lists(&fixed_intervals, &other_intervals, is_precolored_cpu_interval, NULL); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3266 |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3267 // to ensure a walking until the last instruction id, add a dummy interval |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3268 // with a high operation id |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3269 other_intervals = new Interval(any_reg); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3270 other_intervals->add_range(max_jint - 2, max_jint - 1); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3271 IntervalWalker* iw = new IntervalWalker(this, fixed_intervals, other_intervals); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3272 |
0 | 3273 LIR_OpVisitState visitor; |
3274 for (int i = 0; i < block_count(); i++) { | |
3275 BlockBegin* block = block_at(i); | |
3276 | |
3277 LIR_OpList* instructions = block->lir()->instructions_list(); | |
3278 | |
3279 for (int j = 0; j < instructions->length(); j++) { | |
3280 LIR_Op* op = instructions->at(j); | |
3281 int op_id = op->id(); | |
3282 | |
3283 visitor.visit(op); | |
3284 | |
722
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3285 if (visitor.info_count() > 0) { |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3286 iw->walk_before(op->id()); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3287 bool check_live = true; |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3288 if (op->code() == lir_move) { |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3289 LIR_Op1* move = (LIR_Op1*)op; |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3290 check_live = (move->patch_code() == lir_patch_none); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3291 } |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3292 LIR_OpBranch* branch = op->as_OpBranch(); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3293 if (branch != NULL && branch->stub() != NULL && branch->stub()->is_exception_throw_stub()) { |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3294 // Don't bother checking the stub in this case since the |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3295 // exception stub will never return to normal control flow. |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3296 check_live = false; |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3297 } |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3298 |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3299 // Make sure none of the fixed registers is live across an |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3300 // oopmap since we can't handle that correctly. |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3301 if (check_live) { |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3302 for (Interval* interval = iw->active_first(fixedKind); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3303 interval != Interval::end(); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3304 interval = interval->next()) { |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3305 if (interval->current_to() > op->id() + 1) { |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3306 // This interval is live out of this op so make sure |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3307 // that this interval represents some value that's |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3308 // referenced by this op either as an input or output. |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3309 bool ok = false; |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3310 for_each_visitor_mode(mode) { |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3311 int n = visitor.opr_count(mode); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3312 for (int k = 0; k < n; k++) { |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3313 LIR_Opr opr = visitor.opr_at(mode, k); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3314 if (opr->is_fixed_cpu()) { |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3315 if (interval_at(reg_num(opr)) == interval) { |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3316 ok = true; |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3317 break; |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3318 } |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3319 int hi = reg_numHi(opr); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3320 if (hi != -1 && interval_at(hi) == interval) { |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3321 ok = true; |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3322 break; |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3323 } |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3324 } |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3325 } |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3326 } |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3327 assert(ok, "fixed intervals should never be live across an oopmap point"); |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3328 } |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3329 } |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3330 } |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3331 } |
a134d9824964
6828024: verification of fixed interval usage is too weak
never
parents:
337
diff
changeset
|
3332 |
0 | 3333 // oop-maps at calls do not contain registers, so check is not needed |
3334 if (!visitor.has_call()) { | |
3335 | |
3336 for_each_visitor_mode(mode) { | |
3337 int n = visitor.opr_count(mode); | |
3338 for (int k = 0; k < n; k++) { | |
3339 LIR_Opr opr = visitor.opr_at(mode, k); | |
3340 | |
3341 if (opr->is_fixed_cpu() && opr->is_oop()) { | |
3342 // operand is a non-virtual cpu register and contains an oop | |
3343 TRACE_LINEAR_SCAN(4, op->print_on(tty); tty->print("checking operand "); opr->print(); tty->cr()); | |
3344 | |
3345 Interval* interval = interval_at(reg_num(opr)); | |
3346 assert(interval != NULL, "no interval"); | |
3347 | |
3348 if (mode == LIR_OpVisitState::inputMode) { | |
3349 if (interval->to() >= op_id + 1) { | |
3350 assert(interval->to() < op_id + 2 || | |
3351 interval->has_hole_between(op_id, op_id + 2), | |
3352 "oop input operand live after instruction"); | |
3353 } | |
3354 } else if (mode == LIR_OpVisitState::outputMode) { | |
3355 if (interval->from() <= op_id - 1) { | |
3356 assert(interval->has_hole_between(op_id - 1, op_id), | |
3357 "oop input operand live after instruction"); | |
3358 } | |
3359 } | |
3360 } | |
3361 } | |
3362 } | |
3363 } | |
3364 } | |
3365 } | |
3366 } | |
3367 | |
3368 | |
3369 void LinearScan::verify_constants() { | |
3370 int num_regs = num_virtual_regs(); | |
3371 int size = live_set_size(); | |
3372 int num_blocks = block_count(); | |
3373 | |
3374 for (int i = 0; i < num_blocks; i++) { | |
3375 BlockBegin* block = block_at(i); | |
3376 BitMap live_at_edge = block->live_in(); | |
3377 | |
3378 // visit all registers where the live_at_edge bit is set | |
304 | 3379 for (int r = (int)live_at_edge.get_next_one_offset(0, size); r < size; r = (int)live_at_edge.get_next_one_offset(r + 1, size)) { |
0 | 3380 TRACE_LINEAR_SCAN(4, tty->print("checking interval %d of block B%d", r, block->block_id())); |
3381 | |
3382 Value value = gen()->instruction_for_vreg(r); | |
3383 | |
3384 assert(value != NULL, "all intervals live across block boundaries must have Value"); | |
3385 assert(value->operand()->is_register() && value->operand()->is_virtual(), "value must have virtual operand"); | |
3386 assert(value->operand()->vreg_number() == r, "register number must match"); | |
3387 // TKR assert(value->as_Constant() == NULL || value->is_pinned(), "only pinned constants can be alive accross block boundaries"); | |
3388 } | |
3389 } | |
3390 } | |
3391 | |
3392 | |
3393 class RegisterVerifier: public StackObj { | |
3394 private: | |
3395 LinearScan* _allocator; | |
3396 BlockList _work_list; // all blocks that must be processed | |
3397 IntervalsList _saved_states; // saved information of previous check | |
3398 | |
3399 // simplified access to methods of LinearScan | |
3400 Compilation* compilation() const { return _allocator->compilation(); } | |
3401 Interval* interval_at(int reg_num) const { return _allocator->interval_at(reg_num); } | |
3402 int reg_num(LIR_Opr opr) const { return _allocator->reg_num(opr); } | |
3403 | |
3404 // currently, only registers are processed | |
3405 int state_size() { return LinearScan::nof_regs; } | |
3406 | |
3407 // accessors | |
3408 IntervalList* state_for_block(BlockBegin* block) { return _saved_states.at(block->block_id()); } | |
3409 void set_state_for_block(BlockBegin* block, IntervalList* saved_state) { _saved_states.at_put(block->block_id(), saved_state); } | |
3410 void add_to_work_list(BlockBegin* block) { if (!_work_list.contains(block)) _work_list.append(block); } | |
3411 | |
3412 // helper functions | |
3413 IntervalList* copy(IntervalList* input_state); | |
3414 void state_put(IntervalList* input_state, int reg, Interval* interval); | |
3415 bool check_state(IntervalList* input_state, int reg, Interval* interval); | |
3416 | |
3417 void process_block(BlockBegin* block); | |
3418 void process_xhandler(XHandler* xhandler, IntervalList* input_state); | |
3419 void process_successor(BlockBegin* block, IntervalList* input_state); | |
3420 void process_operations(LIR_List* ops, IntervalList* input_state); | |
3421 | |
3422 public: | |
3423 RegisterVerifier(LinearScan* allocator) | |
3424 : _allocator(allocator) | |
3425 , _work_list(16) | |
3426 , _saved_states(BlockBegin::number_of_blocks(), NULL) | |
3427 { } | |
3428 | |
3429 void verify(BlockBegin* start); | |
3430 }; | |
3431 | |
3432 | |
3433 // entry function from LinearScan that starts the verification | |
3434 void LinearScan::verify_registers() { | |
3435 RegisterVerifier verifier(this); | |
3436 verifier.verify(block_at(0)); | |
3437 } | |
3438 | |
3439 | |
3440 void RegisterVerifier::verify(BlockBegin* start) { | |
3441 // setup input registers (method arguments) for first block | |
3442 IntervalList* input_state = new IntervalList(state_size(), NULL); | |
3443 CallingConvention* args = compilation()->frame_map()->incoming_arguments(); | |
3444 for (int n = 0; n < args->length(); n++) { | |
3445 LIR_Opr opr = args->at(n); | |
3446 if (opr->is_register()) { | |
3447 Interval* interval = interval_at(reg_num(opr)); | |
3448 | |
3449 if (interval->assigned_reg() < state_size()) { | |
3450 input_state->at_put(interval->assigned_reg(), interval); | |
3451 } | |
3452 if (interval->assigned_regHi() != LinearScan::any_reg && interval->assigned_regHi() < state_size()) { | |
3453 input_state->at_put(interval->assigned_regHi(), interval); | |
3454 } | |
3455 } | |
3456 } | |
3457 | |
3458 set_state_for_block(start, input_state); | |
3459 add_to_work_list(start); | |
3460 | |
3461 // main loop for verification | |
3462 do { | |
3463 BlockBegin* block = _work_list.at(0); | |
3464 _work_list.remove_at(0); | |
3465 | |
3466 process_block(block); | |
3467 } while (!_work_list.is_empty()); | |
3468 } | |
3469 | |
3470 void RegisterVerifier::process_block(BlockBegin* block) { | |
3471 TRACE_LINEAR_SCAN(2, tty->cr(); tty->print_cr("process_block B%d", block->block_id())); | |
3472 | |
3473 // must copy state because it is modified | |
3474 IntervalList* input_state = copy(state_for_block(block)); | |
3475 | |
3476 if (TraceLinearScanLevel >= 4) { | |
3477 tty->print_cr("Input-State of intervals:"); | |
3478 tty->print(" "); | |
3479 for (int i = 0; i < state_size(); i++) { | |
3480 if (input_state->at(i) != NULL) { | |
3481 tty->print(" %4d", input_state->at(i)->reg_num()); | |
3482 } else { | |
3483 tty->print(" __"); | |
3484 } | |
3485 } | |
3486 tty->cr(); | |
3487 tty->cr(); | |
3488 } | |
3489 | |
3490 // process all operations of the block | |
3491 process_operations(block->lir(), input_state); | |
3492 | |
3493 // iterate all successors | |
3494 for (int i = 0; i < block->number_of_sux(); i++) { | |
3495 process_successor(block->sux_at(i), input_state); | |
3496 } | |
3497 } | |
3498 | |
3499 void RegisterVerifier::process_xhandler(XHandler* xhandler, IntervalList* input_state) { | |
3500 TRACE_LINEAR_SCAN(2, tty->print_cr("process_xhandler B%d", xhandler->entry_block()->block_id())); | |
3501 | |
3502 // must copy state because it is modified | |
3503 input_state = copy(input_state); | |
3504 | |
3505 if (xhandler->entry_code() != NULL) { | |
3506 process_operations(xhandler->entry_code(), input_state); | |
3507 } | |
3508 process_successor(xhandler->entry_block(), input_state); | |
3509 } | |
3510 | |
3511 void RegisterVerifier::process_successor(BlockBegin* block, IntervalList* input_state) { | |
3512 IntervalList* saved_state = state_for_block(block); | |
3513 | |
3514 if (saved_state != NULL) { | |
3515 // this block was already processed before. | |
3516 // check if new input_state is consistent with saved_state | |
3517 | |
3518 bool saved_state_correct = true; | |
3519 for (int i = 0; i < state_size(); i++) { | |
3520 if (input_state->at(i) != saved_state->at(i)) { | |
3521 // current input_state and previous saved_state assume a different | |
3522 // interval in this register -> assume that this register is invalid | |
3523 if (saved_state->at(i) != NULL) { | |
3524 // invalidate old calculation only if it assumed that | |
3525 // register was valid. when the register was already invalid, | |
3526 // then the old calculation was correct. | |
3527 saved_state_correct = false; | |
3528 saved_state->at_put(i, NULL); | |
3529 | |
3530 TRACE_LINEAR_SCAN(4, tty->print_cr("process_successor B%d: invalidating slot %d", block->block_id(), i)); | |
3531 } | |
3532 } | |
3533 } | |
3534 | |
3535 if (saved_state_correct) { | |
3536 // already processed block with correct input_state | |
3537 TRACE_LINEAR_SCAN(2, tty->print_cr("process_successor B%d: previous visit already correct", block->block_id())); | |
3538 } else { | |
3539 // must re-visit this block | |
3540 TRACE_LINEAR_SCAN(2, tty->print_cr("process_successor B%d: must re-visit because input state changed", block->block_id())); | |
3541 add_to_work_list(block); | |
3542 } | |
3543 | |
3544 } else { | |
3545 // block was not processed before, so set initial input_state | |
3546 TRACE_LINEAR_SCAN(2, tty->print_cr("process_successor B%d: initial visit", block->block_id())); | |
3547 | |
3548 set_state_for_block(block, copy(input_state)); | |
3549 add_to_work_list(block); | |
3550 } | |
3551 } | |
3552 | |
3553 | |
3554 IntervalList* RegisterVerifier::copy(IntervalList* input_state) { | |
3555 IntervalList* copy_state = new IntervalList(input_state->length()); | |
3556 copy_state->push_all(input_state); | |
3557 return copy_state; | |
3558 } | |
3559 | |
3560 void RegisterVerifier::state_put(IntervalList* input_state, int reg, Interval* interval) { | |
3561 if (reg != LinearScan::any_reg && reg < state_size()) { | |
3562 if (interval != NULL) { | |
3563 TRACE_LINEAR_SCAN(4, tty->print_cr(" reg[%d] = %d", reg, interval->reg_num())); | |
3564 } else if (input_state->at(reg) != NULL) { | |
3565 TRACE_LINEAR_SCAN(4, tty->print_cr(" reg[%d] = NULL", reg)); | |
3566 } | |
3567 | |
3568 input_state->at_put(reg, interval); | |
3569 } | |
3570 } | |
3571 | |
3572 bool RegisterVerifier::check_state(IntervalList* input_state, int reg, Interval* interval) { | |
3573 if (reg != LinearScan::any_reg && reg < state_size()) { | |
3574 if (input_state->at(reg) != interval) { | |
3575 tty->print_cr("!! Error in register allocation: register %d does not contain interval %d", reg, interval->reg_num()); | |
3576 return true; | |
3577 } | |
3578 } | |
3579 return false; | |
3580 } | |
3581 | |
3582 void RegisterVerifier::process_operations(LIR_List* ops, IntervalList* input_state) { | |
3583 // visit all instructions of the block | |
3584 LIR_OpVisitState visitor; | |
3585 bool has_error = false; | |
3586 | |
3587 for (int i = 0; i < ops->length(); i++) { | |
3588 LIR_Op* op = ops->at(i); | |
3589 visitor.visit(op); | |
3590 | |
3591 TRACE_LINEAR_SCAN(4, op->print_on(tty)); | |
3592 | |
3593 // check if input operands are correct | |
3594 int j; | |
3595 int n = visitor.opr_count(LIR_OpVisitState::inputMode); | |
3596 for (j = 0; j < n; j++) { | |
3597 LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::inputMode, j); | |
3598 if (opr->is_register() && LinearScan::is_processed_reg_num(reg_num(opr))) { | |
3599 Interval* interval = interval_at(reg_num(opr)); | |
3600 if (op->id() != -1) { | |
3601 interval = interval->split_child_at_op_id(op->id(), LIR_OpVisitState::inputMode); | |
3602 } | |
3603 | |
3604 has_error |= check_state(input_state, interval->assigned_reg(), interval->split_parent()); | |
3605 has_error |= check_state(input_state, interval->assigned_regHi(), interval->split_parent()); | |
3606 | |
3607 // When an operand is marked with is_last_use, then the fpu stack allocator | |
3608 // removes the register from the fpu stack -> the register contains no value | |
3609 if (opr->is_last_use()) { | |
3610 state_put(input_state, interval->assigned_reg(), NULL); | |
3611 state_put(input_state, interval->assigned_regHi(), NULL); | |
3612 } | |
3613 } | |
3614 } | |
3615 | |
3616 // invalidate all caller save registers at calls | |
3617 if (visitor.has_call()) { | |
2002 | 3618 for (j = 0; j < FrameMap::nof_caller_save_cpu_regs(); j++) { |
0 | 3619 state_put(input_state, reg_num(FrameMap::caller_save_cpu_reg_at(j)), NULL); |
3620 } | |
3621 for (j = 0; j < FrameMap::nof_caller_save_fpu_regs; j++) { | |
3622 state_put(input_state, reg_num(FrameMap::caller_save_fpu_reg_at(j)), NULL); | |
3623 } | |
3624 | |
304 | 3625 #ifdef X86 |
0 | 3626 for (j = 0; j < FrameMap::nof_caller_save_xmm_regs; j++) { |
3627 state_put(input_state, reg_num(FrameMap::caller_save_xmm_reg_at(j)), NULL); | |
3628 } | |
3629 #endif | |
3630 } | |
3631 | |
3632 // process xhandler before output and temp operands | |
3633 XHandlers* xhandlers = visitor.all_xhandler(); | |
3634 n = xhandlers->length(); | |
3635 for (int k = 0; k < n; k++) { | |
3636 process_xhandler(xhandlers->handler_at(k), input_state); | |
3637 } | |
3638 | |
3639 // set temp operands (some operations use temp operands also as output operands, so can't set them NULL) | |
3640 n = visitor.opr_count(LIR_OpVisitState::tempMode); | |
3641 for (j = 0; j < n; j++) { | |
3642 LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::tempMode, j); | |
3643 if (opr->is_register() && LinearScan::is_processed_reg_num(reg_num(opr))) { | |
3644 Interval* interval = interval_at(reg_num(opr)); | |
3645 if (op->id() != -1) { | |
3646 interval = interval->split_child_at_op_id(op->id(), LIR_OpVisitState::tempMode); | |
3647 } | |
3648 | |
3649 state_put(input_state, interval->assigned_reg(), interval->split_parent()); | |
3650 state_put(input_state, interval->assigned_regHi(), interval->split_parent()); | |
3651 } | |
3652 } | |
3653 | |
3654 // set output operands | |
3655 n = visitor.opr_count(LIR_OpVisitState::outputMode); | |
3656 for (j = 0; j < n; j++) { | |
3657 LIR_Opr opr = visitor.opr_at(LIR_OpVisitState::outputMode, j); | |
3658 if (opr->is_register() && LinearScan::is_processed_reg_num(reg_num(opr))) { | |
3659 Interval* interval = interval_at(reg_num(opr)); | |
3660 if (op->id() != -1) { | |
3661 interval = interval->split_child_at_op_id(op->id(), LIR_OpVisitState::outputMode); | |
3662 } | |
3663 | |
3664 state_put(input_state, interval->assigned_reg(), interval->split_parent()); | |
3665 state_put(input_state, interval->assigned_regHi(), interval->split_parent()); | |
3666 } | |
3667 } | |
3668 } | |
3669 assert(has_error == false, "Error in register allocation"); | |
3670 } | |
3671 | |
3672 #endif // ASSERT | |
3673 | |
3674 | |
3675 | |
3676 // **** Implementation of MoveResolver ****************************** | |
3677 | |
3678 MoveResolver::MoveResolver(LinearScan* allocator) : | |
3679 _allocator(allocator), | |
3680 _multiple_reads_allowed(false), | |
3681 _mapping_from(8), | |
3682 _mapping_from_opr(8), | |
3683 _mapping_to(8), | |
3684 _insert_list(NULL), | |
3685 _insert_idx(-1), | |
3686 _insertion_buffer() | |
3687 { | |
3688 for (int i = 0; i < LinearScan::nof_regs; i++) { | |
3689 _register_blocked[i] = 0; | |
3690 } | |
3691 DEBUG_ONLY(check_empty()); | |
3692 } | |
3693 | |
3694 | |
3695 #ifdef ASSERT | |
3696 | |
3697 void MoveResolver::check_empty() { | |
3698 assert(_mapping_from.length() == 0 && _mapping_from_opr.length() == 0 && _mapping_to.length() == 0, "list must be empty before and after processing"); | |
3699 for (int i = 0; i < LinearScan::nof_regs; i++) { | |
3700 assert(register_blocked(i) == 0, "register map must be empty before and after processing"); | |
3701 } | |
3702 assert(_multiple_reads_allowed == false, "must have default value"); | |
3703 } | |
3704 | |
3705 void MoveResolver::verify_before_resolve() { | |
3706 assert(_mapping_from.length() == _mapping_from_opr.length(), "length must be equal"); | |
3707 assert(_mapping_from.length() == _mapping_to.length(), "length must be equal"); | |
3708 assert(_insert_list != NULL && _insert_idx != -1, "insert position not set"); | |
3709 | |
3710 int i, j; | |
3711 if (!_multiple_reads_allowed) { | |
3712 for (i = 0; i < _mapping_from.length(); i++) { | |
3713 for (j = i + 1; j < _mapping_from.length(); j++) { | |
3714 assert(_mapping_from.at(i) == NULL || _mapping_from.at(i) != _mapping_from.at(j), "cannot read from same interval twice"); | |
3715 } | |
3716 } | |
3717 } | |
3718 | |
3719 for (i = 0; i < _mapping_to.length(); i++) { | |
3720 for (j = i + 1; j < _mapping_to.length(); j++) { | |
3721 assert(_mapping_to.at(i) != _mapping_to.at(j), "cannot write to same interval twice"); | |
3722 } | |
3723 } | |
3724 | |
3725 | |
3726 BitMap used_regs(LinearScan::nof_regs + allocator()->frame_map()->argcount() + allocator()->max_spills()); | |
3727 used_regs.clear(); | |
3728 if (!_multiple_reads_allowed) { | |
3729 for (i = 0; i < _mapping_from.length(); i++) { | |
3730 Interval* it = _mapping_from.at(i); | |
3731 if (it != NULL) { | |
3732 assert(!used_regs.at(it->assigned_reg()), "cannot read from same register twice"); | |
3733 used_regs.set_bit(it->assigned_reg()); | |
3734 | |
3735 if (it->assigned_regHi() != LinearScan::any_reg) { | |
3736 assert(!used_regs.at(it->assigned_regHi()), "cannot read from same register twice"); | |
3737 used_regs.set_bit(it->assigned_regHi()); | |
3738 } | |
3739 } | |
3740 } | |
3741 } | |
3742 | |
3743 used_regs.clear(); | |
3744 for (i = 0; i < _mapping_to.length(); i++) { | |
3745 Interval* it = _mapping_to.at(i); | |
3746 assert(!used_regs.at(it->assigned_reg()), "cannot write to same register twice"); | |
3747 used_regs.set_bit(it->assigned_reg()); | |
3748 | |
3749 if (it->assigned_regHi() != LinearScan::any_reg) { | |
3750 assert(!used_regs.at(it->assigned_regHi()), "cannot write to same register twice"); | |
3751 used_regs.set_bit(it->assigned_regHi()); | |
3752 } | |
3753 } | |
3754 | |
3755 used_regs.clear(); | |
3756 for (i = 0; i < _mapping_from.length(); i++) { | |
3757 Interval* it = _mapping_from.at(i); | |
3758 if (it != NULL && it->assigned_reg() >= LinearScan::nof_regs) { | |
3759 used_regs.set_bit(it->assigned_reg()); | |
3760 } | |
3761 } | |
3762 for (i = 0; i < _mapping_to.length(); i++) { | |
3763 Interval* it = _mapping_to.at(i); | |
3764 assert(!used_regs.at(it->assigned_reg()) || it->assigned_reg() == _mapping_from.at(i)->assigned_reg(), "stack slots used in _mapping_from must be disjoint to _mapping_to"); | |
3765 } | |
3766 } | |
3767 | |
3768 #endif // ASSERT | |
3769 | |
3770 | |
3771 // mark assigned_reg and assigned_regHi of the interval as blocked | |
3772 void MoveResolver::block_registers(Interval* it) { | |
3773 int reg = it->assigned_reg(); | |
3774 if (reg < LinearScan::nof_regs) { | |
3775 assert(_multiple_reads_allowed || register_blocked(reg) == 0, "register already marked as used"); | |
3776 set_register_blocked(reg, 1); | |
3777 } | |
3778 reg = it->assigned_regHi(); | |
3779 if (reg != LinearScan::any_reg && reg < LinearScan::nof_regs) { | |
3780 assert(_multiple_reads_allowed || register_blocked(reg) == 0, "register already marked as used"); | |
3781 set_register_blocked(reg, 1); | |
3782 } | |
3783 } | |
3784 | |
3785 // mark assigned_reg and assigned_regHi of the interval as unblocked | |
3786 void MoveResolver::unblock_registers(Interval* it) { | |
3787 int reg = it->assigned_reg(); | |
3788 if (reg < LinearScan::nof_regs) { | |
3789 assert(register_blocked(reg) > 0, "register already marked as unused"); | |
3790 set_register_blocked(reg, -1); | |
3791 } | |
3792 reg = it->assigned_regHi(); | |
3793 if (reg != LinearScan::any_reg && reg < LinearScan::nof_regs) { | |
3794 assert(register_blocked(reg) > 0, "register already marked as unused"); | |
3795 set_register_blocked(reg, -1); | |
3796 } | |
3797 } | |
3798 | |
3799 // check if assigned_reg and assigned_regHi of the to-interval are not blocked (or only blocked by from) | |
3800 bool MoveResolver::save_to_process_move(Interval* from, Interval* to) { | |
3801 int from_reg = -1; | |
3802 int from_regHi = -1; | |
3803 if (from != NULL) { | |
3804 from_reg = from->assigned_reg(); | |
3805 from_regHi = from->assigned_regHi(); | |
3806 } | |
3807 | |
3808 int reg = to->assigned_reg(); | |
3809 if (reg < LinearScan::nof_regs) { | |
3810 if (register_blocked(reg) > 1 || (register_blocked(reg) == 1 && reg != from_reg && reg != from_regHi)) { | |
3811 return false; | |
3812 } | |
3813 } | |
3814 reg = to->assigned_regHi(); | |
3815 if (reg != LinearScan::any_reg && reg < LinearScan::nof_regs) { | |
3816 if (register_blocked(reg) > 1 || (register_blocked(reg) == 1 && reg != from_reg && reg != from_regHi)) { | |
3817 return false; | |
3818 } | |
3819 } | |
3820 | |
3821 return true; | |
3822 } | |
3823 | |
3824 | |
3825 void MoveResolver::create_insertion_buffer(LIR_List* list) { | |
3826 assert(!_insertion_buffer.initialized(), "overwriting existing buffer"); | |
3827 _insertion_buffer.init(list); | |
3828 } | |
3829 | |
3830 void MoveResolver::append_insertion_buffer() { | |
3831 if (_insertion_buffer.initialized()) { | |
3832 _insertion_buffer.lir_list()->append(&_insertion_buffer); | |
3833 } | |
3834 assert(!_insertion_buffer.initialized(), "must be uninitialized now"); | |
3835 | |
3836 _insert_list = NULL; | |
3837 _insert_idx = -1; | |
3838 } | |
3839 | |
3840 void MoveResolver::insert_move(Interval* from_interval, Interval* to_interval) { | |
3841 assert(from_interval->reg_num() != to_interval->reg_num(), "from and to interval equal"); | |
3842 assert(from_interval->type() == to_interval->type(), "move between different types"); | |
3843 assert(_insert_list != NULL && _insert_idx != -1, "must setup insert position first"); | |
3844 assert(_insertion_buffer.lir_list() == _insert_list, "wrong insertion buffer"); | |
3845 | |
3846 LIR_Opr from_opr = LIR_OprFact::virtual_register(from_interval->reg_num(), from_interval->type()); | |
3847 LIR_Opr to_opr = LIR_OprFact::virtual_register(to_interval->reg_num(), to_interval->type()); | |
3848 | |
3849 if (!_multiple_reads_allowed) { | |
3850 // the last_use flag is an optimization for FPU stack allocation. When the same | |
3851 // input interval is used in more than one move, then it is too difficult to determine | |
3852 // if this move is really the last use. | |
3853 from_opr = from_opr->make_last_use(); | |
3854 } | |
3855 _insertion_buffer.move(_insert_idx, from_opr, to_opr); | |
3856 | |
3857 TRACE_LINEAR_SCAN(4, tty->print_cr("MoveResolver: inserted move from register %d (%d, %d) to %d (%d, %d)", from_interval->reg_num(), from_interval->assigned_reg(), from_interval->assigned_regHi(), to_interval->reg_num(), to_interval->assigned_reg(), to_interval->assigned_regHi())); | |
3858 } | |
3859 | |
3860 void MoveResolver::insert_move(LIR_Opr from_opr, Interval* to_interval) { | |
3861 assert(from_opr->type() == to_interval->type(), "move between different types"); | |
3862 assert(_insert_list != NULL && _insert_idx != -1, "must setup insert position first"); | |
3863 assert(_insertion_buffer.lir_list() == _insert_list, "wrong insertion buffer"); | |
3864 | |
3865 LIR_Opr to_opr = LIR_OprFact::virtual_register(to_interval->reg_num(), to_interval->type()); | |
3866 _insertion_buffer.move(_insert_idx, from_opr, to_opr); | |
3867 | |
3868 TRACE_LINEAR_SCAN(4, tty->print("MoveResolver: inserted move from constant "); from_opr->print(); tty->print_cr(" to %d (%d, %d)", to_interval->reg_num(), to_interval->assigned_reg(), to_interval->assigned_regHi())); | |
3869 } | |
3870 | |
3871 | |
3872 void MoveResolver::resolve_mappings() { | |
3873 TRACE_LINEAR_SCAN(4, tty->print_cr("MoveResolver: resolving mappings for Block B%d, index %d", _insert_list->block() != NULL ? _insert_list->block()->block_id() : -1, _insert_idx)); | |
3874 DEBUG_ONLY(verify_before_resolve()); | |
3875 | |
3876 // Block all registers that are used as input operands of a move. | |
3877 // When a register is blocked, no move to this register is emitted. | |
3878 // This is necessary for detecting cycles in moves. | |
3879 int i; | |
3880 for (i = _mapping_from.length() - 1; i >= 0; i--) { | |
3881 Interval* from_interval = _mapping_from.at(i); | |
3882 if (from_interval != NULL) { | |
3883 block_registers(from_interval); | |
3884 } | |
3885 } | |
3886 | |
3887 int spill_candidate = -1; | |
3888 while (_mapping_from.length() > 0) { | |
3889 bool processed_interval = false; | |
3890 | |
3891 for (i = _mapping_from.length() - 1; i >= 0; i--) { | |
3892 Interval* from_interval = _mapping_from.at(i); | |
3893 Interval* to_interval = _mapping_to.at(i); | |
3894 | |
3895 if (save_to_process_move(from_interval, to_interval)) { | |
3896 // this inverval can be processed because target is free | |
3897 if (from_interval != NULL) { | |
3898 insert_move(from_interval, to_interval); | |
3899 unblock_registers(from_interval); | |
3900 } else { | |
3901 insert_move(_mapping_from_opr.at(i), to_interval); | |
3902 } | |
3903 _mapping_from.remove_at(i); | |
3904 _mapping_from_opr.remove_at(i); | |
3905 _mapping_to.remove_at(i); | |
3906 | |
3907 processed_interval = true; | |
3908 } else if (from_interval != NULL && from_interval->assigned_reg() < LinearScan::nof_regs) { | |
3909 // this interval cannot be processed now because target is not free | |
3910 // it starts in a register, so it is a possible candidate for spilling | |
3911 spill_candidate = i; | |
3912 } | |
3913 } | |
3914 | |
3915 if (!processed_interval) { | |
3916 // no move could be processed because there is a cycle in the move list | |
3917 // (e.g. r1 -> r2, r2 -> r1), so one interval must be spilled to memory | |
3918 assert(spill_candidate != -1, "no interval in register for spilling found"); | |
3919 | |
3920 // create a new spill interval and assign a stack slot to it | |
3921 Interval* from_interval = _mapping_from.at(spill_candidate); | |
3922 Interval* spill_interval = new Interval(-1); | |
3923 spill_interval->set_type(from_interval->type()); | |
3924 | |
3925 // add a dummy range because real position is difficult to calculate | |
3926 // Note: this range is a special case when the integrity of the allocation is checked | |
3927 spill_interval->add_range(1, 2); | |
3928 | |
3929 // do not allocate a new spill slot for temporary interval, but | |
3930 // use spill slot assigned to from_interval. Otherwise moves from | |
3931 // one stack slot to another can happen (not allowed by LIR_Assembler | |
3932 int spill_slot = from_interval->canonical_spill_slot(); | |
3933 if (spill_slot < 0) { | |
3934 spill_slot = allocator()->allocate_spill_slot(type2spill_size[spill_interval->type()] == 2); | |
3935 from_interval->set_canonical_spill_slot(spill_slot); | |
3936 } | |
3937 spill_interval->assign_reg(spill_slot); | |
3938 allocator()->append_interval(spill_interval); | |
3939 | |
3940 TRACE_LINEAR_SCAN(4, tty->print_cr("created new Interval %d for spilling", spill_interval->reg_num())); | |
3941 | |
3942 // insert a move from register to stack and update the mapping | |
3943 insert_move(from_interval, spill_interval); | |
3944 _mapping_from.at_put(spill_candidate, spill_interval); | |
3945 unblock_registers(from_interval); | |
3946 } | |
3947 } | |
3948 | |
3949 // reset to default value | |
3950 _multiple_reads_allowed = false; | |
3951 | |
3952 // check that all intervals have been processed | |
3953 DEBUG_ONLY(check_empty()); | |
3954 } | |
3955 | |
3956 | |
3957 void MoveResolver::set_insert_position(LIR_List* insert_list, int insert_idx) { | |
3958 TRACE_LINEAR_SCAN(4, tty->print_cr("MoveResolver: setting insert position to Block B%d, index %d", insert_list->block() != NULL ? insert_list->block()->block_id() : -1, insert_idx)); | |
3959 assert(_insert_list == NULL && _insert_idx == -1, "use move_insert_position instead of set_insert_position when data already set"); | |
3960 | |
3961 create_insertion_buffer(insert_list); | |
3962 _insert_list = insert_list; | |
3963 _insert_idx = insert_idx; | |
3964 } | |
3965 | |
3966 void MoveResolver::move_insert_position(LIR_List* insert_list, int insert_idx) { | |
3967 TRACE_LINEAR_SCAN(4, tty->print_cr("MoveResolver: moving insert position to Block B%d, index %d", insert_list->block() != NULL ? insert_list->block()->block_id() : -1, insert_idx)); | |
3968 | |
3969 if (_insert_list != NULL && (insert_list != _insert_list || insert_idx != _insert_idx)) { | |
3970 // insert position changed -> resolve current mappings | |
3971 resolve_mappings(); | |
3972 } | |
3973 | |
3974 if (insert_list != _insert_list) { | |
3975 // block changed -> append insertion_buffer because it is | |
3976 // bound to a specific block and create a new insertion_buffer | |
3977 append_insertion_buffer(); | |
3978 create_insertion_buffer(insert_list); | |
3979 } | |
3980 | |
3981 _insert_list = insert_list; | |
3982 _insert_idx = insert_idx; | |
3983 } | |
3984 | |
3985 void MoveResolver::add_mapping(Interval* from_interval, Interval* to_interval) { | |
3986 TRACE_LINEAR_SCAN(4, tty->print_cr("MoveResolver: adding mapping from %d (%d, %d) to %d (%d, %d)", from_interval->reg_num(), from_interval->assigned_reg(), from_interval->assigned_regHi(), to_interval->reg_num(), to_interval->assigned_reg(), to_interval->assigned_regHi())); | |
3987 | |
3988 _mapping_from.append(from_interval); | |
3989 _mapping_from_opr.append(LIR_OprFact::illegalOpr); | |
3990 _mapping_to.append(to_interval); | |
3991 } | |
3992 | |
3993 | |
3994 void MoveResolver::add_mapping(LIR_Opr from_opr, Interval* to_interval) { | |
3995 TRACE_LINEAR_SCAN(4, tty->print("MoveResolver: adding mapping from "); from_opr->print(); tty->print_cr(" to %d (%d, %d)", to_interval->reg_num(), to_interval->assigned_reg(), to_interval->assigned_regHi())); | |
3996 assert(from_opr->is_constant(), "only for constants"); | |
3997 | |
3998 _mapping_from.append(NULL); | |
3999 _mapping_from_opr.append(from_opr); | |
4000 _mapping_to.append(to_interval); | |
4001 } | |
4002 | |
4003 void MoveResolver::resolve_and_append_moves() { | |
4004 if (has_mappings()) { | |
4005 resolve_mappings(); | |
4006 } | |
4007 append_insertion_buffer(); | |
4008 } | |
4009 | |
4010 | |
4011 | |
4012 // **** Implementation of Range ************************************* | |
4013 | |
4014 Range::Range(int from, int to, Range* next) : | |
4015 _from(from), | |
4016 _to(to), | |
4017 _next(next) | |
4018 { | |
4019 } | |
4020 | |
4021 // initialize sentinel | |
4022 Range* Range::_end = NULL; | |
1584 | 4023 void Range::initialize(Arena* arena) { |
4024 _end = new (arena) Range(max_jint, max_jint, NULL); | |
0 | 4025 } |
4026 | |
4027 int Range::intersects_at(Range* r2) const { | |
4028 const Range* r1 = this; | |
4029 | |
4030 assert(r1 != NULL && r2 != NULL, "null ranges not allowed"); | |
4031 assert(r1 != _end && r2 != _end, "empty ranges not allowed"); | |
4032 | |
4033 do { | |
4034 if (r1->from() < r2->from()) { | |
4035 if (r1->to() <= r2->from()) { | |
4036 r1 = r1->next(); if (r1 == _end) return -1; | |
4037 } else { | |
4038 return r2->from(); | |
4039 } | |
4040 } else if (r2->from() < r1->from()) { | |
4041 if (r2->to() <= r1->from()) { | |
4042 r2 = r2->next(); if (r2 == _end) return -1; | |
4043 } else { | |
4044 return r1->from(); | |
4045 } | |
4046 } else { // r1->from() == r2->from() | |
4047 if (r1->from() == r1->to()) { | |
4048 r1 = r1->next(); if (r1 == _end) return -1; | |
4049 } else if (r2->from() == r2->to()) { | |
4050 r2 = r2->next(); if (r2 == _end) return -1; | |
4051 } else { | |
4052 return r1->from(); | |
4053 } | |
4054 } | |
4055 } while (true); | |
4056 } | |
4057 | |
4058 #ifndef PRODUCT | |
4059 void Range::print(outputStream* out) const { | |
4060 out->print("[%d, %d[ ", _from, _to); | |
4061 } | |
4062 #endif | |
4063 | |
4064 | |
4065 | |
4066 // **** Implementation of Interval ********************************** | |
4067 | |
4068 // initialize sentinel | |
4069 Interval* Interval::_end = NULL; | |
1584 | 4070 void Interval::initialize(Arena* arena) { |
4071 Range::initialize(arena); | |
4072 _end = new (arena) Interval(-1); | |
0 | 4073 } |
4074 | |
4075 Interval::Interval(int reg_num) : | |
4076 _reg_num(reg_num), | |
4077 _type(T_ILLEGAL), | |
4078 _first(Range::end()), | |
4079 _use_pos_and_kinds(12), | |
4080 _current(Range::end()), | |
4081 _next(_end), | |
4082 _state(invalidState), | |
4083 _assigned_reg(LinearScan::any_reg), | |
4084 _assigned_regHi(LinearScan::any_reg), | |
4085 _cached_to(-1), | |
4086 _cached_opr(LIR_OprFact::illegalOpr), | |
4087 _cached_vm_reg(VMRegImpl::Bad()), | |
4088 _split_children(0), | |
4089 _canonical_spill_slot(-1), | |
4090 _insert_move_when_activated(false), | |
4091 _register_hint(NULL), | |
4092 _spill_state(noDefinitionFound), | |
4093 _spill_definition_pos(-1) | |
4094 { | |
4095 _split_parent = this; | |
4096 _current_split_child = this; | |
4097 } | |
4098 | |
4099 int Interval::calc_to() { | |
4100 assert(_first != Range::end(), "interval has no range"); | |
4101 | |
4102 Range* r = _first; | |
4103 while (r->next() != Range::end()) { | |
4104 r = r->next(); | |
4105 } | |
4106 return r->to(); | |
4107 } | |
4108 | |
4109 | |
4110 #ifdef ASSERT | |
4111 // consistency check of split-children | |
4112 void Interval::check_split_children() { | |
4113 if (_split_children.length() > 0) { | |
4114 assert(is_split_parent(), "only split parents can have children"); | |
4115 | |
4116 for (int i = 0; i < _split_children.length(); i++) { | |
4117 Interval* i1 = _split_children.at(i); | |
4118 | |
4119 assert(i1->split_parent() == this, "not a split child of this interval"); | |
4120 assert(i1->type() == type(), "must be equal for all split children"); | |
4121 assert(i1->canonical_spill_slot() == canonical_spill_slot(), "must be equal for all split children"); | |
4122 | |
4123 for (int j = i + 1; j < _split_children.length(); j++) { | |
4124 Interval* i2 = _split_children.at(j); | |
4125 | |
4126 assert(i1->reg_num() != i2->reg_num(), "same register number"); | |
4127 | |
4128 if (i1->from() < i2->from()) { | |
4129 assert(i1->to() <= i2->from() && i1->to() < i2->to(), "intervals overlapping"); | |
4130 } else { | |
4131 assert(i2->from() < i1->from(), "intervals start at same op_id"); | |
4132 assert(i2->to() <= i1->from() && i2->to() < i1->to(), "intervals overlapping"); | |
4133 } | |
4134 } | |
4135 } | |
4136 } | |
4137 } | |
4138 #endif // ASSERT | |
4139 | |
4140 Interval* Interval::register_hint(bool search_split_child) const { | |
4141 if (!search_split_child) { | |
4142 return _register_hint; | |
4143 } | |
4144 | |
4145 if (_register_hint != NULL) { | |
4146 assert(_register_hint->is_split_parent(), "ony split parents are valid hint registers"); | |
4147 | |
4148 if (_register_hint->assigned_reg() >= 0 && _register_hint->assigned_reg() < LinearScan::nof_regs) { | |
4149 return _register_hint; | |
4150 | |
4151 } else if (_register_hint->_split_children.length() > 0) { | |
4152 // search the first split child that has a register assigned | |
4153 int len = _register_hint->_split_children.length(); | |
4154 for (int i = 0; i < len; i++) { | |
4155 Interval* cur = _register_hint->_split_children.at(i); | |
4156 | |
4157 if (cur->assigned_reg() >= 0 && cur->assigned_reg() < LinearScan::nof_regs) { | |
4158 return cur; | |
4159 } | |
4160 } | |
4161 } | |
4162 } | |
4163 | |
4164 // no hint interval found that has a register assigned | |
4165 return NULL; | |
4166 } | |
4167 | |
4168 | |
4169 Interval* Interval::split_child_at_op_id(int op_id, LIR_OpVisitState::OprMode mode) { | |
4170 assert(is_split_parent(), "can only be called for split parents"); | |
4171 assert(op_id >= 0, "invalid op_id (method can not be called for spill moves)"); | |
4172 | |
4173 Interval* result; | |
4174 if (_split_children.length() == 0) { | |
4175 result = this; | |
4176 } else { | |
4177 result = NULL; | |
4178 int len = _split_children.length(); | |
4179 | |
4180 // in outputMode, the end of the interval (op_id == cur->to()) is not valid | |
4181 int to_offset = (mode == LIR_OpVisitState::outputMode ? 0 : 1); | |
4182 | |
4183 int i; | |
4184 for (i = 0; i < len; i++) { | |
4185 Interval* cur = _split_children.at(i); | |
4186 if (cur->from() <= op_id && op_id < cur->to() + to_offset) { | |
4187 if (i > 0) { | |
4188 // exchange current split child to start of list (faster access for next call) | |
4189 _split_children.at_put(i, _split_children.at(0)); | |
4190 _split_children.at_put(0, cur); | |
4191 } | |
4192 | |
4193 // interval found | |
4194 result = cur; | |
4195 break; | |
4196 } | |
4197 } | |
4198 | |
4199 #ifdef ASSERT | |
4200 for (i = 0; i < len; i++) { | |
4201 Interval* tmp = _split_children.at(i); | |
4202 if (tmp != result && tmp->from() <= op_id && op_id < tmp->to() + to_offset) { | |
4203 tty->print_cr("two valid result intervals found for op_id %d: %d and %d", op_id, result->reg_num(), tmp->reg_num()); | |
4204 result->print(); | |
4205 tmp->print(); | |
4206 assert(false, "two valid result intervals found"); | |
4207 } | |
4208 } | |
4209 #endif | |
4210 } | |
4211 | |
4212 assert(result != NULL, "no matching interval found"); | |
4213 assert(result->covers(op_id, mode), "op_id not covered by interval"); | |
4214 | |
4215 return result; | |
4216 } | |
4217 | |
4218 | |
4219 // returns the last split child that ends before the given op_id | |
4220 Interval* Interval::split_child_before_op_id(int op_id) { | |
4221 assert(op_id >= 0, "invalid op_id"); | |
4222 | |
4223 Interval* parent = split_parent(); | |
4224 Interval* result = NULL; | |
4225 | |
4226 int len = parent->_split_children.length(); | |
4227 assert(len > 0, "no split children available"); | |
4228 | |
4229 for (int i = len - 1; i >= 0; i--) { | |
4230 Interval* cur = parent->_split_children.at(i); | |
4231 if (cur->to() <= op_id && (result == NULL || result->to() < cur->to())) { | |
4232 result = cur; | |
4233 } | |
4234 } | |
4235 | |
4236 assert(result != NULL, "no split child found"); | |
4237 return result; | |
4238 } | |
4239 | |
4240 | |
4241 // checks if op_id is covered by any split child | |
4242 bool Interval::split_child_covers(int op_id, LIR_OpVisitState::OprMode mode) { | |
4243 assert(is_split_parent(), "can only be called for split parents"); | |
4244 assert(op_id >= 0, "invalid op_id (method can not be called for spill moves)"); | |
4245 | |
4246 if (_split_children.length() == 0) { | |
4247 // simple case if interval was not split | |
4248 return covers(op_id, mode); | |
4249 | |
4250 } else { | |
4251 // extended case: check all split children | |
4252 int len = _split_children.length(); | |
4253 for (int i = 0; i < len; i++) { | |
4254 Interval* cur = _split_children.at(i); | |
4255 if (cur->covers(op_id, mode)) { | |
4256 return true; | |
4257 } | |
4258 } | |
4259 return false; | |
4260 } | |
4261 } | |
4262 | |
4263 | |
4264 // Note: use positions are sorted descending -> first use has highest index | |
4265 int Interval::first_usage(IntervalUseKind min_use_kind) const { | |
4266 assert(LinearScan::is_virtual_interval(this), "cannot access use positions for fixed intervals"); | |
4267 | |
4268 for (int i = _use_pos_and_kinds.length() - 2; i >= 0; i -= 2) { | |
4269 if (_use_pos_and_kinds.at(i + 1) >= min_use_kind) { | |
4270 return _use_pos_and_kinds.at(i); | |
4271 } | |
4272 } | |
4273 return max_jint; | |
4274 } | |
4275 | |
4276 int Interval::next_usage(IntervalUseKind min_use_kind, int from) const { | |
4277 assert(LinearScan::is_virtual_interval(this), "cannot access use positions for fixed intervals"); | |
4278 | |
4279 for (int i = _use_pos_and_kinds.length() - 2; i >= 0; i -= 2) { | |
4280 if (_use_pos_and_kinds.at(i) >= from && _use_pos_and_kinds.at(i + 1) >= min_use_kind) { | |
4281 return _use_pos_and_kinds.at(i); | |
4282 } | |
4283 } | |
4284 return max_jint; | |
4285 } | |
4286 | |
4287 int Interval::next_usage_exact(IntervalUseKind exact_use_kind, int from) const { | |
4288 assert(LinearScan::is_virtual_interval(this), "cannot access use positions for fixed intervals"); | |
4289 | |
4290 for (int i = _use_pos_and_kinds.length() - 2; i >= 0; i -= 2) { | |
4291 if (_use_pos_and_kinds.at(i) >= from && _use_pos_and_kinds.at(i + 1) == exact_use_kind) { | |
4292 return _use_pos_and_kinds.at(i); | |
4293 } | |
4294 } | |
4295 return max_jint; | |
4296 } | |
4297 | |
4298 int Interval::previous_usage(IntervalUseKind min_use_kind, int from) const { | |
4299 assert(LinearScan::is_virtual_interval(this), "cannot access use positions for fixed intervals"); | |
4300 | |
4301 int prev = 0; | |
4302 for (int i = _use_pos_and_kinds.length() - 2; i >= 0; i -= 2) { | |
4303 if (_use_pos_and_kinds.at(i) > from) { | |
4304 return prev; | |
4305 } | |
4306 if (_use_pos_and_kinds.at(i + 1) >= min_use_kind) { | |
4307 prev = _use_pos_and_kinds.at(i); | |
4308 } | |
4309 } | |
4310 return prev; | |
4311 } | |
4312 | |
4313 void Interval::add_use_pos(int pos, IntervalUseKind use_kind) { | |
4314 assert(covers(pos, LIR_OpVisitState::inputMode), "use position not covered by live range"); | |
4315 | |
4316 // do not add use positions for precolored intervals because | |
4317 // they are never used | |
4318 if (use_kind != noUse && reg_num() >= LIR_OprDesc::vreg_base) { | |
4319 #ifdef ASSERT | |
4320 assert(_use_pos_and_kinds.length() % 2 == 0, "must be"); | |
4321 for (int i = 0; i < _use_pos_and_kinds.length(); i += 2) { | |
4322 assert(pos <= _use_pos_and_kinds.at(i), "already added a use-position with lower position"); | |
4323 assert(_use_pos_and_kinds.at(i + 1) >= firstValidKind && _use_pos_and_kinds.at(i + 1) <= lastValidKind, "invalid use kind"); | |
4324 if (i > 0) { | |
4325 assert(_use_pos_and_kinds.at(i) < _use_pos_and_kinds.at(i - 2), "not sorted descending"); | |
4326 } | |
4327 } | |
4328 #endif | |
4329 | |
4330 // Note: add_use is called in descending order, so list gets sorted | |
4331 // automatically by just appending new use positions | |
4332 int len = _use_pos_and_kinds.length(); | |
4333 if (len == 0 || _use_pos_and_kinds.at(len - 2) > pos) { | |
4334 _use_pos_and_kinds.append(pos); | |
4335 _use_pos_and_kinds.append(use_kind); | |
4336 } else if (_use_pos_and_kinds.at(len - 1) < use_kind) { | |
4337 assert(_use_pos_and_kinds.at(len - 2) == pos, "list not sorted correctly"); | |
4338 _use_pos_and_kinds.at_put(len - 1, use_kind); | |
4339 } | |
4340 } | |
4341 } | |
4342 | |
4343 void Interval::add_range(int from, int to) { | |
4344 assert(from < to, "invalid range"); | |
4345 assert(first() == Range::end() || to < first()->next()->from(), "not inserting at begin of interval"); | |
4346 assert(from <= first()->to(), "not inserting at begin of interval"); | |
4347 | |
4348 if (first()->from() <= to) { | |
4349 // join intersecting ranges | |
4350 first()->set_from(MIN2(from, first()->from())); | |
4351 first()->set_to (MAX2(to, first()->to())); | |
4352 } else { | |
4353 // insert new range | |
4354 _first = new Range(from, to, first()); | |
4355 } | |
4356 } | |
4357 | |
4358 Interval* Interval::new_split_child() { | |
4359 // allocate new interval | |
4360 Interval* result = new Interval(-1); | |
4361 result->set_type(type()); | |
4362 | |
4363 Interval* parent = split_parent(); | |
4364 result->_split_parent = parent; | |
4365 result->set_register_hint(parent); | |
4366 | |
4367 // insert new interval in children-list of parent | |
4368 if (parent->_split_children.length() == 0) { | |
4369 assert(is_split_parent(), "list must be initialized at first split"); | |
4370 | |
4371 parent->_split_children = IntervalList(4); | |
4372 parent->_split_children.append(this); | |
4373 } | |
4374 parent->_split_children.append(result); | |
4375 | |
4376 return result; | |
4377 } | |
4378 | |
4379 // split this interval at the specified position and return | |
4380 // the remainder as a new interval. | |
4381 // | |
4382 // when an interval is split, a bi-directional link is established between the original interval | |
4383 // (the split parent) and the intervals that are split off this interval (the split children) | |
4384 // When a split child is split again, the new created interval is also a direct child | |
4385 // of the original parent (there is no tree of split children stored, but a flat list) | |
4386 // All split children are spilled to the same stack slot (stored in _canonical_spill_slot) | |
4387 // | |
4388 // Note: The new interval has no valid reg_num | |
4389 Interval* Interval::split(int split_pos) { | |
4390 assert(LinearScan::is_virtual_interval(this), "cannot split fixed intervals"); | |
4391 | |
4392 // allocate new interval | |
4393 Interval* result = new_split_child(); | |
4394 | |
4395 // split the ranges | |
4396 Range* prev = NULL; | |
4397 Range* cur = _first; | |
4398 while (cur != Range::end() && cur->to() <= split_pos) { | |
4399 prev = cur; | |
4400 cur = cur->next(); | |
4401 } | |
4402 assert(cur != Range::end(), "split interval after end of last range"); | |
4403 | |
4404 if (cur->from() < split_pos) { | |
4405 result->_first = new Range(split_pos, cur->to(), cur->next()); | |
4406 cur->set_to(split_pos); | |
4407 cur->set_next(Range::end()); | |
4408 | |
4409 } else { | |
4410 assert(prev != NULL, "split before start of first range"); | |
4411 result->_first = cur; | |
4412 prev->set_next(Range::end()); | |
4413 } | |
4414 result->_current = result->_first; | |
4415 _cached_to = -1; // clear cached value | |
4416 | |
4417 // split list of use positions | |
4418 int total_len = _use_pos_and_kinds.length(); | |
4419 int start_idx = total_len - 2; | |
4420 while (start_idx >= 0 && _use_pos_and_kinds.at(start_idx) < split_pos) { | |
4421 start_idx -= 2; | |
4422 } | |
4423 | |
4424 intStack new_use_pos_and_kinds(total_len - start_idx); | |
4425 int i; | |
4426 for (i = start_idx + 2; i < total_len; i++) { | |
4427 new_use_pos_and_kinds.append(_use_pos_and_kinds.at(i)); | |
4428 } | |
4429 | |
4430 _use_pos_and_kinds.truncate(start_idx + 2); | |
4431 result->_use_pos_and_kinds = _use_pos_and_kinds; | |
4432 _use_pos_and_kinds = new_use_pos_and_kinds; | |
4433 | |
4434 #ifdef ASSERT | |
4435 assert(_use_pos_and_kinds.length() % 2 == 0, "must have use kind for each use pos"); | |
4436 assert(result->_use_pos_and_kinds.length() % 2 == 0, "must have use kind for each use pos"); | |
4437 assert(_use_pos_and_kinds.length() + result->_use_pos_and_kinds.length() == total_len, "missed some entries"); | |
4438 | |
4439 for (i = 0; i < _use_pos_and_kinds.length(); i += 2) { | |
4440 assert(_use_pos_and_kinds.at(i) < split_pos, "must be"); | |
4441 assert(_use_pos_and_kinds.at(i + 1) >= firstValidKind && _use_pos_and_kinds.at(i + 1) <= lastValidKind, "invalid use kind"); | |
4442 } | |
4443 for (i = 0; i < result->_use_pos_and_kinds.length(); i += 2) { | |
4444 assert(result->_use_pos_and_kinds.at(i) >= split_pos, "must be"); | |
4445 assert(result->_use_pos_and_kinds.at(i + 1) >= firstValidKind && result->_use_pos_and_kinds.at(i + 1) <= lastValidKind, "invalid use kind"); | |
4446 } | |
4447 #endif | |
4448 | |
4449 return result; | |
4450 } | |
4451 | |
4452 // split this interval at the specified position and return | |
4453 // the head as a new interval (the original interval is the tail) | |
4454 // | |
4455 // Currently, only the first range can be split, and the new interval | |
4456 // must not have split positions | |
4457 Interval* Interval::split_from_start(int split_pos) { | |
4458 assert(LinearScan::is_virtual_interval(this), "cannot split fixed intervals"); | |
4459 assert(split_pos > from() && split_pos < to(), "can only split inside interval"); | |
4460 assert(split_pos > _first->from() && split_pos <= _first->to(), "can only split inside first range"); | |
4461 assert(first_usage(noUse) > split_pos, "can not split when use positions are present"); | |
4462 | |
4463 // allocate new interval | |
4464 Interval* result = new_split_child(); | |
4465 | |
4466 // the new created interval has only one range (checked by assertion above), | |
4467 // so the splitting of the ranges is very simple | |
4468 result->add_range(_first->from(), split_pos); | |
4469 | |
4470 if (split_pos == _first->to()) { | |
4471 assert(_first->next() != Range::end(), "must not be at end"); | |
4472 _first = _first->next(); | |
4473 } else { | |
4474 _first->set_from(split_pos); | |
4475 } | |
4476 | |
4477 return result; | |
4478 } | |
4479 | |
4480 | |
4481 // returns true if the op_id is inside the interval | |
4482 bool Interval::covers(int op_id, LIR_OpVisitState::OprMode mode) const { | |
4483 Range* cur = _first; | |
4484 | |
4485 while (cur != Range::end() && cur->to() < op_id) { | |
4486 cur = cur->next(); | |
4487 } | |
4488 if (cur != Range::end()) { | |
4489 assert(cur->to() != cur->next()->from(), "ranges not separated"); | |
4490 | |
4491 if (mode == LIR_OpVisitState::outputMode) { | |
4492 return cur->from() <= op_id && op_id < cur->to(); | |
4493 } else { | |
4494 return cur->from() <= op_id && op_id <= cur->to(); | |
4495 } | |
4496 } | |
4497 return false; | |
4498 } | |
4499 | |
4500 // returns true if the interval has any hole between hole_from and hole_to | |
4501 // (even if the hole has only the length 1) | |
4502 bool Interval::has_hole_between(int hole_from, int hole_to) { | |
4503 assert(hole_from < hole_to, "check"); | |
4504 assert(from() <= hole_from && hole_to <= to(), "index out of interval"); | |
4505 | |
4506 Range* cur = _first; | |
4507 while (cur != Range::end()) { | |
4508 assert(cur->to() < cur->next()->from(), "no space between ranges"); | |
4509 | |
4510 // hole-range starts before this range -> hole | |
4511 if (hole_from < cur->from()) { | |
4512 return true; | |
4513 | |
4514 // hole-range completely inside this range -> no hole | |
4515 } else if (hole_to <= cur->to()) { | |
4516 return false; | |
4517 | |
4518 // overlapping of hole-range with this range -> hole | |
4519 } else if (hole_from <= cur->to()) { | |
4520 return true; | |
4521 } | |
4522 | |
4523 cur = cur->next(); | |
4524 } | |
4525 | |
4526 return false; | |
4527 } | |
4528 | |
4529 | |
4530 #ifndef PRODUCT | |
4531 void Interval::print(outputStream* out) const { | |
4532 const char* SpillState2Name[] = { "no definition", "no spill store", "one spill store", "store at definition", "start in memory", "no optimization" }; | |
4533 const char* UseKind2Name[] = { "N", "L", "S", "M" }; | |
4534 | |
4535 const char* type_name; | |
4536 LIR_Opr opr = LIR_OprFact::illegal(); | |
4537 if (reg_num() < LIR_OprDesc::vreg_base) { | |
4538 type_name = "fixed"; | |
4539 // need a temporary operand for fixed intervals because type() cannot be called | |
4540 if (assigned_reg() >= pd_first_cpu_reg && assigned_reg() <= pd_last_cpu_reg) { | |
4541 opr = LIR_OprFact::single_cpu(assigned_reg()); | |
4542 } else if (assigned_reg() >= pd_first_fpu_reg && assigned_reg() <= pd_last_fpu_reg) { | |
4543 opr = LIR_OprFact::single_fpu(assigned_reg() - pd_first_fpu_reg); | |
304 | 4544 #ifdef X86 |
0 | 4545 } else if (assigned_reg() >= pd_first_xmm_reg && assigned_reg() <= pd_last_xmm_reg) { |
4546 opr = LIR_OprFact::single_xmm(assigned_reg() - pd_first_xmm_reg); | |
4547 #endif | |
4548 } else { | |
4549 ShouldNotReachHere(); | |
4550 } | |
4551 } else { | |
4552 type_name = type2name(type()); | |
2081
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
4553 if (assigned_reg() != -1 && |
7223744c2784
6579789: Internal error "c1_LinearScan.cpp:1429 Error: assert(false,"")" in debuggee with fastdebug VM
never
parents:
2002
diff
changeset
|
4554 (LinearScan::num_physical_regs(type()) == 1 || assigned_regHi() != -1)) { |
0 | 4555 opr = LinearScan::calc_operand_for_interval(this); |
4556 } | |
4557 } | |
4558 | |
4559 out->print("%d %s ", reg_num(), type_name); | |
4560 if (opr->is_valid()) { | |
4561 out->print("\""); | |
4562 opr->print(out); | |
4563 out->print("\" "); | |
4564 } | |
4565 out->print("%d %d ", split_parent()->reg_num(), (register_hint(false) != NULL ? register_hint(false)->reg_num() : -1)); | |
4566 | |
4567 // print ranges | |
4568 Range* cur = _first; | |
4569 while (cur != Range::end()) { | |
4570 cur->print(out); | |
4571 cur = cur->next(); | |
4572 assert(cur != NULL, "range list not closed with range sentinel"); | |
4573 } | |
4574 | |
4575 // print use positions | |
4576 int prev = 0; | |
4577 assert(_use_pos_and_kinds.length() % 2 == 0, "must be"); | |
4578 for (int i =_use_pos_and_kinds.length() - 2; i >= 0; i -= 2) { | |
4579 assert(_use_pos_and_kinds.at(i + 1) >= firstValidKind && _use_pos_and_kinds.at(i + 1) <= lastValidKind, "invalid use kind"); | |
4580 assert(prev < _use_pos_and_kinds.at(i), "use positions not sorted"); | |
4581 | |
4582 out->print("%d %s ", _use_pos_and_kinds.at(i), UseKind2Name[_use_pos_and_kinds.at(i + 1)]); | |
4583 prev = _use_pos_and_kinds.at(i); | |
4584 } | |
4585 | |
4586 out->print(" \"%s\"", SpillState2Name[spill_state()]); | |
4587 out->cr(); | |
4588 } | |
4589 #endif | |
4590 | |
4591 | |
4592 | |
4593 // **** Implementation of IntervalWalker **************************** | |
4594 | |
4595 IntervalWalker::IntervalWalker(LinearScan* allocator, Interval* unhandled_fixed_first, Interval* unhandled_any_first) | |
4596 : _compilation(allocator->compilation()) | |
4597 , _allocator(allocator) | |
4598 { | |
4599 _unhandled_first[fixedKind] = unhandled_fixed_first; | |
4600 _unhandled_first[anyKind] = unhandled_any_first; | |
4601 _active_first[fixedKind] = Interval::end(); | |
4602 _inactive_first[fixedKind] = Interval::end(); | |
4603 _active_first[anyKind] = Interval::end(); | |
4604 _inactive_first[anyKind] = Interval::end(); | |
4605 _current_position = -1; | |
4606 _current = NULL; | |
4607 next_interval(); | |
4608 } | |
4609 | |
4610 | |
4611 // append interval at top of list | |
4612 void IntervalWalker::append_unsorted(Interval** list, Interval* interval) { | |
4613 interval->set_next(*list); *list = interval; | |
4614 } | |
4615 | |
4616 | |
4617 // append interval in order of current range from() | |
4618 void IntervalWalker::append_sorted(Interval** list, Interval* interval) { | |
4619 Interval* prev = NULL; | |
4620 Interval* cur = *list; | |
4621 while (cur->current_from() < interval->current_from()) { | |
4622 prev = cur; cur = cur->next(); | |
4623 } | |
4624 if (prev == NULL) { | |
4625 *list = interval; | |
4626 } else { | |
4627 prev->set_next(interval); | |
4628 } | |
4629 interval->set_next(cur); | |
4630 } | |
4631 | |
4632 void IntervalWalker::append_to_unhandled(Interval** list, Interval* interval) { | |
4633 assert(interval->from() >= current()->current_from(), "cannot append new interval before current walk position"); | |
4634 | |
4635 Interval* prev = NULL; | |
4636 Interval* cur = *list; | |
4637 while (cur->from() < interval->from() || (cur->from() == interval->from() && cur->first_usage(noUse) < interval->first_usage(noUse))) { | |
4638 prev = cur; cur = cur->next(); | |
4639 } | |
4640 if (prev == NULL) { | |
4641 *list = interval; | |
4642 } else { | |
4643 prev->set_next(interval); | |
4644 } | |
4645 interval->set_next(cur); | |
4646 } | |
4647 | |
4648 | |
4649 inline bool IntervalWalker::remove_from_list(Interval** list, Interval* i) { | |
4650 while (*list != Interval::end() && *list != i) { | |
4651 list = (*list)->next_addr(); | |
4652 } | |
4653 if (*list != Interval::end()) { | |
4654 assert(*list == i, "check"); | |
4655 *list = (*list)->next(); | |
4656 return true; | |
4657 } else { | |
4658 return false; | |
4659 } | |
4660 } | |
4661 | |
4662 void IntervalWalker::remove_from_list(Interval* i) { | |
4663 bool deleted; | |
4664 | |
4665 if (i->state() == activeState) { | |
4666 deleted = remove_from_list(active_first_addr(anyKind), i); | |
4667 } else { | |
4668 assert(i->state() == inactiveState, "invalid state"); | |
4669 deleted = remove_from_list(inactive_first_addr(anyKind), i); | |
4670 } | |
4671 | |
4672 assert(deleted, "interval has not been found in list"); | |
4673 } | |
4674 | |
4675 | |
4676 void IntervalWalker::walk_to(IntervalState state, int from) { | |
4677 assert (state == activeState || state == inactiveState, "wrong state"); | |
4678 for_each_interval_kind(kind) { | |
4679 Interval** prev = state == activeState ? active_first_addr(kind) : inactive_first_addr(kind); | |
4680 Interval* next = *prev; | |
4681 while (next->current_from() <= from) { | |
4682 Interval* cur = next; | |
4683 next = cur->next(); | |
4684 | |
4685 bool range_has_changed = false; | |
4686 while (cur->current_to() <= from) { | |
4687 cur->next_range(); | |
4688 range_has_changed = true; | |
4689 } | |
4690 | |
4691 // also handle move from inactive list to active list | |
4692 range_has_changed = range_has_changed || (state == inactiveState && cur->current_from() <= from); | |
4693 | |
4694 if (range_has_changed) { | |
4695 // remove cur from list | |
4696 *prev = next; | |
4697 if (cur->current_at_end()) { | |
4698 // move to handled state (not maintained as a list) | |
4699 cur->set_state(handledState); | |
4700 interval_moved(cur, kind, state, handledState); | |
4701 } else if (cur->current_from() <= from){ | |
4702 // sort into active list | |
4703 append_sorted(active_first_addr(kind), cur); | |
4704 cur->set_state(activeState); | |
4705 if (*prev == cur) { | |
4706 assert(state == activeState, "check"); | |
4707 prev = cur->next_addr(); | |
4708 } | |
4709 interval_moved(cur, kind, state, activeState); | |
4710 } else { | |
4711 // sort into inactive list | |
4712 append_sorted(inactive_first_addr(kind), cur); | |
4713 cur->set_state(inactiveState); | |
4714 if (*prev == cur) { | |
4715 assert(state == inactiveState, "check"); | |
4716 prev = cur->next_addr(); | |
4717 } | |
4718 interval_moved(cur, kind, state, inactiveState); | |
4719 } | |
4720 } else { | |
4721 prev = cur->next_addr(); | |
4722 continue; | |
4723 } | |
4724 } | |
4725 } | |
4726 } | |
4727 | |
4728 | |
4729 void IntervalWalker::next_interval() { | |
4730 IntervalKind kind; | |
4731 Interval* any = _unhandled_first[anyKind]; | |
4732 Interval* fixed = _unhandled_first[fixedKind]; | |
4733 | |
4734 if (any != Interval::end()) { | |
4735 // intervals may start at same position -> prefer fixed interval | |
4736 kind = fixed != Interval::end() && fixed->from() <= any->from() ? fixedKind : anyKind; | |
4737 | |
4738 assert (kind == fixedKind && fixed->from() <= any->from() || | |
4739 kind == anyKind && any->from() <= fixed->from(), "wrong interval!!!"); | |
4740 assert(any == Interval::end() || fixed == Interval::end() || any->from() != fixed->from() || kind == fixedKind, "if fixed and any-Interval start at same position, fixed must be processed first"); | |
4741 | |
4742 } else if (fixed != Interval::end()) { | |
4743 kind = fixedKind; | |
4744 } else { | |
4745 _current = NULL; return; | |
4746 } | |
4747 _current_kind = kind; | |
4748 _current = _unhandled_first[kind]; | |
4749 _unhandled_first[kind] = _current->next(); | |
4750 _current->set_next(Interval::end()); | |
4751 _current->rewind_range(); | |
4752 } | |
4753 | |
4754 | |
4755 void IntervalWalker::walk_to(int lir_op_id) { | |
4756 assert(_current_position <= lir_op_id, "can not walk backwards"); | |
4757 while (current() != NULL) { | |
4758 bool is_active = current()->from() <= lir_op_id; | |
4759 int id = is_active ? current()->from() : lir_op_id; | |
4760 | |
4761 TRACE_LINEAR_SCAN(2, if (_current_position < id) { tty->cr(); tty->print_cr("walk_to(%d) **************************************************************", id); }) | |
4762 | |
4763 // set _current_position prior to call of walk_to | |
4764 _current_position = id; | |
4765 | |
4766 // call walk_to even if _current_position == id | |
4767 walk_to(activeState, id); | |
4768 walk_to(inactiveState, id); | |
4769 | |
4770 if (is_active) { | |
4771 current()->set_state(activeState); | |
4772 if (activate_current()) { | |
4773 append_sorted(active_first_addr(current_kind()), current()); | |
4774 interval_moved(current(), current_kind(), unhandledState, activeState); | |
4775 } | |
4776 | |
4777 next_interval(); | |
4778 } else { | |
4779 return; | |
4780 } | |
4781 } | |
4782 } | |
4783 | |
4784 void IntervalWalker::interval_moved(Interval* interval, IntervalKind kind, IntervalState from, IntervalState to) { | |
4785 #ifndef PRODUCT | |
4786 if (TraceLinearScanLevel >= 4) { | |
4787 #define print_state(state) \ | |
4788 switch(state) {\ | |
4789 case unhandledState: tty->print("unhandled"); break;\ | |
4790 case activeState: tty->print("active"); break;\ | |
4791 case inactiveState: tty->print("inactive"); break;\ | |
4792 case handledState: tty->print("handled"); break;\ | |
4793 default: ShouldNotReachHere(); \ | |
4794 } | |
4795 | |
4796 print_state(from); tty->print(" to "); print_state(to); | |
4797 tty->fill_to(23); | |
4798 interval->print(); | |
4799 | |
4800 #undef print_state | |
4801 } | |
4802 #endif | |
4803 } | |
4804 | |
4805 | |
4806 | |
4807 // **** Implementation of LinearScanWalker ************************** | |
4808 | |
4809 LinearScanWalker::LinearScanWalker(LinearScan* allocator, Interval* unhandled_fixed_first, Interval* unhandled_any_first) | |
4810 : IntervalWalker(allocator, unhandled_fixed_first, unhandled_any_first) | |
4811 , _move_resolver(allocator) | |
4812 { | |
4813 for (int i = 0; i < LinearScan::nof_regs; i++) { | |
4814 _spill_intervals[i] = new IntervalList(2); | |
4815 } | |
4816 } | |
4817 | |
4818 | |
4819 inline void LinearScanWalker::init_use_lists(bool only_process_use_pos) { | |
4820 for (int i = _first_reg; i <= _last_reg; i++) { | |
4821 _use_pos[i] = max_jint; | |
4822 | |
4823 if (!only_process_use_pos) { | |
4824 _block_pos[i] = max_jint; | |
4825 _spill_intervals[i]->clear(); | |
4826 } | |
4827 } | |
4828 } | |
4829 | |
4830 inline void LinearScanWalker::exclude_from_use(int reg) { | |
4831 assert(reg < LinearScan::nof_regs, "interval must have a register assigned (stack slots not allowed)"); | |
4832 if (reg >= _first_reg && reg <= _last_reg) { | |
4833 _use_pos[reg] = 0; | |
4834 } | |
4835 } | |
4836 inline void LinearScanWalker::exclude_from_use(Interval* i) { | |
4837 assert(i->assigned_reg() != any_reg, "interval has no register assigned"); | |
4838 | |
4839 exclude_from_use(i->assigned_reg()); | |
4840 exclude_from_use(i->assigned_regHi()); | |
4841 } | |
4842 | |
4843 inline void LinearScanWalker::set_use_pos(int reg, Interval* i, int use_pos, bool only_process_use_pos) { | |
4844 assert(use_pos != 0, "must use exclude_from_use to set use_pos to 0"); | |
4845 | |
4846 if (reg >= _first_reg && reg <= _last_reg) { | |
4847 if (_use_pos[reg] > use_pos) { | |
4848 _use_pos[reg] = use_pos; | |
4849 } | |
4850 if (!only_process_use_pos) { | |
4851 _spill_intervals[reg]->append(i); | |
4852 } | |
4853 } | |
4854 } | |
4855 inline void LinearScanWalker::set_use_pos(Interval* i, int use_pos, bool only_process_use_pos) { | |
4856 assert(i->assigned_reg() != any_reg, "interval has no register assigned"); | |
4857 if (use_pos != -1) { | |
4858 set_use_pos(i->assigned_reg(), i, use_pos, only_process_use_pos); | |
4859 set_use_pos(i->assigned_regHi(), i, use_pos, only_process_use_pos); | |
4860 } | |
4861 } | |
4862 | |
4863 inline void LinearScanWalker::set_block_pos(int reg, Interval* i, int block_pos) { | |
4864 if (reg >= _first_reg && reg <= _last_reg) { | |
4865 if (_block_pos[reg] > block_pos) { | |
4866 _block_pos[reg] = block_pos; | |
4867 } | |
4868 if (_use_pos[reg] > block_pos) { | |
4869 _use_pos[reg] = block_pos; | |
4870 } | |
4871 } | |
4872 } | |
4873 inline void LinearScanWalker::set_block_pos(Interval* i, int block_pos) { | |
4874 assert(i->assigned_reg() != any_reg, "interval has no register assigned"); | |
4875 if (block_pos != -1) { | |
4876 set_block_pos(i->assigned_reg(), i, block_pos); | |
4877 set_block_pos(i->assigned_regHi(), i, block_pos); | |
4878 } | |
4879 } | |
4880 | |
4881 | |
4882 void LinearScanWalker::free_exclude_active_fixed() { | |
4883 Interval* list = active_first(fixedKind); | |
4884 while (list != Interval::end()) { | |
4885 assert(list->assigned_reg() < LinearScan::nof_regs, "active interval must have a register assigned"); | |
4886 exclude_from_use(list); | |
4887 list = list->next(); | |
4888 } | |
4889 } | |
4890 | |
4891 void LinearScanWalker::free_exclude_active_any() { | |
4892 Interval* list = active_first(anyKind); | |
4893 while (list != Interval::end()) { | |
4894 exclude_from_use(list); | |
4895 list = list->next(); | |
4896 } | |
4897 } | |
4898 | |
4899 void LinearScanWalker::free_collect_inactive_fixed(Interval* cur) { | |
4900 Interval* list = inactive_first(fixedKind); | |
4901 while (list != Interval::end()) { | |
4902 if (cur->to() <= list->current_from()) { | |
4903 assert(list->current_intersects_at(cur) == -1, "must not intersect"); | |
4904 set_use_pos(list, list->current_from(), true); | |
4905 } else { | |
4906 set_use_pos(list, list->current_intersects_at(cur), true); | |
4907 } | |
4908 list = list->next(); | |
4909 } | |
4910 } | |
4911 | |
4912 void LinearScanWalker::free_collect_inactive_any(Interval* cur) { | |
4913 Interval* list = inactive_first(anyKind); | |
4914 while (list != Interval::end()) { | |
4915 set_use_pos(list, list->current_intersects_at(cur), true); | |
4916 list = list->next(); | |
4917 } | |
4918 } | |
4919 | |
4920 void LinearScanWalker::free_collect_unhandled(IntervalKind kind, Interval* cur) { | |
4921 Interval* list = unhandled_first(kind); | |
4922 while (list != Interval::end()) { | |
4923 set_use_pos(list, list->intersects_at(cur), true); | |
4924 if (kind == fixedKind && cur->to() <= list->from()) { | |
4925 set_use_pos(list, list->from(), true); | |
4926 } | |
4927 list = list->next(); | |
4928 } | |
4929 } | |
4930 | |
4931 void LinearScanWalker::spill_exclude_active_fixed() { | |
4932 Interval* list = active_first(fixedKind); | |
4933 while (list != Interval::end()) { | |
4934 exclude_from_use(list); | |
4935 list = list->next(); | |
4936 } | |
4937 } | |
4938 | |
4939 void LinearScanWalker::spill_block_unhandled_fixed(Interval* cur) { | |
4940 Interval* list = unhandled_first(fixedKind); | |
4941 while (list != Interval::end()) { | |
4942 set_block_pos(list, list->intersects_at(cur)); | |
4943 list = list->next(); | |
4944 } | |
4945 } | |
4946 | |
4947 void LinearScanWalker::spill_block_inactive_fixed(Interval* cur) { | |
4948 Interval* list = inactive_first(fixedKind); | |
4949 while (list != Interval::end()) { | |
4950 if (cur->to() > list->current_from()) { | |
4951 set_block_pos(list, list->current_intersects_at(cur)); | |
4952 } else { | |
4953 assert(list->current_intersects_at(cur) == -1, "invalid optimization: intervals intersect"); | |
4954 } | |
4955 | |
4956 list = list->next(); | |
4957 } | |
4958 } | |
4959 | |
4960 void LinearScanWalker::spill_collect_active_any() { | |
4961 Interval* list = active_first(anyKind); | |
4962 while (list != Interval::end()) { | |
4963 set_use_pos(list, MIN2(list->next_usage(loopEndMarker, _current_position), list->to()), false); | |
4964 list = list->next(); | |
4965 } | |
4966 } | |
4967 | |
4968 void LinearScanWalker::spill_collect_inactive_any(Interval* cur) { | |
4969 Interval* list = inactive_first(anyKind); | |
4970 while (list != Interval::end()) { | |
4971 if (list->current_intersects(cur)) { | |
4972 set_use_pos(list, MIN2(list->next_usage(loopEndMarker, _current_position), list->to()), false); | |
4973 } | |
4974 list = list->next(); | |
4975 } | |
4976 } | |
4977 | |
4978 | |
4979 void LinearScanWalker::insert_move(int op_id, Interval* src_it, Interval* dst_it) { | |
4980 // output all moves here. When source and target are equal, the move is | |
4981 // optimized away later in assign_reg_nums | |
4982 | |
4983 op_id = (op_id + 1) & ~1; | |
4984 BlockBegin* op_block = allocator()->block_of_op_with_id(op_id); | |
4985 assert(op_id > 0 && allocator()->block_of_op_with_id(op_id - 2) == op_block, "cannot insert move at block boundary"); | |
4986 | |
4987 // calculate index of instruction inside instruction list of current block | |
4988 // the minimal index (for a block with no spill moves) can be calculated because the | |
4989 // numbering of instructions is known. | |
4990 // When the block already contains spill moves, the index must be increased until the | |
4991 // correct index is reached. | |
4992 LIR_OpList* list = op_block->lir()->instructions_list(); | |
4993 int index = (op_id - list->at(0)->id()) / 2; | |
4994 assert(list->at(index)->id() <= op_id, "error in calculation"); | |
4995 | |
4996 while (list->at(index)->id() != op_id) { | |
4997 index++; | |
4998 assert(0 <= index && index < list->length(), "index out of bounds"); | |
4999 } | |
5000 assert(1 <= index && index < list->length(), "index out of bounds"); | |
5001 assert(list->at(index)->id() == op_id, "error in calculation"); | |
5002 | |
5003 // insert new instruction before instruction at position index | |
5004 _move_resolver.move_insert_position(op_block->lir(), index - 1); | |
5005 _move_resolver.add_mapping(src_it, dst_it); | |
5006 } | |
5007 | |
5008 | |
5009 int LinearScanWalker::find_optimal_split_pos(BlockBegin* min_block, BlockBegin* max_block, int max_split_pos) { | |
5010 int from_block_nr = min_block->linear_scan_number(); | |
5011 int to_block_nr = max_block->linear_scan_number(); | |
5012 | |
5013 assert(0 <= from_block_nr && from_block_nr < block_count(), "out of range"); | |
5014 assert(0 <= to_block_nr && to_block_nr < block_count(), "out of range"); | |
5015 assert(from_block_nr < to_block_nr, "must cross block boundary"); | |
5016 | |
5017 // Try to split at end of max_block. If this would be after | |
5018 // max_split_pos, then use the begin of max_block | |
5019 int optimal_split_pos = max_block->last_lir_instruction_id() + 2; | |
5020 if (optimal_split_pos > max_split_pos) { | |
5021 optimal_split_pos = max_block->first_lir_instruction_id(); | |
5022 } | |
5023 | |
5024 int min_loop_depth = max_block->loop_depth(); | |
5025 for (int i = to_block_nr - 1; i >= from_block_nr; i--) { | |
5026 BlockBegin* cur = block_at(i); | |
5027 | |
5028 if (cur->loop_depth() < min_loop_depth) { | |
5029 // block with lower loop-depth found -> split at the end of this block | |
5030 min_loop_depth = cur->loop_depth(); | |
5031 optimal_split_pos = cur->last_lir_instruction_id() + 2; | |
5032 } | |
5033 } | |
5034 assert(optimal_split_pos > allocator()->max_lir_op_id() || allocator()->is_block_begin(optimal_split_pos), "algorithm must move split pos to block boundary"); | |
5035 | |
5036 return optimal_split_pos; | |
5037 } | |
5038 | |
5039 | |
5040 int LinearScanWalker::find_optimal_split_pos(Interval* it, int min_split_pos, int max_split_pos, bool do_loop_optimization) { | |
5041 int optimal_split_pos = -1; | |
5042 if (min_split_pos == max_split_pos) { | |
5043 // trivial case, no optimization of split position possible | |
5044 TRACE_LINEAR_SCAN(4, tty->print_cr(" min-pos and max-pos are equal, no optimization possible")); | |
5045 optimal_split_pos = min_split_pos; | |
5046 | |
5047 } else { | |
5048 assert(min_split_pos < max_split_pos, "must be true then"); | |
5049 assert(min_split_pos > 0, "cannot access min_split_pos - 1 otherwise"); | |
5050 | |
5051 // reason for using min_split_pos - 1: when the minimal split pos is exactly at the | |
5052 // beginning of a block, then min_split_pos is also a possible split position. | |
5053 // Use the block before as min_block, because then min_block->last_lir_instruction_id() + 2 == min_split_pos | |
5054 BlockBegin* min_block = allocator()->block_of_op_with_id(min_split_pos - 1); | |
5055 | |
5056 // reason for using max_split_pos - 1: otherwise there would be an assertion failure | |
5057 // when an interval ends at the end of the last block of the method | |
5058 // (in this case, max_split_pos == allocator()->max_lir_op_id() + 2, and there is no | |
5059 // block at this op_id) | |
5060 BlockBegin* max_block = allocator()->block_of_op_with_id(max_split_pos - 1); | |
5061 | |
5062 assert(min_block->linear_scan_number() <= max_block->linear_scan_number(), "invalid order"); | |
5063 if (min_block == max_block) { | |
5064 // split position cannot be moved to block boundary, so split as late as possible | |
5065 TRACE_LINEAR_SCAN(4, tty->print_cr(" cannot move split pos to block boundary because min_pos and max_pos are in same block")); | |
5066 optimal_split_pos = max_split_pos; | |
5067 | |
5068 } else if (it->has_hole_between(max_split_pos - 1, max_split_pos) && !allocator()->is_block_begin(max_split_pos)) { | |
5069 // Do not move split position if the interval has a hole before max_split_pos. | |
5070 // Intervals resulting from Phi-Functions have more than one definition (marked | |
5071 // as mustHaveRegister) with a hole before each definition. When the register is needed | |
5072 // for the second definition, an earlier reloading is unnecessary. | |
5073 TRACE_LINEAR_SCAN(4, tty->print_cr(" interval has hole just before max_split_pos, so splitting at max_split_pos")); | |
5074 optimal_split_pos = max_split_pos; | |
5075 | |
5076 } else { | |
5077 // seach optimal block boundary between min_split_pos and max_split_pos | |
5078 TRACE_LINEAR_SCAN(4, tty->print_cr(" moving split pos to optimal block boundary between block B%d and B%d", min_block->block_id(), max_block->block_id())); | |
5079 | |
5080 if (do_loop_optimization) { | |
5081 // Loop optimization: if a loop-end marker is found between min- and max-position, | |
5082 // then split before this loop | |
5083 int loop_end_pos = it->next_usage_exact(loopEndMarker, min_block->last_lir_instruction_id() + 2); | |
5084 TRACE_LINEAR_SCAN(4, tty->print_cr(" loop optimization: loop end found at pos %d", loop_end_pos)); | |
5085 | |
5086 assert(loop_end_pos > min_split_pos, "invalid order"); | |
5087 if (loop_end_pos < max_split_pos) { | |
5088 // loop-end marker found between min- and max-position | |
5089 // if it is not the end marker for the same loop as the min-position, then move | |
5090 // the max-position to this loop block. | |
5091 // Desired result: uses tagged as shouldHaveRegister inside a loop cause a reloading | |
5092 // of the interval (normally, only mustHaveRegister causes a reloading) | |
5093 BlockBegin* loop_block = allocator()->block_of_op_with_id(loop_end_pos); | |
5094 | |
5095 TRACE_LINEAR_SCAN(4, tty->print_cr(" interval is used in loop that ends in block B%d, so trying to move max_block back from B%d to B%d", loop_block->block_id(), max_block->block_id(), loop_block->block_id())); | |
5096 assert(loop_block != min_block, "loop_block and min_block must be different because block boundary is needed between"); | |
5097 | |
5098 optimal_split_pos = find_optimal_split_pos(min_block, loop_block, loop_block->last_lir_instruction_id() + 2); | |
5099 if (optimal_split_pos == loop_block->last_lir_instruction_id() + 2) { | |
5100 optimal_split_pos = -1; | |
5101 TRACE_LINEAR_SCAN(4, tty->print_cr(" loop optimization not necessary")); | |
5102 } else { | |
5103 TRACE_LINEAR_SCAN(4, tty->print_cr(" loop optimization successful")); | |
5104 } | |
5105 } | |
5106 } | |
5107 | |
5108 if (optimal_split_pos == -1) { | |
5109 // not calculated by loop optimization | |
5110 optimal_split_pos = find_optimal_split_pos(min_block, max_block, max_split_pos); | |
5111 } | |
5112 } | |
5113 } | |
5114 TRACE_LINEAR_SCAN(4, tty->print_cr(" optimal split position: %d", optimal_split_pos)); | |
5115 | |
5116 return optimal_split_pos; | |
5117 } | |
5118 | |
5119 | |
5120 /* | |
5121 split an interval at the optimal position between min_split_pos and | |
5122 max_split_pos in two parts: | |
5123 1) the left part has already a location assigned | |
5124 2) the right part is sorted into to the unhandled-list | |
5125 */ | |
5126 void LinearScanWalker::split_before_usage(Interval* it, int min_split_pos, int max_split_pos) { | |
5127 TRACE_LINEAR_SCAN(2, tty->print ("----- splitting interval: "); it->print()); | |
5128 TRACE_LINEAR_SCAN(2, tty->print_cr(" between %d and %d", min_split_pos, max_split_pos)); | |
5129 | |
5130 assert(it->from() < min_split_pos, "cannot split at start of interval"); | |
5131 assert(current_position() < min_split_pos, "cannot split before current position"); | |
5132 assert(min_split_pos <= max_split_pos, "invalid order"); | |
5133 assert(max_split_pos <= it->to(), "cannot split after end of interval"); | |
5134 | |
5135 int optimal_split_pos = find_optimal_split_pos(it, min_split_pos, max_split_pos, true); | |
5136 | |
5137 assert(min_split_pos <= optimal_split_pos && optimal_split_pos <= max_split_pos, "out of range"); | |
5138 assert(optimal_split_pos <= it->to(), "cannot split after end of interval"); | |
5139 assert(optimal_split_pos > it->from(), "cannot split at start of interval"); | |
5140 | |
5141 if (optimal_split_pos == it->to() && it->next_usage(mustHaveRegister, min_split_pos) == max_jint) { | |
5142 // the split position would be just before the end of the interval | |
5143 // -> no split at all necessary | |
5144 TRACE_LINEAR_SCAN(4, tty->print_cr(" no split necessary because optimal split position is at end of interval")); | |
5145 return; | |
5146 } | |
5147 | |
5148 // must calculate this before the actual split is performed and before split position is moved to odd op_id | |
5149 bool move_necessary = !allocator()->is_block_begin(optimal_split_pos) && !it->has_hole_between(optimal_split_pos - 1, optimal_split_pos); | |
5150 | |
5151 if (!allocator()->is_block_begin(optimal_split_pos)) { | |
5152 // move position before actual instruction (odd op_id) | |
5153 optimal_split_pos = (optimal_split_pos - 1) | 1; | |
5154 } | |
5155 | |
5156 TRACE_LINEAR_SCAN(4, tty->print_cr(" splitting at position %d", optimal_split_pos)); | |
5157 assert(allocator()->is_block_begin(optimal_split_pos) || (optimal_split_pos % 2 == 1), "split pos must be odd when not on block boundary"); | |
5158 assert(!allocator()->is_block_begin(optimal_split_pos) || (optimal_split_pos % 2 == 0), "split pos must be even on block boundary"); | |
5159 | |
5160 Interval* split_part = it->split(optimal_split_pos); | |
5161 | |
5162 allocator()->append_interval(split_part); | |
5163 allocator()->copy_register_flags(it, split_part); | |
5164 split_part->set_insert_move_when_activated(move_necessary); | |
5165 append_to_unhandled(unhandled_first_addr(anyKind), split_part); | |
5166 | |
5167 TRACE_LINEAR_SCAN(2, tty->print_cr(" split interval in two parts (insert_move_when_activated: %d)", move_necessary)); | |
5168 TRACE_LINEAR_SCAN(2, tty->print (" "); it->print()); | |
5169 TRACE_LINEAR_SCAN(2, tty->print (" "); split_part->print()); | |
5170 } | |
5171 | |
5172 /* | |
5173 split an interval at the optimal position between min_split_pos and | |
5174 max_split_pos in two parts: | |
5175 1) the left part has already a location assigned | |
5176 2) the right part is always on the stack and therefore ignored in further processing | |
5177 */ | |
5178 void LinearScanWalker::split_for_spilling(Interval* it) { | |
5179 // calculate allowed range of splitting position | |
5180 int max_split_pos = current_position(); | |
5181 int min_split_pos = MAX2(it->previous_usage(shouldHaveRegister, max_split_pos) + 1, it->from()); | |
5182 | |
5183 TRACE_LINEAR_SCAN(2, tty->print ("----- splitting and spilling interval: "); it->print()); | |
5184 TRACE_LINEAR_SCAN(2, tty->print_cr(" between %d and %d", min_split_pos, max_split_pos)); | |
5185 | |
5186 assert(it->state() == activeState, "why spill interval that is not active?"); | |
5187 assert(it->from() <= min_split_pos, "cannot split before start of interval"); | |
5188 assert(min_split_pos <= max_split_pos, "invalid order"); | |
5189 assert(max_split_pos < it->to(), "cannot split at end end of interval"); | |
5190 assert(current_position() < it->to(), "interval must not end before current position"); | |
5191 | |
5192 if (min_split_pos == it->from()) { | |
5193 // the whole interval is never used, so spill it entirely to memory | |
5194 TRACE_LINEAR_SCAN(2, tty->print_cr(" spilling entire interval because split pos is at beginning of interval")); | |
5195 assert(it->first_usage(shouldHaveRegister) > current_position(), "interval must not have use position before current_position"); | |
5196 | |
5197 allocator()->assign_spill_slot(it); | |
5198 allocator()->change_spill_state(it, min_split_pos); | |
5199 | |
5200 // Also kick parent intervals out of register to memory when they have no use | |
5201 // position. This avoids short interval in register surrounded by intervals in | |
5202 // memory -> avoid useless moves from memory to register and back | |
5203 Interval* parent = it; | |
5204 while (parent != NULL && parent->is_split_child()) { | |
5205 parent = parent->split_child_before_op_id(parent->from()); | |
5206 | |
5207 if (parent->assigned_reg() < LinearScan::nof_regs) { | |
5208 if (parent->first_usage(shouldHaveRegister) == max_jint) { | |
5209 // parent is never used, so kick it out of its assigned register | |
5210 TRACE_LINEAR_SCAN(4, tty->print_cr(" kicking out interval %d out of its register because it is never used", parent->reg_num())); | |
5211 allocator()->assign_spill_slot(parent); | |
5212 } else { | |
5213 // do not go further back because the register is actually used by the interval | |
5214 parent = NULL; | |
5215 } | |
5216 } | |
5217 } | |
5218 | |
5219 } else { | |
5220 // search optimal split pos, split interval and spill only the right hand part | |
5221 int optimal_split_pos = find_optimal_split_pos(it, min_split_pos, max_split_pos, false); | |
5222 | |
5223 assert(min_split_pos <= optimal_split_pos && optimal_split_pos <= max_split_pos, "out of range"); | |
5224 assert(optimal_split_pos < it->to(), "cannot split at end of interval"); | |
5225 assert(optimal_split_pos >= it->from(), "cannot split before start of interval"); | |
5226 | |
5227 if (!allocator()->is_block_begin(optimal_split_pos)) { | |
5228 // move position before actual instruction (odd op_id) | |
5229 optimal_split_pos = (optimal_split_pos - 1) | 1; | |
5230 } | |
5231 | |
5232 TRACE_LINEAR_SCAN(4, tty->print_cr(" splitting at position %d", optimal_split_pos)); | |
5233 assert(allocator()->is_block_begin(optimal_split_pos) || (optimal_split_pos % 2 == 1), "split pos must be odd when not on block boundary"); | |
5234 assert(!allocator()->is_block_begin(optimal_split_pos) || (optimal_split_pos % 2 == 0), "split pos must be even on block boundary"); | |
5235 | |
5236 Interval* spilled_part = it->split(optimal_split_pos); | |
5237 allocator()->append_interval(spilled_part); | |
5238 allocator()->assign_spill_slot(spilled_part); | |
5239 allocator()->change_spill_state(spilled_part, optimal_split_pos); | |
5240 | |
5241 if (!allocator()->is_block_begin(optimal_split_pos)) { | |
5242 TRACE_LINEAR_SCAN(4, tty->print_cr(" inserting move from interval %d to %d", it->reg_num(), spilled_part->reg_num())); | |
5243 insert_move(optimal_split_pos, it, spilled_part); | |
5244 } | |
5245 | |
5246 // the current_split_child is needed later when moves are inserted for reloading | |
5247 assert(spilled_part->current_split_child() == it, "overwriting wrong current_split_child"); | |
5248 spilled_part->make_current_split_child(); | |
5249 | |
5250 TRACE_LINEAR_SCAN(2, tty->print_cr(" split interval in two parts")); | |
5251 TRACE_LINEAR_SCAN(2, tty->print (" "); it->print()); | |
5252 TRACE_LINEAR_SCAN(2, tty->print (" "); spilled_part->print()); | |
5253 } | |
5254 } | |
5255 | |
5256 | |
5257 void LinearScanWalker::split_stack_interval(Interval* it) { | |
5258 int min_split_pos = current_position() + 1; | |
5259 int max_split_pos = MIN2(it->first_usage(shouldHaveRegister), it->to()); | |
5260 | |
5261 split_before_usage(it, min_split_pos, max_split_pos); | |
5262 } | |
5263 | |
5264 void LinearScanWalker::split_when_partial_register_available(Interval* it, int register_available_until) { | |
5265 int min_split_pos = MAX2(it->previous_usage(shouldHaveRegister, register_available_until), it->from() + 1); | |
5266 int max_split_pos = register_available_until; | |
5267 | |
5268 split_before_usage(it, min_split_pos, max_split_pos); | |
5269 } | |
5270 | |
5271 void LinearScanWalker::split_and_spill_interval(Interval* it) { | |
5272 assert(it->state() == activeState || it->state() == inactiveState, "other states not allowed"); | |
5273 | |
5274 int current_pos = current_position(); | |
5275 if (it->state() == inactiveState) { | |
5276 // the interval is currently inactive, so no spill slot is needed for now. | |
5277 // when the split part is activated, the interval has a new chance to get a register, | |
5278 // so in the best case no stack slot is necessary | |
5279 assert(it->has_hole_between(current_pos - 1, current_pos + 1), "interval can not be inactive otherwise"); | |
5280 split_before_usage(it, current_pos + 1, current_pos + 1); | |
5281 | |
5282 } else { | |
5283 // search the position where the interval must have a register and split | |
5284 // at the optimal position before. | |
5285 // The new created part is added to the unhandled list and will get a register | |
5286 // when it is activated | |
5287 int min_split_pos = current_pos + 1; | |
5288 int max_split_pos = MIN2(it->next_usage(mustHaveRegister, min_split_pos), it->to()); | |
5289 | |
5290 split_before_usage(it, min_split_pos, max_split_pos); | |
5291 | |
5292 assert(it->next_usage(mustHaveRegister, current_pos) == max_jint, "the remaining part is spilled to stack and therefore has no register"); | |
5293 split_for_spilling(it); | |
5294 } | |
5295 } | |
5296 | |
5297 | |
5298 int LinearScanWalker::find_free_reg(int reg_needed_until, int interval_to, int hint_reg, int ignore_reg, bool* need_split) { | |
5299 int min_full_reg = any_reg; | |
5300 int max_partial_reg = any_reg; | |
5301 | |
5302 for (int i = _first_reg; i <= _last_reg; i++) { | |
5303 if (i == ignore_reg) { | |
5304 // this register must be ignored | |
5305 | |
5306 } else if (_use_pos[i] >= interval_to) { | |
5307 // this register is free for the full interval | |
5308 if (min_full_reg == any_reg || i == hint_reg || (_use_pos[i] < _use_pos[min_full_reg] && min_full_reg != hint_reg)) { | |
5309 min_full_reg = i; | |
5310 } | |
5311 } else if (_use_pos[i] > reg_needed_until) { | |
5312 // this register is at least free until reg_needed_until | |
5313 if (max_partial_reg == any_reg || i == hint_reg || (_use_pos[i] > _use_pos[max_partial_reg] && max_partial_reg != hint_reg)) { | |
5314 max_partial_reg = i; | |
5315 } | |
5316 } | |
5317 } | |
5318 | |
5319 if (min_full_reg != any_reg) { | |
5320 return min_full_reg; | |
5321 } else if (max_partial_reg != any_reg) { | |
5322 *need_split = true; | |
5323 return max_partial_reg; | |
5324 } else { | |
5325 return any_reg; | |
5326 } | |
5327 } | |
5328 | |
5329 int LinearScanWalker::find_free_double_reg(int reg_needed_until, int interval_to, int hint_reg, bool* need_split) { | |
5330 assert((_last_reg - _first_reg + 1) % 2 == 0, "adjust algorithm"); | |
5331 | |
5332 int min_full_reg = any_reg; | |
5333 int max_partial_reg = any_reg; | |
5334 | |
5335 for (int i = _first_reg; i < _last_reg; i+=2) { | |
5336 if (_use_pos[i] >= interval_to && _use_pos[i + 1] >= interval_to) { | |
5337 // this register is free for the full interval | |
5338 if (min_full_reg == any_reg || i == hint_reg || (_use_pos[i] < _use_pos[min_full_reg] && min_full_reg != hint_reg)) { | |
5339 min_full_reg = i; | |
5340 } | |
5341 } else if (_use_pos[i] > reg_needed_until && _use_pos[i + 1] > reg_needed_until) { | |
5342 // this register is at least free until reg_needed_until | |
5343 if (max_partial_reg == any_reg || i == hint_reg || (_use_pos[i] > _use_pos[max_partial_reg] && max_partial_reg != hint_reg)) { | |
5344 max_partial_reg = i; | |
5345 } | |
5346 } | |
5347 } | |
5348 | |
5349 if (min_full_reg != any_reg) { | |
5350 return min_full_reg; | |
5351 } else if (max_partial_reg != any_reg) { | |
5352 *need_split = true; | |
5353 return max_partial_reg; | |
5354 } else { | |
5355 return any_reg; | |
5356 } | |
5357 } | |
5358 | |
5359 | |
5360 bool LinearScanWalker::alloc_free_reg(Interval* cur) { | |
5361 TRACE_LINEAR_SCAN(2, tty->print("trying to find free register for "); cur->print()); | |
5362 | |
5363 init_use_lists(true); | |
5364 free_exclude_active_fixed(); | |
5365 free_exclude_active_any(); | |
5366 free_collect_inactive_fixed(cur); | |
5367 free_collect_inactive_any(cur); | |
5368 // free_collect_unhandled(fixedKind, cur); | |
5369 assert(unhandled_first(fixedKind) == Interval::end(), "must not have unhandled fixed intervals because all fixed intervals have a use at position 0"); | |
5370 | |
5371 // _use_pos contains the start of the next interval that has this register assigned | |
5372 // (either as a fixed register or a normal allocated register in the past) | |
5373 // only intervals overlapping with cur are processed, non-overlapping invervals can be ignored safely | |
5374 TRACE_LINEAR_SCAN(4, tty->print_cr(" state of registers:")); | |
5375 TRACE_LINEAR_SCAN(4, for (int i = _first_reg; i <= _last_reg; i++) tty->print_cr(" reg %d: use_pos: %d", i, _use_pos[i])); | |
5376 | |
5377 int hint_reg, hint_regHi; | |
5378 Interval* register_hint = cur->register_hint(); | |
5379 if (register_hint != NULL) { | |
5380 hint_reg = register_hint->assigned_reg(); | |
5381 hint_regHi = register_hint->assigned_regHi(); | |
5382 | |
5383 if (allocator()->is_precolored_cpu_interval(register_hint)) { | |
5384 assert(hint_reg != any_reg && hint_regHi == any_reg, "must be for fixed intervals"); | |
5385 hint_regHi = hint_reg + 1; // connect e.g. eax-edx | |
5386 } | |
5387 TRACE_LINEAR_SCAN(4, tty->print(" hint registers %d, %d from interval ", hint_reg, hint_regHi); register_hint->print()); | |
5388 | |
5389 } else { | |
5390 hint_reg = any_reg; | |
5391 hint_regHi = any_reg; | |
5392 } | |
5393 assert(hint_reg == any_reg || hint_reg != hint_regHi, "hint reg and regHi equal"); | |
5394 assert(cur->assigned_reg() == any_reg && cur->assigned_regHi() == any_reg, "register already assigned to interval"); | |
5395 | |
5396 // the register must be free at least until this position | |
5397 int reg_needed_until = cur->from() + 1; | |
5398 int interval_to = cur->to(); | |
5399 | |
5400 bool need_split = false; | |
5401 int split_pos = -1; | |
5402 int reg = any_reg; | |
5403 int regHi = any_reg; | |
5404 | |
5405 if (_adjacent_regs) { | |
5406 reg = find_free_double_reg(reg_needed_until, interval_to, hint_reg, &need_split); | |
5407 regHi = reg + 1; | |
5408 if (reg == any_reg) { | |
5409 return false; | |
5410 } | |
5411 split_pos = MIN2(_use_pos[reg], _use_pos[regHi]); | |
5412 | |
5413 } else { | |
5414 reg = find_free_reg(reg_needed_until, interval_to, hint_reg, any_reg, &need_split); | |
5415 if (reg == any_reg) { | |
5416 return false; | |
5417 } | |
5418 split_pos = _use_pos[reg]; | |
5419 | |
5420 if (_num_phys_regs == 2) { | |
5421 regHi = find_free_reg(reg_needed_until, interval_to, hint_regHi, reg, &need_split); | |
5422 | |
5423 if (_use_pos[reg] < interval_to && regHi == any_reg) { | |
5424 // do not split interval if only one register can be assigned until the split pos | |
5425 // (when one register is found for the whole interval, split&spill is only | |
5426 // performed for the hi register) | |
5427 return false; | |
5428 | |
5429 } else if (regHi != any_reg) { | |
5430 split_pos = MIN2(split_pos, _use_pos[regHi]); | |
5431 | |
5432 // sort register numbers to prevent e.g. a move from eax,ebx to ebx,eax | |
5433 if (reg > regHi) { | |
5434 int temp = reg; | |
5435 reg = regHi; | |
5436 regHi = temp; | |
5437 } | |
5438 } | |
5439 } | |
5440 } | |
5441 | |
5442 cur->assign_reg(reg, regHi); | |
5443 TRACE_LINEAR_SCAN(2, tty->print_cr("selected register %d, %d", reg, regHi)); | |
5444 | |
5445 assert(split_pos > 0, "invalid split_pos"); | |
5446 if (need_split) { | |
5447 // register not available for full interval, so split it | |
5448 split_when_partial_register_available(cur, split_pos); | |
5449 } | |
5450 | |
5451 // only return true if interval is completely assigned | |
5452 return _num_phys_regs == 1 || regHi != any_reg; | |
5453 } | |
5454 | |
5455 | |
5456 int LinearScanWalker::find_locked_reg(int reg_needed_until, int interval_to, int hint_reg, int ignore_reg, bool* need_split) { | |
5457 int max_reg = any_reg; | |
5458 | |
5459 for (int i = _first_reg; i <= _last_reg; i++) { | |
5460 if (i == ignore_reg) { | |
5461 // this register must be ignored | |
5462 | |
5463 } else if (_use_pos[i] > reg_needed_until) { | |
5464 if (max_reg == any_reg || i == hint_reg || (_use_pos[i] > _use_pos[max_reg] && max_reg != hint_reg)) { | |
5465 max_reg = i; | |
5466 } | |
5467 } | |
5468 } | |
5469 | |
5470 if (max_reg != any_reg && _block_pos[max_reg] <= interval_to) { | |
5471 *need_split = true; | |
5472 } | |
5473 | |
5474 return max_reg; | |
5475 } | |
5476 | |
5477 int LinearScanWalker::find_locked_double_reg(int reg_needed_until, int interval_to, int hint_reg, bool* need_split) { | |
5478 assert((_last_reg - _first_reg + 1) % 2 == 0, "adjust algorithm"); | |
5479 | |
5480 int max_reg = any_reg; | |
5481 | |
5482 for (int i = _first_reg; i < _last_reg; i+=2) { | |
5483 if (_use_pos[i] > reg_needed_until && _use_pos[i + 1] > reg_needed_until) { | |
5484 if (max_reg == any_reg || _use_pos[i] > _use_pos[max_reg]) { | |
5485 max_reg = i; | |
5486 } | |
5487 } | |
5488 } | |
5489 | |
5490 if (_block_pos[max_reg] <= interval_to || _block_pos[max_reg + 1] <= interval_to) { | |
5491 *need_split = true; | |
5492 } | |
5493 | |
5494 return max_reg; | |
5495 } | |
5496 | |
5497 void LinearScanWalker::split_and_spill_intersecting_intervals(int reg, int regHi) { | |
5498 assert(reg != any_reg, "no register assigned"); | |
5499 | |
5500 for (int i = 0; i < _spill_intervals[reg]->length(); i++) { | |
5501 Interval* it = _spill_intervals[reg]->at(i); | |
5502 remove_from_list(it); | |
5503 split_and_spill_interval(it); | |
5504 } | |
5505 | |
5506 if (regHi != any_reg) { | |
5507 IntervalList* processed = _spill_intervals[reg]; | |
5508 for (int i = 0; i < _spill_intervals[regHi]->length(); i++) { | |
5509 Interval* it = _spill_intervals[regHi]->at(i); | |
5510 if (processed->index_of(it) == -1) { | |
5511 remove_from_list(it); | |
5512 split_and_spill_interval(it); | |
5513 } | |
5514 } | |
5515 } | |
5516 } | |
5517 | |
5518 | |
5519 // Split an Interval and spill it to memory so that cur can be placed in a register | |
5520 void LinearScanWalker::alloc_locked_reg(Interval* cur) { | |
5521 TRACE_LINEAR_SCAN(2, tty->print("need to split and spill to get register for "); cur->print()); | |
5522 | |
5523 // collect current usage of registers | |
5524 init_use_lists(false); | |
5525 spill_exclude_active_fixed(); | |
5526 // spill_block_unhandled_fixed(cur); | |
5527 assert(unhandled_first(fixedKind) == Interval::end(), "must not have unhandled fixed intervals because all fixed intervals have a use at position 0"); | |
5528 spill_block_inactive_fixed(cur); | |
5529 spill_collect_active_any(); | |
5530 spill_collect_inactive_any(cur); | |
5531 | |
5532 #ifndef PRODUCT | |
5533 if (TraceLinearScanLevel >= 4) { | |
5534 tty->print_cr(" state of registers:"); | |
5535 for (int i = _first_reg; i <= _last_reg; i++) { | |
5536 tty->print(" reg %d: use_pos: %d, block_pos: %d, intervals: ", i, _use_pos[i], _block_pos[i]); | |
5537 for (int j = 0; j < _spill_intervals[i]->length(); j++) { | |
5538 tty->print("%d ", _spill_intervals[i]->at(j)->reg_num()); | |
5539 } | |
5540 tty->cr(); | |
5541 } | |
5542 } | |
5543 #endif | |
5544 | |
5545 // the register must be free at least until this position | |
5546 int reg_needed_until = MIN2(cur->first_usage(mustHaveRegister), cur->from() + 1); | |
5547 int interval_to = cur->to(); | |
5548 assert (reg_needed_until > 0 && reg_needed_until < max_jint, "interval has no use"); | |
5549 | |
5550 int split_pos = 0; | |
5551 int use_pos = 0; | |
5552 bool need_split = false; | |
5553 int reg, regHi; | |
5554 | |
5555 if (_adjacent_regs) { | |
5556 reg = find_locked_double_reg(reg_needed_until, interval_to, any_reg, &need_split); | |
5557 regHi = reg + 1; | |
5558 | |
5559 if (reg != any_reg) { | |
5560 use_pos = MIN2(_use_pos[reg], _use_pos[regHi]); | |
5561 split_pos = MIN2(_block_pos[reg], _block_pos[regHi]); | |
5562 } | |
5563 } else { | |
5564 reg = find_locked_reg(reg_needed_until, interval_to, any_reg, cur->assigned_reg(), &need_split); | |
5565 regHi = any_reg; | |
5566 | |
5567 if (reg != any_reg) { | |
5568 use_pos = _use_pos[reg]; | |
5569 split_pos = _block_pos[reg]; | |
5570 | |
5571 if (_num_phys_regs == 2) { | |
5572 if (cur->assigned_reg() != any_reg) { | |
5573 regHi = reg; | |
5574 reg = cur->assigned_reg(); | |
5575 } else { | |
5576 regHi = find_locked_reg(reg_needed_until, interval_to, any_reg, reg, &need_split); | |
5577 if (regHi != any_reg) { | |
5578 use_pos = MIN2(use_pos, _use_pos[regHi]); | |
5579 split_pos = MIN2(split_pos, _block_pos[regHi]); | |
5580 } | |
5581 } | |
5582 | |
5583 if (regHi != any_reg && reg > regHi) { | |
5584 // sort register numbers to prevent e.g. a move from eax,ebx to ebx,eax | |
5585 int temp = reg; | |
5586 reg = regHi; | |
5587 regHi = temp; | |
5588 } | |
5589 } | |
5590 } | |
5591 } | |
5592 | |
5593 if (reg == any_reg || (_num_phys_regs == 2 && regHi == any_reg) || use_pos <= cur->first_usage(mustHaveRegister)) { | |
5594 // the first use of cur is later than the spilling position -> spill cur | |
5595 TRACE_LINEAR_SCAN(4, tty->print_cr("able to spill current interval. first_usage(register): %d, use_pos: %d", cur->first_usage(mustHaveRegister), use_pos)); | |
5596 | |
5597 if (cur->first_usage(mustHaveRegister) <= cur->from() + 1) { | |
5598 assert(false, "cannot spill interval that is used in first instruction (possible reason: no register found)"); | |
5599 // assign a reasonable register and do a bailout in product mode to avoid errors | |
5600 allocator()->assign_spill_slot(cur); | |
5601 BAILOUT("LinearScan: no register found"); | |
5602 } | |
5603 | |
5604 split_and_spill_interval(cur); | |
5605 } else { | |
5606 TRACE_LINEAR_SCAN(4, tty->print_cr("decided to use register %d, %d", reg, regHi)); | |
5607 assert(reg != any_reg && (_num_phys_regs == 1 || regHi != any_reg), "no register found"); | |
5608 assert(split_pos > 0, "invalid split_pos"); | |
5609 assert(need_split == false || split_pos > cur->from(), "splitting interval at from"); | |
5610 | |
5611 cur->assign_reg(reg, regHi); | |
5612 if (need_split) { | |
5613 // register not available for full interval, so split it | |
5614 split_when_partial_register_available(cur, split_pos); | |
5615 } | |
5616 | |
5617 // perform splitting and spilling for all affected intervalls | |
5618 split_and_spill_intersecting_intervals(reg, regHi); | |
5619 } | |
5620 } | |
5621 | |
5622 bool LinearScanWalker::no_allocation_possible(Interval* cur) { | |
304 | 5623 #ifdef X86 |
0 | 5624 // fast calculation of intervals that can never get a register because the |
5625 // the next instruction is a call that blocks all registers | |
5626 // Note: this does not work if callee-saved registers are available (e.g. on Sparc) | |
5627 | |
5628 // check if this interval is the result of a split operation | |
5629 // (an interval got a register until this position) | |
5630 int pos = cur->from(); | |
5631 if ((pos & 1) == 1) { | |
5632 // the current instruction is a call that blocks all registers | |
5633 if (pos < allocator()->max_lir_op_id() && allocator()->has_call(pos + 1)) { | |
5634 TRACE_LINEAR_SCAN(4, tty->print_cr(" free register cannot be available because all registers blocked by following call")); | |
5635 | |
5636 // safety check that there is really no register available | |
5637 assert(alloc_free_reg(cur) == false, "found a register for this interval"); | |
5638 return true; | |
5639 } | |
5640 | |
5641 } | |
5642 #endif | |
5643 return false; | |
5644 } | |
5645 | |
5646 void LinearScanWalker::init_vars_for_alloc(Interval* cur) { | |
5647 BasicType type = cur->type(); | |
5648 _num_phys_regs = LinearScan::num_physical_regs(type); | |
5649 _adjacent_regs = LinearScan::requires_adjacent_regs(type); | |
5650 | |
5651 if (pd_init_regs_for_alloc(cur)) { | |
5652 // the appropriate register range was selected. | |
5653 } else if (type == T_FLOAT || type == T_DOUBLE) { | |
5654 _first_reg = pd_first_fpu_reg; | |
5655 _last_reg = pd_last_fpu_reg; | |
5656 } else { | |
5657 _first_reg = pd_first_cpu_reg; | |
2002 | 5658 _last_reg = FrameMap::last_cpu_reg(); |
0 | 5659 } |
5660 | |
5661 assert(0 <= _first_reg && _first_reg < LinearScan::nof_regs, "out of range"); | |
5662 assert(0 <= _last_reg && _last_reg < LinearScan::nof_regs, "out of range"); | |
5663 } | |
5664 | |
5665 | |
5666 bool LinearScanWalker::is_move(LIR_Op* op, Interval* from, Interval* to) { | |
5667 if (op->code() != lir_move) { | |
5668 return false; | |
5669 } | |
5670 assert(op->as_Op1() != NULL, "move must be LIR_Op1"); | |
5671 | |
5672 LIR_Opr in = ((LIR_Op1*)op)->in_opr(); | |
5673 LIR_Opr res = ((LIR_Op1*)op)->result_opr(); | |
5674 return in->is_virtual() && res->is_virtual() && in->vreg_number() == from->reg_num() && res->vreg_number() == to->reg_num(); | |
5675 } | |
5676 | |
5677 // optimization (especially for phi functions of nested loops): | |
5678 // assign same spill slot to non-intersecting intervals | |
5679 void LinearScanWalker::combine_spilled_intervals(Interval* cur) { | |
5680 if (cur->is_split_child()) { | |
5681 // optimization is only suitable for split parents | |
5682 return; | |
5683 } | |
5684 | |
5685 Interval* register_hint = cur->register_hint(false); | |
5686 if (register_hint == NULL) { | |
5687 // cur is not the target of a move, otherwise register_hint would be set | |
5688 return; | |
5689 } | |
5690 assert(register_hint->is_split_parent(), "register hint must be split parent"); | |
5691 | |
5692 if (cur->spill_state() != noOptimization || register_hint->spill_state() != noOptimization) { | |
5693 // combining the stack slots for intervals where spill move optimization is applied | |
5694 // is not benefitial and would cause problems | |
5695 return; | |
5696 } | |
5697 | |
5698 int begin_pos = cur->from(); | |
5699 int end_pos = cur->to(); | |
5700 if (end_pos > allocator()->max_lir_op_id() || (begin_pos & 1) != 0 || (end_pos & 1) != 0) { | |
5701 // safety check that lir_op_with_id is allowed | |
5702 return; | |
5703 } | |
5704 | |
5705 if (!is_move(allocator()->lir_op_with_id(begin_pos), register_hint, cur) || !is_move(allocator()->lir_op_with_id(end_pos), cur, register_hint)) { | |
5706 // cur and register_hint are not connected with two moves | |
5707 return; | |
5708 } | |
5709 | |
5710 Interval* begin_hint = register_hint->split_child_at_op_id(begin_pos, LIR_OpVisitState::inputMode); | |
5711 Interval* end_hint = register_hint->split_child_at_op_id(end_pos, LIR_OpVisitState::outputMode); | |
5712 if (begin_hint == end_hint || begin_hint->to() != begin_pos || end_hint->from() != end_pos) { | |
5713 // register_hint must be split, otherwise the re-writing of use positions does not work | |
5714 return; | |
5715 } | |
5716 | |
5717 assert(begin_hint->assigned_reg() != any_reg, "must have register assigned"); | |
5718 assert(end_hint->assigned_reg() == any_reg, "must not have register assigned"); | |
5719 assert(cur->first_usage(mustHaveRegister) == begin_pos, "must have use position at begin of interval because of move"); | |
5720 assert(end_hint->first_usage(mustHaveRegister) == end_pos, "must have use position at begin of interval because of move"); | |
5721 | |
5722 if (begin_hint->assigned_reg() < LinearScan::nof_regs) { | |
5723 // register_hint is not spilled at begin_pos, so it would not be benefitial to immediately spill cur | |
5724 return; | |
5725 } | |
5726 assert(register_hint->canonical_spill_slot() != -1, "must be set when part of interval was spilled"); | |
5727 | |
5728 // modify intervals such that cur gets the same stack slot as register_hint | |
5729 // delete use positions to prevent the intervals to get a register at beginning | |
5730 cur->set_canonical_spill_slot(register_hint->canonical_spill_slot()); | |
5731 cur->remove_first_use_pos(); | |
5732 end_hint->remove_first_use_pos(); | |
5733 } | |
5734 | |
5735 | |
5736 // allocate a physical register or memory location to an interval | |
5737 bool LinearScanWalker::activate_current() { | |
5738 Interval* cur = current(); | |
5739 bool result = true; | |
5740 | |
5741 TRACE_LINEAR_SCAN(2, tty->print ("+++++ activating interval "); cur->print()); | |
5742 TRACE_LINEAR_SCAN(4, tty->print_cr(" split_parent: %d, insert_move_when_activated: %d", cur->split_parent()->reg_num(), cur->insert_move_when_activated())); | |
5743 | |
5744 if (cur->assigned_reg() >= LinearScan::nof_regs) { | |
5745 // activating an interval that has a stack slot assigned -> split it at first use position | |
5746 // used for method parameters | |
5747 TRACE_LINEAR_SCAN(4, tty->print_cr(" interval has spill slot assigned (method parameter) -> split it before first use")); | |
5748 | |
5749 split_stack_interval(cur); | |
5750 result = false; | |
5751 | |
5752 } else if (allocator()->gen()->is_vreg_flag_set(cur->reg_num(), LIRGenerator::must_start_in_memory)) { | |
5753 // activating an interval that must start in a stack slot, but may get a register later | |
5754 // used for lir_roundfp: rounding is done by store to stack and reload later | |
5755 TRACE_LINEAR_SCAN(4, tty->print_cr(" interval must start in stack slot -> split it before first use")); | |
5756 assert(cur->assigned_reg() == any_reg && cur->assigned_regHi() == any_reg, "register already assigned"); | |
5757 | |
5758 allocator()->assign_spill_slot(cur); | |
5759 split_stack_interval(cur); | |
5760 result = false; | |
5761 | |
5762 } else if (cur->assigned_reg() == any_reg) { | |
5763 // interval has not assigned register -> normal allocation | |
5764 // (this is the normal case for most intervals) | |
5765 TRACE_LINEAR_SCAN(4, tty->print_cr(" normal allocation of register")); | |
5766 | |
5767 // assign same spill slot to non-intersecting intervals | |
5768 combine_spilled_intervals(cur); | |
5769 | |
5770 init_vars_for_alloc(cur); | |
5771 if (no_allocation_possible(cur) || !alloc_free_reg(cur)) { | |
5772 // no empty register available. | |
5773 // split and spill another interval so that this interval gets a register | |
5774 alloc_locked_reg(cur); | |
5775 } | |
5776 | |
5777 // spilled intervals need not be move to active-list | |
5778 if (cur->assigned_reg() >= LinearScan::nof_regs) { | |
5779 result = false; | |
5780 } | |
5781 } | |
5782 | |
5783 // load spilled values that become active from stack slot to register | |
5784 if (cur->insert_move_when_activated()) { | |
5785 assert(cur->is_split_child(), "must be"); | |
5786 assert(cur->current_split_child() != NULL, "must be"); | |
5787 assert(cur->current_split_child()->reg_num() != cur->reg_num(), "cannot insert move between same interval"); | |
5788 TRACE_LINEAR_SCAN(4, tty->print_cr("Inserting move from interval %d to %d because insert_move_when_activated is set", cur->current_split_child()->reg_num(), cur->reg_num())); | |
5789 | |
5790 insert_move(cur->from(), cur->current_split_child(), cur); | |
5791 } | |
5792 cur->make_current_split_child(); | |
5793 | |
5794 return result; // true = interval is moved to active list | |
5795 } | |
5796 | |
5797 | |
5798 // Implementation of EdgeMoveOptimizer | |
5799 | |
5800 EdgeMoveOptimizer::EdgeMoveOptimizer() : | |
5801 _edge_instructions(4), | |
5802 _edge_instructions_idx(4) | |
5803 { | |
5804 } | |
5805 | |
5806 void EdgeMoveOptimizer::optimize(BlockList* code) { | |
5807 EdgeMoveOptimizer optimizer = EdgeMoveOptimizer(); | |
5808 | |
5809 // ignore the first block in the list (index 0 is not processed) | |
5810 for (int i = code->length() - 1; i >= 1; i--) { | |
5811 BlockBegin* block = code->at(i); | |
5812 | |
5813 if (block->number_of_preds() > 1 && !block->is_set(BlockBegin::exception_entry_flag)) { | |
5814 optimizer.optimize_moves_at_block_end(block); | |
5815 } | |
5816 if (block->number_of_sux() == 2) { | |
5817 optimizer.optimize_moves_at_block_begin(block); | |
5818 } | |
5819 } | |
5820 } | |
5821 | |
5822 | |
5823 // clear all internal data structures | |
5824 void EdgeMoveOptimizer::init_instructions() { | |
5825 _edge_instructions.clear(); | |
5826 _edge_instructions_idx.clear(); | |
5827 } | |
5828 | |
5829 // append a lir-instruction-list and the index of the current operation in to the list | |
5830 void EdgeMoveOptimizer::append_instructions(LIR_OpList* instructions, int instructions_idx) { | |
5831 _edge_instructions.append(instructions); | |
5832 _edge_instructions_idx.append(instructions_idx); | |
5833 } | |
5834 | |
5835 // return the current operation of the given edge (predecessor or successor) | |
5836 LIR_Op* EdgeMoveOptimizer::instruction_at(int edge) { | |
5837 LIR_OpList* instructions = _edge_instructions.at(edge); | |
5838 int idx = _edge_instructions_idx.at(edge); | |
5839 | |
5840 if (idx < instructions->length()) { | |
5841 return instructions->at(idx); | |
5842 } else { | |
5843 return NULL; | |
5844 } | |
5845 } | |
5846 | |
5847 // removes the current operation of the given edge (predecessor or successor) | |
5848 void EdgeMoveOptimizer::remove_cur_instruction(int edge, bool decrement_index) { | |
5849 LIR_OpList* instructions = _edge_instructions.at(edge); | |
5850 int idx = _edge_instructions_idx.at(edge); | |
5851 instructions->remove_at(idx); | |
5852 | |
5853 if (decrement_index) { | |
5854 _edge_instructions_idx.at_put(edge, idx - 1); | |
5855 } | |
5856 } | |
5857 | |
5858 | |
5859 bool EdgeMoveOptimizer::operations_different(LIR_Op* op1, LIR_Op* op2) { | |
5860 if (op1 == NULL || op2 == NULL) { | |
5861 // at least one block is already empty -> no optimization possible | |
5862 return true; | |
5863 } | |
5864 | |
5865 if (op1->code() == lir_move && op2->code() == lir_move) { | |
5866 assert(op1->as_Op1() != NULL, "move must be LIR_Op1"); | |
5867 assert(op2->as_Op1() != NULL, "move must be LIR_Op1"); | |
5868 LIR_Op1* move1 = (LIR_Op1*)op1; | |
5869 LIR_Op1* move2 = (LIR_Op1*)op2; | |
5870 if (move1->info() == move2->info() && move1->in_opr() == move2->in_opr() && move1->result_opr() == move2->result_opr()) { | |
5871 // these moves are exactly equal and can be optimized | |
5872 return false; | |
5873 } | |
5874 | |
5875 } else if (op1->code() == lir_fxch && op2->code() == lir_fxch) { | |
5876 assert(op1->as_Op1() != NULL, "fxch must be LIR_Op1"); | |
5877 assert(op2->as_Op1() != NULL, "fxch must be LIR_Op1"); | |
5878 LIR_Op1* fxch1 = (LIR_Op1*)op1; | |
5879 LIR_Op1* fxch2 = (LIR_Op1*)op2; | |
5880 if (fxch1->in_opr()->as_jint() == fxch2->in_opr()->as_jint()) { | |
5881 // equal FPU stack operations can be optimized | |
5882 return false; | |
5883 } | |
5884 | |
5885 } else if (op1->code() == lir_fpop_raw && op2->code() == lir_fpop_raw) { | |
5886 // equal FPU stack operations can be optimized | |
5887 return false; | |
5888 } | |
5889 | |
5890 // no optimization possible | |
5891 return true; | |
5892 } | |
5893 | |
5894 void EdgeMoveOptimizer::optimize_moves_at_block_end(BlockBegin* block) { | |
5895 TRACE_LINEAR_SCAN(4, tty->print_cr("optimizing moves at end of block B%d", block->block_id())); | |
5896 | |
5897 if (block->is_predecessor(block)) { | |
5898 // currently we can't handle this correctly. | |
5899 return; | |
5900 } | |
5901 | |
5902 init_instructions(); | |
5903 int num_preds = block->number_of_preds(); | |
5904 assert(num_preds > 1, "do not call otherwise"); | |
5905 assert(!block->is_set(BlockBegin::exception_entry_flag), "exception handlers not allowed"); | |
5906 | |
5907 // setup a list with the lir-instructions of all predecessors | |
5908 int i; | |
5909 for (i = 0; i < num_preds; i++) { | |
5910 BlockBegin* pred = block->pred_at(i); | |
5911 LIR_OpList* pred_instructions = pred->lir()->instructions_list(); | |
5912 | |
5913 if (pred->number_of_sux() != 1) { | |
5914 // this can happen with switch-statements where multiple edges are between | |
5915 // the same blocks. | |
5916 return; | |
5917 } | |
5918 | |
5919 assert(pred->number_of_sux() == 1, "can handle only one successor"); | |
5920 assert(pred->sux_at(0) == block, "invalid control flow"); | |
5921 assert(pred_instructions->last()->code() == lir_branch, "block with successor must end with branch"); | |
5922 assert(pred_instructions->last()->as_OpBranch() != NULL, "branch must be LIR_OpBranch"); | |
5923 assert(pred_instructions->last()->as_OpBranch()->cond() == lir_cond_always, "block must end with unconditional branch"); | |
5924 | |
5925 if (pred_instructions->last()->info() != NULL) { | |
5926 // can not optimize instructions when debug info is needed | |
5927 return; | |
5928 } | |
5929 | |
5930 // ignore the unconditional branch at the end of the block | |
5931 append_instructions(pred_instructions, pred_instructions->length() - 2); | |
5932 } | |
5933 | |
5934 | |
5935 // process lir-instructions while all predecessors end with the same instruction | |
5936 while (true) { | |
5937 LIR_Op* op = instruction_at(0); | |
5938 for (i = 1; i < num_preds; i++) { | |
5939 if (operations_different(op, instruction_at(i))) { | |
5940 // these instructions are different and cannot be optimized -> | |
5941 // no further optimization possible | |
5942 return; | |
5943 } | |
5944 } | |
5945 | |
5946 TRACE_LINEAR_SCAN(4, tty->print("found instruction that is equal in all %d predecessors: ", num_preds); op->print()); | |
5947 | |
5948 // insert the instruction at the beginning of the current block | |
5949 block->lir()->insert_before(1, op); | |
5950 | |
5951 // delete the instruction at the end of all predecessors | |
5952 for (i = 0; i < num_preds; i++) { | |
5953 remove_cur_instruction(i, true); | |
5954 } | |
5955 } | |
5956 } | |
5957 | |
5958 | |
5959 void EdgeMoveOptimizer::optimize_moves_at_block_begin(BlockBegin* block) { | |
5960 TRACE_LINEAR_SCAN(4, tty->print_cr("optimization moves at begin of block B%d", block->block_id())); | |
5961 | |
5962 init_instructions(); | |
5963 int num_sux = block->number_of_sux(); | |
5964 | |
5965 LIR_OpList* cur_instructions = block->lir()->instructions_list(); | |
5966 | |
5967 assert(num_sux == 2, "method should not be called otherwise"); | |
5968 assert(cur_instructions->last()->code() == lir_branch, "block with successor must end with branch"); | |
5969 assert(cur_instructions->last()->as_OpBranch() != NULL, "branch must be LIR_OpBranch"); | |
5970 assert(cur_instructions->last()->as_OpBranch()->cond() == lir_cond_always, "block must end with unconditional branch"); | |
5971 | |
5972 if (cur_instructions->last()->info() != NULL) { | |
5973 // can no optimize instructions when debug info is needed | |
5974 return; | |
5975 } | |
5976 | |
5977 LIR_Op* branch = cur_instructions->at(cur_instructions->length() - 2); | |
5978 if (branch->info() != NULL || (branch->code() != lir_branch && branch->code() != lir_cond_float_branch)) { | |
5979 // not a valid case for optimization | |
5980 // currently, only blocks that end with two branches (conditional branch followed | |
5981 // by unconditional branch) are optimized | |
5982 return; | |
5983 } | |
5984 | |
5985 // now it is guaranteed that the block ends with two branch instructions. | |
5986 // the instructions are inserted at the end of the block before these two branches | |
5987 int insert_idx = cur_instructions->length() - 2; | |
5988 | |
5989 int i; | |
5990 #ifdef ASSERT | |
5991 for (i = insert_idx - 1; i >= 0; i--) { | |
5992 LIR_Op* op = cur_instructions->at(i); | |
5993 if ((op->code() == lir_branch || op->code() == lir_cond_float_branch) && ((LIR_OpBranch*)op)->block() != NULL) { | |
5994 assert(false, "block with two successors can have only two branch instructions"); | |
5995 } | |
5996 } | |
5997 #endif | |
5998 | |
5999 // setup a list with the lir-instructions of all successors | |
6000 for (i = 0; i < num_sux; i++) { | |
6001 BlockBegin* sux = block->sux_at(i); | |
6002 LIR_OpList* sux_instructions = sux->lir()->instructions_list(); | |
6003 | |
6004 assert(sux_instructions->at(0)->code() == lir_label, "block must start with label"); | |
6005 | |
6006 if (sux->number_of_preds() != 1) { | |
6007 // this can happen with switch-statements where multiple edges are between | |
6008 // the same blocks. | |
6009 return; | |
6010 } | |
6011 assert(sux->pred_at(0) == block, "invalid control flow"); | |
6012 assert(!sux->is_set(BlockBegin::exception_entry_flag), "exception handlers not allowed"); | |
6013 | |
6014 // ignore the label at the beginning of the block | |
6015 append_instructions(sux_instructions, 1); | |
6016 } | |
6017 | |
6018 // process lir-instructions while all successors begin with the same instruction | |
6019 while (true) { | |
6020 LIR_Op* op = instruction_at(0); | |
6021 for (i = 1; i < num_sux; i++) { | |
6022 if (operations_different(op, instruction_at(i))) { | |
6023 // these instructions are different and cannot be optimized -> | |
6024 // no further optimization possible | |
6025 return; | |
6026 } | |
6027 } | |
6028 | |
6029 TRACE_LINEAR_SCAN(4, tty->print("----- found instruction that is equal in all %d successors: ", num_sux); op->print()); | |
6030 | |
6031 // insert instruction at end of current block | |
6032 block->lir()->insert_before(insert_idx, op); | |
6033 insert_idx++; | |
6034 | |
6035 // delete the instructions at the beginning of all successors | |
6036 for (i = 0; i < num_sux; i++) { | |
6037 remove_cur_instruction(i, false); | |
6038 } | |
6039 } | |
6040 } | |
6041 | |
6042 | |
6043 // Implementation of ControlFlowOptimizer | |
6044 | |
6045 ControlFlowOptimizer::ControlFlowOptimizer() : | |
6046 _original_preds(4) | |
6047 { | |
6048 } | |
6049 | |
6050 void ControlFlowOptimizer::optimize(BlockList* code) { | |
6051 ControlFlowOptimizer optimizer = ControlFlowOptimizer(); | |
6052 | |
6053 // push the OSR entry block to the end so that we're not jumping over it. | |
6054 BlockBegin* osr_entry = code->at(0)->end()->as_Base()->osr_entry(); | |
6055 if (osr_entry) { | |
6056 int index = osr_entry->linear_scan_number(); | |
6057 assert(code->at(index) == osr_entry, "wrong index"); | |
6058 code->remove_at(index); | |
6059 code->append(osr_entry); | |
6060 } | |
6061 | |
6062 optimizer.reorder_short_loops(code); | |
6063 optimizer.delete_empty_blocks(code); | |
6064 optimizer.delete_unnecessary_jumps(code); | |
6065 optimizer.delete_jumps_to_return(code); | |
6066 } | |
6067 | |
6068 void ControlFlowOptimizer::reorder_short_loop(BlockList* code, BlockBegin* header_block, int header_idx) { | |
6069 int i = header_idx + 1; | |
6070 int max_end = MIN2(header_idx + ShortLoopSize, code->length()); | |
6071 while (i < max_end && code->at(i)->loop_depth() >= header_block->loop_depth()) { | |
6072 i++; | |
6073 } | |
6074 | |
6075 if (i == code->length() || code->at(i)->loop_depth() < header_block->loop_depth()) { | |
6076 int end_idx = i - 1; | |
6077 BlockBegin* end_block = code->at(end_idx); | |
6078 | |
6079 if (end_block->number_of_sux() == 1 && end_block->sux_at(0) == header_block) { | |
6080 // short loop from header_idx to end_idx found -> reorder blocks such that | |
6081 // the header_block is the last block instead of the first block of the loop | |
6082 TRACE_LINEAR_SCAN(1, tty->print_cr("Reordering short loop: length %d, header B%d, end B%d", | |
6083 end_idx - header_idx + 1, | |
6084 header_block->block_id(), end_block->block_id())); | |
6085 | |
6086 for (int j = header_idx; j < end_idx; j++) { | |
6087 code->at_put(j, code->at(j + 1)); | |
6088 } | |
6089 code->at_put(end_idx, header_block); | |
6090 | |
6091 // correct the flags so that any loop alignment occurs in the right place. | |
6092 assert(code->at(end_idx)->is_set(BlockBegin::backward_branch_target_flag), "must be backward branch target"); | |
6093 code->at(end_idx)->clear(BlockBegin::backward_branch_target_flag); | |
6094 code->at(header_idx)->set(BlockBegin::backward_branch_target_flag); | |
6095 } | |
6096 } | |
6097 } | |
6098 | |
6099 void ControlFlowOptimizer::reorder_short_loops(BlockList* code) { | |
6100 for (int i = code->length() - 1; i >= 0; i--) { | |
6101 BlockBegin* block = code->at(i); | |
6102 | |
6103 if (block->is_set(BlockBegin::linear_scan_loop_header_flag)) { | |
6104 reorder_short_loop(code, block, i); | |
6105 } | |
6106 } | |
6107 | |
6108 DEBUG_ONLY(verify(code)); | |
6109 } | |
6110 | |
6111 // only blocks with exactly one successor can be deleted. Such blocks | |
6112 // must always end with an unconditional branch to this successor | |
6113 bool ControlFlowOptimizer::can_delete_block(BlockBegin* block) { | |
6114 if (block->number_of_sux() != 1 || block->number_of_exception_handlers() != 0 || block->is_entry_block()) { | |
6115 return false; | |
6116 } | |
6117 | |
6118 LIR_OpList* instructions = block->lir()->instructions_list(); | |
6119 | |
6120 assert(instructions->length() >= 2, "block must have label and branch"); | |
6121 assert(instructions->at(0)->code() == lir_label, "first instruction must always be a label"); | |
6122 assert(instructions->last()->as_OpBranch() != NULL, "last instrcution must always be a branch"); | |
6123 assert(instructions->last()->as_OpBranch()->cond() == lir_cond_always, "branch must be unconditional"); | |
6124 assert(instructions->last()->as_OpBranch()->block() == block->sux_at(0), "branch target must be the successor"); | |
6125 | |
6126 // block must have exactly one successor | |
6127 | |
6128 if (instructions->length() == 2 && instructions->last()->info() == NULL) { | |
6129 return true; | |
6130 } | |
6131 return false; | |
6132 } | |
6133 | |
6134 // substitute branch targets in all branch-instructions of this blocks | |
6135 void ControlFlowOptimizer::substitute_branch_target(BlockBegin* block, BlockBegin* target_from, BlockBegin* target_to) { | |
6136 TRACE_LINEAR_SCAN(3, tty->print_cr("Deleting empty block: substituting from B%d to B%d inside B%d", target_from->block_id(), target_to->block_id(), block->block_id())); | |
6137 | |
6138 LIR_OpList* instructions = block->lir()->instructions_list(); | |
6139 | |
6140 assert(instructions->at(0)->code() == lir_label, "first instruction must always be a label"); | |
6141 for (int i = instructions->length() - 1; i >= 1; i--) { | |
6142 LIR_Op* op = instructions->at(i); | |
6143 | |
6144 if (op->code() == lir_branch || op->code() == lir_cond_float_branch) { | |
6145 assert(op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch"); | |
6146 LIR_OpBranch* branch = (LIR_OpBranch*)op; | |
6147 | |
6148 if (branch->block() == target_from) { | |
6149 branch->change_block(target_to); | |
6150 } | |
6151 if (branch->ublock() == target_from) { | |
6152 branch->change_ublock(target_to); | |
6153 } | |
6154 } | |
6155 } | |
6156 } | |
6157 | |
6158 void ControlFlowOptimizer::delete_empty_blocks(BlockList* code) { | |
6159 int old_pos = 0; | |
6160 int new_pos = 0; | |
6161 int num_blocks = code->length(); | |
6162 | |
6163 while (old_pos < num_blocks) { | |
6164 BlockBegin* block = code->at(old_pos); | |
6165 | |
6166 if (can_delete_block(block)) { | |
6167 BlockBegin* new_target = block->sux_at(0); | |
6168 | |
6169 // propagate backward branch target flag for correct code alignment | |
6170 if (block->is_set(BlockBegin::backward_branch_target_flag)) { | |
6171 new_target->set(BlockBegin::backward_branch_target_flag); | |
6172 } | |
6173 | |
6174 // collect a list with all predecessors that contains each predecessor only once | |
6175 // the predecessors of cur are changed during the substitution, so a copy of the | |
6176 // predecessor list is necessary | |
6177 int j; | |
6178 _original_preds.clear(); | |
6179 for (j = block->number_of_preds() - 1; j >= 0; j--) { | |
6180 BlockBegin* pred = block->pred_at(j); | |
6181 if (_original_preds.index_of(pred) == -1) { | |
6182 _original_preds.append(pred); | |
6183 } | |
6184 } | |
6185 | |
6186 for (j = _original_preds.length() - 1; j >= 0; j--) { | |
6187 BlockBegin* pred = _original_preds.at(j); | |
6188 substitute_branch_target(pred, block, new_target); | |
6189 pred->substitute_sux(block, new_target); | |
6190 } | |
6191 } else { | |
6192 // adjust position of this block in the block list if blocks before | |
6193 // have been deleted | |
6194 if (new_pos != old_pos) { | |
6195 code->at_put(new_pos, code->at(old_pos)); | |
6196 } | |
6197 new_pos++; | |
6198 } | |
6199 old_pos++; | |
6200 } | |
6201 code->truncate(new_pos); | |
6202 | |
6203 DEBUG_ONLY(verify(code)); | |
6204 } | |
6205 | |
6206 void ControlFlowOptimizer::delete_unnecessary_jumps(BlockList* code) { | |
6207 // skip the last block because there a branch is always necessary | |
6208 for (int i = code->length() - 2; i >= 0; i--) { | |
6209 BlockBegin* block = code->at(i); | |
6210 LIR_OpList* instructions = block->lir()->instructions_list(); | |
6211 | |
6212 LIR_Op* last_op = instructions->last(); | |
6213 if (last_op->code() == lir_branch) { | |
6214 assert(last_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch"); | |
6215 LIR_OpBranch* last_branch = (LIR_OpBranch*)last_op; | |
6216 | |
6217 assert(last_branch->block() != NULL, "last branch must always have a block as target"); | |
6218 assert(last_branch->label() == last_branch->block()->label(), "must be equal"); | |
6219 | |
6220 if (last_branch->info() == NULL) { | |
6221 if (last_branch->block() == code->at(i + 1)) { | |
6222 | |
6223 TRACE_LINEAR_SCAN(3, tty->print_cr("Deleting unconditional branch at end of block B%d", block->block_id())); | |
6224 | |
6225 // delete last branch instruction | |
6226 instructions->truncate(instructions->length() - 1); | |
6227 | |
6228 } else { | |
6229 LIR_Op* prev_op = instructions->at(instructions->length() - 2); | |
6230 if (prev_op->code() == lir_branch || prev_op->code() == lir_cond_float_branch) { | |
6231 assert(prev_op->as_OpBranch() != NULL, "branch must be of type LIR_OpBranch"); | |
6232 LIR_OpBranch* prev_branch = (LIR_OpBranch*)prev_op; | |
6233 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
6234 LIR_Op2* prev_cmp = NULL; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
6235 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
6236 for(int j = instructions->length() - 3; j >= 0 && prev_cmp == NULL; j--) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
6237 prev_op = instructions->at(j); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
6238 if(prev_op->code() == lir_cmp) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
6239 assert(prev_op->as_Op2() != NULL, "branch must be of type LIR_Op2"); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
6240 prev_cmp = (LIR_Op2*)prev_op; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
6241 assert(prev_branch->cond() == prev_cmp->condition(), "should be the same"); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
6242 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
6243 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
6244 assert(prev_cmp != NULL, "should have found comp instruction for branch"); |
0 | 6245 if (prev_branch->block() == code->at(i + 1) && prev_branch->info() == NULL) { |
6246 | |
6247 TRACE_LINEAR_SCAN(3, tty->print_cr("Negating conditional branch and deleting unconditional branch at end of block B%d", block->block_id())); | |
6248 | |
6249 // eliminate a conditional branch to the immediate successor | |
6250 prev_branch->change_block(last_branch->block()); | |
6251 prev_branch->negate_cond(); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1584
diff
changeset
|
6252 prev_cmp->set_condition(prev_branch->cond()); |
0 | 6253 instructions->truncate(instructions->length() - 1); |
6254 } | |
6255 } | |
6256 } | |
6257 } | |
6258 } | |
6259 } | |
6260 | |
6261 DEBUG_ONLY(verify(code)); | |
6262 } | |
6263 | |
6264 void ControlFlowOptimizer::delete_jumps_to_return(BlockList* code) { | |
6265 #ifdef ASSERT | |
6266 BitMap return_converted(BlockBegin::number_of_blocks()); | |
6267 return_converted.clear(); | |
6268 #endif | |
6269 | |
6270 for (int i = code->length() - 1; i >= 0; i--) { | |
6271 BlockBegin* block = code->at(i); | |
6272 LIR_OpList* cur_instructions = block->lir()->instructions_list(); | |
6273 LIR_Op* cur_last_op = cur_instructions->last(); | |
6274 | |
6275 assert(cur_instructions->at(0)->code() == lir_label, "first instruction must always be a label"); | |
6276 if (cur_instructions->length() == 2 && cur_last_op->code() == lir_return) { | |
6277 // the block contains only a label and a return | |
6278 // if a predecessor ends with an unconditional jump to this block, then the jump | |
6279 // can be replaced with a return instruction | |
6280 // | |
6281 // Note: the original block with only a return statement cannot be deleted completely | |
6282 // because the predecessors might have other (conditional) jumps to this block | |
6283 // -> this may lead to unnecesary return instructions in the final code | |
6284 | |
6285 assert(cur_last_op->info() == NULL, "return instructions do not have debug information"); | |
6286 assert(block->number_of_sux() == 0 || | |
6287 (return_converted.at(block->block_id()) && block->number_of_sux() == 1), | |
6288 "blocks that end with return must not have successors"); | |
6289 | |
6290 assert(cur_last_op->as_Op1() != NULL, "return must be LIR_Op1"); | |
6291 LIR_Opr return_opr = ((LIR_Op1*)cur_last_op)->in_opr(); | |
6292 | |
6293 for (int j = block->number_of_preds() - 1; j >= 0; j--) { | |
6294 BlockBegin* pred = block->pred_at(j); | |
6295 LIR_OpList* pred_instructions = pred->lir()->instructions_list(); | |
6296 LIR_Op* pred_last_op = pred_instructions->last(); | |
6297 | |
6298 if (pred_last_op->code() == lir_branch) { | |
6299 assert(pred_last_op->as_OpBranch() != NULL, "branch must be LIR_OpBranch"); | |
6300 LIR_OpBranch* pred_last_branch = (LIR_OpBranch*)pred_last_op; | |
6301 | |
6302 if (pred_last_branch->block() == block && pred_last_branch->cond() == lir_cond_always && pred_last_branch->info() == NULL) { | |
6303 // replace the jump to a return with a direct return | |
6304 // Note: currently the edge between the blocks is not deleted | |
6305 pred_instructions->at_put(pred_instructions->length() - 1, new LIR_Op1(lir_return, return_opr)); | |
6306 #ifdef ASSERT | |
6307 return_converted.set_bit(pred->block_id()); | |
6308 #endif | |
6309 } | |
6310 } | |
6311 } | |
6312 } | |
6313 } | |
6314 } | |
6315 | |
6316 | |
6317 #ifdef ASSERT | |
6318 void ControlFlowOptimizer::verify(BlockList* code) { | |
6319 for (int i = 0; i < code->length(); i++) { | |
6320 BlockBegin* block = code->at(i); | |
6321 LIR_OpList* instructions = block->lir()->instructions_list(); | |
6322 | |
6323 int j; | |
6324 for (j = 0; j < instructions->length(); j++) { | |
6325 LIR_OpBranch* op_branch = instructions->at(j)->as_OpBranch(); | |
6326 | |
6327 if (op_branch != NULL) { | |
6328 assert(op_branch->block() == NULL || code->index_of(op_branch->block()) != -1, "branch target not valid"); | |
6329 assert(op_branch->ublock() == NULL || code->index_of(op_branch->ublock()) != -1, "branch target not valid"); | |
6330 } | |
6331 } | |
6332 | |
6333 for (j = 0; j < block->number_of_sux() - 1; j++) { | |
6334 BlockBegin* sux = block->sux_at(j); | |
6335 assert(code->index_of(sux) != -1, "successor not valid"); | |
6336 } | |
6337 | |
6338 for (j = 0; j < block->number_of_preds() - 1; j++) { | |
6339 BlockBegin* pred = block->pred_at(j); | |
6340 assert(code->index_of(pred) != -1, "successor not valid"); | |
6341 } | |
6342 } | |
6343 } | |
6344 #endif | |
6345 | |
6346 | |
6347 #ifndef PRODUCT | |
6348 | |
6349 // Implementation of LinearStatistic | |
6350 | |
6351 const char* LinearScanStatistic::counter_name(int counter_idx) { | |
6352 switch (counter_idx) { | |
6353 case counter_method: return "compiled methods"; | |
6354 case counter_fpu_method: return "methods using fpu"; | |
6355 case counter_loop_method: return "methods with loops"; | |
6356 case counter_exception_method:return "methods with xhandler"; | |
6357 | |
6358 case counter_loop: return "loops"; | |
6359 case counter_block: return "blocks"; | |
6360 case counter_loop_block: return "blocks inside loop"; | |
6361 case counter_exception_block: return "exception handler entries"; | |
6362 case counter_interval: return "intervals"; | |
6363 case counter_fixed_interval: return "fixed intervals"; | |
6364 case counter_range: return "ranges"; | |
6365 case counter_fixed_range: return "fixed ranges"; | |
6366 case counter_use_pos: return "use positions"; | |
6367 case counter_fixed_use_pos: return "fixed use positions"; | |
6368 case counter_spill_slots: return "spill slots"; | |
6369 | |
6370 // counter for classes of lir instructions | |
6371 case counter_instruction: return "total instructions"; | |
6372 case counter_label: return "labels"; | |
6373 case counter_entry: return "method entries"; | |
6374 case counter_return: return "method returns"; | |
6375 case counter_call: return "method calls"; | |
6376 case counter_move: return "moves"; | |
6377 case counter_cmp: return "compare"; | |
6378 case counter_cond_branch: return "conditional branches"; | |
6379 case counter_uncond_branch: return "unconditional branches"; | |
6380 case counter_stub_branch: return "branches to stub"; | |
6381 case counter_alu: return "artithmetic + logic"; | |
6382 case counter_alloc: return "allocations"; | |
6383 case counter_sync: return "synchronisation"; | |
6384 case counter_throw: return "throw"; | |
6385 case counter_unwind: return "unwind"; | |
6386 case counter_typecheck: return "type+null-checks"; | |
6387 case counter_fpu_stack: return "fpu-stack"; | |
6388 case counter_misc_inst: return "other instructions"; | |
6389 case counter_other_inst: return "misc. instructions"; | |
6390 | |
6391 // counter for different types of moves | |
6392 case counter_move_total: return "total moves"; | |
6393 case counter_move_reg_reg: return "register->register"; | |
6394 case counter_move_reg_stack: return "register->stack"; | |
6395 case counter_move_stack_reg: return "stack->register"; | |
6396 case counter_move_stack_stack:return "stack->stack"; | |
6397 case counter_move_reg_mem: return "register->memory"; | |
6398 case counter_move_mem_reg: return "memory->register"; | |
6399 case counter_move_const_any: return "constant->any"; | |
6400 | |
6401 case blank_line_1: return ""; | |
6402 case blank_line_2: return ""; | |
6403 | |
6404 default: ShouldNotReachHere(); return ""; | |
6405 } | |
6406 } | |
6407 | |
6408 LinearScanStatistic::Counter LinearScanStatistic::base_counter(int counter_idx) { | |
6409 if (counter_idx == counter_fpu_method || counter_idx == counter_loop_method || counter_idx == counter_exception_method) { | |
6410 return counter_method; | |
6411 } else if (counter_idx == counter_loop_block || counter_idx == counter_exception_block) { | |
6412 return counter_block; | |
6413 } else if (counter_idx >= counter_instruction && counter_idx <= counter_other_inst) { | |
6414 return counter_instruction; | |
6415 } else if (counter_idx >= counter_move_total && counter_idx <= counter_move_const_any) { | |
6416 return counter_move_total; | |
6417 } | |
6418 return invalid_counter; | |
6419 } | |
6420 | |
6421 LinearScanStatistic::LinearScanStatistic() { | |
6422 for (int i = 0; i < number_of_counters; i++) { | |
6423 _counters_sum[i] = 0; | |
6424 _counters_max[i] = -1; | |
6425 } | |
6426 | |
6427 } | |
6428 | |
6429 // add the method-local numbers to the total sum | |
6430 void LinearScanStatistic::sum_up(LinearScanStatistic &method_statistic) { | |
6431 for (int i = 0; i < number_of_counters; i++) { | |
6432 _counters_sum[i] += method_statistic._counters_sum[i]; | |
6433 _counters_max[i] = MAX2(_counters_max[i], method_statistic._counters_sum[i]); | |
6434 } | |
6435 } | |
6436 | |
6437 void LinearScanStatistic::print(const char* title) { | |
6438 if (CountLinearScan || TraceLinearScanLevel > 0) { | |
6439 tty->cr(); | |
6440 tty->print_cr("***** LinearScan statistic - %s *****", title); | |
6441 | |
6442 for (int i = 0; i < number_of_counters; i++) { | |
6443 if (_counters_sum[i] > 0 || _counters_max[i] >= 0) { | |
6444 tty->print("%25s: %8d", counter_name(i), _counters_sum[i]); | |
6445 | |
6446 if (base_counter(i) != invalid_counter) { | |
6447 tty->print(" (%5.1f%%) ", _counters_sum[i] * 100.0 / _counters_sum[base_counter(i)]); | |
6448 } else { | |
6449 tty->print(" "); | |
6450 } | |
6451 | |
6452 if (_counters_max[i] >= 0) { | |
6453 tty->print("%8d", _counters_max[i]); | |
6454 } | |
6455 } | |
6456 tty->cr(); | |
6457 } | |
6458 } | |
6459 } | |
6460 | |
6461 void LinearScanStatistic::collect(LinearScan* allocator) { | |
6462 inc_counter(counter_method); | |
6463 if (allocator->has_fpu_registers()) { | |
6464 inc_counter(counter_fpu_method); | |
6465 } | |
6466 if (allocator->num_loops() > 0) { | |
6467 inc_counter(counter_loop_method); | |
6468 } | |
6469 inc_counter(counter_loop, allocator->num_loops()); | |
6470 inc_counter(counter_spill_slots, allocator->max_spills()); | |
6471 | |
6472 int i; | |
6473 for (i = 0; i < allocator->interval_count(); i++) { | |
6474 Interval* cur = allocator->interval_at(i); | |
6475 | |
6476 if (cur != NULL) { | |
6477 inc_counter(counter_interval); | |
6478 inc_counter(counter_use_pos, cur->num_use_positions()); | |
6479 if (LinearScan::is_precolored_interval(cur)) { | |
6480 inc_counter(counter_fixed_interval); | |
6481 inc_counter(counter_fixed_use_pos, cur->num_use_positions()); | |
6482 } | |
6483 | |
6484 Range* range = cur->first(); | |
6485 while (range != Range::end()) { | |
6486 inc_counter(counter_range); | |
6487 if (LinearScan::is_precolored_interval(cur)) { | |
6488 inc_counter(counter_fixed_range); | |
6489 } | |
6490 range = range->next(); | |
6491 } | |
6492 } | |
6493 } | |
6494 | |
6495 bool has_xhandlers = false; | |
6496 // Note: only count blocks that are in code-emit order | |
6497 for (i = 0; i < allocator->ir()->code()->length(); i++) { | |
6498 BlockBegin* cur = allocator->ir()->code()->at(i); | |
6499 | |
6500 inc_counter(counter_block); | |
6501 if (cur->loop_depth() > 0) { | |
6502 inc_counter(counter_loop_block); | |
6503 } | |
6504 if (cur->is_set(BlockBegin::exception_entry_flag)) { | |
6505 inc_counter(counter_exception_block); | |
6506 has_xhandlers = true; | |
6507 } | |
6508 | |
6509 LIR_OpList* instructions = cur->lir()->instructions_list(); | |
6510 for (int j = 0; j < instructions->length(); j++) { | |
6511 LIR_Op* op = instructions->at(j); | |
6512 | |
6513 inc_counter(counter_instruction); | |
6514 | |
6515 switch (op->code()) { | |
6516 case lir_label: inc_counter(counter_label); break; | |
6517 case lir_std_entry: | |
6518 case lir_osr_entry: inc_counter(counter_entry); break; | |
6519 case lir_return: inc_counter(counter_return); break; | |
6520 | |
6521 case lir_rtcall: | |
6522 case lir_static_call: | |
6523 case lir_optvirtual_call: | |
6524 case lir_virtual_call: inc_counter(counter_call); break; | |
6525 | |
6526 case lir_move: { | |
6527 inc_counter(counter_move); | |
6528 inc_counter(counter_move_total); | |
6529 | |
6530 LIR_Opr in = op->as_Op1()->in_opr(); | |
6531 LIR_Opr res = op->as_Op1()->result_opr(); | |
6532 if (in->is_register()) { | |
6533 if (res->is_register()) { | |
6534 inc_counter(counter_move_reg_reg); | |
6535 } else if (res->is_stack()) { | |
6536 inc_counter(counter_move_reg_stack); | |
6537 } else if (res->is_address()) { | |
6538 inc_counter(counter_move_reg_mem); | |
6539 } else { | |
6540 ShouldNotReachHere(); | |
6541 } | |
6542 } else if (in->is_stack()) { | |
6543 if (res->is_register()) { | |
6544 inc_counter(counter_move_stack_reg); | |
6545 } else { | |
6546 inc_counter(counter_move_stack_stack); | |
6547 } | |
6548 } else if (in->is_address()) { | |
6549 assert(res->is_register(), "must be"); | |
6550 inc_counter(counter_move_mem_reg); | |
6551 } else if (in->is_constant()) { | |
6552 inc_counter(counter_move_const_any); | |
6553 } else { | |
6554 ShouldNotReachHere(); | |
6555 } | |
6556 break; | |
6557 } | |
6558 | |
6559 case lir_cmp: inc_counter(counter_cmp); break; | |
6560 | |
6561 case lir_branch: | |
6562 case lir_cond_float_branch: { | |
6563 LIR_OpBranch* branch = op->as_OpBranch(); | |
6564 if (branch->block() == NULL) { | |
6565 inc_counter(counter_stub_branch); | |
6566 } else if (branch->cond() == lir_cond_always) { | |
6567 inc_counter(counter_uncond_branch); | |
6568 } else { | |
6569 inc_counter(counter_cond_branch); | |
6570 } | |
6571 break; | |
6572 } | |
6573 | |
6574 case lir_neg: | |
6575 case lir_add: | |
6576 case lir_sub: | |
6577 case lir_mul: | |
6578 case lir_mul_strictfp: | |
6579 case lir_div: | |
6580 case lir_div_strictfp: | |
6581 case lir_rem: | |
6582 case lir_sqrt: | |
6583 case lir_sin: | |
6584 case lir_cos: | |
6585 case lir_abs: | |
6586 case lir_log10: | |
6587 case lir_log: | |
6084
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5906
diff
changeset
|
6588 case lir_pow: |
6759698e3140
7133857: exp() and pow() should use the x87 ISA on x86
roland
parents:
5906
diff
changeset
|
6589 case lir_exp: |
0 | 6590 case lir_logic_and: |
6591 case lir_logic_or: | |
6592 case lir_logic_xor: | |
6593 case lir_shl: | |
6594 case lir_shr: | |
6595 case lir_ushr: inc_counter(counter_alu); break; | |
6596 | |
6597 case lir_alloc_object: | |
6598 case lir_alloc_array: inc_counter(counter_alloc); break; | |
6599 | |
6600 case lir_monaddr: | |
6601 case lir_lock: | |
6602 case lir_unlock: inc_counter(counter_sync); break; | |
6603 | |
6604 case lir_throw: inc_counter(counter_throw); break; | |
6605 | |
6606 case lir_unwind: inc_counter(counter_unwind); break; | |
6607 | |
6608 case lir_null_check: | |
6609 case lir_leal: | |
6610 case lir_instanceof: | |
6611 case lir_checkcast: | |
6612 case lir_store_check: inc_counter(counter_typecheck); break; | |
6613 | |
6614 case lir_fpop_raw: | |
6615 case lir_fxch: | |
6616 case lir_fld: inc_counter(counter_fpu_stack); break; | |
6617 | |
6618 case lir_nop: | |
6619 case lir_push: | |
6620 case lir_pop: | |
6621 case lir_convert: | |
6622 case lir_roundfp: | |
6623 case lir_cmove: inc_counter(counter_misc_inst); break; | |
6624 | |
6625 default: inc_counter(counter_other_inst); break; | |
6626 } | |
6627 } | |
6628 } | |
6629 | |
6630 if (has_xhandlers) { | |
6631 inc_counter(counter_exception_method); | |
6632 } | |
6633 } | |
6634 | |
6635 void LinearScanStatistic::compute(LinearScan* allocator, LinearScanStatistic &global_statistic) { | |
6636 if (CountLinearScan || TraceLinearScanLevel > 0) { | |
6637 | |
6638 LinearScanStatistic local_statistic = LinearScanStatistic(); | |
6639 | |
6640 local_statistic.collect(allocator); | |
6641 global_statistic.sum_up(local_statistic); | |
6642 | |
6643 if (TraceLinearScanLevel > 2) { | |
6644 local_statistic.print("current local statistic"); | |
6645 } | |
6646 } | |
6647 } | |
6648 | |
6649 | |
6650 // Implementation of LinearTimers | |
6651 | |
6652 LinearScanTimers::LinearScanTimers() { | |
6653 for (int i = 0; i < number_of_timers; i++) { | |
6654 timer(i)->reset(); | |
6655 } | |
6656 } | |
6657 | |
6658 const char* LinearScanTimers::timer_name(int idx) { | |
6659 switch (idx) { | |
6660 case timer_do_nothing: return "Nothing (Time Check)"; | |
6661 case timer_number_instructions: return "Number Instructions"; | |
6662 case timer_compute_local_live_sets: return "Local Live Sets"; | |
6663 case timer_compute_global_live_sets: return "Global Live Sets"; | |
6664 case timer_build_intervals: return "Build Intervals"; | |
6665 case timer_sort_intervals_before: return "Sort Intervals Before"; | |
6666 case timer_allocate_registers: return "Allocate Registers"; | |
6667 case timer_resolve_data_flow: return "Resolve Data Flow"; | |
6668 case timer_sort_intervals_after: return "Sort Intervals After"; | |
6669 case timer_eliminate_spill_moves: return "Spill optimization"; | |
6670 case timer_assign_reg_num: return "Assign Reg Num"; | |
6671 case timer_allocate_fpu_stack: return "Allocate FPU Stack"; | |
6672 case timer_optimize_lir: return "Optimize LIR"; | |
6673 default: ShouldNotReachHere(); return ""; | |
6674 } | |
6675 } | |
6676 | |
6677 void LinearScanTimers::begin_method() { | |
6678 if (TimeEachLinearScan) { | |
6679 // reset all timers to measure only current method | |
6680 for (int i = 0; i < number_of_timers; i++) { | |
6681 timer(i)->reset(); | |
6682 } | |
6683 } | |
6684 } | |
6685 | |
6686 void LinearScanTimers::end_method(LinearScan* allocator) { | |
6687 if (TimeEachLinearScan) { | |
6688 | |
6689 double c = timer(timer_do_nothing)->seconds(); | |
6690 double total = 0; | |
6691 for (int i = 1; i < number_of_timers; i++) { | |
6692 total += timer(i)->seconds() - c; | |
6693 } | |
6694 | |
6695 if (total >= 0.0005) { | |
6696 // print all information in one line for automatic processing | |
6697 tty->print("@"); allocator->compilation()->method()->print_name(); | |
6698 | |
6699 tty->print("@ %d ", allocator->compilation()->method()->code_size()); | |
6700 tty->print("@ %d ", allocator->block_at(allocator->block_count() - 1)->last_lir_instruction_id() / 2); | |
6701 tty->print("@ %d ", allocator->block_count()); | |
6702 tty->print("@ %d ", allocator->num_virtual_regs()); | |
6703 tty->print("@ %d ", allocator->interval_count()); | |
6704 tty->print("@ %d ", allocator->_num_calls); | |
6705 tty->print("@ %d ", allocator->num_loops()); | |
6706 | |
6707 tty->print("@ %6.6f ", total); | |
6708 for (int i = 1; i < number_of_timers; i++) { | |
6709 tty->print("@ %4.1f ", ((timer(i)->seconds() - c) / total) * 100); | |
6710 } | |
6711 tty->cr(); | |
6712 } | |
6713 } | |
6714 } | |
6715 | |
6716 void LinearScanTimers::print(double total_time) { | |
6717 if (TimeLinearScan) { | |
6718 // correction value: sum of dummy-timer that only measures the time that | |
6719 // is necesary to start and stop itself | |
6720 double c = timer(timer_do_nothing)->seconds(); | |
6721 | |
6722 for (int i = 0; i < number_of_timers; i++) { | |
6723 double t = timer(i)->seconds(); | |
6724 tty->print_cr(" %25s: %6.3f s (%4.1f%%) corrected: %6.3f s (%4.1f%%)", timer_name(i), t, (t / total_time) * 100.0, t - c, (t - c) / (total_time - 2 * number_of_timers * c) * 100); | |
6725 } | |
6726 } | |
6727 } | |
6728 | |
6729 #endif // #ifndef PRODUCT |