hotspot/src/share/vm/opto/gcm.cpp
changeset 1498 346bf226078e
parent 1070 e03de091796e
child 2016 c1f73fa547fe
--- a/hotspot/src/share/vm/opto/gcm.cpp	Thu Oct 30 17:08:48 2008 -0700
+++ b/hotspot/src/share/vm/opto/gcm.cpp	Thu Nov 06 14:59:10 2008 -0800
@@ -1319,11 +1319,33 @@
 //------------------------------Estimate_Block_Frequency-----------------------
 // Estimate block frequencies based on IfNode probabilities.
 void PhaseCFG::Estimate_Block_Frequency() {
-  int cnts = C->method() ? C->method()->interpreter_invocation_count() : 1;
-  // Most of our algorithms will die horribly if frequency can become
-  // negative so make sure cnts is a sane value.
-  if( cnts <= 0 ) cnts = 1;
-  float f = (float)cnts/(float)FreqCountInvocations;
+
+  // Force conditional branches leading to uncommon traps to be unlikely,
+  // not because we get to the uncommon_trap with less relative frequency,
+  // but because an uncommon_trap typically causes a deopt, so we only get
+  // there once.
+  if (C->do_freq_based_layout()) {
+    Block_List worklist;
+    Block* root_blk = _blocks[0];
+    for (uint i = 1; i < root_blk->num_preds(); i++) {
+      Block *pb = _bbs[root_blk->pred(i)->_idx];
+      if (pb->has_uncommon_code()) {
+        worklist.push(pb);
+      }
+    }
+    while (worklist.size() > 0) {
+      Block* uct = worklist.pop();
+      if (uct == _broot) continue;
+      for (uint i = 1; i < uct->num_preds(); i++) {
+        Block *pb = _bbs[uct->pred(i)->_idx];
+        if (pb->_num_succs == 1) {
+          worklist.push(pb);
+        } else if (pb->num_fall_throughs() == 2) {
+          pb->update_uncommon_branch(uct);
+        }
+      }
+    }
+  }
 
   // Create the loop tree and calculate loop depth.
   _root_loop = create_loop_tree();
@@ -1333,25 +1355,27 @@
   _root_loop->compute_freq();
 
   // Adjust all frequencies to be relative to a single method entry
-  _root_loop->_freq = f * 1.0;
+  _root_loop->_freq = 1.0;
   _root_loop->scale_freq();
 
   // force paths ending at uncommon traps to be infrequent
-  Block_List worklist;
-  Block* root_blk = _blocks[0];
-  for (uint i = 0; i < root_blk->num_preds(); i++) {
-    Block *pb = _bbs[root_blk->pred(i)->_idx];
-    if (pb->has_uncommon_code()) {
-      worklist.push(pb);
+  if (!C->do_freq_based_layout()) {
+    Block_List worklist;
+    Block* root_blk = _blocks[0];
+    for (uint i = 1; i < root_blk->num_preds(); i++) {
+      Block *pb = _bbs[root_blk->pred(i)->_idx];
+      if (pb->has_uncommon_code()) {
+        worklist.push(pb);
+      }
     }
-  }
-  while (worklist.size() > 0) {
-    Block* uct = worklist.pop();
-    uct->_freq = PROB_MIN;
-    for (uint i = 0; i < uct->num_preds(); i++) {
-      Block *pb = _bbs[uct->pred(i)->_idx];
-      if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
-        worklist.push(pb);
+    while (worklist.size() > 0) {
+      Block* uct = worklist.pop();
+      uct->_freq = PROB_MIN;
+      for (uint i = 1; i < uct->num_preds(); i++) {
+        Block *pb = _bbs[uct->pred(i)->_idx];
+        if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
+          worklist.push(pb);
+        }
       }
     }
   }
@@ -1556,22 +1580,6 @@
     }
   }
 
-#if 0
-  // Raise frequency of the loop backedge block, in an effort
-  // to keep it empty.  Skip the method level "loop".
-  if (_parent != NULL) {
-    CFGElement* s = _members.at(_members.length() - 1);
-    if (s->is_block()) {
-      Block* bk = s->as_Block();
-      if (bk->_num_succs == 1 && bk->_succs[0] == hd) {
-        // almost any value >= 1.0f works
-        // FIXME: raw constant
-        bk->_freq = 1.05f;
-      }
-    }
-  }
-#endif
-
   // For all loops other than the outer, "method" loop,
   // sum and normalize the exit probability. The "method" loop
   // should keep the initial exit probability of 1, so that
@@ -1589,12 +1597,15 @@
     // the probability of exit per loop entry.
     for (int i = 0; i < _exits.length(); i++) {
       Block* et = _exits.at(i).get_target();
-      float new_prob = _exits.at(i).get_prob() / exits_sum;
+      float new_prob = 0.0f;
+      if (_exits.at(i).get_prob() > 0.0f) {
+        new_prob = _exits.at(i).get_prob() / exits_sum;
+      }
       BlockProbPair bpp(et, new_prob);
       _exits.at_put(i, bpp);
     }
 
-    // Save the total, but guard against unreasoable probability,
+    // Save the total, but guard against unreasonable probability,
     // as the value is used to estimate the loop trip count.
     // An infinite trip count would blur relative block
     // frequencies.
@@ -1688,6 +1699,137 @@
   return 0.0f;
 }
 
+//------------------------------num_fall_throughs-----------------------------
+// Return the number of fall-through candidates for a block
+int Block::num_fall_throughs() {
+  int eidx = end_idx();
+  Node *n = _nodes[eidx];  // Get ending Node
+
+  int op = n->Opcode();
+  if (n->is_Mach()) {
+    if (n->is_MachNullCheck()) {
+      // In theory, either side can fall-thru, for simplicity sake,
+      // let's say only the false branch can now.
+      return 1;
+    }
+    op = n->as_Mach()->ideal_Opcode();
+  }
+
+  // Switch on branch type
+  switch( op ) {
+  case Op_CountedLoopEnd:
+  case Op_If:
+    return 2;
+
+  case Op_Root:
+  case Op_Goto:
+    return 1;
+
+  case Op_Catch: {
+    for (uint i = 0; i < _num_succs; i++) {
+      const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
+      if (ci->_con == CatchProjNode::fall_through_index) {
+        return 1;
+      }
+    }
+    return 0;
+  }
+
+  case Op_Jump:
+  case Op_NeverBranch:
+  case Op_TailCall:
+  case Op_TailJump:
+  case Op_Return:
+  case Op_Halt:
+  case Op_Rethrow:
+    return 0;
+
+  default:
+    ShouldNotReachHere();
+  }
+
+  return 0;
+}
+
+//------------------------------succ_fall_through-----------------------------
+// Return true if a specific successor could be fall-through target.
+bool Block::succ_fall_through(uint i) {
+  int eidx = end_idx();
+  Node *n = _nodes[eidx];  // Get ending Node
+
+  int op = n->Opcode();
+  if (n->is_Mach()) {
+    if (n->is_MachNullCheck()) {
+      // In theory, either side can fall-thru, for simplicity sake,
+      // let's say only the false branch can now.
+      return _nodes[i + eidx + 1]->Opcode() == Op_IfFalse;
+    }
+    op = n->as_Mach()->ideal_Opcode();
+  }
+
+  // Switch on branch type
+  switch( op ) {
+  case Op_CountedLoopEnd:
+  case Op_If:
+  case Op_Root:
+  case Op_Goto:
+    return true;
+
+  case Op_Catch: {
+    const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj();
+    return ci->_con == CatchProjNode::fall_through_index;
+  }
+
+  case Op_Jump:
+  case Op_NeverBranch:
+  case Op_TailCall:
+  case Op_TailJump:
+  case Op_Return:
+  case Op_Halt:
+  case Op_Rethrow:
+    return false;
+
+  default:
+    ShouldNotReachHere();
+  }
+
+  return false;
+}
+
+//------------------------------update_uncommon_branch------------------------
+// Update the probability of a two-branch to be uncommon
+void Block::update_uncommon_branch(Block* ub) {
+  int eidx = end_idx();
+  Node *n = _nodes[eidx];  // Get ending Node
+
+  int op = n->as_Mach()->ideal_Opcode();
+
+  assert(op == Op_CountedLoopEnd || op == Op_If, "must be a If");
+  assert(num_fall_throughs() == 2, "must be a two way branch block");
+
+  // Which successor is ub?
+  uint s;
+  for (s = 0; s <_num_succs; s++) {
+    if (_succs[s] == ub) break;
+  }
+  assert(s < 2, "uncommon successor must be found");
+
+  // If ub is the true path, make the proability small, else
+  // ub is the false path, and make the probability large
+  bool invert = (_nodes[s + eidx + 1]->Opcode() == Op_IfFalse);
+
+  // Get existing probability
+  float p = n->as_MachIf()->_prob;
+
+  if (invert) p = 1.0 - p;
+  if (p > PROB_MIN) {
+    p = PROB_MIN;
+  }
+  if (invert) p = 1.0 - p;
+
+  n->as_MachIf()->_prob = p;
+}
+
 //------------------------------update_succ_freq-------------------------------
 // Update the appropriate frequency associated with block 'b', a succesor of
 // a block in this loop.