mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 03:24:38 +02:00
7035946: Up to 15% regression on JDK 7 b136 vs b135 on specjvm2008.crypto.rsa on x64
Revert changes which caused regression. Reviewed-by: never
This commit is contained in:
parent
67ba51cae8
commit
92b2b44b18
1 changed files with 32 additions and 23 deletions
|
@ -582,20 +582,25 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
|
||||||
|
|
||||||
// Build a canonical trip test.
|
// Build a canonical trip test.
|
||||||
// Clone code, as old values may be in use.
|
// Clone code, as old values may be in use.
|
||||||
Node* nphi = PhiNode::make(x, init_trip, TypeInt::INT);
|
|
||||||
nphi = _igvn.register_new_node_with_optimizer(nphi);
|
|
||||||
set_ctrl(nphi, get_ctrl(phi));
|
|
||||||
|
|
||||||
incr = incr->clone();
|
incr = incr->clone();
|
||||||
incr->set_req(1,nphi);
|
incr->set_req(1,phi);
|
||||||
incr->set_req(2,stride);
|
incr->set_req(2,stride);
|
||||||
incr = _igvn.register_new_node_with_optimizer(incr);
|
incr = _igvn.register_new_node_with_optimizer(incr);
|
||||||
set_early_ctrl( incr );
|
set_early_ctrl( incr );
|
||||||
|
_igvn.hash_delete(phi);
|
||||||
|
phi->set_req_X( LoopNode::LoopBackControl, incr, &_igvn );
|
||||||
|
|
||||||
nphi->set_req(LoopNode::LoopBackControl, incr);
|
// If phi type is more restrictive than Int, raise to
|
||||||
|
// Int to prevent (almost) infinite recursion in igvn
|
||||||
|
// which can only handle integer types for constants or minint..maxint.
|
||||||
|
if (!TypeInt::INT->higher_equal(phi->bottom_type())) {
|
||||||
|
Node* nphi = PhiNode::make(phi->in(0), phi->in(LoopNode::EntryControl), TypeInt::INT);
|
||||||
|
nphi->set_req(LoopNode::LoopBackControl, phi->in(LoopNode::LoopBackControl));
|
||||||
|
nphi = _igvn.register_new_node_with_optimizer(nphi);
|
||||||
|
set_ctrl(nphi, get_ctrl(phi));
|
||||||
_igvn.replace_node(phi, nphi);
|
_igvn.replace_node(phi, nphi);
|
||||||
phi = nphi->as_Phi();
|
phi = nphi->as_Phi();
|
||||||
|
}
|
||||||
cmp = cmp->clone();
|
cmp = cmp->clone();
|
||||||
cmp->set_req(1,incr);
|
cmp->set_req(1,incr);
|
||||||
cmp->set_req(2,limit);
|
cmp->set_req(2,limit);
|
||||||
|
@ -1618,8 +1623,6 @@ void PhaseIdealLoop::replace_parallel_iv(IdealLoopTree *loop) {
|
||||||
Node *phi = cl->phi();
|
Node *phi = cl->phi();
|
||||||
int stride_con = cl->stride_con();
|
int stride_con = cl->stride_con();
|
||||||
|
|
||||||
PhaseGVN *gvn = &_igvn;
|
|
||||||
|
|
||||||
// Visit all children, looking for Phis
|
// Visit all children, looking for Phis
|
||||||
for (DUIterator i = cl->outs(); cl->has_out(i); i++) {
|
for (DUIterator i = cl->outs(); cl->has_out(i); i++) {
|
||||||
Node *out = cl->out(i);
|
Node *out = cl->out(i);
|
||||||
|
@ -1655,25 +1658,31 @@ void PhaseIdealLoop::replace_parallel_iv(IdealLoopTree *loop) {
|
||||||
int ratio_con = stride_con2/stride_con;
|
int ratio_con = stride_con2/stride_con;
|
||||||
|
|
||||||
if ((ratio_con * stride_con) == stride_con2) { // Check for exact
|
if ((ratio_con * stride_con) == stride_con2) { // Check for exact
|
||||||
|
#ifndef PRODUCT
|
||||||
|
if (TraceLoopOpts) {
|
||||||
|
tty->print("Parallel IV: %d ", phi2->_idx);
|
||||||
|
loop->dump_head();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// Convert to using the trip counter. The parallel induction
|
// Convert to using the trip counter. The parallel induction
|
||||||
// variable differs from the trip counter by a loop-invariant
|
// variable differs from the trip counter by a loop-invariant
|
||||||
// amount, the difference between their respective initial values.
|
// amount, the difference between their respective initial values.
|
||||||
// It is scaled by the 'ratio_con'.
|
// It is scaled by the 'ratio_con'.
|
||||||
// Perform local Ideal transformation since in most cases ratio == 1.
|
|
||||||
Node* ratio = _igvn.intcon(ratio_con);
|
Node* ratio = _igvn.intcon(ratio_con);
|
||||||
set_ctrl(ratio, C->root());
|
set_ctrl(ratio, C->root());
|
||||||
Node* hook = new (C, 3) Node(3);
|
Node* ratio_init = new (C, 3) MulINode(init, ratio);
|
||||||
Node* ratio_init = gvn->transform(new (C, 3) MulINode(init, ratio));
|
_igvn.register_new_node_with_optimizer(ratio_init, init);
|
||||||
hook->init_req(0, ratio_init);
|
set_early_ctrl(ratio_init);
|
||||||
Node* diff = gvn->transform(new (C, 3) SubINode(init2, ratio_init));
|
Node* diff = new (C, 3) SubINode(init2, ratio_init);
|
||||||
hook->init_req(1, diff);
|
_igvn.register_new_node_with_optimizer(diff, init2);
|
||||||
Node* ratio_idx = gvn->transform(new (C, 3) MulINode(phi, ratio));
|
set_early_ctrl(diff);
|
||||||
hook->init_req(2, ratio_idx);
|
Node* ratio_idx = new (C, 3) MulINode(phi, ratio);
|
||||||
Node* add = gvn->transform(new (C, 3) AddINode(ratio_idx, diff));
|
_igvn.register_new_node_with_optimizer(ratio_idx, phi);
|
||||||
set_subtree_ctrl(add);
|
set_ctrl(ratio_idx, cl);
|
||||||
|
Node* add = new (C, 3) AddINode(ratio_idx, diff);
|
||||||
|
_igvn.register_new_node_with_optimizer(add);
|
||||||
|
set_ctrl(add, cl);
|
||||||
_igvn.replace_node( phi2, add );
|
_igvn.replace_node( phi2, add );
|
||||||
// Free up intermediate goo
|
|
||||||
_igvn.remove_dead_node(hook);
|
|
||||||
// Sometimes an induction variable is unused
|
// Sometimes an induction variable is unused
|
||||||
if (add->outcnt() == 0) {
|
if (add->outcnt() == 0) {
|
||||||
_igvn.remove_dead_node(add);
|
_igvn.remove_dead_node(add);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue