Mercurial > hg > truffle
comparison src/share/vm/opto/output.cpp @ 12071:adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
Summary: public methods that don't need to be public should be private.
Reviewed-by: kvn, twisti
author | adlertz |
---|---|
date | Fri, 16 Aug 2013 10:23:55 +0200 |
parents | d1034bd8cefc |
children | 766fac3395d6 e2722a66aba7 |
comparison
equal
deleted
inserted
replaced
12070:afbe18ae0905 | 12071:adb9a7d94cb5 |
---|---|
52 #endif | 52 #endif |
53 | 53 |
54 extern int emit_exception_handler(CodeBuffer &cbuf); | 54 extern int emit_exception_handler(CodeBuffer &cbuf); |
55 extern int emit_deopt_handler(CodeBuffer &cbuf); | 55 extern int emit_deopt_handler(CodeBuffer &cbuf); |
56 | 56 |
57 //------------------------------Output----------------------------------------- | |
58 // Convert Nodes to instruction bits and pass off to the VM | 57 // Convert Nodes to instruction bits and pass off to the VM |
59 void Compile::Output() { | 58 void Compile::Output() { |
60 // RootNode goes | 59 // RootNode goes |
61 assert( _cfg->_broot->_nodes.size() == 0, "" ); | 60 assert( _cfg->get_root_block()->_nodes.size() == 0, "" ); |
62 | 61 |
63 // The number of new nodes (mostly MachNop) is proportional to | 62 // The number of new nodes (mostly MachNop) is proportional to |
64 // the number of java calls and inner loops which are aligned. | 63 // the number of java calls and inner loops which are aligned. |
65 if ( C->check_node_count((NodeLimitFudgeFactor + C->java_calls()*3 + | 64 if ( C->check_node_count((NodeLimitFudgeFactor + C->java_calls()*3 + |
66 C->inner_loops()*(OptoLoopAlignment-1)), | 65 C->inner_loops()*(OptoLoopAlignment-1)), |
67 "out of nodes before code generation" ) ) { | 66 "out of nodes before code generation" ) ) { |
68 return; | 67 return; |
69 } | 68 } |
70 // Make sure I can find the Start Node | 69 // Make sure I can find the Start Node |
71 Block *entry = _cfg->_blocks[1]; | 70 Block *entry = _cfg->get_block(1); |
72 Block *broot = _cfg->_broot; | 71 Block *broot = _cfg->get_root_block(); |
73 | 72 |
74 const StartNode *start = entry->_nodes[0]->as_Start(); | 73 const StartNode *start = entry->_nodes[0]->as_Start(); |
75 | 74 |
76 // Replace StartNode with prolog | 75 // Replace StartNode with prolog |
77 MachPrologNode *prolog = new (this) MachPrologNode(); | 76 MachPrologNode *prolog = new (this) MachPrologNode(); |
107 // runtime stubs or frame converters | 106 // runtime stubs or frame converters |
108 _cfg->insert( entry, 1, new (this) MachBreakpointNode() ); | 107 _cfg->insert( entry, 1, new (this) MachBreakpointNode() ); |
109 } | 108 } |
110 | 109 |
111 // Insert epilogs before every return | 110 // Insert epilogs before every return |
112 for( uint i=0; i<_cfg->_num_blocks; i++ ) { | 111 for (uint i = 0; i < _cfg->number_of_blocks(); i++) { |
113 Block *b = _cfg->_blocks[i]; | 112 Block* block = _cfg->get_block(i); |
114 if( !b->is_connector() && b->non_connector_successor(0) == _cfg->_broot ) { // Found a program exit point? | 113 if (!block->is_connector() && block->non_connector_successor(0) == _cfg->get_root_block()) { // Found a program exit point? |
115 Node *m = b->end(); | 114 Node* m = block->end(); |
116 if( m->is_Mach() && m->as_Mach()->ideal_Opcode() != Op_Halt ) { | 115 if (m->is_Mach() && m->as_Mach()->ideal_Opcode() != Op_Halt) { |
117 MachEpilogNode *epilog = new (this) MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return); | 116 MachEpilogNode* epilog = new (this) MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return); |
118 b->add_inst( epilog ); | 117 block->add_inst(epilog); |
119 _cfg->map_node_to_block(epilog, b); | 118 _cfg->map_node_to_block(epilog, block); |
120 } | 119 } |
121 } | 120 } |
122 } | 121 } |
123 | 122 |
124 # ifdef ENABLE_ZAP_DEAD_LOCALS | 123 # ifdef ENABLE_ZAP_DEAD_LOCALS |
125 if ( ZapDeadCompiledLocals ) Insert_zap_nodes(); | 124 if (ZapDeadCompiledLocals) { |
125 Insert_zap_nodes(); | |
126 } | |
126 # endif | 127 # endif |
127 | 128 |
128 uint* blk_starts = NEW_RESOURCE_ARRAY(uint,_cfg->_num_blocks+1); | 129 uint* blk_starts = NEW_RESOURCE_ARRAY(uint, _cfg->number_of_blocks() + 1); |
129 blk_starts[0] = 0; | 130 blk_starts[0] = 0; |
130 | 131 |
131 // Initialize code buffer and process short branches. | 132 // Initialize code buffer and process short branches. |
132 CodeBuffer* cb = init_buffer(blk_starts); | 133 CodeBuffer* cb = init_buffer(blk_starts); |
133 | 134 |
134 if (cb == NULL || failing()) return; | 135 if (cb == NULL || failing()) { |
136 return; | |
137 } | |
135 | 138 |
136 ScheduleAndBundle(); | 139 ScheduleAndBundle(); |
137 | 140 |
138 #ifndef PRODUCT | 141 #ifndef PRODUCT |
139 if (trace_opto_output()) { | 142 if (trace_opto_output()) { |
140 tty->print("\n---- After ScheduleAndBundle ----\n"); | 143 tty->print("\n---- After ScheduleAndBundle ----\n"); |
141 for (uint i = 0; i < _cfg->_num_blocks; i++) { | 144 for (uint i = 0; i < _cfg->number_of_blocks(); i++) { |
142 tty->print("\nBB#%03d:\n", i); | 145 tty->print("\nBB#%03d:\n", i); |
143 Block *bb = _cfg->_blocks[i]; | 146 Block* block = _cfg->get_block(i); |
144 for (uint j = 0; j < bb->_nodes.size(); j++) { | 147 for (uint j = 0; j < block->_nodes.size(); j++) { |
145 Node *n = bb->_nodes[j]; | 148 Node* n = block->_nodes[j]; |
146 OptoReg::Name reg = _regalloc->get_reg_first(n); | 149 OptoReg::Name reg = _regalloc->get_reg_first(n); |
147 tty->print(" %-6s ", reg >= 0 && reg < REG_COUNT ? Matcher::regName[reg] : ""); | 150 tty->print(" %-6s ", reg >= 0 && reg < REG_COUNT ? Matcher::regName[reg] : ""); |
148 n->dump(); | 151 n->dump(); |
149 } | 152 } |
150 } | 153 } |
151 } | 154 } |
152 #endif | 155 #endif |
153 | 156 |
154 if (failing()) return; | 157 if (failing()) { |
158 return; | |
159 } | |
155 | 160 |
156 BuildOopMaps(); | 161 BuildOopMaps(); |
157 | 162 |
158 if (failing()) return; | 163 if (failing()) { |
164 return; | |
165 } | |
159 | 166 |
160 fill_buffer(cb, blk_starts); | 167 fill_buffer(cb, blk_starts); |
161 } | 168 } |
162 | 169 |
163 bool Compile::need_stack_bang(int frame_size_in_bytes) const { | 170 bool Compile::need_stack_bang(int frame_size_in_bytes) const { |
215 | 222 |
216 if ( _method == NULL ) | 223 if ( _method == NULL ) |
217 return; // no safepoints/oopmaps emitted for calls in stubs,so we don't care | 224 return; // no safepoints/oopmaps emitted for calls in stubs,so we don't care |
218 | 225 |
219 // Insert call to zap runtime stub before every node with an oop map | 226 // Insert call to zap runtime stub before every node with an oop map |
220 for( uint i=0; i<_cfg->_num_blocks; i++ ) { | 227 for( uint i=0; i<_cfg->number_of_blocks(); i++ ) { |
221 Block *b = _cfg->_blocks[i]; | 228 Block *b = _cfg->get_block(i); |
222 for ( uint j = 0; j < b->_nodes.size(); ++j ) { | 229 for ( uint j = 0; j < b->_nodes.size(); ++j ) { |
223 Node *n = b->_nodes[j]; | 230 Node *n = b->_nodes[j]; |
224 | 231 |
225 // Determining if we should insert a zap-a-lot node in output. | 232 // Determining if we should insert a zap-a-lot node in output. |
226 // We do that for all nodes that has oopmap info, except for calls | 233 // We do that for all nodes that has oopmap info, except for calls |
273 // Add the cloned OopMap to the zap node | 280 // Add the cloned OopMap to the zap node |
274 ideal_node->set_oop_map(clone); | 281 ideal_node->set_oop_map(clone); |
275 return _matcher->match_sfpt(ideal_node); | 282 return _matcher->match_sfpt(ideal_node); |
276 } | 283 } |
277 | 284 |
278 //------------------------------is_node_getting_a_safepoint-------------------- | |
279 bool Compile::is_node_getting_a_safepoint( Node* n) { | 285 bool Compile::is_node_getting_a_safepoint( Node* n) { |
280 // This code duplicates the logic prior to the call of add_safepoint | 286 // This code duplicates the logic prior to the call of add_safepoint |
281 // below in this file. | 287 // below in this file. |
282 if( n->is_MachSafePoint() ) return true; | 288 if( n->is_MachSafePoint() ) return true; |
283 return false; | 289 return false; |
284 } | 290 } |
285 | 291 |
286 # endif // ENABLE_ZAP_DEAD_LOCALS | 292 # endif // ENABLE_ZAP_DEAD_LOCALS |
287 | 293 |
288 //------------------------------compute_loop_first_inst_sizes------------------ | |
289 // Compute the size of first NumberOfLoopInstrToAlign instructions at the top | 294 // Compute the size of first NumberOfLoopInstrToAlign instructions at the top |
290 // of a loop. When aligning a loop we need to provide enough instructions | 295 // of a loop. When aligning a loop we need to provide enough instructions |
291 // in cpu's fetch buffer to feed decoders. The loop alignment could be | 296 // in cpu's fetch buffer to feed decoders. The loop alignment could be |
292 // avoided if we have enough instructions in fetch buffer at the head of a loop. | 297 // avoided if we have enough instructions in fetch buffer at the head of a loop. |
293 // By default, the size is set to 999999 by Block's constructor so that | 298 // By default, the size is set to 999999 by Block's constructor so that |
300 // The next condition is used to gate the loop alignment optimization. | 305 // The next condition is used to gate the loop alignment optimization. |
301 // Don't aligned a loop if there are enough instructions at the head of a loop | 306 // Don't aligned a loop if there are enough instructions at the head of a loop |
302 // or alignment padding is larger then MaxLoopPad. By default, MaxLoopPad | 307 // or alignment padding is larger then MaxLoopPad. By default, MaxLoopPad |
303 // is equal to OptoLoopAlignment-1 except on new Intel cpus, where it is | 308 // is equal to OptoLoopAlignment-1 except on new Intel cpus, where it is |
304 // equal to 11 bytes which is the largest address NOP instruction. | 309 // equal to 11 bytes which is the largest address NOP instruction. |
305 if( MaxLoopPad < OptoLoopAlignment-1 ) { | 310 if (MaxLoopPad < OptoLoopAlignment - 1) { |
306 uint last_block = _cfg->_num_blocks-1; | 311 uint last_block = _cfg->number_of_blocks() - 1; |
307 for( uint i=1; i <= last_block; i++ ) { | 312 for (uint i = 1; i <= last_block; i++) { |
308 Block *b = _cfg->_blocks[i]; | 313 Block* block = _cfg->get_block(i); |
309 // Check the first loop's block which requires an alignment. | 314 // Check the first loop's block which requires an alignment. |
310 if( b->loop_alignment() > (uint)relocInfo::addr_unit() ) { | 315 if (block->loop_alignment() > (uint)relocInfo::addr_unit()) { |
311 uint sum_size = 0; | 316 uint sum_size = 0; |
312 uint inst_cnt = NumberOfLoopInstrToAlign; | 317 uint inst_cnt = NumberOfLoopInstrToAlign; |
313 inst_cnt = b->compute_first_inst_size(sum_size, inst_cnt, _regalloc); | 318 inst_cnt = block->compute_first_inst_size(sum_size, inst_cnt, _regalloc); |
314 | 319 |
315 // Check subsequent fallthrough blocks if the loop's first | 320 // Check subsequent fallthrough blocks if the loop's first |
316 // block(s) does not have enough instructions. | 321 // block(s) does not have enough instructions. |
317 Block *nb = b; | 322 Block *nb = block; |
318 while( inst_cnt > 0 && | 323 while(inst_cnt > 0 && |
319 i < last_block && | 324 i < last_block && |
320 !_cfg->_blocks[i+1]->has_loop_alignment() && | 325 !_cfg->get_block(i + 1)->has_loop_alignment() && |
321 !nb->has_successor(b) ) { | 326 !nb->has_successor(block)) { |
322 i++; | 327 i++; |
323 nb = _cfg->_blocks[i]; | 328 nb = _cfg->get_block(i); |
324 inst_cnt = nb->compute_first_inst_size(sum_size, inst_cnt, _regalloc); | 329 inst_cnt = nb->compute_first_inst_size(sum_size, inst_cnt, _regalloc); |
325 } // while( inst_cnt > 0 && i < last_block ) | 330 } // while( inst_cnt > 0 && i < last_block ) |
326 | 331 |
327 b->set_first_inst_size(sum_size); | 332 block->set_first_inst_size(sum_size); |
328 } // f( b->head()->is_Loop() ) | 333 } // f( b->head()->is_Loop() ) |
329 } // for( i <= last_block ) | 334 } // for( i <= last_block ) |
330 } // if( MaxLoopPad < OptoLoopAlignment-1 ) | 335 } // if( MaxLoopPad < OptoLoopAlignment-1 ) |
331 } | 336 } |
332 | 337 |
333 //----------------------shorten_branches--------------------------------------- | |
334 // The architecture description provides short branch variants for some long | 338 // The architecture description provides short branch variants for some long |
335 // branch instructions. Replace eligible long branches with short branches. | 339 // branch instructions. Replace eligible long branches with short branches. |
336 void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size, int& stub_size) { | 340 void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size, int& stub_size) { |
337 | |
338 // ------------------ | |
339 // Compute size of each block, method size, and relocation information size | 341 // Compute size of each block, method size, and relocation information size |
340 uint nblocks = _cfg->_num_blocks; | 342 uint nblocks = _cfg->number_of_blocks(); |
341 | 343 |
342 uint* jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks); | 344 uint* jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks); |
343 uint* jmp_size = NEW_RESOURCE_ARRAY(uint,nblocks); | 345 uint* jmp_size = NEW_RESOURCE_ARRAY(uint,nblocks); |
344 int* jmp_nidx = NEW_RESOURCE_ARRAY(int ,nblocks); | 346 int* jmp_nidx = NEW_RESOURCE_ARRAY(int ,nblocks); |
345 DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,nblocks); ) | 347 DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,nblocks); ) |
362 // Step one, perform a pessimistic sizing pass. | 364 // Step one, perform a pessimistic sizing pass. |
363 uint last_call_adr = max_uint; | 365 uint last_call_adr = max_uint; |
364 uint last_avoid_back_to_back_adr = max_uint; | 366 uint last_avoid_back_to_back_adr = max_uint; |
365 uint nop_size = (new (this) MachNopNode())->size(_regalloc); | 367 uint nop_size = (new (this) MachNopNode())->size(_regalloc); |
366 for (uint i = 0; i < nblocks; i++) { // For all blocks | 368 for (uint i = 0; i < nblocks; i++) { // For all blocks |
367 Block *b = _cfg->_blocks[i]; | 369 Block* block = _cfg->get_block(i); |
368 | 370 |
369 // During short branch replacement, we store the relative (to blk_starts) | 371 // During short branch replacement, we store the relative (to blk_starts) |
370 // offset of jump in jmp_offset, rather than the absolute offset of jump. | 372 // offset of jump in jmp_offset, rather than the absolute offset of jump. |
371 // This is so that we do not need to recompute sizes of all nodes when | 373 // This is so that we do not need to recompute sizes of all nodes when |
372 // we compute correct blk_starts in our next sizing pass. | 374 // we compute correct blk_starts in our next sizing pass. |
375 jmp_nidx[i] = -1; | 377 jmp_nidx[i] = -1; |
376 DEBUG_ONLY( jmp_target[i] = 0; ) | 378 DEBUG_ONLY( jmp_target[i] = 0; ) |
377 DEBUG_ONLY( jmp_rule[i] = 0; ) | 379 DEBUG_ONLY( jmp_rule[i] = 0; ) |
378 | 380 |
379 // Sum all instruction sizes to compute block size | 381 // Sum all instruction sizes to compute block size |
380 uint last_inst = b->_nodes.size(); | 382 uint last_inst = block->_nodes.size(); |
381 uint blk_size = 0; | 383 uint blk_size = 0; |
382 for (uint j = 0; j < last_inst; j++) { | 384 for (uint j = 0; j < last_inst; j++) { |
383 Node* nj = b->_nodes[j]; | 385 Node* nj = block->_nodes[j]; |
384 // Handle machine instruction nodes | 386 // Handle machine instruction nodes |
385 if (nj->is_Mach()) { | 387 if (nj->is_Mach()) { |
386 MachNode *mach = nj->as_Mach(); | 388 MachNode *mach = nj->as_Mach(); |
387 blk_size += (mach->alignment_required() - 1) * relocInfo::addr_unit(); // assume worst case padding | 389 blk_size += (mach->alignment_required() - 1) * relocInfo::addr_unit(); // assume worst case padding |
388 reloc_size += mach->reloc(); | 390 reloc_size += mach->reloc(); |
439 } | 441 } |
440 | 442 |
441 // When the next block starts a loop, we may insert pad NOP | 443 // When the next block starts a loop, we may insert pad NOP |
442 // instructions. Since we cannot know our future alignment, | 444 // instructions. Since we cannot know our future alignment, |
443 // assume the worst. | 445 // assume the worst. |
444 if (i< nblocks-1) { | 446 if (i < nblocks - 1) { |
445 Block *nb = _cfg->_blocks[i+1]; | 447 Block* nb = _cfg->get_block(i + 1); |
446 int max_loop_pad = nb->code_alignment()-relocInfo::addr_unit(); | 448 int max_loop_pad = nb->code_alignment()-relocInfo::addr_unit(); |
447 if (max_loop_pad > 0) { | 449 if (max_loop_pad > 0) { |
448 assert(is_power_of_2(max_loop_pad+relocInfo::addr_unit()), ""); | 450 assert(is_power_of_2(max_loop_pad+relocInfo::addr_unit()), ""); |
449 // Adjust last_call_adr and/or last_avoid_back_to_back_adr. | 451 // Adjust last_call_adr and/or last_avoid_back_to_back_adr. |
450 // If either is the last instruction in this block, bump by | 452 // If either is the last instruction in this block, bump by |
471 while (has_short_branch_candidate && progress) { | 473 while (has_short_branch_candidate && progress) { |
472 progress = false; | 474 progress = false; |
473 has_short_branch_candidate = false; | 475 has_short_branch_candidate = false; |
474 int adjust_block_start = 0; | 476 int adjust_block_start = 0; |
475 for (uint i = 0; i < nblocks; i++) { | 477 for (uint i = 0; i < nblocks; i++) { |
476 Block *b = _cfg->_blocks[i]; | 478 Block* block = _cfg->get_block(i); |
477 int idx = jmp_nidx[i]; | 479 int idx = jmp_nidx[i]; |
478 MachNode* mach = (idx == -1) ? NULL: b->_nodes[idx]->as_Mach(); | 480 MachNode* mach = (idx == -1) ? NULL: block->_nodes[idx]->as_Mach(); |
479 if (mach != NULL && mach->may_be_short_branch()) { | 481 if (mach != NULL && mach->may_be_short_branch()) { |
480 #ifdef ASSERT | 482 #ifdef ASSERT |
481 assert(jmp_size[i] > 0 && mach->is_MachBranch(), "sanity"); | 483 assert(jmp_size[i] > 0 && mach->is_MachBranch(), "sanity"); |
482 int j; | 484 int j; |
483 // Find the branch; ignore trailing NOPs. | 485 // Find the branch; ignore trailing NOPs. |
484 for (j = b->_nodes.size()-1; j>=0; j--) { | 486 for (j = block->_nodes.size()-1; j>=0; j--) { |
485 Node* n = b->_nodes[j]; | 487 Node* n = block->_nodes[j]; |
486 if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con) | 488 if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con) |
487 break; | 489 break; |
488 } | 490 } |
489 assert(j >= 0 && j == idx && b->_nodes[j] == (Node*)mach, "sanity"); | 491 assert(j >= 0 && j == idx && block->_nodes[j] == (Node*)mach, "sanity"); |
490 #endif | 492 #endif |
491 int br_size = jmp_size[i]; | 493 int br_size = jmp_size[i]; |
492 int br_offs = blk_starts[i] + jmp_offset[i]; | 494 int br_offs = blk_starts[i] + jmp_offset[i]; |
493 | 495 |
494 // This requires the TRUE branch target be in succs[0] | 496 // This requires the TRUE branch target be in succs[0] |
495 uint bnum = b->non_connector_successor(0)->_pre_order; | 497 uint bnum = block->non_connector_successor(0)->_pre_order; |
496 int offset = blk_starts[bnum] - br_offs; | 498 int offset = blk_starts[bnum] - br_offs; |
497 if (bnum > i) { // adjust following block's offset | 499 if (bnum > i) { // adjust following block's offset |
498 offset -= adjust_block_start; | 500 offset -= adjust_block_start; |
499 } | 501 } |
500 // In the following code a nop could be inserted before | 502 // In the following code a nop could be inserted before |
518 if (needs_padding && replacement->avoid_back_to_back()) { | 520 if (needs_padding && replacement->avoid_back_to_back()) { |
519 jmp_offset[i] += nop_size; | 521 jmp_offset[i] += nop_size; |
520 diff -= nop_size; | 522 diff -= nop_size; |
521 } | 523 } |
522 adjust_block_start += diff; | 524 adjust_block_start += diff; |
523 b->_nodes.map(idx, replacement); | 525 block->_nodes.map(idx, replacement); |
524 mach->subsume_by(replacement, C); | 526 mach->subsume_by(replacement, C); |
525 mach = replacement; | 527 mach = replacement; |
526 progress = true; | 528 progress = true; |
527 | 529 |
528 jmp_size[i] = new_size; | 530 jmp_size[i] = new_size; |
1081 assert(_frame_slots >= 0 && _frame_slots < 1000000, "sanity check"); | 1083 assert(_frame_slots >= 0 && _frame_slots < 1000000, "sanity check"); |
1082 | 1084 |
1083 if (has_mach_constant_base_node()) { | 1085 if (has_mach_constant_base_node()) { |
1084 // Fill the constant table. | 1086 // Fill the constant table. |
1085 // Note: This must happen before shorten_branches. | 1087 // Note: This must happen before shorten_branches. |
1086 for (uint i = 0; i < _cfg->_num_blocks; i++) { | 1088 for (uint i = 0; i < _cfg->number_of_blocks(); i++) { |
1087 Block* b = _cfg->_blocks[i]; | 1089 Block* b = _cfg->get_block(i); |
1088 | 1090 |
1089 for (uint j = 0; j < b->_nodes.size(); j++) { | 1091 for (uint j = 0; j < b->_nodes.size(); j++) { |
1090 Node* n = b->_nodes[j]; | 1092 Node* n = b->_nodes[j]; |
1091 | 1093 |
1092 // If the node is a MachConstantNode evaluate the constant | 1094 // If the node is a MachConstantNode evaluate the constant |
1168 _oop_map_set = new OopMapSet(); | 1170 _oop_map_set = new OopMapSet(); |
1169 | 1171 |
1170 // !!!!! This preserves old handling of oopmaps for now | 1172 // !!!!! This preserves old handling of oopmaps for now |
1171 debug_info()->set_oopmaps(_oop_map_set); | 1173 debug_info()->set_oopmaps(_oop_map_set); |
1172 | 1174 |
1173 uint nblocks = _cfg->_num_blocks; | 1175 uint nblocks = _cfg->number_of_blocks(); |
1174 // Count and start of implicit null check instructions | 1176 // Count and start of implicit null check instructions |
1175 uint inct_cnt = 0; | 1177 uint inct_cnt = 0; |
1176 uint *inct_starts = NEW_RESOURCE_ARRAY(uint, nblocks+1); | 1178 uint *inct_starts = NEW_RESOURCE_ARRAY(uint, nblocks+1); |
1177 | 1179 |
1178 // Count and start of calls | 1180 // Count and start of calls |
1216 | 1218 |
1217 // ------------------ | 1219 // ------------------ |
1218 // Now fill in the code buffer | 1220 // Now fill in the code buffer |
1219 Node *delay_slot = NULL; | 1221 Node *delay_slot = NULL; |
1220 | 1222 |
1221 for (uint i=0; i < nblocks; i++) { | 1223 for (uint i = 0; i < nblocks; i++) { |
1222 Block *b = _cfg->_blocks[i]; | 1224 Block* block = _cfg->get_block(i); |
1223 | 1225 Node* head = block->head(); |
1224 Node *head = b->head(); | |
1225 | 1226 |
1226 // If this block needs to start aligned (i.e, can be reached other | 1227 // If this block needs to start aligned (i.e, can be reached other |
1227 // than by falling-thru from the previous block), then force the | 1228 // than by falling-thru from the previous block), then force the |
1228 // start of a new bundle. | 1229 // start of a new bundle. |
1229 if (Pipeline::requires_bundling() && starts_bundle(head)) | 1230 if (Pipeline::requires_bundling() && starts_bundle(head)) { |
1230 cb->flush_bundle(true); | 1231 cb->flush_bundle(true); |
1232 } | |
1231 | 1233 |
1232 #ifdef ASSERT | 1234 #ifdef ASSERT |
1233 if (!b->is_connector()) { | 1235 if (!block->is_connector()) { |
1234 stringStream st; | 1236 stringStream st; |
1235 b->dump_head(_cfg, &st); | 1237 block->dump_head(_cfg, &st); |
1236 MacroAssembler(cb).block_comment(st.as_string()); | 1238 MacroAssembler(cb).block_comment(st.as_string()); |
1237 } | 1239 } |
1238 jmp_target[i] = 0; | 1240 jmp_target[i] = 0; |
1239 jmp_offset[i] = 0; | 1241 jmp_offset[i] = 0; |
1240 jmp_size[i] = 0; | 1242 jmp_size[i] = 0; |
1241 jmp_rule[i] = 0; | 1243 jmp_rule[i] = 0; |
1242 #endif | 1244 #endif |
1243 int blk_offset = current_offset; | 1245 int blk_offset = current_offset; |
1244 | 1246 |
1245 // Define the label at the beginning of the basic block | 1247 // Define the label at the beginning of the basic block |
1246 MacroAssembler(cb).bind(blk_labels[b->_pre_order]); | 1248 MacroAssembler(cb).bind(blk_labels[block->_pre_order]); |
1247 | 1249 |
1248 uint last_inst = b->_nodes.size(); | 1250 uint last_inst = block->_nodes.size(); |
1249 | 1251 |
1250 // Emit block normally, except for last instruction. | 1252 // Emit block normally, except for last instruction. |
1251 // Emit means "dump code bits into code buffer". | 1253 // Emit means "dump code bits into code buffer". |
1252 for (uint j = 0; j<last_inst; j++) { | 1254 for (uint j = 0; j<last_inst; j++) { |
1253 | 1255 |
1254 // Get the node | 1256 // Get the node |
1255 Node* n = b->_nodes[j]; | 1257 Node* n = block->_nodes[j]; |
1256 | 1258 |
1257 // See if delay slots are supported | 1259 // See if delay slots are supported |
1258 if (valid_bundle_info(n) && | 1260 if (valid_bundle_info(n) && |
1259 node_bundling(n)->used_in_unconditional_delay()) { | 1261 node_bundling(n)->used_in_unconditional_delay()) { |
1260 assert(delay_slot == NULL, "no use of delay slot node"); | 1262 assert(delay_slot == NULL, "no use of delay slot node"); |
1304 | 1306 |
1305 if(padding > 0) { | 1307 if(padding > 0) { |
1306 assert((padding % nop_size) == 0, "padding is not a multiple of NOP size"); | 1308 assert((padding % nop_size) == 0, "padding is not a multiple of NOP size"); |
1307 int nops_cnt = padding / nop_size; | 1309 int nops_cnt = padding / nop_size; |
1308 MachNode *nop = new (this) MachNopNode(nops_cnt); | 1310 MachNode *nop = new (this) MachNopNode(nops_cnt); |
1309 b->_nodes.insert(j++, nop); | 1311 block->_nodes.insert(j++, nop); |
1310 last_inst++; | 1312 last_inst++; |
1311 _cfg->map_node_to_block(nop, b); | 1313 _cfg->map_node_to_block(nop, block); |
1312 nop->emit(*cb, _regalloc); | 1314 nop->emit(*cb, _regalloc); |
1313 cb->flush_bundle(true); | 1315 cb->flush_bundle(true); |
1314 current_offset = cb->insts_size(); | 1316 current_offset = cb->insts_size(); |
1315 } | 1317 } |
1316 | 1318 |
1320 | 1322 |
1321 // This destination address is NOT PC-relative | 1323 // This destination address is NOT PC-relative |
1322 mcall->method_set((intptr_t)mcall->entry_point()); | 1324 mcall->method_set((intptr_t)mcall->entry_point()); |
1323 | 1325 |
1324 // Save the return address | 1326 // Save the return address |
1325 call_returns[b->_pre_order] = current_offset + mcall->ret_addr_offset(); | 1327 call_returns[block->_pre_order] = current_offset + mcall->ret_addr_offset(); |
1326 | 1328 |
1327 if (mcall->is_MachCallLeaf()) { | 1329 if (mcall->is_MachCallLeaf()) { |
1328 is_mcall = false; | 1330 is_mcall = false; |
1329 is_sfn = false; | 1331 is_sfn = false; |
1330 } | 1332 } |
1357 } | 1359 } |
1358 | 1360 |
1359 // If this is a branch, then fill in the label with the target BB's label | 1361 // If this is a branch, then fill in the label with the target BB's label |
1360 else if (mach->is_MachBranch()) { | 1362 else if (mach->is_MachBranch()) { |
1361 // This requires the TRUE branch target be in succs[0] | 1363 // This requires the TRUE branch target be in succs[0] |
1362 uint block_num = b->non_connector_successor(0)->_pre_order; | 1364 uint block_num = block->non_connector_successor(0)->_pre_order; |
1363 | 1365 |
1364 // Try to replace long branch if delay slot is not used, | 1366 // Try to replace long branch if delay slot is not used, |
1365 // it is mostly for back branches since forward branch's | 1367 // it is mostly for back branches since forward branch's |
1366 // distance is not updated yet. | 1368 // distance is not updated yet. |
1367 bool delay_slot_is_used = valid_bundle_info(n) && | 1369 bool delay_slot_is_used = valid_bundle_info(n) && |
1390 int new_size = replacement->size(_regalloc); | 1392 int new_size = replacement->size(_regalloc); |
1391 assert((br_size - new_size) >= (int)nop_size, "short_branch size should be smaller"); | 1393 assert((br_size - new_size) >= (int)nop_size, "short_branch size should be smaller"); |
1392 // Insert padding between avoid_back_to_back branches. | 1394 // Insert padding between avoid_back_to_back branches. |
1393 if (needs_padding && replacement->avoid_back_to_back()) { | 1395 if (needs_padding && replacement->avoid_back_to_back()) { |
1394 MachNode *nop = new (this) MachNopNode(); | 1396 MachNode *nop = new (this) MachNopNode(); |
1395 b->_nodes.insert(j++, nop); | 1397 block->_nodes.insert(j++, nop); |
1396 _cfg->map_node_to_block(nop, b); | 1398 _cfg->map_node_to_block(nop, block); |
1397 last_inst++; | 1399 last_inst++; |
1398 nop->emit(*cb, _regalloc); | 1400 nop->emit(*cb, _regalloc); |
1399 cb->flush_bundle(true); | 1401 cb->flush_bundle(true); |
1400 current_offset = cb->insts_size(); | 1402 current_offset = cb->insts_size(); |
1401 } | 1403 } |
1403 jmp_target[i] = block_num; | 1405 jmp_target[i] = block_num; |
1404 jmp_offset[i] = current_offset - blk_offset; | 1406 jmp_offset[i] = current_offset - blk_offset; |
1405 jmp_size[i] = new_size; | 1407 jmp_size[i] = new_size; |
1406 jmp_rule[i] = mach->rule(); | 1408 jmp_rule[i] = mach->rule(); |
1407 #endif | 1409 #endif |
1408 b->_nodes.map(j, replacement); | 1410 block->_nodes.map(j, replacement); |
1409 mach->subsume_by(replacement, C); | 1411 mach->subsume_by(replacement, C); |
1410 n = replacement; | 1412 n = replacement; |
1411 mach = replacement; | 1413 mach = replacement; |
1412 } | 1414 } |
1413 } | 1415 } |
1414 mach->as_MachBranch()->label_set( &blk_labels[block_num], block_num ); | 1416 mach->as_MachBranch()->label_set( &blk_labels[block_num], block_num ); |
1415 } else if (mach->ideal_Opcode() == Op_Jump) { | 1417 } else if (mach->ideal_Opcode() == Op_Jump) { |
1416 for (uint h = 0; h < b->_num_succs; h++) { | 1418 for (uint h = 0; h < block->_num_succs; h++) { |
1417 Block* succs_block = b->_succs[h]; | 1419 Block* succs_block = block->_succs[h]; |
1418 for (uint j = 1; j < succs_block->num_preds(); j++) { | 1420 for (uint j = 1; j < succs_block->num_preds(); j++) { |
1419 Node* jpn = succs_block->pred(j); | 1421 Node* jpn = succs_block->pred(j); |
1420 if (jpn->is_JumpProj() && jpn->in(0) == mach) { | 1422 if (jpn->is_JumpProj() && jpn->in(0) == mach) { |
1421 uint block_num = succs_block->non_connector()->_pre_order; | 1423 uint block_num = succs_block->non_connector()->_pre_order; |
1422 Label *blkLabel = &blk_labels[block_num]; | 1424 Label *blkLabel = &blk_labels[block_num]; |
1423 mach->add_case_label(jpn->as_JumpProj()->proj_no(), blkLabel); | 1425 mach->add_case_label(jpn->as_JumpProj()->proj_no(), blkLabel); |
1424 } | 1426 } |
1425 } | 1427 } |
1426 } | 1428 } |
1427 } | 1429 } |
1428 | |
1429 #ifdef ASSERT | 1430 #ifdef ASSERT |
1430 // Check that oop-store precedes the card-mark | 1431 // Check that oop-store precedes the card-mark |
1431 else if (mach->ideal_Opcode() == Op_StoreCM) { | 1432 else if (mach->ideal_Opcode() == Op_StoreCM) { |
1432 uint storeCM_idx = j; | 1433 uint storeCM_idx = j; |
1433 int count = 0; | 1434 int count = 0; |
1434 for (uint prec = mach->req(); prec < mach->len(); prec++) { | 1435 for (uint prec = mach->req(); prec < mach->len(); prec++) { |
1435 Node *oop_store = mach->in(prec); // Precedence edge | 1436 Node *oop_store = mach->in(prec); // Precedence edge |
1436 if (oop_store == NULL) continue; | 1437 if (oop_store == NULL) continue; |
1437 count++; | 1438 count++; |
1438 uint i4; | 1439 uint i4; |
1439 for( i4 = 0; i4 < last_inst; ++i4 ) { | 1440 for (i4 = 0; i4 < last_inst; ++i4) { |
1440 if( b->_nodes[i4] == oop_store ) break; | 1441 if (block->_nodes[i4] == oop_store) { |
1442 break; | |
1443 } | |
1441 } | 1444 } |
1442 // Note: This test can provide a false failure if other precedence | 1445 // Note: This test can provide a false failure if other precedence |
1443 // edges have been added to the storeCMNode. | 1446 // edges have been added to the storeCMNode. |
1444 assert( i4 == last_inst || i4 < storeCM_idx, "CM card-mark executes before oop-store"); | 1447 assert(i4 == last_inst || i4 < storeCM_idx, "CM card-mark executes before oop-store"); |
1445 } | 1448 } |
1446 assert(count > 0, "storeCM expects at least one precedence edge"); | 1449 assert(count > 0, "storeCM expects at least one precedence edge"); |
1447 } | 1450 } |
1448 #endif | 1451 #endif |
1449 | |
1450 else if (!n->is_Proj()) { | 1452 else if (!n->is_Proj()) { |
1451 // Remember the beginning of the previous instruction, in case | 1453 // Remember the beginning of the previous instruction, in case |
1452 // it's followed by a flag-kill and a null-check. Happens on | 1454 // it's followed by a flag-kill and a null-check. Happens on |
1453 // Intel all the time, with add-to-memory kind of opcodes. | 1455 // Intel all the time, with add-to-memory kind of opcodes. |
1454 previous_offset = current_offset; | 1456 previous_offset = current_offset; |
1540 } // End for all instructions in block | 1542 } // End for all instructions in block |
1541 | 1543 |
1542 // If the next block is the top of a loop, pad this block out to align | 1544 // If the next block is the top of a loop, pad this block out to align |
1543 // the loop top a little. Helps prevent pipe stalls at loop back branches. | 1545 // the loop top a little. Helps prevent pipe stalls at loop back branches. |
1544 if (i < nblocks-1) { | 1546 if (i < nblocks-1) { |
1545 Block *nb = _cfg->_blocks[i+1]; | 1547 Block *nb = _cfg->get_block(i + 1); |
1546 int padding = nb->alignment_padding(current_offset); | 1548 int padding = nb->alignment_padding(current_offset); |
1547 if( padding > 0 ) { | 1549 if( padding > 0 ) { |
1548 MachNode *nop = new (this) MachNopNode(padding / nop_size); | 1550 MachNode *nop = new (this) MachNopNode(padding / nop_size); |
1549 b->_nodes.insert( b->_nodes.size(), nop ); | 1551 block->_nodes.insert(block->_nodes.size(), nop); |
1550 _cfg->map_node_to_block(nop, b); | 1552 _cfg->map_node_to_block(nop, block); |
1551 nop->emit(*cb, _regalloc); | 1553 nop->emit(*cb, _regalloc); |
1552 current_offset = cb->insts_size(); | 1554 current_offset = cb->insts_size(); |
1553 } | 1555 } |
1554 } | 1556 } |
1555 // Verify that the distance for generated before forward | 1557 // Verify that the distance for generated before forward |
1584 assert(false, "Displacement too large for short jmp"); | 1586 assert(false, "Displacement too large for short jmp"); |
1585 } | 1587 } |
1586 } | 1588 } |
1587 } | 1589 } |
1588 #endif | 1590 #endif |
1589 | |
1590 // ------------------ | |
1591 | 1591 |
1592 #ifndef PRODUCT | 1592 #ifndef PRODUCT |
1593 // Information on the size of the method, without the extraneous code | 1593 // Information on the size of the method, without the extraneous code |
1594 Scheduling::increment_method_size(cb->insts_size()); | 1594 Scheduling::increment_method_size(cb->insts_size()); |
1595 #endif | 1595 #endif |
1647 | 1647 |
1648 void Compile::FillExceptionTables(uint cnt, uint *call_returns, uint *inct_starts, Label *blk_labels) { | 1648 void Compile::FillExceptionTables(uint cnt, uint *call_returns, uint *inct_starts, Label *blk_labels) { |
1649 _inc_table.set_size(cnt); | 1649 _inc_table.set_size(cnt); |
1650 | 1650 |
1651 uint inct_cnt = 0; | 1651 uint inct_cnt = 0; |
1652 for( uint i=0; i<_cfg->_num_blocks; i++ ) { | 1652 for (uint i = 0; i < _cfg->number_of_blocks(); i++) { |
1653 Block *b = _cfg->_blocks[i]; | 1653 Block* block = _cfg->get_block(i); |
1654 Node *n = NULL; | 1654 Node *n = NULL; |
1655 int j; | 1655 int j; |
1656 | 1656 |
1657 // Find the branch; ignore trailing NOPs. | 1657 // Find the branch; ignore trailing NOPs. |
1658 for( j = b->_nodes.size()-1; j>=0; j-- ) { | 1658 for (j = block->_nodes.size() - 1; j >= 0; j--) { |
1659 n = b->_nodes[j]; | 1659 n = block->_nodes[j]; |
1660 if( !n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con ) | 1660 if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con) { |
1661 break; | 1661 break; |
1662 } | |
1662 } | 1663 } |
1663 | 1664 |
1664 // If we didn't find anything, continue | 1665 // If we didn't find anything, continue |
1665 if( j < 0 ) continue; | 1666 if (j < 0) { |
1667 continue; | |
1668 } | |
1666 | 1669 |
1667 // Compute ExceptionHandlerTable subtable entry and add it | 1670 // Compute ExceptionHandlerTable subtable entry and add it |
1668 // (skip empty blocks) | 1671 // (skip empty blocks) |
1669 if( n->is_Catch() ) { | 1672 if (n->is_Catch()) { |
1670 | 1673 |
1671 // Get the offset of the return from the call | 1674 // Get the offset of the return from the call |
1672 uint call_return = call_returns[b->_pre_order]; | 1675 uint call_return = call_returns[block->_pre_order]; |
1673 #ifdef ASSERT | 1676 #ifdef ASSERT |
1674 assert( call_return > 0, "no call seen for this basic block" ); | 1677 assert( call_return > 0, "no call seen for this basic block" ); |
1675 while( b->_nodes[--j]->is_MachProj() ) ; | 1678 while (block->_nodes[--j]->is_MachProj()) ; |
1676 assert( b->_nodes[j]->is_MachCall(), "CatchProj must follow call" ); | 1679 assert(block->_nodes[j]->is_MachCall(), "CatchProj must follow call"); |
1677 #endif | 1680 #endif |
1678 // last instruction is a CatchNode, find it's CatchProjNodes | 1681 // last instruction is a CatchNode, find it's CatchProjNodes |
1679 int nof_succs = b->_num_succs; | 1682 int nof_succs = block->_num_succs; |
1680 // allocate space | 1683 // allocate space |
1681 GrowableArray<intptr_t> handler_bcis(nof_succs); | 1684 GrowableArray<intptr_t> handler_bcis(nof_succs); |
1682 GrowableArray<intptr_t> handler_pcos(nof_succs); | 1685 GrowableArray<intptr_t> handler_pcos(nof_succs); |
1683 // iterate through all successors | 1686 // iterate through all successors |
1684 for (int j = 0; j < nof_succs; j++) { | 1687 for (int j = 0; j < nof_succs; j++) { |
1685 Block* s = b->_succs[j]; | 1688 Block* s = block->_succs[j]; |
1686 bool found_p = false; | 1689 bool found_p = false; |
1687 for( uint k = 1; k < s->num_preds(); k++ ) { | 1690 for (uint k = 1; k < s->num_preds(); k++) { |
1688 Node *pk = s->pred(k); | 1691 Node* pk = s->pred(k); |
1689 if( pk->is_CatchProj() && pk->in(0) == n ) { | 1692 if (pk->is_CatchProj() && pk->in(0) == n) { |
1690 const CatchProjNode* p = pk->as_CatchProj(); | 1693 const CatchProjNode* p = pk->as_CatchProj(); |
1691 found_p = true; | 1694 found_p = true; |
1692 // add the corresponding handler bci & pco information | 1695 // add the corresponding handler bci & pco information |
1693 if( p->_con != CatchProjNode::fall_through_index ) { | 1696 if (p->_con != CatchProjNode::fall_through_index) { |
1694 // p leads to an exception handler (and is not fall through) | 1697 // p leads to an exception handler (and is not fall through) |
1695 assert(s == _cfg->_blocks[s->_pre_order],"bad numbering"); | 1698 assert(s == _cfg->get_block(s->_pre_order), "bad numbering"); |
1696 // no duplicates, please | 1699 // no duplicates, please |
1697 if( !handler_bcis.contains(p->handler_bci()) ) { | 1700 if (!handler_bcis.contains(p->handler_bci())) { |
1698 uint block_num = s->non_connector()->_pre_order; | 1701 uint block_num = s->non_connector()->_pre_order; |
1699 handler_bcis.append(p->handler_bci()); | 1702 handler_bcis.append(p->handler_bci()); |
1700 handler_pcos.append(blk_labels[block_num].loc_pos()); | 1703 handler_pcos.append(blk_labels[block_num].loc_pos()); |
1701 } | 1704 } |
1702 } | 1705 } |
1711 _handler_table.add_subtable(call_return, &handler_bcis, NULL, &handler_pcos); | 1714 _handler_table.add_subtable(call_return, &handler_bcis, NULL, &handler_pcos); |
1712 continue; | 1715 continue; |
1713 } | 1716 } |
1714 | 1717 |
1715 // Handle implicit null exception table updates | 1718 // Handle implicit null exception table updates |
1716 if( n->is_MachNullCheck() ) { | 1719 if (n->is_MachNullCheck()) { |
1717 uint block_num = b->non_connector_successor(0)->_pre_order; | 1720 uint block_num = block->non_connector_successor(0)->_pre_order; |
1718 _inc_table.append( inct_starts[inct_cnt++], blk_labels[block_num].loc_pos() ); | 1721 _inc_table.append(inct_starts[inct_cnt++], blk_labels[block_num].loc_pos()); |
1719 continue; | 1722 continue; |
1720 } | 1723 } |
1721 } // End of for all blocks fill in exception table entries | 1724 } // End of for all blocks fill in exception table entries |
1722 } | 1725 } |
1723 | 1726 |
1772 memset(_node_latency, 0, node_max * sizeof(unsigned short)); | 1775 memset(_node_latency, 0, node_max * sizeof(unsigned short)); |
1773 memset(_uses, 0, node_max * sizeof(short)); | 1776 memset(_uses, 0, node_max * sizeof(short)); |
1774 memset(_current_latency, 0, node_max * sizeof(unsigned short)); | 1777 memset(_current_latency, 0, node_max * sizeof(unsigned short)); |
1775 | 1778 |
1776 // Clear the bundling information | 1779 // Clear the bundling information |
1777 memcpy(_bundle_use_elements, | 1780 memcpy(_bundle_use_elements, Pipeline_Use::elaborated_elements, sizeof(Pipeline_Use::elaborated_elements)); |
1778 Pipeline_Use::elaborated_elements, | |
1779 sizeof(Pipeline_Use::elaborated_elements)); | |
1780 | 1781 |
1781 // Get the last node | 1782 // Get the last node |
1782 Block *bb = _cfg->_blocks[_cfg->_blocks.size()-1]; | 1783 Block* block = _cfg->get_block(_cfg->number_of_blocks() - 1); |
1783 | 1784 |
1784 _next_node = bb->_nodes[bb->_nodes.size()-1]; | 1785 _next_node = block->_nodes[block->_nodes.size() - 1]; |
1785 } | 1786 } |
1786 | 1787 |
1787 #ifndef PRODUCT | 1788 #ifndef PRODUCT |
1788 // Scheduling destructor | 1789 // Scheduling destructor |
1789 Scheduling::~Scheduling() { | 1790 Scheduling::~Scheduling() { |
1829 memcpy(_bundle_use_elements, | 1830 memcpy(_bundle_use_elements, |
1830 Pipeline_Use::elaborated_elements, | 1831 Pipeline_Use::elaborated_elements, |
1831 sizeof(Pipeline_Use::elaborated_elements)); | 1832 sizeof(Pipeline_Use::elaborated_elements)); |
1832 } | 1833 } |
1833 | 1834 |
1834 //------------------------------ScheduleAndBundle------------------------------ | |
1835 // Perform instruction scheduling and bundling over the sequence of | 1835 // Perform instruction scheduling and bundling over the sequence of |
1836 // instructions in backwards order. | 1836 // instructions in backwards order. |
1837 void Compile::ScheduleAndBundle() { | 1837 void Compile::ScheduleAndBundle() { |
1838 | 1838 |
1839 // Don't optimize this if it isn't a method | 1839 // Don't optimize this if it isn't a method |
1856 // Walk backwards over each basic block, computing the needed alignment | 1856 // Walk backwards over each basic block, computing the needed alignment |
1857 // Walk over all the basic blocks | 1857 // Walk over all the basic blocks |
1858 scheduling.DoScheduling(); | 1858 scheduling.DoScheduling(); |
1859 } | 1859 } |
1860 | 1860 |
1861 //------------------------------ComputeLocalLatenciesForward------------------- | |
1862 // Compute the latency of all the instructions. This is fairly simple, | 1861 // Compute the latency of all the instructions. This is fairly simple, |
1863 // because we already have a legal ordering. Walk over the instructions | 1862 // because we already have a legal ordering. Walk over the instructions |
1864 // from first to last, and compute the latency of the instruction based | 1863 // from first to last, and compute the latency of the instruction based |
1865 // on the latency of the preceding instruction(s). | 1864 // on the latency of the preceding instruction(s). |
1866 void Scheduling::ComputeLocalLatenciesForward(const Block *bb) { | 1865 void Scheduling::ComputeLocalLatenciesForward(const Block *bb) { |
2026 #endif | 2025 #endif |
2027 | 2026 |
2028 return _available[0]; | 2027 return _available[0]; |
2029 } | 2028 } |
2030 | 2029 |
2031 //------------------------------AddNodeToAvailableList------------------------- | |
2032 void Scheduling::AddNodeToAvailableList(Node *n) { | 2030 void Scheduling::AddNodeToAvailableList(Node *n) { |
2033 assert( !n->is_Proj(), "projections never directly made available" ); | 2031 assert( !n->is_Proj(), "projections never directly made available" ); |
2034 #ifndef PRODUCT | 2032 #ifndef PRODUCT |
2035 if (_cfg->C->trace_opto_output()) { | 2033 if (_cfg->C->trace_opto_output()) { |
2036 tty->print("# AddNodeToAvailableList: "); | 2034 tty->print("# AddNodeToAvailableList: "); |
2072 if (_cfg->C->trace_opto_output()) | 2070 if (_cfg->C->trace_opto_output()) |
2073 dump_available(); | 2071 dump_available(); |
2074 #endif | 2072 #endif |
2075 } | 2073 } |
2076 | 2074 |
2077 //------------------------------DecrementUseCounts----------------------------- | |
2078 void Scheduling::DecrementUseCounts(Node *n, const Block *bb) { | 2075 void Scheduling::DecrementUseCounts(Node *n, const Block *bb) { |
2079 for ( uint i=0; i < n->len(); i++ ) { | 2076 for ( uint i=0; i < n->len(); i++ ) { |
2080 Node *def = n->in(i); | 2077 Node *def = n->in(i); |
2081 if (!def) continue; | 2078 if (!def) continue; |
2082 if( def->is_Proj() ) // If this is a machine projection, then | 2079 if( def->is_Proj() ) // If this is a machine projection, then |
2095 if ((--_uses[def->_idx]) == 0) | 2092 if ((--_uses[def->_idx]) == 0) |
2096 AddNodeToAvailableList(def); | 2093 AddNodeToAvailableList(def); |
2097 } | 2094 } |
2098 } | 2095 } |
2099 | 2096 |
2100 //------------------------------AddNodeToBundle-------------------------------- | |
2101 void Scheduling::AddNodeToBundle(Node *n, const Block *bb) { | 2097 void Scheduling::AddNodeToBundle(Node *n, const Block *bb) { |
2102 #ifndef PRODUCT | 2098 #ifndef PRODUCT |
2103 if (_cfg->C->trace_opto_output()) { | 2099 if (_cfg->C->trace_opto_output()) { |
2104 tty->print("# AddNodeToBundle: "); | 2100 tty->print("# AddNodeToBundle: "); |
2105 n->dump(); | 2101 n->dump(); |
2310 // Walk all the definitions, decrementing use counts, and | 2306 // Walk all the definitions, decrementing use counts, and |
2311 // if a definition has a 0 use count, place it in the available list. | 2307 // if a definition has a 0 use count, place it in the available list. |
2312 DecrementUseCounts(n,bb); | 2308 DecrementUseCounts(n,bb); |
2313 } | 2309 } |
2314 | 2310 |
2315 //------------------------------ComputeUseCount-------------------------------- | |
2316 // This method sets the use count within a basic block. We will ignore all | 2311 // This method sets the use count within a basic block. We will ignore all |
2317 // uses outside the current basic block. As we are doing a backwards walk, | 2312 // uses outside the current basic block. As we are doing a backwards walk, |
2318 // any node we reach that has a use count of 0 may be scheduled. This also | 2313 // any node we reach that has a use count of 0 may be scheduled. This also |
2319 // avoids the problem of cyclic references from phi nodes, as long as phi | 2314 // avoids the problem of cyclic references from phi nodes, as long as phi |
2320 // nodes are at the front of the basic block. This method also initializes | 2315 // nodes are at the front of the basic block. This method also initializes |
2395 | 2390 |
2396 Block *succ_bb = NULL; | 2391 Block *succ_bb = NULL; |
2397 Block *bb; | 2392 Block *bb; |
2398 | 2393 |
2399 // Walk over all the basic blocks in reverse order | 2394 // Walk over all the basic blocks in reverse order |
2400 for( int i=_cfg->_num_blocks-1; i >= 0; succ_bb = bb, i-- ) { | 2395 for (int i = _cfg->number_of_blocks() - 1; i >= 0; succ_bb = bb, i--) { |
2401 bb = _cfg->_blocks[i]; | 2396 bb = _cfg->get_block(i); |
2402 | 2397 |
2403 #ifndef PRODUCT | 2398 #ifndef PRODUCT |
2404 if (_cfg->C->trace_opto_output()) { | 2399 if (_cfg->C->trace_opto_output()) { |
2405 tty->print("# Schedule BB#%03d (initial)\n", i); | 2400 tty->print("# Schedule BB#%03d (initial)\n", i); |
2406 for (uint j = 0; j < bb->_nodes.size(); j++) | 2401 for (uint j = 0; j < bb->_nodes.size(); j++) { |
2407 bb->_nodes[j]->dump(); | 2402 bb->_nodes[j]->dump(); |
2403 } | |
2408 } | 2404 } |
2409 #endif | 2405 #endif |
2410 | 2406 |
2411 // On the head node, skip processing | 2407 // On the head node, skip processing |
2412 if( bb == _cfg->_broot ) | 2408 if (bb == _cfg->get_root_block()) { |
2413 continue; | 2409 continue; |
2410 } | |
2414 | 2411 |
2415 // Skip empty, connector blocks | 2412 // Skip empty, connector blocks |
2416 if (bb->is_connector()) | 2413 if (bb->is_connector()) |
2417 continue; | 2414 continue; |
2418 | 2415 |
2545 // Record final node-bundling array location | 2542 // Record final node-bundling array location |
2546 _regalloc->C->set_node_bundling_base(_node_bundling_base); | 2543 _regalloc->C->set_node_bundling_base(_node_bundling_base); |
2547 | 2544 |
2548 } // end DoScheduling | 2545 } // end DoScheduling |
2549 | 2546 |
2550 //------------------------------verify_good_schedule--------------------------- | |
2551 // Verify that no live-range used in the block is killed in the block by a | 2547 // Verify that no live-range used in the block is killed in the block by a |
2552 // wrong DEF. This doesn't verify live-ranges that span blocks. | 2548 // wrong DEF. This doesn't verify live-ranges that span blocks. |
2553 | 2549 |
2554 // Check for edge existence. Used to avoid adding redundant precedence edges. | 2550 // Check for edge existence. Used to avoid adding redundant precedence edges. |
2555 static bool edge_from_to( Node *from, Node *to ) { | 2551 static bool edge_from_to( Node *from, Node *to ) { |
2558 return true; | 2554 return true; |
2559 return false; | 2555 return false; |
2560 } | 2556 } |
2561 | 2557 |
2562 #ifdef ASSERT | 2558 #ifdef ASSERT |
2563 //------------------------------verify_do_def---------------------------------- | |
2564 void Scheduling::verify_do_def( Node *n, OptoReg::Name def, const char *msg ) { | 2559 void Scheduling::verify_do_def( Node *n, OptoReg::Name def, const char *msg ) { |
2565 // Check for bad kills | 2560 // Check for bad kills |
2566 if( OptoReg::is_valid(def) ) { // Ignore stores & control flow | 2561 if( OptoReg::is_valid(def) ) { // Ignore stores & control flow |
2567 Node *prior_use = _reg_node[def]; | 2562 Node *prior_use = _reg_node[def]; |
2568 if( prior_use && !edge_from_to(prior_use,n) ) { | 2563 if( prior_use && !edge_from_to(prior_use,n) ) { |
2574 } | 2569 } |
2575 _reg_node.map(def,NULL); // Kill live USEs | 2570 _reg_node.map(def,NULL); // Kill live USEs |
2576 } | 2571 } |
2577 } | 2572 } |
2578 | 2573 |
2579 //------------------------------verify_good_schedule--------------------------- | |
2580 void Scheduling::verify_good_schedule( Block *b, const char *msg ) { | 2574 void Scheduling::verify_good_schedule( Block *b, const char *msg ) { |
2581 | 2575 |
2582 // Zap to something reasonable for the verify code | 2576 // Zap to something reasonable for the verify code |
2583 _reg_node.clear(); | 2577 _reg_node.clear(); |
2584 | 2578 |
2634 if( from != to && // No cycles (for things like LD L0,[L0+4] ) | 2628 if( from != to && // No cycles (for things like LD L0,[L0+4] ) |
2635 !edge_from_to( from, to ) ) // Avoid duplicate edge | 2629 !edge_from_to( from, to ) ) // Avoid duplicate edge |
2636 from->add_prec(to); | 2630 from->add_prec(to); |
2637 } | 2631 } |
2638 | 2632 |
2639 //------------------------------anti_do_def------------------------------------ | |
2640 void Scheduling::anti_do_def( Block *b, Node *def, OptoReg::Name def_reg, int is_def ) { | 2633 void Scheduling::anti_do_def( Block *b, Node *def, OptoReg::Name def_reg, int is_def ) { |
2641 if( !OptoReg::is_valid(def_reg) ) // Ignore stores & control flow | 2634 if( !OptoReg::is_valid(def_reg) ) // Ignore stores & control flow |
2642 return; | 2635 return; |
2643 | 2636 |
2644 Node *pinch = _reg_node[def_reg]; // Get pinch point | 2637 Node *pinch = _reg_node[def_reg]; // Get pinch point |
2704 | 2697 |
2705 // Add edge from kill to pinch-point | 2698 // Add edge from kill to pinch-point |
2706 add_prec_edge_from_to(kill,pinch); | 2699 add_prec_edge_from_to(kill,pinch); |
2707 } | 2700 } |
2708 | 2701 |
2709 //------------------------------anti_do_use------------------------------------ | |
2710 void Scheduling::anti_do_use( Block *b, Node *use, OptoReg::Name use_reg ) { | 2702 void Scheduling::anti_do_use( Block *b, Node *use, OptoReg::Name use_reg ) { |
2711 if( !OptoReg::is_valid(use_reg) ) // Ignore stores & control flow | 2703 if( !OptoReg::is_valid(use_reg) ) // Ignore stores & control flow |
2712 return; | 2704 return; |
2713 Node *pinch = _reg_node[use_reg]; // Get pinch point | 2705 Node *pinch = _reg_node[use_reg]; // Get pinch point |
2714 // Check for no later def_reg/kill in block | 2706 // Check for no later def_reg/kill in block |
2725 | 2717 |
2726 add_prec_edge_from_to(pinch,use); | 2718 add_prec_edge_from_to(pinch,use); |
2727 } | 2719 } |
2728 } | 2720 } |
2729 | 2721 |
2730 //------------------------------ComputeRegisterAntidependences----------------- | |
2731 // We insert antidependences between the reads and following write of | 2722 // We insert antidependences between the reads and following write of |
2732 // allocated registers to prevent illegal code motion. Hopefully, the | 2723 // allocated registers to prevent illegal code motion. Hopefully, the |
2733 // number of added references should be fairly small, especially as we | 2724 // number of added references should be fairly small, especially as we |
2734 // are only adding references within the current basic block. | 2725 // are only adding references within the current basic block. |
2735 void Scheduling::ComputeRegisterAntidependencies(Block *b) { | 2726 void Scheduling::ComputeRegisterAntidependencies(Block *b) { |
2858 // Garbage collect pinch nodes that were not consumed. | 2849 // Garbage collect pinch nodes that were not consumed. |
2859 // They are usually created by a fat kill MachProj for a call. | 2850 // They are usually created by a fat kill MachProj for a call. |
2860 garbage_collect_pinch_nodes(); | 2851 garbage_collect_pinch_nodes(); |
2861 } | 2852 } |
2862 } | 2853 } |
2863 | |
2864 //------------------------------garbage_collect_pinch_nodes------------------------------- | |
2865 | 2854 |
2866 // Garbage collect pinch nodes for reuse by other blocks. | 2855 // Garbage collect pinch nodes for reuse by other blocks. |
2867 // | 2856 // |
2868 // The block scheduler's insertion of anti-dependence | 2857 // The block scheduler's insertion of anti-dependence |
2869 // edges creates many pinch nodes when the block contains | 2858 // edges creates many pinch nodes when the block contains |
2935 } | 2924 } |
2936 // May have a later_def entry | 2925 // May have a later_def entry |
2937 pinch->set_req(0, NULL); | 2926 pinch->set_req(0, NULL); |
2938 } | 2927 } |
2939 | 2928 |
2940 //------------------------------print_statistics------------------------------- | |
2941 #ifndef PRODUCT | 2929 #ifndef PRODUCT |
2942 | 2930 |
2943 void Scheduling::dump_available() const { | 2931 void Scheduling::dump_available() const { |
2944 tty->print("#Availist "); | 2932 tty->print("#Availist "); |
2945 for (uint i = 0; i < _available.size(); i++) | 2933 for (uint i = 0; i < _available.size(); i++) |