78 |
78 |
79 //============================================================================= |
79 //============================================================================= |
80 |
80 |
81 uint Block::code_alignment() { |
81 uint Block::code_alignment() { |
82 // Check for Root block |
82 // Check for Root block |
83 if( _pre_order == 0 ) return CodeEntryAlignment; |
83 if (_pre_order == 0) return CodeEntryAlignment; |
84 // Check for Start block |
84 // Check for Start block |
85 if( _pre_order == 1 ) return InteriorEntryAlignment; |
85 if (_pre_order == 1) return InteriorEntryAlignment; |
86 // Check for loop alignment |
86 // Check for loop alignment |
87 if (has_loop_alignment()) return loop_alignment(); |
87 if (has_loop_alignment()) return loop_alignment(); |
88 |
88 |
89 return 1; // no particular alignment |
89 return relocInfo::addr_unit(); // no particular alignment |
90 } |
90 } |
91 |
91 |
92 uint Block::compute_loop_alignment() { |
92 uint Block::compute_loop_alignment() { |
93 Node *h = head(); |
93 Node *h = head(); |
94 if( h->is_Loop() && h->as_Loop()->is_inner_loop() ) { |
94 int unit_sz = relocInfo::addr_unit(); |
|
95 if (h->is_Loop() && h->as_Loop()->is_inner_loop()) { |
95 // Pre- and post-loops have low trip count so do not bother with |
96 // Pre- and post-loops have low trip count so do not bother with |
96 // NOPs for align loop head. The constants are hidden from tuning |
97 // NOPs for align loop head. The constants are hidden from tuning |
97 // but only because my "divide by 4" heuristic surely gets nearly |
98 // but only because my "divide by 4" heuristic surely gets nearly |
98 // all possible gain (a "do not align at all" heuristic has a |
99 // all possible gain (a "do not align at all" heuristic has a |
99 // chance of getting a really tiny gain). |
100 // chance of getting a really tiny gain). |
100 if( h->is_CountedLoop() && (h->as_CountedLoop()->is_pre_loop() || |
101 if (h->is_CountedLoop() && (h->as_CountedLoop()->is_pre_loop() || |
101 h->as_CountedLoop()->is_post_loop()) ) |
102 h->as_CountedLoop()->is_post_loop())) { |
102 return (OptoLoopAlignment > 4) ? (OptoLoopAlignment>>2) : 1; |
103 return (OptoLoopAlignment > 4*unit_sz) ? (OptoLoopAlignment>>2) : unit_sz; |
|
104 } |
103 // Loops with low backedge frequency should not be aligned. |
105 // Loops with low backedge frequency should not be aligned. |
104 Node *n = h->in(LoopNode::LoopBackControl)->in(0); |
106 Node *n = h->in(LoopNode::LoopBackControl)->in(0); |
105 if( n->is_MachIf() && n->as_MachIf()->_prob < 0.01 ) { |
107 if (n->is_MachIf() && n->as_MachIf()->_prob < 0.01) { |
106 return 1; // Loop does not loop, more often than not! |
108 return unit_sz; // Loop does not loop, more often than not! |
107 } |
109 } |
108 return OptoLoopAlignment; // Otherwise align loop head |
110 return OptoLoopAlignment; // Otherwise align loop head |
109 } |
111 } |
110 |
112 |
111 return 1; // no particular alignment |
113 return unit_sz; // no particular alignment |
112 } |
114 } |
113 |
115 |
114 //----------------------------------------------------------------------------- |
116 //----------------------------------------------------------------------------- |
115 // Compute the size of first 'inst_cnt' instructions in this block. |
117 // Compute the size of first 'inst_cnt' instructions in this block. |
116 // Return the number of instructions left to compute if the block has |
118 // Return the number of instructions left to compute if the block has |
269 return false; |
271 return false; |
270 } |
272 } |
271 |
273 |
272 //------------------------------dump------------------------------------------- |
274 //------------------------------dump------------------------------------------- |
273 #ifndef PRODUCT |
275 #ifndef PRODUCT |
274 void Block::dump_bidx(const Block* orig) const { |
276 void Block::dump_bidx(const Block* orig, outputStream* st) const { |
275 if (_pre_order) tty->print("B%d",_pre_order); |
277 if (_pre_order) st->print("B%d",_pre_order); |
276 else tty->print("N%d", head()->_idx); |
278 else st->print("N%d", head()->_idx); |
277 |
279 |
278 if (Verbose && orig != this) { |
280 if (Verbose && orig != this) { |
279 // Dump the original block's idx |
281 // Dump the original block's idx |
280 tty->print(" ("); |
282 st->print(" ("); |
281 orig->dump_bidx(orig); |
283 orig->dump_bidx(orig, st); |
282 tty->print(")"); |
284 st->print(")"); |
283 } |
285 } |
284 } |
286 } |
285 |
287 |
286 void Block::dump_pred(const Block_Array *bbs, Block* orig) const { |
288 void Block::dump_pred(const Block_Array *bbs, Block* orig, outputStream* st) const { |
287 if (is_connector()) { |
289 if (is_connector()) { |
288 for (uint i=1; i<num_preds(); i++) { |
290 for (uint i=1; i<num_preds(); i++) { |
289 Block *p = ((*bbs)[pred(i)->_idx]); |
291 Block *p = ((*bbs)[pred(i)->_idx]); |
290 p->dump_pred(bbs, orig); |
292 p->dump_pred(bbs, orig, st); |
291 } |
293 } |
292 } else { |
294 } else { |
293 dump_bidx(orig); |
295 dump_bidx(orig, st); |
294 tty->print(" "); |
296 st->print(" "); |
295 } |
297 } |
296 } |
298 } |
297 |
299 |
298 void Block::dump_head( const Block_Array *bbs ) const { |
300 void Block::dump_head( const Block_Array *bbs, outputStream* st ) const { |
299 // Print the basic block |
301 // Print the basic block |
300 dump_bidx(this); |
302 dump_bidx(this, st); |
301 tty->print(": #\t"); |
303 st->print(": #\t"); |
302 |
304 |
303 // Print the incoming CFG edges and the outgoing CFG edges |
305 // Print the incoming CFG edges and the outgoing CFG edges |
304 for( uint i=0; i<_num_succs; i++ ) { |
306 for( uint i=0; i<_num_succs; i++ ) { |
305 non_connector_successor(i)->dump_bidx(_succs[i]); |
307 non_connector_successor(i)->dump_bidx(_succs[i], st); |
306 tty->print(" "); |
308 st->print(" "); |
307 } |
309 } |
308 tty->print("<- "); |
310 st->print("<- "); |
309 if( head()->is_block_start() ) { |
311 if( head()->is_block_start() ) { |
310 for (uint i=1; i<num_preds(); i++) { |
312 for (uint i=1; i<num_preds(); i++) { |
311 Node *s = pred(i); |
313 Node *s = pred(i); |
312 if (bbs) { |
314 if (bbs) { |
313 Block *p = (*bbs)[s->_idx]; |
315 Block *p = (*bbs)[s->_idx]; |
314 p->dump_pred(bbs, p); |
316 p->dump_pred(bbs, p, st); |
315 } else { |
317 } else { |
316 while (!s->is_block_start()) |
318 while (!s->is_block_start()) |
317 s = s->in(0); |
319 s = s->in(0); |
318 tty->print("N%d ", s->_idx ); |
320 st->print("N%d ", s->_idx ); |
319 } |
321 } |
320 } |
322 } |
321 } else |
323 } else |
322 tty->print("BLOCK HEAD IS JUNK "); |
324 st->print("BLOCK HEAD IS JUNK "); |
323 |
325 |
324 // Print loop, if any |
326 // Print loop, if any |
325 const Block *bhead = this; // Head of self-loop |
327 const Block *bhead = this; // Head of self-loop |
326 Node *bh = bhead->head(); |
328 Node *bh = bhead->head(); |
327 if( bbs && bh->is_Loop() && !head()->is_Root() ) { |
329 if( bbs && bh->is_Loop() && !head()->is_Root() ) { |
328 LoopNode *loop = bh->as_Loop(); |
330 LoopNode *loop = bh->as_Loop(); |
329 const Block *bx = (*bbs)[loop->in(LoopNode::LoopBackControl)->_idx]; |
331 const Block *bx = (*bbs)[loop->in(LoopNode::LoopBackControl)->_idx]; |
330 while (bx->is_connector()) { |
332 while (bx->is_connector()) { |
331 bx = (*bbs)[bx->pred(1)->_idx]; |
333 bx = (*bbs)[bx->pred(1)->_idx]; |
332 } |
334 } |
333 tty->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order); |
335 st->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order); |
334 // Dump any loop-specific bits, especially for CountedLoops. |
336 // Dump any loop-specific bits, especially for CountedLoops. |
335 loop->dump_spec(tty); |
337 loop->dump_spec(st); |
336 } else if (has_loop_alignment()) { |
338 } else if (has_loop_alignment()) { |
337 tty->print(" top-of-loop"); |
339 st->print(" top-of-loop"); |
338 } |
340 } |
339 tty->print(" Freq: %g",_freq); |
341 st->print(" Freq: %g",_freq); |
340 if( Verbose || WizardMode ) { |
342 if( Verbose || WizardMode ) { |
341 tty->print(" IDom: %d/#%d", _idom ? _idom->_pre_order : 0, _dom_depth); |
343 st->print(" IDom: %d/#%d", _idom ? _idom->_pre_order : 0, _dom_depth); |
342 tty->print(" RegPressure: %d",_reg_pressure); |
344 st->print(" RegPressure: %d",_reg_pressure); |
343 tty->print(" IHRP Index: %d",_ihrp_index); |
345 st->print(" IHRP Index: %d",_ihrp_index); |
344 tty->print(" FRegPressure: %d",_freg_pressure); |
346 st->print(" FRegPressure: %d",_freg_pressure); |
345 tty->print(" FHRP Index: %d",_fhrp_index); |
347 st->print(" FHRP Index: %d",_fhrp_index); |
346 } |
348 } |
347 tty->print_cr(""); |
349 st->print_cr(""); |
348 } |
350 } |
349 |
351 |
350 void Block::dump() const { dump(0); } |
352 void Block::dump() const { dump(NULL); } |
351 |
353 |
352 void Block::dump( const Block_Array *bbs ) const { |
354 void Block::dump( const Block_Array *bbs ) const { |
353 dump_head(bbs); |
355 dump_head(bbs); |
354 uint cnt = _nodes.size(); |
356 uint cnt = _nodes.size(); |
355 for( uint i=0; i<cnt; i++ ) |
357 for( uint i=0; i<cnt; i++ ) |
439 |
441 |
440 // Put self in array of basic blocks |
442 // Put self in array of basic blocks |
441 Block *bb = new (_bbs._arena) Block(_bbs._arena,p); |
443 Block *bb = new (_bbs._arena) Block(_bbs._arena,p); |
442 _bbs.map(p->_idx,bb); |
444 _bbs.map(p->_idx,bb); |
443 _bbs.map(x->_idx,bb); |
445 _bbs.map(x->_idx,bb); |
444 if( x != p ) // Only for root is x == p |
446 if( x != p ) { // Only for root is x == p |
445 bb->_nodes.push((Node*)x); |
447 bb->_nodes.push((Node*)x); |
446 |
448 } |
447 // Now handle predecessors |
449 // Now handle predecessors |
448 ++sum; // Count 1 for self block |
450 ++sum; // Count 1 for self block |
449 uint cnt = bb->num_preds(); |
451 uint cnt = bb->num_preds(); |
450 for (int i = (cnt - 1); i > 0; i-- ) { // For all predecessors |
452 for (int i = (cnt - 1); i > 0; i-- ) { // For all predecessors |
451 Node *prevproj = p->in(i); // Get prior input |
453 Node *prevproj = p->in(i); // Get prior input |