# HG changeset patch # User kvn # Date 1270487835 25200 # Node ID eb79484f795f1ea9175e4f0a9c5fe1607546fbf0 # Parent 9bb91718aaf2cf802bca0422467e07eb054ac7ce 6937111: Restore optimization for Phi of AddP (6552204) Summary: Restored the original code which was removed by the fix for 6614100. Reviewed-by: never diff -r 9bb91718aaf2 -r eb79484f795f src/share/vm/opto/cfgnode.cpp --- a/src/share/vm/opto/cfgnode.cpp Fri Apr 02 15:55:04 2010 -0700 +++ b/src/share/vm/opto/cfgnode.cpp Mon Apr 05 10:17:15 2010 -0700 @@ -1653,6 +1653,64 @@ if (opt != NULL) return opt; } + if (in(1) != NULL && in(1)->Opcode() == Op_AddP && can_reshape) { + // Try to undo Phi of AddP: + // (Phi (AddP base base y) (AddP base2 base2 y)) + // becomes: + // newbase := (Phi base base2) + // (AddP newbase newbase y) + // + // This occurs as a result of unsuccessful split_thru_phi and + // interferes with taking advantage of addressing modes. See the + // clone_shift_expressions code in matcher.cpp + Node* addp = in(1); + const Type* type = addp->in(AddPNode::Base)->bottom_type(); + Node* y = addp->in(AddPNode::Offset); + if (y != NULL && addp->in(AddPNode::Base) == addp->in(AddPNode::Address)) { + // make sure that all the inputs are similar to the first one, + // i.e. AddP with base == address and same offset as first AddP + bool doit = true; + for (uint i = 2; i < req(); i++) { + if (in(i) == NULL || + in(i)->Opcode() != Op_AddP || + in(i)->in(AddPNode::Base) != in(i)->in(AddPNode::Address) || + in(i)->in(AddPNode::Offset) != y) { + doit = false; + break; + } + // Accumulate type for resulting Phi + type = type->meet(in(i)->in(AddPNode::Base)->bottom_type()); + } + Node* base = NULL; + if (doit) { + // Check for neighboring AddP nodes in a tree. + // If they have a base, use that it. + for (DUIterator_Fast kmax, k = this->fast_outs(kmax); k < kmax; k++) { + Node* u = this->fast_out(k); + if (u->is_AddP()) { + Node* base2 = u->in(AddPNode::Base); + if (base2 != NULL && !base2->is_top()) { + if (base == NULL) + base = base2; + else if (base != base2) + { doit = false; break; } + } + } + } + } + if (doit) { + if (base == NULL) { + base = new (phase->C, in(0)->req()) PhiNode(in(0), type, NULL); + for (uint i = 1; i < req(); i++) { + base->init_req(i, in(i)->in(AddPNode::Base)); + } + phase->is_IterGVN()->register_new_node_with_optimizer(base); + } + return new (phase->C, 4) AddPNode(base, base, y); + } + } + } + // Split phis through memory merges, so that the memory merges will go away. // Piggy-back this transformation on the search for a unique input.... // It will be as if the merged memory is the unique value of the phi.