207 return op == Op_Halt; |
207 return op == Op_Halt; |
208 } |
208 } |
209 |
209 |
210 // True if block is low enough frequency or guarded by a test which |
210 // True if block is low enough frequency or guarded by a test which |
211 // mostly does not go here. |
211 // mostly does not go here. |
212 bool Block::is_uncommon(PhaseCFG* cfg) const { |
212 bool PhaseCFG::is_uncommon(const Block* block) { |
213 // Initial blocks must never be moved, so are never uncommon. |
213 // Initial blocks must never be moved, so are never uncommon. |
214 if (head()->is_Root() || head()->is_Start()) return false; |
214 if (block->head()->is_Root() || block->head()->is_Start()) return false; |
215 |
215 |
216 // Check for way-low freq |
216 // Check for way-low freq |
217 if( _freq < BLOCK_FREQUENCY(0.00001f) ) return true; |
217 if(block->_freq < BLOCK_FREQUENCY(0.00001f) ) return true; |
218 |
218 |
219 // Look for code shape indicating uncommon_trap or slow path |
219 // Look for code shape indicating uncommon_trap or slow path |
220 if (has_uncommon_code()) return true; |
220 if (block->has_uncommon_code()) return true; |
221 |
221 |
222 const float epsilon = 0.05f; |
222 const float epsilon = 0.05f; |
223 const float guard_factor = PROB_UNLIKELY_MAG(4) / (1.f - epsilon); |
223 const float guard_factor = PROB_UNLIKELY_MAG(4) / (1.f - epsilon); |
224 uint uncommon_preds = 0; |
224 uint uncommon_preds = 0; |
225 uint freq_preds = 0; |
225 uint freq_preds = 0; |
226 uint uncommon_for_freq_preds = 0; |
226 uint uncommon_for_freq_preds = 0; |
227 |
227 |
228 for( uint i=1; i<num_preds(); i++ ) { |
228 for( uint i=1; i< block->num_preds(); i++ ) { |
229 Block* guard = cfg->get_block_for_node(pred(i)); |
229 Block* guard = get_block_for_node(block->pred(i)); |
230 // Check to see if this block follows its guard 1 time out of 10000 |
230 // Check to see if this block follows its guard 1 time out of 10000 |
231 // or less. |
231 // or less. |
232 // |
232 // |
233 // See list of magnitude-4 unlikely probabilities in cfgnode.hpp which |
233 // See list of magnitude-4 unlikely probabilities in cfgnode.hpp which |
234 // we intend to be "uncommon", such as slow-path TLE allocation, |
234 // we intend to be "uncommon", such as slow-path TLE allocation, |
242 // The next check is (guard->_freq < 1.e-5 * 9500.). |
242 // The next check is (guard->_freq < 1.e-5 * 9500.). |
243 if(guard->_freq*BLOCK_FREQUENCY(guard_factor) < BLOCK_FREQUENCY(0.00001f)) { |
243 if(guard->_freq*BLOCK_FREQUENCY(guard_factor) < BLOCK_FREQUENCY(0.00001f)) { |
244 uncommon_preds++; |
244 uncommon_preds++; |
245 } else { |
245 } else { |
246 freq_preds++; |
246 freq_preds++; |
247 if( _freq < guard->_freq * guard_factor ) { |
247 if(block->_freq < guard->_freq * guard_factor ) { |
248 uncommon_for_freq_preds++; |
248 uncommon_for_freq_preds++; |
249 } |
249 } |
250 } |
250 } |
251 } |
251 } |
252 if( num_preds() > 1 && |
252 if( block->num_preds() > 1 && |
253 // The block is uncommon if all preds are uncommon or |
253 // The block is uncommon if all preds are uncommon or |
254 (uncommon_preds == (num_preds()-1) || |
254 (uncommon_preds == (block->num_preds()-1) || |
255 // it is uncommon for all frequent preds. |
255 // it is uncommon for all frequent preds. |
256 uncommon_for_freq_preds == freq_preds) ) { |
256 uncommon_for_freq_preds == freq_preds) ) { |
257 return true; |
257 return true; |
258 } |
258 } |
259 return false; |
259 return false; |
667 convert_NeverBranch_to_Goto(block); |
667 convert_NeverBranch_to_Goto(block); |
668 } |
668 } |
669 |
669 |
670 // Look for uncommon blocks and move to end. |
670 // Look for uncommon blocks and move to end. |
671 if (!C->do_freq_based_layout()) { |
671 if (!C->do_freq_based_layout()) { |
672 if (block->is_uncommon(this)) { |
672 if (is_uncommon(block)) { |
673 move_to_end(block, i); |
673 move_to_end(block, i); |
674 last--; // No longer check for being uncommon! |
674 last--; // No longer check for being uncommon! |
675 if (no_flip_branch(block)) { // Fall-thru case must follow? |
675 if (no_flip_branch(block)) { // Fall-thru case must follow? |
676 // Find the fall-thru block |
676 // Find the fall-thru block |
677 block = get_block(i); |
677 block = get_block(i); |