annotate src/share/vm/opto/loopTransform.cpp @ 4710:41406797186b

7113012: G1: rename not-fully-young GCs as "mixed" Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets). Reviewed-by: johnc, brutisso
author tonyp
date Fri, 16 Dec 2011 02:14:27 -0500
parents da6a29fb0da5
children 5e990493719e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2426
1d1603768966 7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents: 2417
diff changeset
2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1303
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1303
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1303
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
26 #include "compiler/compileLog.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
27 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
28 #include "opto/addnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
29 #include "opto/callnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
30 #include "opto/connode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
31 #include "opto/divnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
32 #include "opto/loopnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
33 #include "opto/mulnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
34 #include "opto/rootnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
35 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1844
diff changeset
36 #include "opto/subnode.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 //------------------------------is_loop_exit-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // Given an IfNode, return the loop-exiting projection or NULL if both
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // arms remain in the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
41 Node *IdealLoopTree::is_loop_exit(Node *iff) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
42 if( iff->outcnt() != 2 ) return NULL; // Ignore partially dead tests
a61af66fc99e Initial load
duke
parents:
diff changeset
43 PhaseIdealLoop *phase = _phase;
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // Test is an IfNode, has 2 projections. If BOTH are in the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // we need loop unswitching instead of peeling.
a61af66fc99e Initial load
duke
parents:
diff changeset
46 if( !is_member(phase->get_loop( iff->raw_out(0) )) )
a61af66fc99e Initial load
duke
parents:
diff changeset
47 return iff->raw_out(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
48 if( !is_member(phase->get_loop( iff->raw_out(1) )) )
a61af66fc99e Initial load
duke
parents:
diff changeset
49 return iff->raw_out(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
50 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 }
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 //------------------------------record_for_igvn----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // Put loop body on igvn work list
a61af66fc99e Initial load
duke
parents:
diff changeset
59 void IdealLoopTree::record_for_igvn() {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 for( uint i = 0; i < _body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 Node *n = _body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
62 _phase->_igvn._worklist.push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
63 }
a61af66fc99e Initial load
duke
parents:
diff changeset
64 }
a61af66fc99e Initial load
duke
parents:
diff changeset
65
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
66 //------------------------------compute_exact_trip_count-----------------------
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
67 // Compute loop exact trip count if possible. Do not recalculate trip count for
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
68 // split loops (pre-main-post) which have their limits and inits behind Opaque node.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
69 void IdealLoopTree::compute_exact_trip_count( PhaseIdealLoop *phase ) {
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
70 if (!_head->as_Loop()->is_valid_counted_loop()) {
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
71 return;
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
72 }
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
73 CountedLoopNode* cl = _head->as_CountedLoop();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
74 // Trip count may become nonexact for iteration split loops since
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
75 // RCE modifies limits. Note, _trip_count value is not reset since
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
76 // it is used to limit unrolling of main loop.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
77 cl->set_nonexact_trip_count();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
78
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
79 // Loop's test should be part of loop.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
80 if (!phase->is_member(this, phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue))))
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
81 return; // Infinite loop
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
82
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
83 #ifdef ASSERT
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
84 BoolTest::mask bt = cl->loopexit()->test_trip();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
85 assert(bt == BoolTest::lt || bt == BoolTest::gt ||
3782
aacaff365100 7052494: Eclipse test fails on JDK 7 b142
kvn
parents: 3398
diff changeset
86 bt == BoolTest::ne, "canonical test is expected");
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
87 #endif
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
88
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
89 Node* init_n = cl->init_trip();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
90 Node* limit_n = cl->limit();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
91 if (init_n != NULL && init_n->is_Con() &&
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
92 limit_n != NULL && limit_n->is_Con()) {
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
93 // Use longs to avoid integer overflow.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
94 int stride_con = cl->stride_con();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
95 long init_con = cl->init_trip()->get_int();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
96 long limit_con = cl->limit()->get_int();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
97 int stride_m = stride_con - (stride_con > 0 ? 1 : -1);
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
98 long trip_count = (limit_con - init_con + stride_m)/stride_con;
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
99 if (trip_count > 0 && (julong)trip_count < (julong)max_juint) {
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
100 // Set exact trip count.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
101 cl->set_exact_trip_count((uint)trip_count);
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
102 }
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
103 }
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
104 }
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
105
0
a61af66fc99e Initial load
duke
parents:
diff changeset
106 //------------------------------compute_profile_trip_cnt----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // Compute loop trip count from profile data as
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // (backedge_count + loop_exit_count) / loop_exit_count
a61af66fc99e Initial load
duke
parents:
diff changeset
109 void IdealLoopTree::compute_profile_trip_cnt( PhaseIdealLoop *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 if (!_head->is_CountedLoop()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
113 CountedLoopNode* head = _head->as_CountedLoop();
a61af66fc99e Initial load
duke
parents:
diff changeset
114 if (head->profile_trip_cnt() != COUNT_UNKNOWN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
115 return; // Already computed
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117 float trip_cnt = (float)max_jint; // default is big
a61af66fc99e Initial load
duke
parents:
diff changeset
118
a61af66fc99e Initial load
duke
parents:
diff changeset
119 Node* back = head->in(LoopNode::LoopBackControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
120 while (back != head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 if ((back->Opcode() == Op_IfTrue || back->Opcode() == Op_IfFalse) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
122 back->in(0) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
123 back->in(0)->is_If() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
124 back->in(0)->as_If()->_fcnt != COUNT_UNKNOWN &&
a61af66fc99e Initial load
duke
parents:
diff changeset
125 back->in(0)->as_If()->_prob != PROB_UNKNOWN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128 back = phase->idom(back);
a61af66fc99e Initial load
duke
parents:
diff changeset
129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
130 if (back != head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 assert((back->Opcode() == Op_IfTrue || back->Opcode() == Op_IfFalse) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
132 back->in(0), "if-projection exists");
a61af66fc99e Initial load
duke
parents:
diff changeset
133 IfNode* back_if = back->in(0)->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
134 float loop_back_cnt = back_if->_fcnt * back_if->_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // Now compute a loop exit count
a61af66fc99e Initial load
duke
parents:
diff changeset
137 float loop_exit_cnt = 0.0f;
a61af66fc99e Initial load
duke
parents:
diff changeset
138 for( uint i = 0; i < _body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
139 Node *n = _body[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
140 if( n->is_If() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 IfNode *iff = n->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
142 if( iff->_fcnt != COUNT_UNKNOWN && iff->_prob != PROB_UNKNOWN ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
143 Node *exit = is_loop_exit(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
144 if( exit ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
145 float exit_prob = iff->_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 if (exit->Opcode() == Op_IfFalse) exit_prob = 1.0 - exit_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 if (exit_prob > PROB_MIN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 float exit_cnt = iff->_fcnt * exit_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 loop_exit_cnt += exit_cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
155 if (loop_exit_cnt > 0.0f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 trip_cnt = (loop_back_cnt + loop_exit_cnt) / loop_exit_cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // No exit count so use
a61af66fc99e Initial load
duke
parents:
diff changeset
159 trip_cnt = loop_back_cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
163 if (TraceProfileTripCount) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 tty->print_cr("compute_profile_trip_cnt lp: %d cnt: %f\n", head->_idx, trip_cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
167 head->set_profile_trip_cnt(trip_cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 //---------------------is_invariant_addition-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Return nonzero index of invariant operand for an Add or Sub
605
98cb887364d3 6810672: Comment typos
twisti
parents: 420
diff changeset
172 // of (nonconstant) invariant and variant values. Helper for reassociate_invariants.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
173 int IdealLoopTree::is_invariant_addition(Node* n, PhaseIdealLoop *phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 int op = n->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
175 if (op == Op_AddI || op == Op_SubI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
176 bool in1_invar = this->is_invariant(n->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
177 bool in2_invar = this->is_invariant(n->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
178 if (in1_invar && !in2_invar) return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
179 if (!in1_invar && in2_invar) return 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
181 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 //---------------------reassociate_add_sub-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // Reassociate invariant add and subtract expressions:
a61af66fc99e Initial load
duke
parents:
diff changeset
186 //
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // inv1 + (x + inv2) => ( inv1 + inv2) + x
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // (x + inv2) + inv1 => ( inv1 + inv2) + x
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // inv1 + (x - inv2) => ( inv1 - inv2) + x
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // inv1 - (inv2 - x) => ( inv1 - inv2) + x
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // (x + inv2) - inv1 => (-inv1 + inv2) + x
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // (x - inv2) + inv1 => ( inv1 - inv2) + x
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // (x - inv2) - inv1 => (-inv1 - inv2) + x
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // inv1 + (inv2 - x) => ( inv1 + inv2) - x
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // inv1 - (x - inv2) => ( inv1 + inv2) - x
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // (inv2 - x) + inv1 => ( inv1 + inv2) - x
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // (inv2 - x) - inv1 => (-inv1 + inv2) - x
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // inv1 - (x + inv2) => ( inv1 - inv2) - x
a61af66fc99e Initial load
duke
parents:
diff changeset
199 //
a61af66fc99e Initial load
duke
parents:
diff changeset
200 Node* IdealLoopTree::reassociate_add_sub(Node* n1, PhaseIdealLoop *phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
201 if (!n1->is_Add() && !n1->is_Sub() || n1->outcnt() == 0) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 if (is_invariant(n1)) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 int inv1_idx = is_invariant_addition(n1, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
204 if (!inv1_idx) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // Don't mess with add of constant (igvn moves them to expression tree root.)
a61af66fc99e Initial load
duke
parents:
diff changeset
206 if (n1->is_Add() && n1->in(2)->is_Con()) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 Node* inv1 = n1->in(inv1_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
208 Node* n2 = n1->in(3 - inv1_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 int inv2_idx = is_invariant_addition(n2, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
210 if (!inv2_idx) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
211 Node* x = n2->in(3 - inv2_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
212 Node* inv2 = n2->in(inv2_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
213
a61af66fc99e Initial load
duke
parents:
diff changeset
214 bool neg_x = n2->is_Sub() && inv2_idx == 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 bool neg_inv2 = n2->is_Sub() && inv2_idx == 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 bool neg_inv1 = n1->is_Sub() && inv1_idx == 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if (n1->is_Sub() && inv1_idx == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 neg_x = !neg_x;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 neg_inv2 = !neg_inv2;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221 Node* inv1_c = phase->get_ctrl(inv1);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 Node* inv2_c = phase->get_ctrl(inv2);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 Node* n_inv1;
a61af66fc99e Initial load
duke
parents:
diff changeset
224 if (neg_inv1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 Node *zero = phase->_igvn.intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
226 phase->set_ctrl(zero, phase->C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
227 n_inv1 = new (phase->C, 3) SubINode(zero, inv1);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 phase->register_new_node(n_inv1, inv1_c);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 n_inv1 = inv1;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232 Node* inv;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 if (neg_inv2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 inv = new (phase->C, 3) SubINode(n_inv1, inv2);
a61af66fc99e Initial load
duke
parents:
diff changeset
235 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 inv = new (phase->C, 3) AddINode(n_inv1, inv2);
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238 phase->register_new_node(inv, phase->get_early_ctrl(inv));
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 Node* addx;
a61af66fc99e Initial load
duke
parents:
diff changeset
241 if (neg_x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
242 addx = new (phase->C, 3) SubINode(inv, x);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
244 addx = new (phase->C, 3) AddINode(x, inv);
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246 phase->register_new_node(addx, phase->get_ctrl(x));
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1552
diff changeset
247 phase->_igvn.replace_node(n1, addx);
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
248 assert(phase->get_loop(phase->get_ctrl(n1)) == this, "");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
249 _body.yank(n1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
250 return addx;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 //---------------------reassociate_invariants-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // Reassociate invariant expressions:
a61af66fc99e Initial load
duke
parents:
diff changeset
255 void IdealLoopTree::reassociate_invariants(PhaseIdealLoop *phase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
256 for (int i = _body.size() - 1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
257 Node *n = _body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
258 for (int j = 0; j < 5; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
259 Node* nn = reassociate_add_sub(n, phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
260 if (nn == NULL) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
261 n = nn; // again
a61af66fc99e Initial load
duke
parents:
diff changeset
262 };
a61af66fc99e Initial load
duke
parents:
diff changeset
263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
265
a61af66fc99e Initial load
duke
parents:
diff changeset
266 //------------------------------policy_peeling---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // Return TRUE or FALSE if the loop should be peeled or not. Peel if we can
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // make some loop-invariant test (usually a null-check) happen before the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
269 bool IdealLoopTree::policy_peeling( PhaseIdealLoop *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
270 Node *test = ((IdealLoopTree*)this)->tail();
a61af66fc99e Initial load
duke
parents:
diff changeset
271 int body_size = ((IdealLoopTree*)this)->_body.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
272 int uniq = phase->C->unique();
a61af66fc99e Initial load
duke
parents:
diff changeset
273 // Peeling does loop cloning which can result in O(N^2) node construction
a61af66fc99e Initial load
duke
parents:
diff changeset
274 if( body_size > 255 /* Prevent overflow for large body_size */
a61af66fc99e Initial load
duke
parents:
diff changeset
275 || (body_size * body_size + uniq > MaxNodeLimit) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
276 return false; // too large to safely clone
a61af66fc99e Initial load
duke
parents:
diff changeset
277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
278 while( test != _head ) { // Scan till run off top of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
279 if( test->is_If() ) { // Test?
a61af66fc99e Initial load
duke
parents:
diff changeset
280 Node *ctrl = phase->get_ctrl(test->in(1));
a61af66fc99e Initial load
duke
parents:
diff changeset
281 if (ctrl->is_top())
a61af66fc99e Initial load
duke
parents:
diff changeset
282 return false; // Found dead test on live IF? No peeling!
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // Standard IF only has one input value to check for loop invariance
a61af66fc99e Initial load
duke
parents:
diff changeset
284 assert( test->Opcode() == Op_If || test->Opcode() == Op_CountedLoopEnd, "Check this code when new subtype is added");
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // Condition is not a member of this loop?
a61af66fc99e Initial load
duke
parents:
diff changeset
286 if( !is_member(phase->get_loop(ctrl)) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
287 is_loop_exit(test) )
a61af66fc99e Initial load
duke
parents:
diff changeset
288 return true; // Found reason to peel!
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // Walk up dominators to loop _head looking for test which is
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // executed on every path thru loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
292 test = phase->idom(test);
a61af66fc99e Initial load
duke
parents:
diff changeset
293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
294 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297 //------------------------------peeled_dom_test_elim---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // If we got the effect of peeling, either by actually peeling or by making
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // a pre-loop which must execute at least once, we can remove all
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // loop-invariant dominated tests in the main body.
a61af66fc99e Initial load
duke
parents:
diff changeset
301 void PhaseIdealLoop::peeled_dom_test_elim( IdealLoopTree *loop, Node_List &old_new ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
302 bool progress = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
303 while( progress ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 progress = false; // Reset for next iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
305 Node *prev = loop->_head->in(LoopNode::LoopBackControl);//loop->tail();
a61af66fc99e Initial load
duke
parents:
diff changeset
306 Node *test = prev->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
307 while( test != loop->_head ) { // Scan till run off top of loop
a61af66fc99e Initial load
duke
parents:
diff changeset
308
a61af66fc99e Initial load
duke
parents:
diff changeset
309 int p_op = prev->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
310 if( (p_op == Op_IfFalse || p_op == Op_IfTrue) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
311 test->is_If() && // Test?
a61af66fc99e Initial load
duke
parents:
diff changeset
312 !test->in(1)->is_Con() && // And not already obvious?
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // Condition is not a member of this loop?
a61af66fc99e Initial load
duke
parents:
diff changeset
314 !loop->is_member(get_loop(get_ctrl(test->in(1))))){
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // Walk loop body looking for instances of this test
a61af66fc99e Initial load
duke
parents:
diff changeset
316 for( uint i = 0; i < loop->_body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 Node *n = loop->_body.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
318 if( n->is_If() && n->in(1) == test->in(1) /*&& n != loop->tail()->in(0)*/ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // IfNode was dominated by version in peeled loop body
a61af66fc99e Initial load
duke
parents:
diff changeset
320 progress = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
321 dominated_by( old_new[prev->_idx], n );
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
325 prev = test;
a61af66fc99e Initial load
duke
parents:
diff changeset
326 test = idom(test);
a61af66fc99e Initial load
duke
parents:
diff changeset
327 } // End of scan tests in loop
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329 } // End of while( progress )
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 //------------------------------do_peeling-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // Peel the first iteration of the given loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // Step 1: Clone the loop body. The clone becomes the peeled iteration.
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // The pre-loop illegally has 2 control users (old & new loops).
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // Step 2: Make the old-loop fall-in edges point to the peeled iteration.
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // Do this by making the old-loop fall-in edges act as if they came
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // around the loopback from the prior iteration (follow the old-loop
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // backedges) and then map to the new peeled iteration. This leaves
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // the pre-loop with only 1 user (the new peeled iteration), but the
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // peeled-loop backedge has 2 users.
a61af66fc99e Initial load
duke
parents:
diff changeset
342 // Step 3: Cut the backedge on the clone (so its not a loop) and remove the
a61af66fc99e Initial load
duke
parents:
diff changeset
343 // extra backedge user.
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
344 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
345 // orig
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
346 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
347 // stmt1
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
348 // |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
349 // v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
350 // loop predicate
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
351 // |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
352 // v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
353 // loop<----+
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
354 // | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
355 // stmt2 |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
356 // | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
357 // v |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
358 // if ^
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
359 // / \ |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
360 // / \ |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
361 // v v |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
362 // false true |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
363 // / \ |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
364 // / ----+
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
365 // |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
366 // v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
367 // exit
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
368 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
369 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
370 // after clone loop
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
371 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
372 // stmt1
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
373 // |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
374 // v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
375 // loop predicate
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
376 // / \
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
377 // clone / \ orig
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
378 // / \
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
379 // / \
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
380 // v v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
381 // +---->loop clone loop<----+
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
382 // | | | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
383 // | stmt2 clone stmt2 |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
384 // | | | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
385 // | v v |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
386 // ^ if clone If ^
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
387 // | / \ / \ |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
388 // | / \ / \ |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
389 // | v v v v |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
390 // | true false false true |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
391 // | / \ / \ |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
392 // +---- \ / ----+
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
393 // \ /
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
394 // 1v v2
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
395 // region
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
396 // |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
397 // v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
398 // exit
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
399 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
400 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
401 // after peel and predicate move
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
402 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
403 // stmt1
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
404 // /
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
405 // /
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
406 // clone / orig
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
407 // /
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
408 // / +----------+
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
409 // / | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
410 // / loop predicate |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
411 // / | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
412 // v v |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
413 // TOP-->loop clone loop<----+ |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
414 // | | | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
415 // stmt2 clone stmt2 | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
416 // | | | ^
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
417 // v v | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
418 // if clone If ^ |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
419 // / \ / \ | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
420 // / \ / \ | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
421 // v v v v | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
422 // true false false true | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
423 // | \ / \ | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
424 // | \ / ----+ ^
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
425 // | \ / |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
426 // | 1v v2 |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
427 // v region |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
428 // | | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
429 // | v |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
430 // | exit |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
431 // | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
432 // +--------------->-----------------+
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
433 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
434 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
435 // final graph
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
436 //
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
437 // stmt1
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
438 // |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
439 // v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
440 // stmt2 clone
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
441 // |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
442 // v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
443 // if clone
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
444 // / |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
445 // / |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
446 // v v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
447 // false true
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
448 // | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
449 // | v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
450 // | loop predicate
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
451 // | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
452 // | v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
453 // | loop<----+
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
454 // | | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
455 // | stmt2 |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
456 // | | |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
457 // | v |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
458 // v if ^
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
459 // | / \ |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
460 // | / \ |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
461 // | v v |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
462 // | false true |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
463 // | | \ |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
464 // v v --+
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
465 // region
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
466 // |
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
467 // v
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
468 // exit
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
469 //
0
a61af66fc99e Initial load
duke
parents:
diff changeset
470 void PhaseIdealLoop::do_peeling( IdealLoopTree *loop, Node_List &old_new ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
471
a61af66fc99e Initial load
duke
parents:
diff changeset
472 C->set_major_progress();
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // Peeling a 'main' loop in a pre/main/post situation obfuscates the
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // 'pre' loop from the main and the 'pre' can no longer have it's
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // iterations adjusted. Therefore, we need to declare this loop as
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // no longer a 'main' loop; it will need new pre and post loops before
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // we can do further RCE.
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
478 #ifndef PRODUCT
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
479 if (TraceLoopOpts) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
480 tty->print("Peel ");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
481 loop->dump_head();
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
482 }
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
483 #endif
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
484 Node* head = loop->_head;
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
485 bool counted_loop = head->is_CountedLoop();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
486 if (counted_loop) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
487 CountedLoopNode *cl = head->as_CountedLoop();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
488 assert(cl->trip_count() > 0, "peeling a fully unrolled loop");
a61af66fc99e Initial load
duke
parents:
diff changeset
489 cl->set_trip_count(cl->trip_count() - 1);
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
490 if (cl->is_main_loop()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
491 cl->set_normal_loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
492 #ifndef PRODUCT
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
493 if (PrintOpto && VerifyLoopOptimizations) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
494 tty->print("Peeling a 'main' loop; resetting to 'normal' ");
a61af66fc99e Initial load
duke
parents:
diff changeset
495 loop->dump_head();
a61af66fc99e Initial load
duke
parents:
diff changeset
496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
497 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
498 }
a61af66fc99e Initial load
duke
parents:
diff changeset
499 }
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
500 Node* entry = head->in(LoopNode::EntryControl);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
501
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // Step 1: Clone the loop body. The clone becomes the peeled iteration.
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // The pre-loop illegally has 2 control users (old & new loops).
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
504 clone_loop( loop, old_new, dom_depth(head) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
505
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // Step 2: Make the old-loop fall-in edges point to the peeled iteration.
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // Do this by making the old-loop fall-in edges act as if they came
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // around the loopback from the prior iteration (follow the old-loop
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // backedges) and then map to the new peeled iteration. This leaves
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // the pre-loop with only 1 user (the new peeled iteration), but the
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // peeled-loop backedge has 2 users.
3845
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3788
diff changeset
512 Node* new_entry = old_new[head->in(LoopNode::LoopBackControl)->_idx];
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
513 _igvn.hash_delete(head);
3845
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3788
diff changeset
514 head->set_req(LoopNode::EntryControl, new_entry);
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
515 for (DUIterator_Fast jmax, j = head->fast_outs(jmax); j < jmax; j++) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
516 Node* old = head->fast_out(j);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
517 if (old->in(0) == loop->_head && old->req() == 3 && old->is_Phi()) {
3845
c96c3eb1efae 7068051: SIGSEGV in PhaseIdealLoop::build_loop_late_post
kvn
parents: 3788
diff changeset
518 Node* new_exit_value = old_new[old->in(LoopNode::LoopBackControl)->_idx];
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
519 if (!new_exit_value ) // Backedge value is ALSO loop invariant?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
520 // Then loop body backedge value remains the same.
a61af66fc99e Initial load
duke
parents:
diff changeset
521 new_exit_value = old->in(LoopNode::LoopBackControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
522 _igvn.hash_delete(old);
a61af66fc99e Initial load
duke
parents:
diff changeset
523 old->set_req(LoopNode::EntryControl, new_exit_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
526
a61af66fc99e Initial load
duke
parents:
diff changeset
527
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // Step 3: Cut the backedge on the clone (so its not a loop) and remove the
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // extra backedge user.
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
530 Node* new_head = old_new[head->_idx];
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
531 _igvn.hash_delete(new_head);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
532 new_head->set_req(LoopNode::LoopBackControl, C->top());
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
533 for (DUIterator_Fast j2max, j2 = new_head->fast_outs(j2max); j2 < j2max; j2++) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
534 Node* use = new_head->fast_out(j2);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
535 if (use->in(0) == new_head && use->req() == 3 && use->is_Phi()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
536 _igvn.hash_delete(use);
a61af66fc99e Initial load
duke
parents:
diff changeset
537 use->set_req(LoopNode::LoopBackControl, C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
540
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // Step 4: Correct dom-depth info. Set to loop-head depth.
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
543 int dd = dom_depth(head);
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
544 set_idom(head, head->in(1), dd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
545 for (uint j3 = 0; j3 < loop->_body.size(); j3++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
546 Node *old = loop->_body.at(j3);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 Node *nnn = old_new[old->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
548 if (!has_ctrl(nnn))
a61af66fc99e Initial load
duke
parents:
diff changeset
549 set_idom(nnn, idom(nnn), dd-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // While we're at it, remove any SafePoints from the peeled code
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
551 if (old->Opcode() == Op_SafePoint) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
552 Node *nnn = old_new[old->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
553 lazy_replace(nnn,nnn->in(TypeFunc::Control));
a61af66fc99e Initial load
duke
parents:
diff changeset
554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
556
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // Now force out all loop-invariant dominating tests. The optimizer
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // finds some, but we _know_ they are all useless.
a61af66fc99e Initial load
duke
parents:
diff changeset
559 peeled_dom_test_elim(loop,old_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
560
a61af66fc99e Initial load
duke
parents:
diff changeset
561 loop->record_for_igvn();
a61af66fc99e Initial load
duke
parents:
diff changeset
562 }
a61af66fc99e Initial load
duke
parents:
diff changeset
563
2453
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
564 #define EMPTY_LOOP_SIZE 7 // number of nodes in an empty loop
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
565
0
a61af66fc99e Initial load
duke
parents:
diff changeset
566 //------------------------------policy_maximally_unroll------------------------
2453
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
567 // Calculate exact loop trip count and return true if loop can be maximally
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
568 // unrolled.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
569 bool IdealLoopTree::policy_maximally_unroll( PhaseIdealLoop *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
570 CountedLoopNode *cl = _head->as_CountedLoop();
2412
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
571 assert(cl->is_normal_loop(), "");
2453
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
572 if (!cl->is_valid_counted_loop())
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
573 return false; // Malformed counted loop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
574
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
575 if (!cl->has_exact_trip_count()) {
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
576 // Trip count is not exact.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
577 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
579
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
580 uint trip_count = cl->trip_count();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
581 // Note, max_juint is used to indicate unknown trip count.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
582 assert(trip_count > 1, "one iteration loop should be optimized out already");
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
583 assert(trip_count < max_juint, "exact trip_count should be less than max_uint.");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
584
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // Real policy: if we maximally unroll, does it get too big?
a61af66fc99e Initial load
duke
parents:
diff changeset
586 // Allow the unrolled mess to get larger than standard loop
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // size. After all, it will no longer be a loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
588 uint body_size = _body.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
589 uint unroll_limit = (uint)LoopUnrollLimit * 4;
a61af66fc99e Initial load
duke
parents:
diff changeset
590 assert( (intx)unroll_limit == LoopUnrollLimit * 4, "LoopUnrollLimit must fit in 32bits");
2412
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
591 if (trip_count > unroll_limit || body_size > unroll_limit) {
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
592 return false;
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
593 }
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
594
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
595 // Fully unroll a loop with few iterations regardless next
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
596 // conditions since following loop optimizations will split
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
597 // such loop anyway (pre-main-post).
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
598 if (trip_count <= 3)
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
599 return true;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
600
2453
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
601 // Take into account that after unroll conjoined heads and tails will fold,
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
602 // otherwise policy_unroll() may allow more unrolling than max unrolling.
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
603 uint new_body_size = EMPTY_LOOP_SIZE + (body_size - EMPTY_LOOP_SIZE) * trip_count;
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
604 uint tst_body_size = (new_body_size - EMPTY_LOOP_SIZE) / trip_count + EMPTY_LOOP_SIZE;
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
605 if (body_size != tst_body_size) // Check for int overflow
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
606 return false;
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
607 if (new_body_size > unroll_limit ||
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
608 // Unrolling can result in a large amount of node construction
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
609 new_body_size >= MaxNodeLimit - phase->C->unique()) {
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
610 return false;
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
611 }
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
612
2412
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
613 // Do not unroll a loop with String intrinsics code.
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
614 // String intrinsics are large and have loops.
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
615 for (uint k = 0; k < _body.size(); k++) {
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
616 Node* n = _body.at(k);
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
617 switch (n->Opcode()) {
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
618 case Op_StrComp:
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
619 case Op_StrEquals:
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
620 case Op_StrIndexOf:
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
621 case Op_AryEq: {
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
622 return false;
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
623 }
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
624 } // switch
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
625 }
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
626
2453
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
627 return true; // Do maximally unroll
0
a61af66fc99e Initial load
duke
parents:
diff changeset
628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630
3333
ae93231c7a1f 7039652: Performance regression after 7004547 changes
kvn
parents: 2468
diff changeset
631 #define MAX_UNROLL 16 // maximum number of unrolls for main loop
ae93231c7a1f 7039652: Performance regression after 7004547 changes
kvn
parents: 2468
diff changeset
632
0
a61af66fc99e Initial load
duke
parents:
diff changeset
633 //------------------------------policy_unroll----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // Return TRUE or FALSE if the loop should be unrolled or not. Unroll if
a61af66fc99e Initial load
duke
parents:
diff changeset
635 // the loop is a CountedLoop and the body is small enough.
a61af66fc99e Initial load
duke
parents:
diff changeset
636 bool IdealLoopTree::policy_unroll( PhaseIdealLoop *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 CountedLoopNode *cl = _head->as_CountedLoop();
2412
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
639 assert(cl->is_normal_loop() || cl->is_main_loop(), "");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
640
2453
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
641 if (!cl->is_valid_counted_loop())
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
642 return false; // Malformed counted loop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
643
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
644 // Protect against over-unrolling.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
645 // After split at least one iteration will be executed in pre-loop.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
646 if (cl->trip_count() <= (uint)(cl->is_normal_loop() ? 2 : 1)) return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
647
3333
ae93231c7a1f 7039652: Performance regression after 7004547 changes
kvn
parents: 2468
diff changeset
648 int future_unroll_ct = cl->unrolled_count() * 2;
ae93231c7a1f 7039652: Performance regression after 7004547 changes
kvn
parents: 2468
diff changeset
649 if (future_unroll_ct > MAX_UNROLL) return false;
2453
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
650
3333
ae93231c7a1f 7039652: Performance regression after 7004547 changes
kvn
parents: 2468
diff changeset
651 // Check for initial stride being a small enough constant
ae93231c7a1f 7039652: Performance regression after 7004547 changes
kvn
parents: 2468
diff changeset
652 if (abs(cl->stride_con()) > (1<<2)*future_unroll_ct) return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
653
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // Don't unroll if the next round of unrolling would push us
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // over the expected trip count of the loop. One is subtracted
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // from the expected trip count because the pre-loop normally
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // executes 1 iteration.
a61af66fc99e Initial load
duke
parents:
diff changeset
658 if (UnrollLimitForProfileCheck > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
659 cl->profile_trip_cnt() != COUNT_UNKNOWN &&
a61af66fc99e Initial load
duke
parents:
diff changeset
660 future_unroll_ct > UnrollLimitForProfileCheck &&
a61af66fc99e Initial load
duke
parents:
diff changeset
661 (float)future_unroll_ct > cl->profile_trip_cnt() - 1.0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
662 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
664
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // When unroll count is greater than LoopUnrollMin, don't unroll if:
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // the residual iterations are more than 10% of the trip count
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // and rounds of "unroll,optimize" are not making significant progress
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // Progress defined as current size less than 20% larger than previous size.
a61af66fc99e Initial load
duke
parents:
diff changeset
669 if (UseSuperWord && cl->node_count_before_unroll() > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
670 future_unroll_ct > LoopUnrollMin &&
a61af66fc99e Initial load
duke
parents:
diff changeset
671 (future_unroll_ct - 1) * 10.0 > cl->profile_trip_cnt() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
672 1.2 * cl->node_count_before_unroll() < (double)_body.size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
673 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
675
a61af66fc99e Initial load
duke
parents:
diff changeset
676 Node *init_n = cl->init_trip();
a61af66fc99e Initial load
duke
parents:
diff changeset
677 Node *limit_n = cl->limit();
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
678 int stride_con = cl->stride_con();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // Non-constant bounds.
a61af66fc99e Initial load
duke
parents:
diff changeset
680 // Protect against over-unrolling when init or/and limit are not constant
a61af66fc99e Initial load
duke
parents:
diff changeset
681 // (so that trip_count's init value is maxint) but iv range is known.
2412
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
682 if (init_n == NULL || !init_n->is_Con() ||
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
683 limit_n == NULL || !limit_n->is_Con()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
684 Node* phi = cl->phi();
2412
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
685 if (phi != NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
686 assert(phi->is_Phi() && phi->in(0) == _head, "Counted loop should have iv phi.");
a61af66fc99e Initial load
duke
parents:
diff changeset
687 const TypeInt* iv_type = phase->_igvn.type(phi)->is_int();
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
688 int next_stride = stride_con * 2; // stride after this unroll
2412
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
689 if (next_stride > 0) {
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
690 if (iv_type->_lo + next_stride <= iv_type->_lo || // overflow
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
691 iv_type->_lo + next_stride > iv_type->_hi) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
692 return false; // over-unrolling
a61af66fc99e Initial load
duke
parents:
diff changeset
693 }
2412
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
694 } else if (next_stride < 0) {
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
695 if (iv_type->_hi + next_stride >= iv_type->_hi || // overflow
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
696 iv_type->_hi + next_stride < iv_type->_lo) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
697 return false; // over-unrolling
a61af66fc99e Initial load
duke
parents:
diff changeset
698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
702
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
703 // After unroll limit will be adjusted: new_limit = limit-stride.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
704 // Bailout if adjustment overflow.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
705 const TypeInt* limit_type = phase->_igvn.type(limit_n)->is_int();
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
706 if (stride_con > 0 && ((limit_type->_hi - stride_con) >= limit_type->_hi) ||
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
707 stride_con < 0 && ((limit_type->_lo - stride_con) <= limit_type->_lo))
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
708 return false; // overflow
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
709
0
a61af66fc99e Initial load
duke
parents:
diff changeset
710 // Adjust body_size to determine if we unroll or not
a61af66fc99e Initial load
duke
parents:
diff changeset
711 uint body_size = _body.size();
3930
da6a29fb0da5 7054211: No loop unrolling done in jdk7b144 for a test update() while loop
kvn
parents: 3850
diff changeset
712 // Key test to unroll loop in CRC32 java code
da6a29fb0da5 7054211: No loop unrolling done in jdk7b144 for a test update() while loop
kvn
parents: 3850
diff changeset
713 int xors_in_loop = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // Also count ModL, DivL and MulL which expand mightly
2412
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
715 for (uint k = 0; k < _body.size(); k++) {
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
716 Node* n = _body.at(k);
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
717 switch (n->Opcode()) {
3930
da6a29fb0da5 7054211: No loop unrolling done in jdk7b144 for a test update() while loop
kvn
parents: 3850
diff changeset
718 case Op_XorI: xors_in_loop++; break; // CRC32 java code
2412
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
719 case Op_ModL: body_size += 30; break;
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
720 case Op_DivL: body_size += 30; break;
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
721 case Op_MulL: body_size += 10; break;
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
722 case Op_StrComp:
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
723 case Op_StrEquals:
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
724 case Op_StrIndexOf:
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
725 case Op_AryEq: {
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
726 // Do not unroll a loop with String intrinsics code.
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
727 // String intrinsics are large and have loops.
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
728 return false;
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
729 }
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
730 } // switch
0
a61af66fc99e Initial load
duke
parents:
diff changeset
731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
732
a61af66fc99e Initial load
duke
parents:
diff changeset
733 // Check for being too big
2412
f9424955eb18 7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents: 2403
diff changeset
734 if (body_size > (uint)LoopUnrollLimit) {
3930
da6a29fb0da5 7054211: No loop unrolling done in jdk7b144 for a test update() while loop
kvn
parents: 3850
diff changeset
735 if (xors_in_loop >= 4 && body_size < (uint)LoopUnrollLimit*4) return true;
da6a29fb0da5 7054211: No loop unrolling done in jdk7b144 for a test update() while loop
kvn
parents: 3850
diff changeset
736 // Normal case: loop too big
0
a61af66fc99e Initial load
duke
parents:
diff changeset
737 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
739
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // Unroll once! (Each trip will soon do double iterations)
a61af66fc99e Initial load
duke
parents:
diff changeset
741 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
743
a61af66fc99e Initial load
duke
parents:
diff changeset
744 //------------------------------policy_align-----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // Return TRUE or FALSE if the loop should be cache-line aligned. Gather the
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // expression that does the alignment. Note that only one array base can be
605
98cb887364d3 6810672: Comment typos
twisti
parents: 420
diff changeset
747 // aligned in a loop (unless the VM guarantees mutual alignment). Note that
0
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // if we vectorize short memory ops into longer memory ops, we may want to
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // increase alignment.
a61af66fc99e Initial load
duke
parents:
diff changeset
750 bool IdealLoopTree::policy_align( PhaseIdealLoop *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
751 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
752 }
a61af66fc99e Initial load
duke
parents:
diff changeset
753
a61af66fc99e Initial load
duke
parents:
diff changeset
754 //------------------------------policy_range_check-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
755 // Return TRUE or FALSE if the loop should be range-check-eliminated.
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // Actually we do iteration-splitting, a more powerful form of RCE.
a61af66fc99e Initial load
duke
parents:
diff changeset
757 bool IdealLoopTree::policy_range_check( PhaseIdealLoop *phase ) const {
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
758 if (!RangeCheckElimination) return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
759
a61af66fc99e Initial load
duke
parents:
diff changeset
760 CountedLoopNode *cl = _head->as_CountedLoop();
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // If we unrolled with no intention of doing RCE and we later
a61af66fc99e Initial load
duke
parents:
diff changeset
762 // changed our minds, we got no pre-loop. Either we need to
a61af66fc99e Initial load
duke
parents:
diff changeset
763 // make a new pre-loop, or we gotta disallow RCE.
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
764 if (cl->is_main_no_pre_loop()) return false; // Disallowed for now.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
765 Node *trip_counter = cl->phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
766
a61af66fc99e Initial load
duke
parents:
diff changeset
767 // Check loop body for tests of trip-counter plus loop-invariant vs
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // loop-invariant.
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
769 for (uint i = 0; i < _body.size(); i++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
770 Node *iff = _body[i];
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
771 if (iff->Opcode() == Op_If) { // Test?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
772
a61af66fc99e Initial load
duke
parents:
diff changeset
773 // Comparing trip+off vs limit
a61af66fc99e Initial load
duke
parents:
diff changeset
774 Node *bol = iff->in(1);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
775 if (bol->req() != 2) continue; // dead constant test
1172
b2b6a9bf6238 6894779: Loop Predication for Loop Optimizer in C2
cfang
parents: 844
diff changeset
776 if (!bol->is_Bool()) {
b2b6a9bf6238 6894779: Loop Predication for Loop Optimizer in C2
cfang
parents: 844
diff changeset
777 assert(UseLoopPredicate && bol->Opcode() == Op_Conv2B, "predicate check only");
b2b6a9bf6238 6894779: Loop Predication for Loop Optimizer in C2
cfang
parents: 844
diff changeset
778 continue;
b2b6a9bf6238 6894779: Loop Predication for Loop Optimizer in C2
cfang
parents: 844
diff changeset
779 }
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
780 if (bol->as_Bool()->_test._test == BoolTest::ne)
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
781 continue; // not RC
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
782
0
a61af66fc99e Initial load
duke
parents:
diff changeset
783 Node *cmp = bol->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
784
a61af66fc99e Initial load
duke
parents:
diff changeset
785 Node *rc_exp = cmp->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
786 Node *limit = cmp->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
787
a61af66fc99e Initial load
duke
parents:
diff changeset
788 Node *limit_c = phase->get_ctrl(limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
789 if( limit_c == phase->C->top() )
a61af66fc99e Initial load
duke
parents:
diff changeset
790 return false; // Found dead test on live IF? No RCE!
a61af66fc99e Initial load
duke
parents:
diff changeset
791 if( is_member(phase->get_loop(limit_c) ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
792 // Compare might have operands swapped; commute them
a61af66fc99e Initial load
duke
parents:
diff changeset
793 rc_exp = cmp->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
794 limit = cmp->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
795 limit_c = phase->get_ctrl(limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
796 if( is_member(phase->get_loop(limit_c) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
797 continue; // Both inputs are loop varying; cannot RCE
a61af66fc99e Initial load
duke
parents:
diff changeset
798 }
a61af66fc99e Initial load
duke
parents:
diff changeset
799
a61af66fc99e Initial load
duke
parents:
diff changeset
800 if (!phase->is_scaled_iv_plus_offset(rc_exp, trip_counter, NULL, NULL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
801 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
803 // Yeah! Found a test like 'trip+off vs limit'
a61af66fc99e Initial load
duke
parents:
diff changeset
804 // Test is an IfNode, has 2 projections. If BOTH are in the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
805 // we need loop unswitching instead of iteration splitting.
a61af66fc99e Initial load
duke
parents:
diff changeset
806 if( is_loop_exit(iff) )
a61af66fc99e Initial load
duke
parents:
diff changeset
807 return true; // Found reason to split iterations
a61af66fc99e Initial load
duke
parents:
diff changeset
808 } // End of is IF
a61af66fc99e Initial load
duke
parents:
diff changeset
809 }
a61af66fc99e Initial load
duke
parents:
diff changeset
810
a61af66fc99e Initial load
duke
parents:
diff changeset
811 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
812 }
a61af66fc99e Initial load
duke
parents:
diff changeset
813
a61af66fc99e Initial load
duke
parents:
diff changeset
814 //------------------------------policy_peel_only-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
815 // Return TRUE or FALSE if the loop should NEVER be RCE'd or aligned. Useful
a61af66fc99e Initial load
duke
parents:
diff changeset
816 // for unrolling loops with NO array accesses.
a61af66fc99e Initial load
duke
parents:
diff changeset
817 bool IdealLoopTree::policy_peel_only( PhaseIdealLoop *phase ) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
818
a61af66fc99e Initial load
duke
parents:
diff changeset
819 for( uint i = 0; i < _body.size(); i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
820 if( _body[i]->is_Mem() )
a61af66fc99e Initial load
duke
parents:
diff changeset
821 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
822
a61af66fc99e Initial load
duke
parents:
diff changeset
823 // No memory accesses at all!
a61af66fc99e Initial load
duke
parents:
diff changeset
824 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
826
a61af66fc99e Initial load
duke
parents:
diff changeset
827 //------------------------------clone_up_backedge_goo--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
828 // If Node n lives in the back_ctrl block and cannot float, we clone a private
a61af66fc99e Initial load
duke
parents:
diff changeset
829 // version of n in preheader_ctrl block and return that, otherwise return n.
3788
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
830 Node *PhaseIdealLoop::clone_up_backedge_goo( Node *back_ctrl, Node *preheader_ctrl, Node *n, VectorSet &visited, Node_Stack &clones ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
831 if( get_ctrl(n) != back_ctrl ) return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
832
3788
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
833 // Only visit once
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
834 if (visited.test_set(n->_idx)) {
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
835 Node *x = clones.find(n->_idx);
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
836 if (x != NULL)
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
837 return x;
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
838 return n;
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
839 }
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
840
0
a61af66fc99e Initial load
duke
parents:
diff changeset
841 Node *x = NULL; // If required, a clone of 'n'
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // Check for 'n' being pinned in the backedge.
a61af66fc99e Initial load
duke
parents:
diff changeset
843 if( n->in(0) && n->in(0) == back_ctrl ) {
3788
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
844 assert(clones.find(n->_idx) == NULL, "dead loop");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
845 x = n->clone(); // Clone a copy of 'n' to preheader
3788
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
846 clones.push(x, n->_idx);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
847 x->set_req( 0, preheader_ctrl ); // Fix x's control input to preheader
a61af66fc99e Initial load
duke
parents:
diff changeset
848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // Recursive fixup any other input edges into x.
a61af66fc99e Initial load
duke
parents:
diff changeset
851 // If there are no changes we can just return 'n', otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
852 // we need to clone a private copy and change it.
a61af66fc99e Initial load
duke
parents:
diff changeset
853 for( uint i = 1; i < n->req(); i++ ) {
3788
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
854 Node *g = clone_up_backedge_goo( back_ctrl, preheader_ctrl, n->in(i), visited, clones );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
855 if( g != n->in(i) ) {
3788
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
856 if( !x ) {
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
857 assert(clones.find(n->_idx) == NULL, "dead loop");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
858 x = n->clone();
3788
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
859 clones.push(x, n->_idx);
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
860 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
861 x->set_req(i, g);
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
864 if( x ) { // x can legally float to pre-header location
a61af66fc99e Initial load
duke
parents:
diff changeset
865 register_new_node( x, preheader_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
866 return x;
a61af66fc99e Initial load
duke
parents:
diff changeset
867 } else { // raise n to cover LCA of uses
a61af66fc99e Initial load
duke
parents:
diff changeset
868 set_ctrl( n, find_non_split_ctrl(back_ctrl->in(0)) );
a61af66fc99e Initial load
duke
parents:
diff changeset
869 }
a61af66fc99e Initial load
duke
parents:
diff changeset
870 return n;
a61af66fc99e Initial load
duke
parents:
diff changeset
871 }
a61af66fc99e Initial load
duke
parents:
diff changeset
872
a61af66fc99e Initial load
duke
parents:
diff changeset
873 //------------------------------insert_pre_post_loops--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
874 // Insert pre and post loops. If peel_only is set, the pre-loop can not have
a61af66fc99e Initial load
duke
parents:
diff changeset
875 // more iterations added. It acts as a 'peel' only, no lower-bound RCE, no
a61af66fc99e Initial load
duke
parents:
diff changeset
876 // alignment. Useful to unroll loops that do no array accesses.
a61af66fc99e Initial load
duke
parents:
diff changeset
877 void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_new, bool peel_only ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
878
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
879 #ifndef PRODUCT
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
880 if (TraceLoopOpts) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
881 if (peel_only)
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
882 tty->print("PeelMainPost ");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
883 else
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
884 tty->print("PreMainPost ");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
885 loop->dump_head();
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
886 }
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
887 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
888 C->set_major_progress();
a61af66fc99e Initial load
duke
parents:
diff changeset
889
a61af66fc99e Initial load
duke
parents:
diff changeset
890 // Find common pieces of the loop being guarded with pre & post loops
a61af66fc99e Initial load
duke
parents:
diff changeset
891 CountedLoopNode *main_head = loop->_head->as_CountedLoop();
a61af66fc99e Initial load
duke
parents:
diff changeset
892 assert( main_head->is_normal_loop(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
893 CountedLoopEndNode *main_end = main_head->loopexit();
a61af66fc99e Initial load
duke
parents:
diff changeset
894 assert( main_end->outcnt() == 2, "1 true, 1 false path only" );
a61af66fc99e Initial load
duke
parents:
diff changeset
895 uint dd_main_head = dom_depth(main_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
896 uint max = main_head->outcnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
897
a61af66fc99e Initial load
duke
parents:
diff changeset
898 Node *pre_header= main_head->in(LoopNode::EntryControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
899 Node *init = main_head->init_trip();
a61af66fc99e Initial load
duke
parents:
diff changeset
900 Node *incr = main_end ->incr();
a61af66fc99e Initial load
duke
parents:
diff changeset
901 Node *limit = main_end ->limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
902 Node *stride = main_end ->stride();
a61af66fc99e Initial load
duke
parents:
diff changeset
903 Node *cmp = main_end ->cmp_node();
a61af66fc99e Initial load
duke
parents:
diff changeset
904 BoolTest::mask b_test = main_end->test_trip();
a61af66fc99e Initial load
duke
parents:
diff changeset
905
a61af66fc99e Initial load
duke
parents:
diff changeset
906 // Need only 1 user of 'bol' because I will be hacking the loop bounds.
a61af66fc99e Initial load
duke
parents:
diff changeset
907 Node *bol = main_end->in(CountedLoopEndNode::TestValue);
a61af66fc99e Initial load
duke
parents:
diff changeset
908 if( bol->outcnt() != 1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
909 bol = bol->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
910 register_new_node(bol,main_end->in(CountedLoopEndNode::TestControl));
a61af66fc99e Initial load
duke
parents:
diff changeset
911 _igvn.hash_delete(main_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
912 main_end->set_req(CountedLoopEndNode::TestValue, bol);
a61af66fc99e Initial load
duke
parents:
diff changeset
913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
914 // Need only 1 user of 'cmp' because I will be hacking the loop bounds.
a61af66fc99e Initial load
duke
parents:
diff changeset
915 if( cmp->outcnt() != 1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
916 cmp = cmp->clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
917 register_new_node(cmp,main_end->in(CountedLoopEndNode::TestControl));
a61af66fc99e Initial load
duke
parents:
diff changeset
918 _igvn.hash_delete(bol);
a61af66fc99e Initial load
duke
parents:
diff changeset
919 bol->set_req(1, cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
921
a61af66fc99e Initial load
duke
parents:
diff changeset
922 //------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
923 // Step A: Create Post-Loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
924 Node* main_exit = main_end->proj_out(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
925 assert( main_exit->Opcode() == Op_IfFalse, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
926 int dd_main_exit = dom_depth(main_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
927
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // Step A1: Clone the loop body. The clone becomes the post-loop. The main
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // loop pre-header illegally has 2 control users (old & new loops).
a61af66fc99e Initial load
duke
parents:
diff changeset
930 clone_loop( loop, old_new, dd_main_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
931 assert( old_new[main_end ->_idx]->Opcode() == Op_CountedLoopEnd, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
932 CountedLoopNode *post_head = old_new[main_head->_idx]->as_CountedLoop();
a61af66fc99e Initial load
duke
parents:
diff changeset
933 post_head->set_post_loop(main_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
934
400
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 367
diff changeset
935 // Reduce the post-loop trip count.
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 367
diff changeset
936 CountedLoopEndNode* post_end = old_new[main_end ->_idx]->as_CountedLoopEnd();
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 367
diff changeset
937 post_end->_prob = PROB_FAIR;
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 367
diff changeset
938
0
a61af66fc99e Initial load
duke
parents:
diff changeset
939 // Build the main-loop normal exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
940 IfFalseNode *new_main_exit = new (C, 1) IfFalseNode(main_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
941 _igvn.register_new_node_with_optimizer( new_main_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
942 set_idom(new_main_exit, main_end, dd_main_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
943 set_loop(new_main_exit, loop->_parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
944
a61af66fc99e Initial load
duke
parents:
diff changeset
945 // Step A2: Build a zero-trip guard for the post-loop. After leaving the
a61af66fc99e Initial load
duke
parents:
diff changeset
946 // main-loop, the post-loop may not execute at all. We 'opaque' the incr
a61af66fc99e Initial load
duke
parents:
diff changeset
947 // (the main-loop trip-counter exit value) because we will be changing
a61af66fc99e Initial load
duke
parents:
diff changeset
948 // the exit value (via unrolling) so we cannot constant-fold away the zero
a61af66fc99e Initial load
duke
parents:
diff changeset
949 // trip guard until all unrolling is done.
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 113
diff changeset
950 Node *zer_opaq = new (C, 2) Opaque1Node(C, incr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
951 Node *zer_cmp = new (C, 3) CmpINode( zer_opaq, limit );
a61af66fc99e Initial load
duke
parents:
diff changeset
952 Node *zer_bol = new (C, 2) BoolNode( zer_cmp, b_test );
a61af66fc99e Initial load
duke
parents:
diff changeset
953 register_new_node( zer_opaq, new_main_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
954 register_new_node( zer_cmp , new_main_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
955 register_new_node( zer_bol , new_main_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
956
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // Build the IfNode
a61af66fc99e Initial load
duke
parents:
diff changeset
958 IfNode *zer_iff = new (C, 2) IfNode( new_main_exit, zer_bol, PROB_FAIR, COUNT_UNKNOWN );
a61af66fc99e Initial load
duke
parents:
diff changeset
959 _igvn.register_new_node_with_optimizer( zer_iff );
a61af66fc99e Initial load
duke
parents:
diff changeset
960 set_idom(zer_iff, new_main_exit, dd_main_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
961 set_loop(zer_iff, loop->_parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
962
a61af66fc99e Initial load
duke
parents:
diff changeset
963 // Plug in the false-path, taken if we need to skip post-loop
a61af66fc99e Initial load
duke
parents:
diff changeset
964 _igvn.hash_delete( main_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
965 main_exit->set_req(0, zer_iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
966 _igvn._worklist.push(main_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
967 set_idom(main_exit, zer_iff, dd_main_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
968 set_idom(main_exit->unique_out(), zer_iff, dd_main_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // Make the true-path, must enter the post loop
a61af66fc99e Initial load
duke
parents:
diff changeset
970 Node *zer_taken = new (C, 1) IfTrueNode( zer_iff );
a61af66fc99e Initial load
duke
parents:
diff changeset
971 _igvn.register_new_node_with_optimizer( zer_taken );
a61af66fc99e Initial load
duke
parents:
diff changeset
972 set_idom(zer_taken, zer_iff, dd_main_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
973 set_loop(zer_taken, loop->_parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // Plug in the true path
a61af66fc99e Initial load
duke
parents:
diff changeset
975 _igvn.hash_delete( post_head );
a61af66fc99e Initial load
duke
parents:
diff changeset
976 post_head->set_req(LoopNode::EntryControl, zer_taken);
a61af66fc99e Initial load
duke
parents:
diff changeset
977 set_idom(post_head, zer_taken, dd_main_exit);
a61af66fc99e Initial load
duke
parents:
diff changeset
978
3788
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
979 Arena *a = Thread::current()->resource_area();
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
980 VectorSet visited(a);
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
981 Node_Stack clones(a, main_head->back_control()->outcnt());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
982 // Step A3: Make the fall-in values to the post-loop come from the
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // fall-out values of the main-loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
984 for (DUIterator_Fast imax, i = main_head->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
985 Node* main_phi = main_head->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
986 if( main_phi->is_Phi() && main_phi->in(0) == main_head && main_phi->outcnt() >0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
987 Node *post_phi = old_new[main_phi->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
988 Node *fallmain = clone_up_backedge_goo(main_head->back_control(),
a61af66fc99e Initial load
duke
parents:
diff changeset
989 post_head->init_control(),
3788
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
990 main_phi->in(LoopNode::LoopBackControl),
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
991 visited, clones);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
992 _igvn.hash_delete(post_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
993 post_phi->set_req( LoopNode::EntryControl, fallmain );
a61af66fc99e Initial load
duke
parents:
diff changeset
994 }
a61af66fc99e Initial load
duke
parents:
diff changeset
995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
996
a61af66fc99e Initial load
duke
parents:
diff changeset
997 // Update local caches for next stanza
a61af66fc99e Initial load
duke
parents:
diff changeset
998 main_exit = new_main_exit;
a61af66fc99e Initial load
duke
parents:
diff changeset
999
a61af66fc99e Initial load
duke
parents:
diff changeset
1000
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 //------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 // Step B: Create Pre-Loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1003
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 // Step B1: Clone the loop body. The clone becomes the pre-loop. The main
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 // loop pre-header illegally has 2 control users (old & new loops).
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 clone_loop( loop, old_new, dd_main_head );
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 CountedLoopNode* pre_head = old_new[main_head->_idx]->as_CountedLoop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 CountedLoopEndNode* pre_end = old_new[main_end ->_idx]->as_CountedLoopEnd();
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 pre_head->set_pre_loop(main_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 Node *pre_incr = old_new[incr->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1011
400
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 367
diff changeset
1012 // Reduce the pre-loop trip count.
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 367
diff changeset
1013 pre_end->_prob = PROB_FAIR;
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 367
diff changeset
1014
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 // Find the pre-loop normal exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 Node* pre_exit = pre_end->proj_out(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 assert( pre_exit->Opcode() == Op_IfFalse, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 IfFalseNode *new_pre_exit = new (C, 1) IfFalseNode(pre_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 _igvn.register_new_node_with_optimizer( new_pre_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 set_idom(new_pre_exit, pre_end, dd_main_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 set_loop(new_pre_exit, loop->_parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
1022
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 // Step B2: Build a zero-trip guard for the main-loop. After leaving the
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 // pre-loop, the main-loop may not execute at all. Later in life this
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // zero-trip guard will become the minimum-trip guard when we unroll
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 // the main-loop.
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 113
diff changeset
1027 Node *min_opaq = new (C, 2) Opaque1Node(C, limit);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 Node *min_cmp = new (C, 3) CmpINode( pre_incr, min_opaq );
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 Node *min_bol = new (C, 2) BoolNode( min_cmp, b_test );
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 register_new_node( min_opaq, new_pre_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 register_new_node( min_cmp , new_pre_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 register_new_node( min_bol , new_pre_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
1033
400
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 367
diff changeset
1034 // Build the IfNode (assume the main-loop is executed always).
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 367
diff changeset
1035 IfNode *min_iff = new (C, 2) IfNode( new_pre_exit, min_bol, PROB_ALWAYS, COUNT_UNKNOWN );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 _igvn.register_new_node_with_optimizer( min_iff );
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 set_idom(min_iff, new_pre_exit, dd_main_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 set_loop(min_iff, loop->_parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
1039
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 // Plug in the false-path, taken if we need to skip main-loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 _igvn.hash_delete( pre_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 pre_exit->set_req(0, min_iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 set_idom(pre_exit, min_iff, dd_main_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 set_idom(pre_exit->unique_out(), min_iff, dd_main_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 // Make the true-path, must enter the main loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 Node *min_taken = new (C, 1) IfTrueNode( min_iff );
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 _igvn.register_new_node_with_optimizer( min_taken );
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 set_idom(min_taken, min_iff, dd_main_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 set_loop(min_taken, loop->_parent);
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 // Plug in the true path
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 _igvn.hash_delete( main_head );
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 main_head->set_req(LoopNode::EntryControl, min_taken);
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 set_idom(main_head, min_taken, dd_main_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
1054
3788
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
1055 visited.Clear();
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
1056 clones.clear();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 // Step B3: Make the fall-in values to the main-loop come from the
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 // fall-out values of the pre-loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 for (DUIterator_Fast i2max, i2 = main_head->fast_outs(i2max); i2 < i2max; i2++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 Node* main_phi = main_head->fast_out(i2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 if( main_phi->is_Phi() && main_phi->in(0) == main_head && main_phi->outcnt() > 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 Node *pre_phi = old_new[main_phi->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 Node *fallpre = clone_up_backedge_goo(pre_head->back_control(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 main_head->init_control(),
3788
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
1065 pre_phi->in(LoopNode::LoopBackControl),
e3cbc9ddd434 7044738: Loop unroll optimization causes incorrect result
kvn
parents: 3782
diff changeset
1066 visited, clones);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 _igvn.hash_delete(main_phi);
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 main_phi->set_req( LoopNode::EntryControl, fallpre );
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1071
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 // Step B4: Shorten the pre-loop to run only 1 iteration (for now).
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 // RCE and alignment may change this later.
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 Node *cmp_end = pre_end->cmp_node();
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 assert( cmp_end->in(2) == limit, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 Node *pre_limit = new (C, 3) AddINode( init, stride );
a61af66fc99e Initial load
duke
parents:
diff changeset
1077
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // Save the original loop limit in this Opaque1 node for
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 // use by range check elimination.
216
8d191a7697e2 6715633: when matching a memory node the adr_type should not change
kvn
parents: 113
diff changeset
1080 Node *pre_opaq = new (C, 3) Opaque1Node(C, pre_limit, limit);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1081
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 register_new_node( pre_limit, pre_head->in(0) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 register_new_node( pre_opaq , pre_head->in(0) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1084
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 // Since no other users of pre-loop compare, I can hack limit directly
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 assert( cmp_end->outcnt() == 1, "no other users" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 _igvn.hash_delete(cmp_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 cmp_end->set_req(2, peel_only ? pre_limit : pre_opaq);
a61af66fc99e Initial load
duke
parents:
diff changeset
1089
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 // Special case for not-equal loop bounds:
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 // Change pre loop test, main loop test, and the
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 // main loop guard test to use lt or gt depending on stride
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // direction:
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 // positive stride use <
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 // negative stride use >
3782
aacaff365100 7052494: Eclipse test fails on JDK 7 b142
kvn
parents: 3398
diff changeset
1096 //
aacaff365100 7052494: Eclipse test fails on JDK 7 b142
kvn
parents: 3398
diff changeset
1097 // not-equal test is kept for post loop to handle case
aacaff365100 7052494: Eclipse test fails on JDK 7 b142
kvn
parents: 3398
diff changeset
1098 // when init > limit when stride > 0 (and reverse).
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1099
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 if (pre_end->in(CountedLoopEndNode::TestValue)->as_Bool()->_test._test == BoolTest::ne) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1101
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 BoolTest::mask new_test = (main_end->stride_con() > 0) ? BoolTest::lt : BoolTest::gt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 // Modify pre loop end condition
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 Node* pre_bol = pre_end->in(CountedLoopEndNode::TestValue)->as_Bool();
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 BoolNode* new_bol0 = new (C, 2) BoolNode(pre_bol->in(1), new_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 register_new_node( new_bol0, pre_head->in(0) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 _igvn.hash_delete(pre_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 pre_end->set_req(CountedLoopEndNode::TestValue, new_bol0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // Modify main loop guard condition
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 assert(min_iff->in(CountedLoopEndNode::TestValue) == min_bol, "guard okay");
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 BoolNode* new_bol1 = new (C, 2) BoolNode(min_bol->in(1), new_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 register_new_node( new_bol1, new_pre_exit );
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 _igvn.hash_delete(min_iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 min_iff->set_req(CountedLoopEndNode::TestValue, new_bol1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 // Modify main loop end condition
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 BoolNode* main_bol = main_end->in(CountedLoopEndNode::TestValue)->as_Bool();
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 BoolNode* new_bol2 = new (C, 2) BoolNode(main_bol->in(1), new_test);
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 register_new_node( new_bol2, main_end->in(CountedLoopEndNode::TestControl) );
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 _igvn.hash_delete(main_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 main_end->set_req(CountedLoopEndNode::TestValue, new_bol2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1122
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 // Flag main loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 main_head->set_main_loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 if( peel_only ) main_head->set_main_no_pre_loop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1126
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1127 // Subtract a trip count for the pre-loop.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1128 main_head->set_trip_count(main_head->trip_count() - 1);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1129
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 // It's difficult to be precise about the trip-counts
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // for the pre/post loops. They are usually very short,
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 // so guess that 4 trips is a reasonable value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 post_head->set_profile_trip_cnt(4.0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 pre_head->set_profile_trip_cnt(4.0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1135
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // Now force out all loop-invariant dominating tests. The optimizer
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // finds some, but we _know_ they are all useless.
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 peeled_dom_test_elim(loop,old_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1140
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 //------------------------------is_invariant-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // Return true if n is invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 bool IdealLoopTree::is_invariant(Node* n) const {
1172
b2b6a9bf6238 6894779: Loop Predication for Loop Optimizer in C2
cfang
parents: 844
diff changeset
1144 Node *n_c = _phase->has_ctrl(n) ? _phase->get_ctrl(n) : n;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 if (n_c->is_top()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 return !is_member(_phase->get_loop(n_c));
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1148
a61af66fc99e Initial load
duke
parents:
diff changeset
1149
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 //------------------------------do_unroll--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // Unroll the loop body one step - make each trip do 2 iterations.
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool adjust_min_trip ) {
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1153 assert(LoopUnrollLimit, "");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1154 CountedLoopNode *loop_head = loop->_head->as_CountedLoop();
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1155 CountedLoopEndNode *loop_end = loop_head->loopexit();
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1156 assert(loop_end, "");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 #ifndef PRODUCT
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1158 if (PrintOpto && VerifyLoopOptimizations) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 tty->print("Unrolling ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 loop->dump_head();
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1161 } else if (TraceLoopOpts) {
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
1162 if (loop_head->trip_count() < (uint)LoopUnrollLimit) {
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1163 tty->print("Unroll %d(%2d) ", loop_head->unrolled_count()*2, loop_head->trip_count());
2453
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
1164 } else {
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1165 tty->print("Unroll %d ", loop_head->unrolled_count()*2);
2453
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
1166 }
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1167 loop->dump_head();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1170
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 // Remember loop node count before unrolling to detect
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 // if rounds of unroll,optimize are making progress
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 loop_head->set_node_count_before_unroll(loop->_body.size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1174
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 Node *ctrl = loop_head->in(LoopNode::EntryControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 Node *limit = loop_head->limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 Node *init = loop_head->init_trip();
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1178 Node *stride = loop_head->stride();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1179
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 Node *opaq = NULL;
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1181 if (adjust_min_trip) { // If not maximally unrolling, need adjustment
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1182 // Search for zero-trip guard.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 assert( loop_head->is_main_loop(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 assert( ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 Node *iff = ctrl->in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 assert( iff->Opcode() == Op_If, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 Node *bol = iff->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 assert( bol->Opcode() == Op_Bool, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 Node *cmp = bol->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 assert( cmp->Opcode() == Op_CmpI, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 opaq = cmp->in(2);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1192 // Occasionally it's possible for a zero-trip guard Opaque1 node to be
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 // optimized away and then another round of loop opts attempted.
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // We can not optimize this particular loop in that case.
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1195 if (opaq->Opcode() != Op_Opaque1)
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1196 return; // Cannot find zero-trip guard! Bail out!
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1197 // Zero-trip test uses an 'opaque' node which is not shared.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1198 assert(opaq->outcnt() == 1 && opaq->in(1) == limit, "");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1200
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 C->set_major_progress();
a61af66fc99e Initial load
duke
parents:
diff changeset
1202
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1203 Node* new_limit = NULL;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1204 if (UnrollLimitCheck) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1205 int stride_con = stride->get_int();
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1206 int stride_p = (stride_con > 0) ? stride_con : -stride_con;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1207 uint old_trip_count = loop_head->trip_count();
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1208 // Verify that unroll policy result is still valid.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1209 assert(old_trip_count > 1 &&
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1210 (!adjust_min_trip || stride_p <= (1<<3)*loop_head->unrolled_count()), "sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1211
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1212 // Adjust loop limit to keep valid iterations number after unroll.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1213 // Use (limit - stride) instead of (((limit - init)/stride) & (-2))*stride
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1214 // which may overflow.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1215 if (!adjust_min_trip) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1216 assert(old_trip_count > 1 && (old_trip_count & 1) == 0,
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1217 "odd trip count for maximally unroll");
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1218 // Don't need to adjust limit for maximally unroll since trip count is even.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1219 } else if (loop_head->has_exact_trip_count() && init->is_Con()) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1220 // Loop's limit is constant. Loop's init could be constant when pre-loop
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1221 // become peeled iteration.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1222 long init_con = init->get_int();
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1223 // We can keep old loop limit if iterations count stays the same:
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1224 // old_trip_count == new_trip_count * 2
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1225 // Note: since old_trip_count >= 2 then new_trip_count >= 1
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1226 // so we also don't need to adjust zero trip test.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1227 long limit_con = limit->get_int();
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1228 // (stride_con*2) not overflow since stride_con <= 8.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1229 int new_stride_con = stride_con * 2;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1230 int stride_m = new_stride_con - (stride_con > 0 ? 1 : -1);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1231 long trip_count = (limit_con - init_con + stride_m)/new_stride_con;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1232 // New trip count should satisfy next conditions.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1233 assert(trip_count > 0 && (julong)trip_count < (julong)max_juint/2, "sanity");
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1234 uint new_trip_count = (uint)trip_count;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1235 adjust_min_trip = (old_trip_count != new_trip_count*2);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1236 }
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1237
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1238 if (adjust_min_trip) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1239 // Step 2: Adjust the trip limit if it is called for.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1240 // The adjustment amount is -stride. Need to make sure if the
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1241 // adjustment underflows or overflows, then the main loop is skipped.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1242 Node* cmp = loop_end->cmp_node();
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1243 assert(cmp->in(2) == limit, "sanity");
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1244 assert(opaq != NULL && opaq->in(1) == limit, "sanity");
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1245
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1246 // Verify that policy_unroll result is still valid.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1247 const TypeInt* limit_type = _igvn.type(limit)->is_int();
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1248 assert(stride_con > 0 && ((limit_type->_hi - stride_con) < limit_type->_hi) ||
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1249 stride_con < 0 && ((limit_type->_lo - stride_con) > limit_type->_lo), "sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1250
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1251 if (limit->is_Con()) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1252 // The check in policy_unroll and the assert above guarantee
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1253 // no underflow if limit is constant.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1254 new_limit = _igvn.intcon(limit->get_int() - stride_con);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1255 set_ctrl(new_limit, C->root());
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1256 } else {
3348
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1257 // Limit is not constant.
3367
3b1d58916d5f 7043552: regression after 7042327
kvn
parents: 3348
diff changeset
1258 if (loop_head->unrolled_count() == 1) { // only for first unroll
3348
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1259 // Separate limit by Opaque node in case it is an incremented
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1260 // variable from previous loop to avoid using pre-incremented
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1261 // value which could increase register pressure.
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1262 // Otherwise reorg_offsets() optimization will create a separate
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1263 // Opaque node for each use of trip-counter and as result
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1264 // zero trip guard limit will be different from loop limit.
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1265 assert(has_ctrl(opaq), "should have it");
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1266 Node* opaq_ctrl = get_ctrl(opaq);
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1267 limit = new (C, 2) Opaque2Node( C, limit );
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1268 register_new_node( limit, opaq_ctrl );
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1269 }
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1270 if (stride_con > 0 && ((limit_type->_lo - stride_con) < limit_type->_lo) ||
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1271 stride_con < 0 && ((limit_type->_hi - stride_con) > limit_type->_hi)) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1272 // No underflow.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1273 new_limit = new (C, 3) SubINode(limit, stride);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1274 } else {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1275 // (limit - stride) may underflow.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1276 // Clamp the adjustment value with MININT or MAXINT:
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1277 //
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1278 // new_limit = limit-stride
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1279 // if (stride > 0)
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1280 // new_limit = (limit < new_limit) ? MININT : new_limit;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1281 // else
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1282 // new_limit = (limit > new_limit) ? MAXINT : new_limit;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1283 //
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1284 BoolTest::mask bt = loop_end->test_trip();
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1285 assert(bt == BoolTest::lt || bt == BoolTest::gt, "canonical test is expected");
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1286 Node* adj_max = _igvn.intcon((stride_con > 0) ? min_jint : max_jint);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1287 set_ctrl(adj_max, C->root());
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1288 Node* old_limit = NULL;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1289 Node* adj_limit = NULL;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1290 Node* bol = limit->is_CMove() ? limit->in(CMoveNode::Condition) : NULL;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1291 if (loop_head->unrolled_count() > 1 &&
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1292 limit->is_CMove() && limit->Opcode() == Op_CMoveI &&
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1293 limit->in(CMoveNode::IfTrue) == adj_max &&
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1294 bol->as_Bool()->_test._test == bt &&
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1295 bol->in(1)->Opcode() == Op_CmpI &&
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1296 bol->in(1)->in(2) == limit->in(CMoveNode::IfFalse)) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1297 // Loop was unrolled before.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1298 // Optimize the limit to avoid nested CMove:
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1299 // use original limit as old limit.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1300 old_limit = bol->in(1)->in(1);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1301 // Adjust previous adjusted limit.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1302 adj_limit = limit->in(CMoveNode::IfFalse);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1303 adj_limit = new (C, 3) SubINode(adj_limit, stride);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1304 } else {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1305 old_limit = limit;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1306 adj_limit = new (C, 3) SubINode(limit, stride);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1307 }
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1308 assert(old_limit != NULL && adj_limit != NULL, "");
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1309 register_new_node( adj_limit, ctrl ); // adjust amount
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1310 Node* adj_cmp = new (C, 3) CmpINode(old_limit, adj_limit);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1311 register_new_node( adj_cmp, ctrl );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1312 Node* adj_bool = new (C, 2) BoolNode(adj_cmp, bt);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1313 register_new_node( adj_bool, ctrl );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1314 new_limit = new (C, 4) CMoveINode(adj_bool, adj_limit, adj_max, TypeInt::INT);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1315 }
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1316 register_new_node(new_limit, ctrl);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1317 }
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1318 assert(new_limit != NULL, "");
3348
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1319 // Replace in loop test.
3398
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1320 assert(loop_end->in(1)->in(1) == cmp, "sanity");
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1321 if (cmp->outcnt() == 1 && loop_end->in(1)->outcnt() == 1) {
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1322 // Don't need to create new test since only one user.
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1323 _igvn.hash_delete(cmp);
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1324 cmp->set_req(2, new_limit);
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1325 } else {
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1326 // Create new test since it is shared.
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1327 Node* ctrl2 = loop_end->in(0);
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1328 Node* cmp2 = cmp->clone();
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1329 cmp2->set_req(2, new_limit);
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1330 register_new_node(cmp2, ctrl2);
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1331 Node* bol2 = loop_end->in(1)->clone();
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1332 bol2->set_req(1, cmp2);
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1333 register_new_node(bol2, ctrl2);
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1334 _igvn.hash_delete(loop_end);
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1335 loop_end->set_req(1, bol2);
789d04408ca3 7045693: java/util/EnumSet/EnumSetBash.java still failing intermittently
kvn
parents: 3383
diff changeset
1336 }
3348
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1337 // Step 3: Find the min-trip test guaranteed before a 'main' loop.
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1338 // Make it a 1-trip test (means at least 2 trips).
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1339
3348
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1340 // Guard test uses an 'opaque' node which is not shared. Hence I
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1341 // can edit it's inputs directly. Hammer in the new limit for the
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1342 // minimum-trip guard.
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1343 assert(opaq->outcnt() == 1, "");
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1344 _igvn.hash_delete(opaq);
f879eafd5835 7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit)
kvn
parents: 3345
diff changeset
1345 opaq->set_req(1, new_limit);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1346 }
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1347
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1348 // Adjust max trip count. The trip count is intentionally rounded
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1349 // down here (e.g. 15-> 7-> 3-> 1) because if we unwittingly over-unroll,
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1350 // the main, unrolled, part of the loop will never execute as it is protected
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1351 // by the min-trip test. See bug 4834191 for a case where we over-unrolled
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1352 // and later determined that part of the unrolled loop was dead.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1353 loop_head->set_trip_count(old_trip_count / 2);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1354
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1355 // Double the count of original iterations in the unrolled loop body.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1356 loop_head->double_unrolled_count();
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1357
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1358 } else { // LoopLimitCheck
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1359
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1360 // Adjust max trip count. The trip count is intentionally rounded
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1361 // down here (e.g. 15-> 7-> 3-> 1) because if we unwittingly over-unroll,
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1362 // the main, unrolled, part of the loop will never execute as it is protected
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1363 // by the min-trip test. See bug 4834191 for a case where we over-unrolled
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1364 // and later determined that part of the unrolled loop was dead.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1365 loop_head->set_trip_count(loop_head->trip_count() / 2);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1366
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1367 // Double the count of original iterations in the unrolled loop body.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1368 loop_head->double_unrolled_count();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1369
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1370 // -----------
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1371 // Step 2: Cut back the trip counter for an unroll amount of 2.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1372 // Loop will normally trip (limit - init)/stride_con. Since it's a
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1373 // CountedLoop this is exact (stride divides limit-init exactly).
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1374 // We are going to double the loop body, so we want to knock off any
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1375 // odd iteration: (trip_cnt & ~1). Then back compute a new limit.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1376 Node *span = new (C, 3) SubINode( limit, init );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1377 register_new_node( span, ctrl );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1378 Node *trip = new (C, 3) DivINode( 0, span, stride );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1379 register_new_node( trip, ctrl );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1380 Node *mtwo = _igvn.intcon(-2);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1381 set_ctrl(mtwo, C->root());
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1382 Node *rond = new (C, 3) AndINode( trip, mtwo );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1383 register_new_node( rond, ctrl );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1384 Node *spn2 = new (C, 3) MulINode( rond, stride );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1385 register_new_node( spn2, ctrl );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1386 new_limit = new (C, 3) AddINode( spn2, init );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1387 register_new_node( new_limit, ctrl );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1388
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1389 // Hammer in the new limit
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1390 Node *ctrl2 = loop_end->in(0);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1391 Node *cmp2 = new (C, 3) CmpINode( loop_head->incr(), new_limit );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1392 register_new_node( cmp2, ctrl2 );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1393 Node *bol2 = new (C, 2) BoolNode( cmp2, loop_end->test_trip() );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1394 register_new_node( bol2, ctrl2 );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1395 _igvn.hash_delete(loop_end);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1396 loop_end->set_req(CountedLoopEndNode::TestValue, bol2);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1397
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1398 // Step 3: Find the min-trip test guaranteed before a 'main' loop.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1399 // Make it a 1-trip test (means at least 2 trips).
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1400 if( adjust_min_trip ) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1401 assert( new_limit != NULL, "" );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1402 // Guard test uses an 'opaque' node which is not shared. Hence I
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1403 // can edit it's inputs directly. Hammer in the new limit for the
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1404 // minimum-trip guard.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1405 assert( opaq->outcnt() == 1, "" );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1406 _igvn.hash_delete(opaq);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1407 opaq->set_req(1, new_limit);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1408 }
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1409 } // LoopLimitCheck
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1410
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 // ---------
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 // Step 4: Clone the loop body. Move it inside the loop. This loop body
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 // represents the odd iterations; since the loop trips an even number of
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 // times its backedge is never taken. Kill the backedge.
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 uint dd = dom_depth(loop_head);
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 clone_loop( loop, old_new, dd );
a61af66fc99e Initial load
duke
parents:
diff changeset
1417
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 // Make backedges of the clone equal to backedges of the original.
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 // Make the fall-in from the original come from the fall-out of the clone.
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 for (DUIterator_Fast jmax, j = loop_head->fast_outs(jmax); j < jmax; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 Node* phi = loop_head->fast_out(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 if( phi->is_Phi() && phi->in(0) == loop_head && phi->outcnt() > 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 Node *newphi = old_new[phi->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 _igvn.hash_delete( phi );
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 _igvn.hash_delete( newphi );
a61af66fc99e Initial load
duke
parents:
diff changeset
1426
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 phi ->set_req(LoopNode:: EntryControl, newphi->in(LoopNode::LoopBackControl));
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 newphi->set_req(LoopNode::LoopBackControl, phi ->in(LoopNode::LoopBackControl));
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 phi ->set_req(LoopNode::LoopBackControl, C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 Node *clone_head = old_new[loop_head->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 _igvn.hash_delete( clone_head );
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 loop_head ->set_req(LoopNode:: EntryControl, clone_head->in(LoopNode::LoopBackControl));
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 clone_head->set_req(LoopNode::LoopBackControl, loop_head ->in(LoopNode::LoopBackControl));
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 loop_head ->set_req(LoopNode::LoopBackControl, C->top());
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 loop->_head = clone_head; // New loop header
a61af66fc99e Initial load
duke
parents:
diff changeset
1438
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 set_idom(loop_head, loop_head ->in(LoopNode::EntryControl), dd);
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 set_idom(clone_head, clone_head->in(LoopNode::EntryControl), dd);
a61af66fc99e Initial load
duke
parents:
diff changeset
1441
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 // Kill the clone's backedge
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 Node *newcle = old_new[loop_end->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 _igvn.hash_delete( newcle );
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 Node *one = _igvn.intcon(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 set_ctrl(one, C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 newcle->set_req(1, one);
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 // Force clone into same loop body
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 uint max = loop->_body.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 for( uint k = 0; k < max; k++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 Node *old = loop->_body.at(k);
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 Node *nnn = old_new[old->_idx];
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 loop->_body.push(nnn);
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 if (!has_ctrl(old))
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 set_loop(nnn, loop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 }
367
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 235
diff changeset
1457
194b8e3a2fc4 6384206: Phis which are later unneeded are impairing our ability to inline based on static types
never
parents: 235
diff changeset
1458 loop->record_for_igvn();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1460
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 //------------------------------do_maximally_unroll----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1462
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 void PhaseIdealLoop::do_maximally_unroll( IdealLoopTree *loop, Node_List &old_new ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 CountedLoopNode *cl = loop->_head->as_CountedLoop();
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1465 assert(cl->has_exact_trip_count(), "trip count is not exact");
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1466 assert(cl->trip_count() > 0, "");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1467 #ifndef PRODUCT
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1468 if (TraceLoopOpts) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1469 tty->print("MaxUnroll %d ", cl->trip_count());
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1470 loop->dump_head();
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1471 }
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1472 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1473
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 // If loop is tripping an odd number of times, peel odd iteration
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1475 if ((cl->trip_count() & 1) == 1) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1476 do_peeling(loop, old_new);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1478
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // Now its tripping an even number of times remaining. Double loop body.
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 // Do not adjust pre-guards; they are not needed and do not exist.
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1481 if (cl->trip_count() > 0) {
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1482 assert((cl->trip_count() & 1) == 0, "missed peeling");
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1483 do_unroll(loop, old_new, false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1486
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 //------------------------------dominates_backedge---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 // Returns true if ctrl is executed on every complete iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 bool IdealLoopTree::dominates_backedge(Node* ctrl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 assert(ctrl->is_CFG(), "must be control");
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 Node* backedge = _head->as_Loop()->in(LoopNode::LoopBackControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 return _phase->dom_lca_internal(ctrl, backedge) == ctrl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1494
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1495 //------------------------------adjust_limit-----------------------------------
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1496 // Helper function for add_constraint().
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1497 Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl) {
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1498 // Compute "I :: (limit-offset)/scale"
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1499 Node *con = new (C, 3) SubINode(rc_limit, offset);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1500 register_new_node(con, pre_ctrl);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1501 Node *X = new (C, 3) DivINode(0, con, scale);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1502 register_new_node(X, pre_ctrl);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1503
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1504 // Adjust loop limit
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1505 loop_limit = (stride_con > 0)
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1506 ? (Node*)(new (C, 3) MinINode(loop_limit, X))
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1507 : (Node*)(new (C, 3) MaxINode(loop_limit, X));
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1508 register_new_node(loop_limit, pre_ctrl);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1509 return loop_limit;
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1510 }
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1511
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 //------------------------------add_constraint---------------------------------
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1513 // Constrain the main loop iterations so the conditions:
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1514 // low_limit <= scale_con * I + offset < upper_limit
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 // always holds true. That is, either increase the number of iterations in
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 // the pre-loop or the post-loop until the condition holds true in the main
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 // loop. Stride, scale, offset and limit are all loop invariant. Further,
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 // stride and scale are constants (offset and limit often are).
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1519 void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset, Node *low_limit, Node *upper_limit, Node *pre_ctrl, Node **pre_limit, Node **main_limit ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 // For positive stride, the pre-loop limit always uses a MAX function
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 // and the main loop a MIN function. For negative stride these are
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 // reversed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1523
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 // Also for positive stride*scale the affine function is increasing, so the
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 // pre-loop must check for underflow and the post-loop for overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 // Negative stride*scale reverses this; pre-loop checks for overflow and
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 // post-loop for underflow.
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1528
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1529 Node *scale = _igvn.intcon(scale_con);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1530 set_ctrl(scale, C->root());
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1531
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1532 if ((stride_con^scale_con) >= 0) { // Use XOR to avoid overflow
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1533 // The overflow limit: scale*I+offset < upper_limit
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1534 // For main-loop compute
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1535 // ( if (scale > 0) /* and stride > 0 */
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1536 // I < (upper_limit-offset)/scale
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1537 // else /* scale < 0 and stride < 0 */
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1538 // I > (upper_limit-offset)/scale
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1539 // )
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1540 //
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1541 // (upper_limit-offset) may overflow or underflow.
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1542 // But it is fine since main loop will either have
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1543 // less iterations or will be skipped in such case.
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1544 *main_limit = adjust_limit(stride_con, scale, offset, upper_limit, *main_limit, pre_ctrl);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1545
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1546 // The underflow limit: low_limit <= scale*I+offset.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1547 // For pre-loop compute
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1548 // NOT(scale*I+offset >= low_limit)
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1549 // scale*I+offset < low_limit
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1550 // ( if (scale > 0) /* and stride > 0 */
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1551 // I < (low_limit-offset)/scale
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1552 // else /* scale < 0 and stride < 0 */
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1553 // I > (low_limit-offset)/scale
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1554 // )
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1555
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1556 if (low_limit->get_int() == -max_jint) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1557 if (!RangeLimitCheck) return;
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1558 // We need this guard when scale*pre_limit+offset >= limit
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1559 // due to underflow. So we need execute pre-loop until
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1560 // scale*I+offset >= min_int. But (min_int-offset) will
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1561 // underflow when offset > 0 and X will be > original_limit
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1562 // when stride > 0. To avoid it we replace positive offset with 0.
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1563 //
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1564 // Also (min_int+1 == -max_int) is used instead of min_int here
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1565 // to avoid problem with scale == -1 (min_int/(-1) == min_int).
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1566 Node* shift = _igvn.intcon(31);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1567 set_ctrl(shift, C->root());
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1568 Node* sign = new (C, 3) RShiftINode(offset, shift);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1569 register_new_node(sign, pre_ctrl);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1570 offset = new (C, 3) AndINode(offset, sign);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1571 register_new_node(offset, pre_ctrl);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1572 } else {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1573 assert(low_limit->get_int() == 0, "wrong low limit for range check");
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1574 // The only problem we have here when offset == min_int
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1575 // since (0-min_int) == min_int. It may be fine for stride > 0
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1576 // but for stride < 0 X will be < original_limit. To avoid it
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1577 // max(pre_limit, original_limit) is used in do_range_check().
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1578 }
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1579 // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1580 *pre_limit = adjust_limit((-stride_con), scale, offset, low_limit, *pre_limit, pre_ctrl);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1581
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1582 } else { // stride_con*scale_con < 0
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1583 // For negative stride*scale pre-loop checks for overflow and
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1584 // post-loop for underflow.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1585 //
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1586 // The overflow limit: scale*I+offset < upper_limit
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1587 // For pre-loop compute
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1588 // NOT(scale*I+offset < upper_limit)
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1589 // scale*I+offset >= upper_limit
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1590 // scale*I+offset+1 > upper_limit
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1591 // ( if (scale < 0) /* and stride > 0 */
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1592 // I < (upper_limit-(offset+1))/scale
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1593 // else /* scale > 0 and stride < 0 */
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1594 // I > (upper_limit-(offset+1))/scale
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1595 // )
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1596 //
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1597 // (upper_limit-offset-1) may underflow or overflow.
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1598 // To avoid it min(pre_limit, original_limit) is used
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1599 // in do_range_check() for stride > 0 and max() for < 0.
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1600 Node *one = _igvn.intcon(1);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1601 set_ctrl(one, C->root());
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1602
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1603 Node *plus_one = new (C, 3) AddINode(offset, one);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1604 register_new_node( plus_one, pre_ctrl );
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1605 // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1606 *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1607
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1608 if (low_limit->get_int() == -max_jint) {
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1609 if (!RangeLimitCheck) return;
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1610 // We need this guard when scale*main_limit+offset >= limit
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1611 // due to underflow. So we need execute main-loop while
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1612 // scale*I+offset+1 > min_int. But (min_int-offset-1) will
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1613 // underflow when (offset+1) > 0 and X will be < main_limit
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1614 // when scale < 0 (and stride > 0). To avoid it we replace
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1615 // positive (offset+1) with 0.
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1616 //
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1617 // Also (min_int+1 == -max_int) is used instead of min_int here
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1618 // to avoid problem with scale == -1 (min_int/(-1) == min_int).
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1619 Node* shift = _igvn.intcon(31);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1620 set_ctrl(shift, C->root());
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1621 Node* sign = new (C, 3) RShiftINode(plus_one, shift);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1622 register_new_node(sign, pre_ctrl);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1623 plus_one = new (C, 3) AndINode(plus_one, sign);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1624 register_new_node(plus_one, pre_ctrl);
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1625 } else {
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1626 assert(low_limit->get_int() == 0, "wrong low limit for range check");
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1627 // The only problem we have here when offset == max_int
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1628 // since (max_int+1) == min_int and (0-min_int) == min_int.
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1629 // But it is fine since main loop will either have
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1630 // less iterations or will be skipped in such case.
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1631 }
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1632 // The underflow limit: low_limit <= scale*I+offset.
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1633 // For main-loop compute
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1634 // scale*I+offset+1 > low_limit
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1635 // ( if (scale < 0) /* and stride > 0 */
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1636 // I < (low_limit-(offset+1))/scale
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1637 // else /* scale > 0 and stride < 0 */
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1638 // I > (low_limit-(offset+1))/scale
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1639 // )
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1640
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1641 *main_limit = adjust_limit(stride_con, scale, plus_one, low_limit, *main_limit, pre_ctrl);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1644
a61af66fc99e Initial load
duke
parents:
diff changeset
1645
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 //------------------------------is_scaled_iv---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 // Return true if exp is a constant times an induction var
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 bool PhaseIdealLoop::is_scaled_iv(Node* exp, Node* iv, int* p_scale) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 if (exp == iv) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 if (p_scale != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 *p_scale = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 int opc = exp->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 if (opc == Op_MulI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 if (exp->in(1) == iv && exp->in(2)->is_Con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 if (p_scale != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 *p_scale = exp->in(2)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 if (exp->in(2) == iv && exp->in(1)->is_Con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 if (p_scale != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 *p_scale = exp->in(1)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 } else if (opc == Op_LShiftI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 if (exp->in(1) == iv && exp->in(2)->is_Con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 if (p_scale != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 *p_scale = 1 << exp->in(2)->get_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1679
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 //-----------------------------is_scaled_iv_plus_offset------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 // Return true if exp is a simple induction variable expression: k1*iv + (invar + k2)
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 bool PhaseIdealLoop::is_scaled_iv_plus_offset(Node* exp, Node* iv, int* p_scale, Node** p_offset, int depth) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 if (is_scaled_iv(exp, iv, p_scale)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 if (p_offset != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 Node *zero = _igvn.intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 set_ctrl(zero, C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 *p_offset = zero;
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 int opc = exp->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 if (opc == Op_AddI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 if (is_scaled_iv(exp->in(1), iv, p_scale)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 if (p_offset != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 *p_offset = exp->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 if (exp->in(2)->is_Con()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 Node* offset2 = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 if (depth < 2 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 is_scaled_iv_plus_offset(exp->in(1), iv, p_scale,
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 p_offset != NULL ? &offset2 : NULL, depth+1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 if (p_offset != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 Node *ctrl_off2 = get_ctrl(offset2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 Node* offset = new (C, 3) AddINode(offset2, exp->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 register_new_node(offset, ctrl_off2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 *p_offset = offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 } else if (opc == Op_SubI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 if (is_scaled_iv(exp->in(1), iv, p_scale)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 if (p_offset != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 Node *zero = _igvn.intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 set_ctrl(zero, C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 Node *ctrl_off = get_ctrl(exp->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 Node* offset = new (C, 3) SubINode(zero, exp->in(2));
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 register_new_node(offset, ctrl_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 *p_offset = offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 if (is_scaled_iv(exp->in(2), iv, p_scale)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 if (p_offset != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 *p_scale *= -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 *p_offset = exp->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1735
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 //------------------------------do_range_check---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 // Eliminate range-checks and other trip-counter vs loop-invariant tests.
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 #ifndef PRODUCT
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1740 if (PrintOpto && VerifyLoopOptimizations) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 tty->print("Range Check Elimination ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 loop->dump_head();
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1743 } else if (TraceLoopOpts) {
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1744 tty->print("RangeCheck ");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1745 loop->dump_head();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 #endif
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1748 assert(RangeCheckElimination, "");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 CountedLoopNode *cl = loop->_head->as_CountedLoop();
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1750 assert(cl->is_main_loop(), "");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1751
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1752 // protect against stride not being a constant
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1753 if (!cl->stride_is_con())
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1754 return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1755
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 // Find the trip counter; we are iteration splitting based on it
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 Node *trip_counter = cl->phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 // Find the main loop limit; we will trim it's iterations
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 // to not ever trip end tests
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 Node *main_limit = cl->limit();
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1761
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1762 // Need to find the main-loop zero-trip guard
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1763 Node *ctrl = cl->in(LoopNode::EntryControl);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1764 assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1765 Node *iffm = ctrl->in(0);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1766 assert(iffm->Opcode() == Op_If, "");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1767 Node *bolzm = iffm->in(1);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1768 assert(bolzm->Opcode() == Op_Bool, "");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1769 Node *cmpzm = bolzm->in(1);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1770 assert(cmpzm->is_Cmp(), "");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1771 Node *opqzm = cmpzm->in(2);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1772 // Can not optimize a loop if zero-trip Opaque1 node is optimized
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1773 // away and then another round of loop opts attempted.
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1774 if (opqzm->Opcode() != Op_Opaque1)
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1775 return;
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1776 assert(opqzm->in(1) == main_limit, "do not understand situation");
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1777
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 // Find the pre-loop limit; we will expand it's iterations to
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 // not ever trip low tests.
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 Node *p_f = iffm->in(0);
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1781 assert(p_f->Opcode() == Op_IfFalse, "");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd();
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1783 assert(pre_end->loopnode()->is_pre_loop(), "");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 Node *pre_opaq1 = pre_end->limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 // Occasionally it's possible for a pre-loop Opaque1 node to be
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 // optimized away and then another round of loop opts attempted.
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 // We can not optimize this particular loop in that case.
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1788 if (pre_opaq1->Opcode() != Op_Opaque1)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 Opaque1Node *pre_opaq = (Opaque1Node*)pre_opaq1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 Node *pre_limit = pre_opaq->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1792
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 // Where do we put new limit calculations
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 Node *pre_ctrl = pre_end->loopnode()->in(LoopNode::EntryControl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1795
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 // Ensure the original loop limit is available from the
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 // pre-loop Opaque1 node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 Node *orig_limit = pre_opaq->original_loop_limit();
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
1799 if (orig_limit == NULL || _igvn.type(orig_limit) == Type::TOP)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1801
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 // Must know if its a count-up or count-down loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1803
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 int stride_con = cl->stride_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 Node *zero = _igvn.intcon(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 Node *one = _igvn.intcon(1);
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1807 // Use symmetrical int range [-max_jint,max_jint]
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1808 Node *mini = _igvn.intcon(-max_jint);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 set_ctrl(zero, C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 set_ctrl(one, C->root());
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1811 set_ctrl(mini, C->root());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1812
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 // Range checks that do not dominate the loop backedge (ie.
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 // conditionally executed) can lengthen the pre loop limit beyond
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 // the original loop limit. To prevent this, the pre limit is
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 // (for stride > 0) MINed with the original loop limit (MAXed
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 // stride < 0) when some range_check (rc) is conditionally
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 // executed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 bool conditional_rc = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1820
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 // Check loop body for tests of trip-counter plus loop-invariant vs
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 // loop-invariant.
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 for( uint i = 0; i < loop->_body.size(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 Node *iff = loop->_body[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 if( iff->Opcode() == Op_If ) { // Test?
a61af66fc99e Initial load
duke
parents:
diff changeset
1826
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 // Test is an IfNode, has 2 projections. If BOTH are in the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 // we need loop unswitching instead of iteration splitting.
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 Node *exit = loop->is_loop_exit(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 if( !exit ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 int flip = (exit->Opcode() == Op_IfTrue) ? 1 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1832
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 // Get boolean condition to test
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 Node *i1 = iff->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 if( !i1->is_Bool() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 BoolNode *bol = i1->as_Bool();
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 BoolTest b_test = bol->_test;
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 // Flip sense of test if exit condition is flipped
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 if( flip )
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 b_test = b_test.negate();
a61af66fc99e Initial load
duke
parents:
diff changeset
1841
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 // Get compare
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 Node *cmp = bol->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1844
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 // Look for trip_counter + offset vs limit
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 Node *rc_exp = cmp->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 Node *limit = cmp->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 jint scale_con= 1; // Assume trip counter not scaled
a61af66fc99e Initial load
duke
parents:
diff changeset
1849
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 Node *limit_c = get_ctrl(limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 if( loop->is_member(get_loop(limit_c) ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 // Compare might have operands swapped; commute them
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 b_test = b_test.commute();
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 rc_exp = cmp->in(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 limit = cmp->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 limit_c = get_ctrl(limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 if( loop->is_member(get_loop(limit_c) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 continue; // Both inputs are loop varying; cannot RCE
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 // Here we know 'limit' is loop invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
1861
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 // 'limit' maybe pinned below the zero trip test (probably from a
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 // previous round of rce), in which case, it can't be used in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 // zero trip test expression which must occur before the zero test's if.
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 if( limit_c == ctrl ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 continue; // Don't rce this check but continue looking for other candidates.
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1868
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 // Check for scaled induction variable plus an offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 Node *offset = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1871
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 if (!is_scaled_iv_plus_offset(rc_exp, trip_counter, &scale_con, &offset)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1875
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 Node *offset_c = get_ctrl(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 if( loop->is_member( get_loop(offset_c) ) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 continue; // Offset is not really loop invariant
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 // Here we know 'offset' is loop invariant.
a61af66fc99e Initial load
duke
parents:
diff changeset
1880
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 // As above for the 'limit', the 'offset' maybe pinned below the
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 // zero trip test.
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 if( offset_c == ctrl ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 continue; // Don't rce this check but continue looking for other candidates.
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 }
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1886 #ifdef ASSERT
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1887 if (TraceRangeLimitCheck) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1888 tty->print_cr("RC bool node%s", flip ? " flipped:" : ":");
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1889 bol->dump(2);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1890 }
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1891 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 // At this point we have the expression as:
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 // scale_con * trip_counter + offset :: limit
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 // where scale_con, offset and limit are loop invariant. Trip_counter
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 // monotonically increases by stride_con, a constant. Both (or either)
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 // stride_con and scale_con can be negative which will flip about the
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 // sense of the test.
a61af66fc99e Initial load
duke
parents:
diff changeset
1898
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 // Adjust pre and main loop limits to guard the correct iteration set
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 if( cmp->Opcode() == Op_CmpU ) {// Unsigned compare is really 2 tests
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 if( b_test._test == BoolTest::lt ) { // Range checks always use lt
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1902 // The underflow and overflow limits: 0 <= scale*I+offset < limit
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1903 add_constraint( stride_con, scale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 if (!conditional_rc) {
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1905 // (0-offset)/scale could be outside of loop iterations range.
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1906 conditional_rc = !loop->dominates_backedge(iff) || RangeLimitCheck;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 if( PrintOpto )
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 tty->print_cr("missed RCE opportunity");
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 continue; // In release mode, ignore it
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 } else { // Otherwise work on normal compares
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 switch( b_test._test ) {
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1917 case BoolTest::gt:
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1918 // Fall into GE case
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1919 case BoolTest::ge:
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1920 // Convert (I*scale+offset) >= Limit to (I*(-scale)+(-offset)) <= -Limit
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 scale_con = -scale_con;
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 offset = new (C, 3) SubINode( zero, offset );
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 register_new_node( offset, pre_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 limit = new (C, 3) SubINode( zero, limit );
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 register_new_node( limit, pre_ctrl );
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 // Fall into LE case
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1927 case BoolTest::le:
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1928 if (b_test._test != BoolTest::gt) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1929 // Convert X <= Y to X < Y+1
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1930 limit = new (C, 3) AddINode( limit, one );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1931 register_new_node( limit, pre_ctrl );
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1932 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 // Fall into LT case
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 case BoolTest::lt:
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1935 // The underflow and overflow limits: MIN_INT <= scale*I+offset < limit
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1936 // Note: (MIN_INT+1 == -MAX_INT) is used instead of MIN_INT here
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1937 // to avoid problem with scale == -1: MIN_INT/(-1) == MIN_INT.
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1938 add_constraint( stride_con, scale_con, offset, mini, limit, pre_ctrl, &pre_limit, &main_limit );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 if (!conditional_rc) {
3383
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1940 // ((MIN_INT+1)-offset)/scale could be outside of loop iterations range.
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1941 // Note: negative offset is replaced with 0 but (MIN_INT+1)/scale could
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1942 // still be outside of loop range.
38569792a45a 7044725: -XX:-UnrollLimitCheck -Xcomp : Exception: String index out of range: 29488
kvn
parents: 3367
diff changeset
1943 conditional_rc = !loop->dominates_backedge(iff) || RangeLimitCheck;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 if( PrintOpto )
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 tty->print_cr("missed RCE opportunity");
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 continue; // Unhandled case
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1954
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 // Kill the eliminated test
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 C->set_major_progress();
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 Node *kill_con = _igvn.intcon( 1-flip );
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 set_ctrl(kill_con, C->root());
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 _igvn.hash_delete(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 iff->set_req(1, kill_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 _igvn._worklist.push(iff);
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 // Find surviving projection
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 assert(iff->is_If(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 ProjNode* dp = ((IfNode*)iff)->proj_out(1-flip);
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 // Find loads off the surviving projection; remove their control edge
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 Node* cd = dp->fast_out(i); // Control-dependent node
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 if( cd->is_Load() ) { // Loads can now float around in the loop
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 _igvn.hash_delete(cd);
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 // Allow the load to float around in the loop, or before it
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 // but NOT before the pre-loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 cd->set_req(0, ctrl); // ctrl, not NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 _igvn._worklist.push(cd);
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 --i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 --imax;
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1978
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 } // End of is IF
a61af66fc99e Initial load
duke
parents:
diff changeset
1980
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1982
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 // Update loop limits
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 if (conditional_rc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 pre_limit = (stride_con > 0) ? (Node*)new (C,3) MinINode(pre_limit, orig_limit)
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 : (Node*)new (C,3) MaxINode(pre_limit, orig_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 register_new_node(pre_limit, pre_ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 _igvn.hash_delete(pre_opaq);
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 pre_opaq->set_req(1, pre_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1991
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 // Note:: we are making the main loop limit no longer precise;
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 // need to round up based on stride.
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1994 cl->set_nonexact_trip_count();
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
1995 if (!LoopLimitCheck && stride_con != 1 && stride_con != -1) { // Cutout for common case
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 // "Standard" round-up logic: ([main_limit-init+(y-1)]/y)*y+init
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 // Hopefully, compiler will optimize for powers of 2.
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 Node *ctrl = get_ctrl(main_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 Node *stride = cl->stride();
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 Node *init = cl->init_trip();
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 Node *span = new (C, 3) SubINode(main_limit,init);
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 register_new_node(span,ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 Node *rndup = _igvn.intcon(stride_con + ((stride_con>0)?-1:1));
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 Node *add = new (C, 3) AddINode(span,rndup);
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 register_new_node(add,ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 Node *div = new (C, 3) DivINode(0,add,stride);
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 register_new_node(div,ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 Node *mul = new (C, 3) MulINode(div,stride);
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 register_new_node(mul,ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 Node *newlim = new (C, 3) AddINode(mul,init);
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 register_new_node(newlim,ctrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 main_limit = newlim;
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2014
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 Node *main_cle = cl->loopexit();
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 Node *main_bol = main_cle->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 // Hacking loop bounds; need private copies of exit test
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 if( main_bol->outcnt() > 1 ) {// BoolNode shared?
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 _igvn.hash_delete(main_cle);
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 main_bol = main_bol->clone();// Clone a private BoolNode
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 register_new_node( main_bol, main_cle->in(0) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 main_cle->set_req(1,main_bol);
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 Node *main_cmp = main_bol->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 if( main_cmp->outcnt() > 1 ) { // CmpNode shared?
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 _igvn.hash_delete(main_bol);
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 main_cmp = main_cmp->clone();// Clone a private CmpNode
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 register_new_node( main_cmp, main_cle->in(0) );
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 main_bol->set_req(1,main_cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 // Hack the now-private loop bounds
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 _igvn.hash_delete(main_cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 main_cmp->set_req(2, main_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 _igvn._worklist.push(main_cmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 // The OpaqueNode is unshared by design
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 _igvn.hash_delete(opqzm);
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 assert( opqzm->outcnt() == 1, "cannot hack shared node" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 opqzm->set_req(1,main_limit);
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 _igvn._worklist.push(opqzm);
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2041
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 //------------------------------DCE_loop_body----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 // Remove simplistic dead code from loop body
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 void IdealLoopTree::DCE_loop_body() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 for( uint i = 0; i < _body.size(); i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 if( _body.at(i)->outcnt() == 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 _body.map( i--, _body.pop() );
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2049
a61af66fc99e Initial load
duke
parents:
diff changeset
2050
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 //------------------------------adjust_loop_exit_prob--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 // Look for loop-exit tests with the 50/50 (or worse) guesses from the parsing stage.
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 // Replace with a 1-in-10 exit guess.
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 void IdealLoopTree::adjust_loop_exit_prob( PhaseIdealLoop *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 Node *test = tail();
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 while( test != _head ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 uint top = test->Opcode();
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 if( top == Op_IfTrue || top == Op_IfFalse ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 int test_con = ((ProjNode*)test)->_con;
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 assert(top == (uint)(test_con? Op_IfTrue: Op_IfFalse), "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 IfNode *iff = test->in(0)->as_If();
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 if( iff->outcnt() == 2 ) { // Ignore dead tests
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 Node *bol = iff->in(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 if( bol && bol->req() > 1 && bol->in(1) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 ((bol->in(1)->Opcode() == Op_StorePConditional ) ||
420
a1980da045cc 6462850: generate biased locking code in C2 ideal graph
kvn
parents: 401
diff changeset
2066 (bol->in(1)->Opcode() == Op_StoreIConditional ) ||
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 (bol->in(1)->Opcode() == Op_StoreLConditional ) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 (bol->in(1)->Opcode() == Op_CompareAndSwapI ) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 (bol->in(1)->Opcode() == Op_CompareAndSwapL ) ||
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 39
diff changeset
2070 (bol->in(1)->Opcode() == Op_CompareAndSwapP ) ||
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 39
diff changeset
2071 (bol->in(1)->Opcode() == Op_CompareAndSwapN )))
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 return; // Allocation loops RARELY take backedge
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 // Find the OTHER exit path from the IF
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 Node* ex = iff->proj_out(1-test_con);
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 float p = iff->_prob;
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 if( !phase->is_member( this, ex ) && iff->_fcnt == COUNT_UNKNOWN ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 if( top == Op_IfTrue ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 if( p < (PROB_FAIR + PROB_UNLIKELY_MAG(3))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 iff->_prob = PROB_STATIC_FREQUENT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 if( p > (PROB_FAIR - PROB_UNLIKELY_MAG(3))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 iff->_prob = PROB_STATIC_INFREQUENT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 test = phase->idom(test);
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2092
a61af66fc99e Initial load
duke
parents:
diff changeset
2093
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 //------------------------------policy_do_remove_empty_loop--------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 // Micro-benchmark spamming. Policy is to always remove empty loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 // The 'DO' part is to replace the trip counter with the value it will
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 // have on the last iteration. This will break the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 // Minimum size must be empty loop
2453
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
2100 if (_body.size() > EMPTY_LOOP_SIZE)
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2101 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2102
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2103 if (!_head->is_CountedLoop())
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2104 return false; // Dead loop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 CountedLoopNode *cl = _head->as_CountedLoop();
3850
6987871cfb9b 7077439: Possible reference through NULL in loopPredicate.cpp:726
kvn
parents: 3845
diff changeset
2106 if (!cl->is_valid_counted_loop())
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2107 return false; // Malformed loop
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2108 if (!phase->is_member(this, phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue))))
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 return false; // Infinite loop
2403
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2110
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 // Ensure only one phi which is the iv.
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 Node* iv = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 for (DUIterator_Fast imax, i = cl->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 Node* n = cl->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 if (n->Opcode() == Op_Phi) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 assert(iv == NULL, "Too many phis" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 iv = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 assert(iv == cl->phi(), "Wrong phi" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 #endif
2403
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2123
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2124 // main and post loops have explicitly created zero trip guard
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2125 bool needs_guard = !cl->is_main_loop() && !cl->is_post_loop();
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2126 if (needs_guard) {
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2127 // Skip guard if values not overlap.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2128 const TypeInt* init_t = phase->_igvn.type(cl->init_trip())->is_int();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2129 const TypeInt* limit_t = phase->_igvn.type(cl->limit())->is_int();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2130 int stride_con = cl->stride_con();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2131 if (stride_con > 0) {
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2132 needs_guard = (init_t->_hi >= limit_t->_lo);
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2133 } else {
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2134 needs_guard = (init_t->_lo <= limit_t->_hi);
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2135 }
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2136 }
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2137 if (needs_guard) {
2403
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2138 // Check for an obvious zero trip guard.
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
2139 Node* inctrl = PhaseIdealLoop::skip_loop_predicates(cl->in(LoopNode::EntryControl));
2403
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2140 if (inctrl->Opcode() == Op_IfTrue) {
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2141 // The test should look like just the backedge of a CountedLoop
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2142 Node* iff = inctrl->in(0);
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2143 if (iff->is_If()) {
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2144 Node* bol = iff->in(1);
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2145 if (bol->is_Bool() && bol->as_Bool()->_test._test == cl->loopexit()->test_trip()) {
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2146 Node* cmp = bol->in(1);
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2147 if (cmp->is_Cmp() && cmp->in(1) == cl->init_trip() && cmp->in(2) == cl->limit()) {
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2148 needs_guard = false;
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2149 }
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2150 }
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2151 }
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2152 }
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2153 }
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2154
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2155 #ifndef PRODUCT
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2156 if (PrintOpto) {
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2157 tty->print("Removing empty loop with%s zero trip guard", needs_guard ? "out" : "");
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2158 this->dump_head();
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2159 } else if (TraceLoopOpts) {
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2160 tty->print("Empty with%s zero trip guard ", needs_guard ? "out" : "");
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2161 this->dump_head();
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2162 }
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2163 #endif
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2164
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2165 if (needs_guard) {
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2166 // Peel the loop to ensure there's a zero trip guard
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2167 Node_List old_new;
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2168 phase->do_peeling(this, old_new);
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2169 }
1927db75dd85 7024475: loop doesn't terminate when compiled
never
parents: 2383
diff changeset
2170
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 // Replace the phi at loop head with the final value of the last
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 // iteration. Then the CountedLoopEnd will collapse (backedge never
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 // taken) and all loop-invariant uses of the exit values will be correct.
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 Node *phi = cl->phi();
3345
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2175 Node *exact_limit = phase->exact_limit(this);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2176 if (exact_limit != cl->limit()) {
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2177 // We also need to replace the original limit to collapse loop exit.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2178 Node* cmp = cl->loopexit()->cmp_node();
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2179 assert(cl->limit() == cmp->in(2), "sanity");
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2180 phase->_igvn._worklist.push(cmp->in(2)); // put limit on worklist
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2181 phase->_igvn.hash_delete(cmp);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2182 cmp->set_req(2, exact_limit);
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2183 phase->_igvn._worklist.push(cmp); // put cmp on worklist
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2184 }
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2185 // Note: the final value after increment should not overflow since
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2186 // counted loop has limit check predicate.
bad7ecd0b6ed 5091921: Sign flip issues in loop optimizer
kvn
parents: 3333
diff changeset
2187 Node *final = new (phase->C, 3) SubINode( exact_limit, cl->stride() );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 phase->register_new_node(final,cl->in(LoopNode::EntryControl));
1621
6027dddc26c6 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 1552
diff changeset
2189 phase->_igvn.replace_node(phi,final);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 phase->C->set_major_progress();
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2193
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2194 //------------------------------policy_do_one_iteration_loop-------------------
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2195 // Convert one iteration loop into normal code.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2196 bool IdealLoopTree::policy_do_one_iteration_loop( PhaseIdealLoop *phase ) {
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2197 if (!_head->as_Loop()->is_valid_counted_loop())
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2198 return false; // Only for counted loop
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2199
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2200 CountedLoopNode *cl = _head->as_CountedLoop();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2201 if (!cl->has_exact_trip_count() || cl->trip_count() != 1) {
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2202 return false;
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2203 }
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2204
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2205 #ifndef PRODUCT
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2206 if(TraceLoopOpts) {
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2207 tty->print("OneIteration ");
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2208 this->dump_head();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2209 }
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2210 #endif
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2211
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2212 Node *init_n = cl->init_trip();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2213 #ifdef ASSERT
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2214 // Loop boundaries should be constant since trip count is exact.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2215 assert(init_n->get_int() + cl->stride_con() >= cl->limit()->get_int(), "should be one iteration");
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2216 #endif
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2217 // Replace the phi at loop head with the value of the init_trip.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2218 // Then the CountedLoopEnd will collapse (backedge will not be taken)
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2219 // and all loop-invariant uses of the exit values will be correct.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2220 phase->_igvn.replace_node(cl->phi(), cl->init_trip());
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2221 phase->C->set_major_progress();
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2222 return true;
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2223 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2224
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 //------------------------------iteration_split_impl---------------------------
401
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 400
diff changeset
2227 bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) {
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2228 // Compute exact loop trip count if possible.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2229 compute_exact_trip_count(phase);
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2230
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2231 // Convert one iteration loop into normal code.
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2232 if (policy_do_one_iteration_loop(phase))
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2233 return true;
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2234
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 // Check and remove empty loops (spam micro-benchmarks)
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2236 if (policy_do_remove_empty_loop(phase))
1172
b2b6a9bf6238 6894779: Loop Predication for Loop Optimizer in C2
cfang
parents: 844
diff changeset
2237 return true; // Here we removed an empty loop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2238
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 bool should_peel = policy_peeling(phase); // Should we peel?
a61af66fc99e Initial load
duke
parents:
diff changeset
2240
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 bool should_unswitch = policy_unswitching(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2242
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 // Non-counted loops may be peeled; exactly 1 iteration is peeled.
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 // This removes loop-invariant tests (usually null checks).
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2245 if (!_head->is_CountedLoop()) { // Non-counted loop
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 if (PartialPeelLoop && phase->partial_peel(this, old_new)) {
401
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 400
diff changeset
2247 // Partial peel succeeded so terminate this round of loop opts
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 400
diff changeset
2248 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 }
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2250 if (should_peel) { // Should we peel?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 if (PrintOpto) tty->print_cr("should_peel");
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 phase->do_peeling(this,old_new);
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2255 } else if (should_unswitch) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 phase->do_unswitching(this, old_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 }
401
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 400
diff changeset
2258 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 CountedLoopNode *cl = _head->as_CountedLoop();
a61af66fc99e Initial load
duke
parents:
diff changeset
2261
3850
6987871cfb9b 7077439: Possible reference through NULL in loopPredicate.cpp:726
kvn
parents: 3845
diff changeset
2262 if (!cl->is_valid_counted_loop()) return true; // Ignore various kinds of broken loops
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2263
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 // Do nothing special to pre- and post- loops
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2265 if (cl->is_pre_loop() || cl->is_post_loop()) return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2266
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 // Compute loop trip count from profile data
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 compute_profile_trip_cnt(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2269
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 // Before attempting fancy unrolling, RCE or alignment, see if we want
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 // to completely unroll this loop or do loop unswitching.
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2272 if (cl->is_normal_loop()) {
789
273b2358ef1a 6837146: Should perform unswitch before maximally unroll in loop transformation
cfang
parents: 605
diff changeset
2273 if (should_unswitch) {
273b2358ef1a 6837146: Should perform unswitch before maximally unroll in loop transformation
cfang
parents: 605
diff changeset
2274 phase->do_unswitching(this, old_new);
273b2358ef1a 6837146: Should perform unswitch before maximally unroll in loop transformation
cfang
parents: 605
diff changeset
2275 return true;
273b2358ef1a 6837146: Should perform unswitch before maximally unroll in loop transformation
cfang
parents: 605
diff changeset
2276 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 bool should_maximally_unroll = policy_maximally_unroll(phase);
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2278 if (should_maximally_unroll) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 // Here we did some unrolling and peeling. Eventually we will
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 // completely unroll this loop and it will no longer be a loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 phase->do_maximally_unroll(this,old_new);
401
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 400
diff changeset
2282 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2285
2453
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
2286 // Skip next optimizations if running low on nodes. Note that
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
2287 // policy_unswitching and policy_maximally_unroll have this check.
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
2288 uint nodes_left = MaxNodeLimit - phase->C->unique();
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
2289 if ((2 * _body.size()) > nodes_left) {
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
2290 return true;
d7a3fed1c1c9 7004547: regular loop unroll should not unroll more than max unrolling
kvn
parents: 2448
diff changeset
2291 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2292
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 // Counted loops may be peeled, may need some iterations run up
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 // front for RCE, and may want to align loop refs to a cache
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 // line. Thus we clone a full loop up front whose trip count is
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 // at least 1 (if peeling), but may be several more.
a61af66fc99e Initial load
duke
parents:
diff changeset
2297
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 // The main loop will start cache-line aligned with at least 1
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 // iteration of the unrolled body (zero-trip test required) and
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 // will have some range checks removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2301
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 // A post-loop will finish any odd iterations (leftover after
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 // unrolling), plus any needed for RCE purposes.
a61af66fc99e Initial load
duke
parents:
diff changeset
2304
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 bool should_unroll = policy_unroll(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2306
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 bool should_rce = policy_range_check(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2308
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 bool should_align = policy_align(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2310
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 // If not RCE'ing (iteration splitting) or Aligning, then we do not
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 // need a pre-loop. We may still need to peel an initial iteration but
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 // we will not be needing an unknown number of pre-iterations.
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 // Basically, if may_rce_align reports FALSE first time through,
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 // we will not be able to later do RCE or Aligning on this loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 bool may_rce_align = !policy_peel_only(phase) || should_rce || should_align;
a61af66fc99e Initial load
duke
parents:
diff changeset
2318
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 // If we have any of these conditions (RCE, alignment, unrolling) met, then
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 // we switch to the pre-/main-/post-loop model. This model also covers
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 // peeling.
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2322 if (should_rce || should_align || should_unroll) {
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2323 if (cl->is_normal_loop()) // Convert to 'pre/main/post' loops
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 phase->insert_pre_post_loops(this,old_new, !may_rce_align);
a61af66fc99e Initial load
duke
parents:
diff changeset
2325
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 // Adjust the pre- and main-loop limits to let the pre and post loops run
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 // with full checks, but the main-loop with no checks. Remove said
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 // checks from the main body.
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2329 if (should_rce)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 phase->do_range_check(this,old_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
2331
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 // Double loop body for unrolling. Adjust the minimum-trip test (will do
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 // twice as many iterations as before) and the main body limit (only do
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 // an even number of trips). If we are peeling, we might enable some RCE
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 // and we'd rather unroll the post-RCE'd loop SO... do not unroll if
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 // peeling.
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2337 if (should_unroll && !should_peel)
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2338 phase->do_unroll(this,old_new, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2339
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 // Adjust the pre-loop limits to align the main body
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 // iterations.
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2342 if (should_align)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
2344
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 } else { // Else we have an unchanged counted loop
2465
3af54845df98 7004555: Add new policy for one iteration loops
kvn
parents: 2453
diff changeset
2346 if (should_peel) // Might want to peel but do nothing else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 phase->do_peeling(this,old_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 }
401
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 400
diff changeset
2349 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2351
a61af66fc99e Initial load
duke
parents:
diff changeset
2352
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 //=============================================================================
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 //------------------------------iteration_split--------------------------------
401
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 400
diff changeset
2355 bool IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 // Recursively iteration split nested loops
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2357 if (_child && !_child->iteration_split(phase, old_new))
401
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 400
diff changeset
2358 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2359
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 // Clean out prior deadwood
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 DCE_loop_body();
a61af66fc99e Initial load
duke
parents:
diff changeset
2362
a61af66fc99e Initial load
duke
parents:
diff changeset
2363
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 // Look for loop-exit tests with my 50/50 guesses from the Parsing stage.
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 // Replace with a 1-in-10 exit guess.
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2366 if (_parent /*not the root loop*/ &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 !_irreducible &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 // Also ignore the occasional dead backedge
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2369 !tail()->is_top()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 adjust_loop_exit_prob(phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2372
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 // Gate unrolling, RCE and peeling efforts.
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2374 if (!_child && // If not an inner loop, do not split
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 !_irreducible &&
39
76256d272075 6667612: (Escape Analysis) disable loop cloning if it has a scalar replaceable allocation
kvn
parents: 0
diff changeset
2376 _allow_optimizations &&
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2377 !tail()->is_top()) { // Also ignore the occasional dead backedge
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 if (!_has_call) {
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2379 if (!iteration_split_impl(phase, old_new)) {
1172
b2b6a9bf6238 6894779: Loop Predication for Loop Optimizer in C2
cfang
parents: 844
diff changeset
2380 return false;
b2b6a9bf6238 6894779: Loop Predication for Loop Optimizer in C2
cfang
parents: 844
diff changeset
2381 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 } else if (policy_unswitching(phase)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 phase->do_unswitching(this, old_new);
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2386
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 // Minor offset re-organization to remove loop-fallout uses of
2383
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2388 // trip counter when there was no major reshaping.
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2389 phase->reorg_offsets(this);
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2390
9dc311b8473e 7008866: Missing loop predicate for loop with multiple entries
kvn
parents: 1972
diff changeset
2391 if (_next && !_next->iteration_split(phase, old_new))
401
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 400
diff changeset
2392 return false;
ee8f06bfb27c 6743188: incomplete fix for 6700047 C2 failed in idom_no_update
never
parents: 400
diff changeset
2393 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 }
1172
b2b6a9bf6238 6894779: Loop Predication for Loop Optimizer in C2
cfang
parents: 844
diff changeset
2395
b2b6a9bf6238 6894779: Loop Predication for Loop Optimizer in C2
cfang
parents: 844
diff changeset
2396
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
2397 //=============================================================================
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2398 // Process all the loops in the loop tree and replace any fill
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2399 // patterns with an intrisc version.
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2400 bool PhaseIdealLoop::do_intrinsify_fill() {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2401 bool changed = false;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2402 for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2403 IdealLoopTree* lpt = iter.current();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2404 changed |= intrinsify_fill(lpt);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2405 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2406 return changed;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2407 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2408
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2409
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2410 // Examine an inner loop looking for a a single store of an invariant
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2411 // value in a unit stride loop,
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2412 bool PhaseIdealLoop::match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& store_value,
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2413 Node*& shift, Node*& con) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2414 const char* msg = NULL;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2415 Node* msg_node = NULL;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2416
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2417 store_value = NULL;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2418 con = NULL;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2419 shift = NULL;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2420
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2421 // Process the loop looking for stores. If there are multiple
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2422 // stores or extra control flow give at this point.
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2423 CountedLoopNode* head = lpt->_head->as_CountedLoop();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2424 for (uint i = 0; msg == NULL && i < lpt->_body.size(); i++) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2425 Node* n = lpt->_body.at(i);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2426 if (n->outcnt() == 0) continue; // Ignore dead
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2427 if (n->is_Store()) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2428 if (store != NULL) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2429 msg = "multiple stores";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2430 break;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2431 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2432 int opc = n->Opcode();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2433 if (opc == Op_StoreP || opc == Op_StoreN || opc == Op_StoreCM) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2434 msg = "oop fills not handled";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2435 break;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2436 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2437 Node* value = n->in(MemNode::ValueIn);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2438 if (!lpt->is_invariant(value)) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2439 msg = "variant store value";
1785
5e4f03302987 6982533: Crash in ~StubRoutines::jbyte_fill with AggressiveOpts enabled
never
parents: 1763
diff changeset
2440 } else if (!_igvn.type(n->in(MemNode::Address))->isa_aryptr()) {
5e4f03302987 6982533: Crash in ~StubRoutines::jbyte_fill with AggressiveOpts enabled
never
parents: 1763
diff changeset
2441 msg = "not array address";
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2442 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2443 store = n;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2444 store_value = value;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2445 } else if (n->is_If() && n != head->loopexit()) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2446 msg = "extra control flow";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2447 msg_node = n;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2448 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2449 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2450
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2451 if (store == NULL) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2452 // No store in loop
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2453 return false;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2454 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2455
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2456 if (msg == NULL && head->stride_con() != 1) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2457 // could handle negative strides too
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2458 if (head->stride_con() < 0) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2459 msg = "negative stride";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2460 } else {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2461 msg = "non-unit stride";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2462 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2463 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2464
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2465 if (msg == NULL && !store->in(MemNode::Address)->is_AddP()) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2466 msg = "can't handle store address";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2467 msg_node = store->in(MemNode::Address);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2468 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2469
1813
c77e8f982901 6984979: OptimizeFill misses some cases with an odd memory graph
never
parents: 1785
diff changeset
2470 if (msg == NULL &&
c77e8f982901 6984979: OptimizeFill misses some cases with an odd memory graph
never
parents: 1785
diff changeset
2471 (!store->in(MemNode::Memory)->is_Phi() ||
c77e8f982901 6984979: OptimizeFill misses some cases with an odd memory graph
never
parents: 1785
diff changeset
2472 store->in(MemNode::Memory)->in(LoopNode::LoopBackControl) != store)) {
c77e8f982901 6984979: OptimizeFill misses some cases with an odd memory graph
never
parents: 1785
diff changeset
2473 msg = "store memory isn't proper phi";
c77e8f982901 6984979: OptimizeFill misses some cases with an odd memory graph
never
parents: 1785
diff changeset
2474 msg_node = store->in(MemNode::Memory);
c77e8f982901 6984979: OptimizeFill misses some cases with an odd memory graph
never
parents: 1785
diff changeset
2475 }
c77e8f982901 6984979: OptimizeFill misses some cases with an odd memory graph
never
parents: 1785
diff changeset
2476
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2477 // Make sure there is an appropriate fill routine
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2478 BasicType t = store->as_Mem()->memory_type();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2479 const char* fill_name;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2480 if (msg == NULL &&
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2481 StubRoutines::select_fill_function(t, false, fill_name) == NULL) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2482 msg = "unsupported store";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2483 msg_node = store;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2484 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2485
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2486 if (msg != NULL) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2487 #ifndef PRODUCT
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2488 if (TraceOptimizeFill) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2489 tty->print_cr("not fill intrinsic candidate: %s", msg);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2490 if (msg_node != NULL) msg_node->dump();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2491 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2492 #endif
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2493 return false;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2494 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2495
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2496 // Make sure the address expression can be handled. It should be
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2497 // head->phi * elsize + con. head->phi might have a ConvI2L.
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2498 Node* elements[4];
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2499 Node* conv = NULL;
1785
5e4f03302987 6982533: Crash in ~StubRoutines::jbyte_fill with AggressiveOpts enabled
never
parents: 1763
diff changeset
2500 bool found_index = false;
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2501 int count = store->in(MemNode::Address)->as_AddP()->unpack_offsets(elements, ARRAY_SIZE(elements));
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2502 for (int e = 0; e < count; e++) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2503 Node* n = elements[e];
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2504 if (n->is_Con() && con == NULL) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2505 con = n;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2506 } else if (n->Opcode() == Op_LShiftX && shift == NULL) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2507 Node* value = n->in(1);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2508 #ifdef _LP64
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2509 if (value->Opcode() == Op_ConvI2L) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2510 conv = value;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2511 value = value->in(1);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2512 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2513 #endif
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2514 if (value != head->phi()) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2515 msg = "unhandled shift in address";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2516 } else {
2448
8b2317d732ec 7026957: assert(type2aelembytes(store->as_Mem()->memory_type(), true) == 1 << shift->in(2)->get_int()) failed
never
parents: 2445
diff changeset
2517 if (type2aelembytes(store->as_Mem()->memory_type(), true) != (1 << n->in(2)->get_int())) {
8b2317d732ec 7026957: assert(type2aelembytes(store->as_Mem()->memory_type(), true) == 1 << shift->in(2)->get_int()) failed
never
parents: 2445
diff changeset
2518 msg = "scale doesn't match";
8b2317d732ec 7026957: assert(type2aelembytes(store->as_Mem()->memory_type(), true) == 1 << shift->in(2)->get_int()) failed
never
parents: 2445
diff changeset
2519 } else {
8b2317d732ec 7026957: assert(type2aelembytes(store->as_Mem()->memory_type(), true) == 1 << shift->in(2)->get_int()) failed
never
parents: 2445
diff changeset
2520 found_index = true;
8b2317d732ec 7026957: assert(type2aelembytes(store->as_Mem()->memory_type(), true) == 1 << shift->in(2)->get_int()) failed
never
parents: 2445
diff changeset
2521 shift = n;
8b2317d732ec 7026957: assert(type2aelembytes(store->as_Mem()->memory_type(), true) == 1 << shift->in(2)->get_int()) failed
never
parents: 2445
diff changeset
2522 }
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2523 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2524 } else if (n->Opcode() == Op_ConvI2L && conv == NULL) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2525 if (n->in(1) == head->phi()) {
1785
5e4f03302987 6982533: Crash in ~StubRoutines::jbyte_fill with AggressiveOpts enabled
never
parents: 1763
diff changeset
2526 found_index = true;
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2527 conv = n;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2528 } else {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2529 msg = "unhandled input to ConvI2L";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2530 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2531 } else if (n == head->phi()) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2532 // no shift, check below for allowed cases
1785
5e4f03302987 6982533: Crash in ~StubRoutines::jbyte_fill with AggressiveOpts enabled
never
parents: 1763
diff changeset
2533 found_index = true;
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2534 } else {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2535 msg = "unhandled node in address";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2536 msg_node = n;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2537 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2538 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2539
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2540 if (count == -1) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2541 msg = "malformed address expression";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2542 msg_node = store;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2543 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2544
1785
5e4f03302987 6982533: Crash in ~StubRoutines::jbyte_fill with AggressiveOpts enabled
never
parents: 1763
diff changeset
2545 if (!found_index) {
5e4f03302987 6982533: Crash in ~StubRoutines::jbyte_fill with AggressiveOpts enabled
never
parents: 1763
diff changeset
2546 msg = "missing use of index";
5e4f03302987 6982533: Crash in ~StubRoutines::jbyte_fill with AggressiveOpts enabled
never
parents: 1763
diff changeset
2547 }
5e4f03302987 6982533: Crash in ~StubRoutines::jbyte_fill with AggressiveOpts enabled
never
parents: 1763
diff changeset
2548
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2549 // byte sized items won't have a shift
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2550 if (msg == NULL && shift == NULL && t != T_BYTE && t != T_BOOLEAN) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2551 msg = "can't find shift";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2552 msg_node = store;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2553 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2554
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2555 if (msg != NULL) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2556 #ifndef PRODUCT
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2557 if (TraceOptimizeFill) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2558 tty->print_cr("not fill intrinsic: %s", msg);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2559 if (msg_node != NULL) msg_node->dump();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2560 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2561 #endif
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2562 return false;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2563 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2564
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2565 // No make sure all the other nodes in the loop can be handled
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2566 VectorSet ok(Thread::current()->resource_area());
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2567
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2568 // store related values are ok
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2569 ok.set(store->_idx);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2570 ok.set(store->in(MemNode::Memory)->_idx);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2571
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2572 // Loop structure is ok
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2573 ok.set(head->_idx);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2574 ok.set(head->loopexit()->_idx);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2575 ok.set(head->phi()->_idx);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2576 ok.set(head->incr()->_idx);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2577 ok.set(head->loopexit()->cmp_node()->_idx);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2578 ok.set(head->loopexit()->in(1)->_idx);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2579
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2580 // Address elements are ok
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2581 if (con) ok.set(con->_idx);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2582 if (shift) ok.set(shift->_idx);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2583 if (conv) ok.set(conv->_idx);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2584
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2585 for (uint i = 0; msg == NULL && i < lpt->_body.size(); i++) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2586 Node* n = lpt->_body.at(i);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2587 if (n->outcnt() == 0) continue; // Ignore dead
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2588 if (ok.test(n->_idx)) continue;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2589 // Backedge projection is ok
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2590 if (n->is_IfTrue() && n->in(0) == head->loopexit()) continue;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2591 if (!n->is_AddP()) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2592 msg = "unhandled node";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2593 msg_node = n;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2594 break;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2595 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2596 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2597
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2598 // Make sure no unexpected values are used outside the loop
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2599 for (uint i = 0; msg == NULL && i < lpt->_body.size(); i++) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2600 Node* n = lpt->_body.at(i);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2601 // These values can be replaced with other nodes if they are used
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2602 // outside the loop.
1813
c77e8f982901 6984979: OptimizeFill misses some cases with an odd memory graph
never
parents: 1785
diff changeset
2603 if (n == store || n == head->loopexit() || n == head->incr() || n == store->in(MemNode::Memory)) continue;
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2604 for (SimpleDUIterator iter(n); iter.has_next(); iter.next()) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2605 Node* use = iter.get();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2606 if (!lpt->_body.contains(use)) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2607 msg = "node is used outside loop";
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2608 // lpt->_body.dump();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2609 msg_node = n;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2610 break;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2611 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2612 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2613 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2614
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2615 #ifdef ASSERT
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2616 if (TraceOptimizeFill) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2617 if (msg != NULL) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2618 tty->print_cr("no fill intrinsic: %s", msg);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2619 if (msg_node != NULL) msg_node->dump();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2620 } else {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2621 tty->print_cr("fill intrinsic for:");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2622 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2623 store->dump();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2624 if (Verbose) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2625 lpt->_body.dump();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2626 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2627 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2628 #endif
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2629
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2630 return msg == NULL;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2631 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2632
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2633
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2634
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2635 bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2636 // Only for counted inner loops
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2637 if (!lpt->is_counted() || !lpt->is_inner()) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2638 return false;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2639 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2640
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2641 // Must have constant stride
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2642 CountedLoopNode* head = lpt->_head->as_CountedLoop();
3850
6987871cfb9b 7077439: Possible reference through NULL in loopPredicate.cpp:726
kvn
parents: 3845
diff changeset
2643 if (!head->is_valid_counted_loop() || !head->is_normal_loop()) {
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2644 return false;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2645 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2646
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2647 // Check that the body only contains a store of a loop invariant
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2648 // value that is indexed by the loop phi.
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2649 Node* store = NULL;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2650 Node* store_value = NULL;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2651 Node* shift = NULL;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2652 Node* offset = NULL;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2653 if (!match_fill_loop(lpt, store, store_value, shift, offset)) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2654 return false;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2655 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2656
2445
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
2657 #ifndef PRODUCT
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
2658 if (TraceLoopOpts) {
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
2659 tty->print("ArrayFill ");
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
2660 lpt->dump_head();
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
2661 }
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
2662 #endif
08eb13460b3a 7004535: Clone loop predicate during loop unswitch
kvn
parents: 2417
diff changeset
2663
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2664 // Now replace the whole loop body by a call to a fill routine that
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2665 // covers the same region as the loop.
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2666 Node* base = store->in(MemNode::Address)->as_AddP()->in(AddPNode::Base);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2667
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2668 // Build an expression for the beginning of the copy region
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2669 Node* index = head->init_trip();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2670 #ifdef _LP64
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2671 index = new (C, 2) ConvI2LNode(index);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2672 _igvn.register_new_node_with_optimizer(index);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2673 #endif
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2674 if (shift != NULL) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2675 // byte arrays don't require a shift but others do.
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2676 index = new (C, 3) LShiftXNode(index, shift->in(2));
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2677 _igvn.register_new_node_with_optimizer(index);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2678 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2679 index = new (C, 4) AddPNode(base, base, index);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2680 _igvn.register_new_node_with_optimizer(index);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2681 Node* from = new (C, 4) AddPNode(base, index, offset);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2682 _igvn.register_new_node_with_optimizer(from);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2683 // Compute the number of elements to copy
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2684 Node* len = new (C, 3) SubINode(head->limit(), head->init_trip());
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2685 _igvn.register_new_node_with_optimizer(len);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2686
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2687 BasicType t = store->as_Mem()->memory_type();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2688 bool aligned = false;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2689 if (offset != NULL && head->init_trip()->is_Con()) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2690 int element_size = type2aelembytes(t);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2691 aligned = (offset->find_intptr_t_type()->get_con() + head->init_trip()->get_int() * element_size) % HeapWordSize == 0;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2692 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2693
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2694 // Build a call to the fill routine
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2695 const char* fill_name;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2696 address fill = StubRoutines::select_fill_function(t, aligned, fill_name);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2697 assert(fill != NULL, "what?");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2698
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2699 // Convert float/double to int/long for fill routines
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2700 if (t == T_FLOAT) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2701 store_value = new (C, 2) MoveF2INode(store_value);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2702 _igvn.register_new_node_with_optimizer(store_value);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2703 } else if (t == T_DOUBLE) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2704 store_value = new (C, 2) MoveD2LNode(store_value);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2705 _igvn.register_new_node_with_optimizer(store_value);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2706 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2707
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2708 Node* mem_phi = store->in(MemNode::Memory);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2709 Node* result_ctrl;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2710 Node* result_mem;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2711 const TypeFunc* call_type = OptoRuntime::array_fill_Type();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2712 int size = call_type->domain()->cnt();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2713 CallLeafNode *call = new (C, size) CallLeafNoFPNode(call_type, fill,
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2714 fill_name, TypeAryPtr::get_array_body_type(t));
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2715 call->init_req(TypeFunc::Parms+0, from);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2716 call->init_req(TypeFunc::Parms+1, store_value);
1844
75588558f1bf 6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents: 1813
diff changeset
2717 #ifdef _LP64
75588558f1bf 6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents: 1813
diff changeset
2718 len = new (C, 2) ConvI2LNode(len);
75588558f1bf 6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents: 1813
diff changeset
2719 _igvn.register_new_node_with_optimizer(len);
75588558f1bf 6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents: 1813
diff changeset
2720 #endif
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2721 call->init_req(TypeFunc::Parms+2, len);
1844
75588558f1bf 6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents: 1813
diff changeset
2722 #ifdef _LP64
75588558f1bf 6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents: 1813
diff changeset
2723 call->init_req(TypeFunc::Parms+3, C->top());
75588558f1bf 6980792: Crash "exception happened outside interpreter, nmethods and vtable stubs (1)"
never
parents: 1813
diff changeset
2724 #endif
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2725 call->init_req( TypeFunc::Control, head->init_control());
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2726 call->init_req( TypeFunc::I_O , C->top() ) ; // does no i/o
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2727 call->init_req( TypeFunc::Memory , mem_phi->in(LoopNode::EntryControl) );
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2728 call->init_req( TypeFunc::ReturnAdr, C->start()->proj_out(TypeFunc::ReturnAdr) );
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2729 call->init_req( TypeFunc::FramePtr, C->start()->proj_out(TypeFunc::FramePtr) );
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2730 _igvn.register_new_node_with_optimizer(call);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2731 result_ctrl = new (C, 1) ProjNode(call,TypeFunc::Control);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2732 _igvn.register_new_node_with_optimizer(result_ctrl);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2733 result_mem = new (C, 1) ProjNode(call,TypeFunc::Memory);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2734 _igvn.register_new_node_with_optimizer(result_mem);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2735
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2736 // If this fill is tightly coupled to an allocation and overwrites
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2737 // the whole body, allow it to take over the zeroing.
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2738 AllocateNode* alloc = AllocateNode::Ideal_allocation(base, this);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2739 if (alloc != NULL && alloc->is_AllocateArray()) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2740 Node* length = alloc->as_AllocateArray()->Ideal_length();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2741 if (head->limit() == length &&
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2742 head->init_trip() == _igvn.intcon(0)) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2743 if (TraceOptimizeFill) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2744 tty->print_cr("Eliminated zeroing in allocation");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2745 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2746 alloc->maybe_set_complete(&_igvn);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2747 } else {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2748 #ifdef ASSERT
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2749 if (TraceOptimizeFill) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2750 tty->print_cr("filling array but bounds don't match");
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2751 alloc->dump();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2752 head->init_trip()->dump();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2753 head->limit()->dump();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2754 length->dump();
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2755 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2756 #endif
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2757 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2758 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2759
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2760 // Redirect the old control and memory edges that are outside the loop.
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2761 Node* exit = head->loopexit()->proj_out(0);
1813
c77e8f982901 6984979: OptimizeFill misses some cases with an odd memory graph
never
parents: 1785
diff changeset
2762 // Sometimes the memory phi of the head is used as the outgoing
c77e8f982901 6984979: OptimizeFill misses some cases with an odd memory graph
never
parents: 1785
diff changeset
2763 // state of the loop. It's safe in this case to replace it with the
c77e8f982901 6984979: OptimizeFill misses some cases with an odd memory graph
never
parents: 1785
diff changeset
2764 // result_mem.
c77e8f982901 6984979: OptimizeFill misses some cases with an odd memory graph
never
parents: 1785
diff changeset
2765 _igvn.replace_node(store->in(MemNode::Memory), result_mem);
1763
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2766 _igvn.replace_node(exit, result_ctrl);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2767 _igvn.replace_node(store, result_mem);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2768 // Any uses the increment outside of the loop become the loop limit.
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2769 _igvn.replace_node(head->incr(), head->limit());
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2770
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2771 // Disconnect the head from the loop.
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2772 for (uint i = 0; i < lpt->_body.size(); i++) {
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2773 Node* n = lpt->_body.at(i);
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2774 _igvn.replace_node(n, C->top());
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2775 }
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2776
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2777 return true;
d6f45b55c972 4809552: Optimize Arrays.fill(...)
never
parents: 1621
diff changeset
2778 }