src/share/vm/opto/cfgnode.cpp
Print this page
rev 3904 : 8005071: Incremental inlining for JSR 292
Summary: post parse inlining driven by number of live nodes.
Reviewed-by:
@@ -361,10 +361,68 @@
}
return true; // The Region node is unreachable - it is dead.
}
+bool RegionNode::try_clean_mem_phi(PhaseGVN *phase) {
+ // Incremental inlining + PhaseStringOpts sometimes produce:
+ //
+ // Some Node \
+ // \ Phi
+ // MergeMem / /
+ // /
+ // IfFalse /
+ // cmpP with 1 top input -- If / \ Region
+ // \ /
+ // IfTrue
+ //
+ // It's expected by PhaseStringOpts that the Region goes away and is
+ // replaced by If's control input but because there's still a Phi,
+ // the Region stays in the graph. The top input from the cmpP is
+ // propagated forward and a subgraph that is useful goes away. The
+ // code below replaces the Phi with the MergeMem so that the Region
+ // is simplified.
+
+ Node* phi = NULL;
+ for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
+ Node* n = fast_out(i);
+ if (n->is_Phi()) {
+ if (phi == NULL) {
+ phi = n;
+ } else if (phi != n) {
+ return true; // more than one phi
+ }
+ }
+ }
+
+ if (phi->as_Phi()->type() == Type::MEMORY && req() == 3 && in(1) && in(2) && in(1)->in(0) == in(2)->in(0)) {
+ MergeMemNode* m = NULL;
+ for(uint i=1; i<phi->req(); ++i) {
+ Node *ii = phi->in(i);
+
+ if (ii && ii->is_MergeMem() && in(i)->outcnt() == 1) {
+ m = ii->as_MergeMem();
+
+ bool ok = true;
+ for(uint i=1; i<phi->req(); ++i) {
+ Node *ii = phi->in(i);
+ if (ii == NULL || ii == m) continue;
+ if (ii != m->base_memory() || (ii->is_MergeMem() && in(i)->outcnt() > 1)) {
+ ok = false;
+ break;
+ }
+ }
+ if (ok) {
+ phase->is_IterGVN()->replace_node(phi, m);
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
//------------------------------Ideal------------------------------------------
// Return a node which is more "ideal" than the current node. Must preserve
// the CFG, but we can still strip out dead paths.
Node *RegionNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if( !can_reshape && !in(0) ) return NULL; // Already degraded to a Copy
@@ -373,10 +431,14 @@
// Check for RegionNode with no Phi users and both inputs come from either
// arm of the same IF. If found, then the control-flow split is useless.
bool has_phis = false;
if (can_reshape) { // Need DU info to check for Phi users
has_phis = (has_phi() != NULL); // Cache result
+ if (has_phis) {
+ has_phis = try_clean_mem_phi(phase);
+ }
+
if (!has_phis) { // No Phi users? Nothing merging?
for (uint i = 1; i < req()-1; i++) {
Node *if1 = in(i);
if( !if1 ) continue;
Node *iff = if1->in(0);