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