mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +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 (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.
|
// Split phis through memory merges, so that the memory merges will go away.
|
||||||
// Piggy-back this transformation on the search for a unique input....
|
// 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.
|
// 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