mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 19:44:41 +02:00
6937111: Restore optimization for Phi of AddP (6552204)
Restored the original code which was removed by the fix for 6614100. Reviewed-by: never
This commit is contained in:
parent
6f0a3e4a80
commit
d72f8abedf
1 changed files with 58 additions and 0 deletions
|
@ -1653,6 +1653,64 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|||
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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue