< prev index next >
src/share/vm/opto/loopTransform.cpp
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
--- 1,7 ----
/*
! * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 68,80 ****
_phase->_igvn._worklist.push(n);
}
}
//------------------------------compute_exact_trip_count-----------------------
! // Compute loop exact trip count if possible. Do not recalculate trip count for
// split loops (pre-main-post) which have their limits and inits behind Opaque node.
! void IdealLoopTree::compute_exact_trip_count( PhaseIdealLoop *phase ) {
if (!_head->as_Loop()->is_valid_counted_loop()) {
return;
}
CountedLoopNode* cl = _head->as_CountedLoop();
// Trip count may become nonexact for iteration split loops since
--- 68,80 ----
_phase->_igvn._worklist.push(n);
}
}
//------------------------------compute_exact_trip_count-----------------------
! // Compute loop trip count if possible. Do not recalculate trip count for
// split loops (pre-main-post) which have their limits and inits behind Opaque node.
! void IdealLoopTree::compute_trip_count(PhaseIdealLoop* phase) {
if (!_head->as_Loop()->is_valid_counted_loop()) {
return;
}
CountedLoopNode* cl = _head->as_CountedLoop();
// Trip count may become nonexact for iteration split loops since
*** 92,112 ****
bt == BoolTest::ne, "canonical test is expected");
#endif
Node* init_n = cl->init_trip();
Node* limit_n = cl->limit();
! if (init_n != NULL && init_n->is_Con() &&
! limit_n != NULL && limit_n->is_Con()) {
// Use longs to avoid integer overflow.
int stride_con = cl->stride_con();
! jlong init_con = cl->init_trip()->get_int();
! jlong limit_con = cl->limit()->get_int();
int stride_m = stride_con - (stride_con > 0 ? 1 : -1);
jlong trip_count = (limit_con - init_con + stride_m)/stride_con;
if (trip_count > 0 && (julong)trip_count < (julong)max_juint) {
// Set exact trip count.
cl->set_exact_trip_count((uint)trip_count);
}
}
}
//------------------------------compute_profile_trip_cnt----------------------------
--- 92,116 ----
bt == BoolTest::ne, "canonical test is expected");
#endif
Node* init_n = cl->init_trip();
Node* limit_n = cl->limit();
! if (init_n != NULL && limit_n != NULL) {
// Use longs to avoid integer overflow.
int stride_con = cl->stride_con();
! jlong init_con = phase->_igvn.type(init_n)->is_int()->_lo;
! jlong limit_con = phase->_igvn.type(limit_n)->is_int()->_hi;
int stride_m = stride_con - (stride_con > 0 ? 1 : -1);
jlong trip_count = (limit_con - init_con + stride_m)/stride_con;
if (trip_count > 0 && (julong)trip_count < (julong)max_juint) {
+ if (init_n->is_Con() && limit_n->is_Con()) {
// Set exact trip count.
cl->set_exact_trip_count((uint)trip_count);
+ } else if (cl->is_normal_loop() && cl->unrolled_count() == 1) {
+ // Set maximum trip count before unrolling.
+ cl->set_trip_count((uint)trip_count);
+ }
}
}
}
//------------------------------compute_profile_trip_cnt----------------------------
*** 1303,1313 ****
// Step A: Create a new post-Loop.
Node* main_exit = main_end->proj_out(false);
assert(main_exit->Opcode() == Op_IfFalse, "");
int dd_main_exit = dom_depth(main_exit);
! // Step A1: Clone the loop body of main. The clone becomes the vector post-loop.
// The main loop pre-header illegally has 2 control users (old & new loops).
clone_loop(loop, old_new, dd_main_exit);
assert(old_new[main_end->_idx]->Opcode() == Op_CountedLoopEnd, "");
post_head = old_new[main_head->_idx]->as_CountedLoop();
post_head->set_normal_loop();
--- 1307,1317 ----
// Step A: Create a new post-Loop.
Node* main_exit = main_end->proj_out(false);
assert(main_exit->Opcode() == Op_IfFalse, "");
int dd_main_exit = dom_depth(main_exit);
! // Step A1: Clone the loop body of main. The clone becomes the post-loop.
// The main loop pre-header illegally has 2 control users (old & new loops).
clone_loop(loop, old_new, dd_main_exit);
assert(old_new[main_end->_idx]->Opcode() == Op_CountedLoopEnd, "");
post_head = old_new[main_head->_idx]->as_CountedLoop();
post_head->set_normal_loop();
*** 2093,2104 ****
// Count number of range checks and reduce by load range limits, if zero,
// the loop is in canonical form to multiversion.
closed_range_checks = 0;
! // Check loop body for tests of trip-counter plus loop-invariant vs
! // loop-invariant.
for( uint i = 0; i < loop->_body.size(); i++ ) {
Node *iff = loop->_body[i];
if (iff->Opcode() == Op_If ||
iff->Opcode() == Op_RangeCheck) { // Test?
// Test is an IfNode, has 2 projections. If BOTH are in the loop
--- 2097,2107 ----
// Count number of range checks and reduce by load range limits, if zero,
// the loop is in canonical form to multiversion.
closed_range_checks = 0;
! // Check loop body for tests of trip-counter plus loop-invariant vs loop-variant.
for( uint i = 0; i < loop->_body.size(); i++ ) {
Node *iff = loop->_body[i];
if (iff->Opcode() == Op_If ||
iff->Opcode() == Op_RangeCheck) { // Test?
// Test is an IfNode, has 2 projections. If BOTH are in the loop
*** 2296,2306 ****
CountedLoopNode *cl = loop->_head->as_CountedLoop();
// skip this loop if it is already checked
if (cl->has_been_range_checked()) return;
! // Now check for existance of range checks
for (uint i = 0; i < loop->_body.size(); i++) {
Node *iff = loop->_body[i];
int iff_opc = iff->Opcode();
if (iff_opc == Op_If || iff_opc == Op_RangeCheck) {
cl->mark_has_range_checks();
--- 2299,2309 ----
CountedLoopNode *cl = loop->_head->as_CountedLoop();
// skip this loop if it is already checked
if (cl->has_been_range_checked()) return;
! // Now check for existence of range checks
for (uint i = 0; i < loop->_body.size(); i++) {
Node *iff = loop->_body[i];
int iff_opc = iff->Opcode();
if (iff_opc == Op_If || iff_opc == Op_RangeCheck) {
cl->mark_has_range_checks();
*** 2317,2327 ****
bool multi_version_succeeded = false;
assert(RangeCheckElimination, "");
CountedLoopNode *legacy_cl = legacy_loop->_head->as_CountedLoop();
assert(legacy_cl->is_post_loop(), "");
! // Check for existance of range checks using the unique instance to make a guard with
Unique_Node_List worklist;
for (uint i = 0; i < legacy_loop->_body.size(); i++) {
Node *iff = legacy_loop->_body[i];
int iff_opc = iff->Opcode();
if (iff_opc == Op_If || iff_opc == Op_RangeCheck) {
--- 2320,2330 ----
bool multi_version_succeeded = false;
assert(RangeCheckElimination, "");
CountedLoopNode *legacy_cl = legacy_loop->_head->as_CountedLoop();
assert(legacy_cl->is_post_loop(), "");
! // Check for existence of range checks using the unique instance to make a guard with
Unique_Node_List worklist;
for (uint i = 0; i < legacy_loop->_body.size(); i++) {
Node *iff = legacy_loop->_body[i];
int iff_opc = iff->Opcode();
if (iff_opc == Op_If || iff_opc == Op_RangeCheck) {
*** 2420,2430 ****
return multi_version_succeeded;
}
//-------------------------poison_rce_post_loop--------------------------------
! // Causes the rce'd post loop to be optimized away if multiverioning fails
void PhaseIdealLoop::poison_rce_post_loop(IdealLoopTree *rce_loop) {
CountedLoopNode *rce_cl = rce_loop->_head->as_CountedLoop();
Node* ctrl = rce_cl->in(LoopNode::EntryControl);
if (ctrl->is_IfTrue() || ctrl->is_IfFalse()) {
Node* iffm = ctrl->in(0);
--- 2423,2433 ----
return multi_version_succeeded;
}
//-------------------------poison_rce_post_loop--------------------------------
! // Causes the rce'd post loop to be optimized away if multiversioning fails
void PhaseIdealLoop::poison_rce_post_loop(IdealLoopTree *rce_loop) {
CountedLoopNode *rce_cl = rce_loop->_head->as_CountedLoop();
Node* ctrl = rce_cl->in(LoopNode::EntryControl);
if (ctrl->is_IfTrue() || ctrl->is_IfFalse()) {
Node* iffm = ctrl->in(0);
*** 2708,2719 ****
}
//=============================================================================
//------------------------------iteration_split_impl---------------------------
bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) {
! // Compute exact loop trip count if possible.
! compute_exact_trip_count(phase);
// Convert one iteration loop into normal code.
if (policy_do_one_iteration_loop(phase))
return true;
--- 2711,2722 ----
}
//=============================================================================
//------------------------------iteration_split_impl---------------------------
bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) {
! // Compute loop trip count if possible.
! compute_trip_count(phase);
// Convert one iteration loop into normal code.
if (policy_do_one_iteration_loop(phase))
return true;
< prev index next >