提交 61b11f71 编写于 作者: N never

Merge

...@@ -522,34 +522,40 @@ void PhaseIdealLoop::do_peeling( IdealLoopTree *loop, Node_List &old_new ) { ...@@ -522,34 +522,40 @@ void PhaseIdealLoop::do_peeling( IdealLoopTree *loop, Node_List &old_new ) {
loop->record_for_igvn(); loop->record_for_igvn();
} }
#define EMPTY_LOOP_SIZE 7 // number of nodes in an empty loop
//------------------------------policy_maximally_unroll------------------------ //------------------------------policy_maximally_unroll------------------------
// Return exact loop trip count, or 0 if not maximally unrolling // Calculate exact loop trip count and return true if loop can be maximally
// unrolled.
bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const { bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const {
CountedLoopNode *cl = _head->as_CountedLoop(); CountedLoopNode *cl = _head->as_CountedLoop();
assert(cl->is_normal_loop(), ""); assert(cl->is_normal_loop(), "");
if (!cl->is_valid_counted_loop())
return false; // Malformed counted loop
Node *init_n = cl->init_trip(); Node *init_n = cl->init_trip();
Node *limit_n = cl->limit(); Node *limit_n = cl->limit();
// Non-constant bounds // Non-constant bounds
if (init_n == NULL || !init_n->is_Con() || if (init_n == NULL || !init_n->is_Con() ||
limit_n == NULL || !limit_n->is_Con() || limit_n == NULL || !limit_n->is_Con()) {
// protect against stride not being a constant
!cl->stride_is_con()) {
return false; return false;
} }
int init = init_n->get_int(); // Use longs to avoid integer overflow.
int limit = limit_n->get_int(); int stride_con = cl->stride_con();
int span = limit - init; long init_con = cl->init_trip()->get_int();
int stride = cl->stride_con(); long limit_con = cl->limit()->get_int();
int stride_m = stride_con - (stride_con > 0 ? 1 : -1);
long trip_cnt = (limit_con - init_con + stride_m)/stride_con;
if (init >= limit || stride > span) { // Note, max_jint is used to indicate unknown trip count.
if (trip_cnt <= 0 || trip_cnt >= (long)max_jint) {
// return a false (no maximally unroll) and the regular unroll/peel // return a false (no maximally unroll) and the regular unroll/peel
// route will make a small mess which CCP will fold away. // route will make a small mess which CCP will fold away.
return false; return false;
} }
uint trip_count = span/stride; // trip_count can be greater than 2 Gig. uint trip_count = (uint)trip_cnt;
assert( (int)trip_count*stride == span, "must divide evenly" ); cl->set_trip_count(trip_count);
// Real policy: if we maximally unroll, does it get too big? // Real policy: if we maximally unroll, does it get too big?
// Allow the unrolled mess to get larger than standard loop // Allow the unrolled mess to get larger than standard loop
...@@ -557,15 +563,29 @@ bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const { ...@@ -557,15 +563,29 @@ bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const {
uint body_size = _body.size(); uint body_size = _body.size();
uint unroll_limit = (uint)LoopUnrollLimit * 4; uint unroll_limit = (uint)LoopUnrollLimit * 4;
assert( (intx)unroll_limit == LoopUnrollLimit * 4, "LoopUnrollLimit must fit in 32bits"); assert( (intx)unroll_limit == LoopUnrollLimit * 4, "LoopUnrollLimit must fit in 32bits");
cl->set_trip_count(trip_count);
if (trip_count > unroll_limit || body_size > unroll_limit) { if (trip_count > unroll_limit || body_size > unroll_limit) {
return false; return false;
} }
// Take into account that after unroll conjoined heads and tails will fold,
// otherwise policy_unroll() may allow more unrolling than max unrolling.
uint new_body_size = EMPTY_LOOP_SIZE + (body_size - EMPTY_LOOP_SIZE) * trip_count;
uint tst_body_size = (new_body_size - EMPTY_LOOP_SIZE) / trip_count + EMPTY_LOOP_SIZE;
if (body_size != tst_body_size) // Check for int overflow
return false;
if (new_body_size > unroll_limit ||
// Unrolling can result in a large amount of node construction
new_body_size >= MaxNodeLimit - phase->C->unique()) {
return false;
}
// Currently we don't have policy to optimize one iteration loops. // Currently we don't have policy to optimize one iteration loops.
// Maximally unrolling transformation is used for that: // Maximally unrolling transformation is used for that:
// it is peeled and the original loop become non reachable (dead). // it is peeled and the original loop become non reachable (dead).
if (trip_count == 1) // Also fully unroll a loop with few iterations regardless next
// conditions since following loop optimizations will split
// such loop anyway (pre-main-post).
if (trip_count <= 3)
return true; return true;
// Do not unroll a loop with String intrinsics code. // Do not unroll a loop with String intrinsics code.
...@@ -582,17 +602,7 @@ bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const { ...@@ -582,17 +602,7 @@ bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const {
} // switch } // switch
} }
if (body_size <= unroll_limit) { return true; // Do maximally unroll
uint new_body_size = body_size * trip_count;
if (new_body_size <= unroll_limit &&
body_size == new_body_size / trip_count &&
// Unrolling can result in a large amount of node construction
new_body_size < MaxNodeLimit - phase->C->unique()) {
return true; // maximally unroll
}
}
return false; // Do not maximally unroll
} }
...@@ -604,12 +614,15 @@ bool IdealLoopTree::policy_unroll( PhaseIdealLoop *phase ) const { ...@@ -604,12 +614,15 @@ bool IdealLoopTree::policy_unroll( PhaseIdealLoop *phase ) const {
CountedLoopNode *cl = _head->as_CountedLoop(); CountedLoopNode *cl = _head->as_CountedLoop();
assert(cl->is_normal_loop() || cl->is_main_loop(), ""); assert(cl->is_normal_loop() || cl->is_main_loop(), "");
// protect against stride not being a constant if (!cl->is_valid_counted_loop())
if (!cl->stride_is_con()) return false; return false; // Malformed counted loop
// protect against over-unrolling // protect against over-unrolling
if (cl->trip_count() <= 1) return false; if (cl->trip_count() <= 1) return false;
// Check for stride being a small enough constant
if (abs(cl->stride_con()) > (1<<3)) return false;
int future_unroll_ct = cl->unrolled_count() * 2; int future_unroll_ct = cl->unrolled_count() * 2;
// Don't unroll if the next round of unrolling would push us // Don't unroll if the next round of unrolling would push us
...@@ -690,9 +703,6 @@ bool IdealLoopTree::policy_unroll( PhaseIdealLoop *phase ) const { ...@@ -690,9 +703,6 @@ bool IdealLoopTree::policy_unroll( PhaseIdealLoop *phase ) const {
return false; return false;
} }
// Check for stride being a small enough constant
if (abs(cl->stride_con()) > (1<<3)) return false;
// Unroll once! (Each trip will soon do double iterations) // Unroll once! (Each trip will soon do double iterations)
return true; return true;
} }
...@@ -1086,7 +1096,11 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad ...@@ -1086,7 +1096,11 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
tty->print("Unrolling "); tty->print("Unrolling ");
loop->dump_head(); loop->dump_head();
} else if (TraceLoopOpts) { } else if (TraceLoopOpts) {
tty->print("Unroll %d ", loop_head->unrolled_count()*2); if (loop_head->trip_count() < LoopUnrollLimit) {
tty->print("Unroll %d(%2d) ", loop_head->unrolled_count()*2, loop_head->trip_count());
} else {
tty->print("Unroll %d ", loop_head->unrolled_count()*2);
}
loop->dump_head(); loop->dump_head();
} }
#endif #endif
...@@ -1761,7 +1775,7 @@ void IdealLoopTree::adjust_loop_exit_prob( PhaseIdealLoop *phase ) { ...@@ -1761,7 +1775,7 @@ void IdealLoopTree::adjust_loop_exit_prob( PhaseIdealLoop *phase ) {
// have on the last iteration. This will break the loop. // have on the last iteration. This will break the loop.
bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) { bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) {
// Minimum size must be empty loop // Minimum size must be empty loop
if (_body.size() > 7/*number of nodes in an empty loop*/) if (_body.size() > EMPTY_LOOP_SIZE)
return false; return false;
if (!_head->is_CountedLoop()) if (!_head->is_CountedLoop())
...@@ -1887,6 +1901,12 @@ bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_ ...@@ -1887,6 +1901,12 @@ bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_
} }
} }
// Skip next optimizations if running low on nodes. Note that
// policy_unswitching and policy_maximally_unroll have this check.
uint nodes_left = MaxNodeLimit - phase->C->unique();
if ((2 * _body.size()) > nodes_left) {
return true;
}
// Counted loops may be peeled, may need some iterations run up // Counted loops may be peeled, may need some iterations run up
// front for RCE, and may want to align loop refs to a cache // front for RCE, and may want to align loop refs to a cache
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册