src/share/vm/opto/loopPredicate.cpp

Tue, 17 Oct 2017 12:58:25 +0800

author
aoqi
date
Tue, 17 Oct 2017 12:58:25 +0800
changeset 7994
04ff2f6cd0eb
parent 7859
c1c199dde5c9
parent 6876
710a3c8b516e
child 8856
ac27a9c85bea
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "precompiled.hpp"
aoqi@0 26 #include "opto/loopnode.hpp"
aoqi@0 27 #include "opto/addnode.hpp"
aoqi@0 28 #include "opto/callnode.hpp"
aoqi@0 29 #include "opto/connode.hpp"
aoqi@0 30 #include "opto/loopnode.hpp"
aoqi@0 31 #include "opto/mulnode.hpp"
aoqi@0 32 #include "opto/rootnode.hpp"
aoqi@0 33 #include "opto/subnode.hpp"
aoqi@0 34
aoqi@0 35 /*
aoqi@0 36 * The general idea of Loop Predication is to insert a predicate on the entry
aoqi@0 37 * path to a loop, and raise a uncommon trap if the check of the condition fails.
aoqi@0 38 * The condition checks are promoted from inside the loop body, and thus
aoqi@0 39 * the checks inside the loop could be eliminated. Currently, loop predication
aoqi@0 40 * optimization has been applied to remove array range check and loop invariant
aoqi@0 41 * checks (such as null checks).
aoqi@0 42 */
aoqi@0 43
aoqi@0 44 //-------------------------------register_control-------------------------
aoqi@0 45 void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred) {
aoqi@0 46 assert(n->is_CFG(), "must be control node");
aoqi@0 47 _igvn.register_new_node_with_optimizer(n);
aoqi@0 48 loop->_body.push(n);
aoqi@0 49 set_loop(n, loop);
aoqi@0 50 // When called from beautify_loops() idom is not constructed yet.
aoqi@0 51 if (_idom != NULL) {
aoqi@0 52 set_idom(n, pred, dom_depth(pred));
aoqi@0 53 }
aoqi@0 54 }
aoqi@0 55
aoqi@0 56 //------------------------------create_new_if_for_predicate------------------------
aoqi@0 57 // create a new if above the uct_if_pattern for the predicate to be promoted.
aoqi@0 58 //
aoqi@0 59 // before after
aoqi@0 60 // ---------- ----------
aoqi@0 61 // ctrl ctrl
aoqi@0 62 // | |
aoqi@0 63 // | |
aoqi@0 64 // v v
aoqi@0 65 // iff new_iff
aoqi@0 66 // / \ / \
aoqi@0 67 // / \ / \
aoqi@0 68 // v v v v
aoqi@0 69 // uncommon_proj cont_proj if_uct if_cont
aoqi@0 70 // \ | | | |
aoqi@0 71 // \ | | | |
aoqi@0 72 // v v v | v
aoqi@0 73 // rgn loop | iff
aoqi@0 74 // | | / \
aoqi@0 75 // | | / \
aoqi@0 76 // v | v v
aoqi@0 77 // uncommon_trap | uncommon_proj cont_proj
aoqi@0 78 // \ \ | |
aoqi@0 79 // \ \ | |
aoqi@0 80 // v v v v
aoqi@0 81 // rgn loop
aoqi@0 82 // |
aoqi@0 83 // |
aoqi@0 84 // v
aoqi@0 85 // uncommon_trap
aoqi@0 86 //
aoqi@0 87 //
aoqi@0 88 // We will create a region to guard the uct call if there is no one there.
aoqi@0 89 // The true projecttion (if_cont) of the new_iff is returned.
aoqi@0 90 // This code is also used to clone predicates to clonned loops.
aoqi@0 91 ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
aoqi@0 92 Deoptimization::DeoptReason reason) {
aoqi@0 93 assert(cont_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
aoqi@0 94 IfNode* iff = cont_proj->in(0)->as_If();
aoqi@0 95
aoqi@0 96 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
aoqi@0 97 Node *rgn = uncommon_proj->unique_ctrl_out();
aoqi@0 98 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
aoqi@0 99
aoqi@0 100 uint proj_index = 1; // region's edge corresponding to uncommon_proj
aoqi@0 101 if (!rgn->is_Region()) { // create a region to guard the call
aoqi@0 102 assert(rgn->is_Call(), "must be call uct");
aoqi@0 103 CallNode* call = rgn->as_Call();
aoqi@0 104 IdealLoopTree* loop = get_loop(call);
aoqi@0 105 rgn = new (C) RegionNode(1);
aoqi@0 106 rgn->add_req(uncommon_proj);
aoqi@0 107 register_control(rgn, loop, uncommon_proj);
aoqi@0 108 _igvn.hash_delete(call);
aoqi@0 109 call->set_req(0, rgn);
aoqi@0 110 // When called from beautify_loops() idom is not constructed yet.
aoqi@0 111 if (_idom != NULL) {
aoqi@0 112 set_idom(call, rgn, dom_depth(rgn));
aoqi@0 113 }
aoqi@0 114 } else {
aoqi@0 115 // Find region's edge corresponding to uncommon_proj
aoqi@0 116 for (; proj_index < rgn->req(); proj_index++)
aoqi@0 117 if (rgn->in(proj_index) == uncommon_proj) break;
aoqi@0 118 assert(proj_index < rgn->req(), "sanity");
aoqi@0 119 }
aoqi@0 120
aoqi@0 121 Node* entry = iff->in(0);
aoqi@0 122 if (new_entry != NULL) {
aoqi@0 123 // Clonning the predicate to new location.
aoqi@0 124 entry = new_entry;
aoqi@0 125 }
aoqi@0 126 // Create new_iff
aoqi@0 127 IdealLoopTree* lp = get_loop(entry);
aoqi@0 128 IfNode *new_iff = iff->clone()->as_If();
aoqi@0 129 new_iff->set_req(0, entry);
aoqi@0 130 register_control(new_iff, lp, entry);
aoqi@0 131 Node *if_cont = new (C) IfTrueNode(new_iff);
aoqi@0 132 Node *if_uct = new (C) IfFalseNode(new_iff);
aoqi@0 133 if (cont_proj->is_IfFalse()) {
aoqi@0 134 // Swap
aoqi@0 135 Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp;
aoqi@0 136 }
aoqi@0 137 register_control(if_cont, lp, new_iff);
aoqi@0 138 register_control(if_uct, get_loop(rgn), new_iff);
aoqi@0 139
aoqi@0 140 // if_uct to rgn
aoqi@0 141 _igvn.hash_delete(rgn);
aoqi@0 142 rgn->add_req(if_uct);
aoqi@0 143 // When called from beautify_loops() idom is not constructed yet.
aoqi@0 144 if (_idom != NULL) {
aoqi@0 145 Node* ridom = idom(rgn);
aoqi@0 146 Node* nrdom = dom_lca(ridom, new_iff);
aoqi@0 147 set_idom(rgn, nrdom, dom_depth(rgn));
aoqi@0 148 }
aoqi@0 149
aoqi@0 150 // If rgn has phis add new edges which has the same
aoqi@0 151 // value as on original uncommon_proj pass.
aoqi@0 152 assert(rgn->in(rgn->req() -1) == if_uct, "new edge should be last");
aoqi@0 153 bool has_phi = false;
aoqi@0 154 for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) {
aoqi@0 155 Node* use = rgn->fast_out(i);
aoqi@0 156 if (use->is_Phi() && use->outcnt() > 0) {
aoqi@0 157 assert(use->in(0) == rgn, "");
aoqi@0 158 _igvn.rehash_node_delayed(use);
aoqi@0 159 use->add_req(use->in(proj_index));
aoqi@0 160 has_phi = true;
aoqi@0 161 }
aoqi@0 162 }
aoqi@0 163 assert(!has_phi || rgn->req() > 3, "no phis when region is created");
aoqi@0 164
aoqi@0 165 if (new_entry == NULL) {
aoqi@0 166 // Attach if_cont to iff
aoqi@0 167 _igvn.hash_delete(iff);
aoqi@0 168 iff->set_req(0, if_cont);
aoqi@0 169 if (_idom != NULL) {
aoqi@0 170 set_idom(iff, if_cont, dom_depth(iff));
aoqi@0 171 }
aoqi@0 172 }
aoqi@0 173 return if_cont->as_Proj();
aoqi@0 174 }
aoqi@0 175
aoqi@0 176 //------------------------------create_new_if_for_predicate------------------------
aoqi@0 177 // Create a new if below new_entry for the predicate to be cloned (IGVN optimization)
aoqi@0 178 ProjNode* PhaseIterGVN::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
aoqi@0 179 Deoptimization::DeoptReason reason) {
aoqi@0 180 assert(new_entry != 0, "only used for clone predicate");
aoqi@0 181 assert(cont_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
aoqi@0 182 IfNode* iff = cont_proj->in(0)->as_If();
aoqi@0 183
aoqi@0 184 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
aoqi@0 185 Node *rgn = uncommon_proj->unique_ctrl_out();
aoqi@0 186 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
aoqi@0 187
aoqi@0 188 uint proj_index = 1; // region's edge corresponding to uncommon_proj
aoqi@0 189 if (!rgn->is_Region()) { // create a region to guard the call
aoqi@0 190 assert(rgn->is_Call(), "must be call uct");
aoqi@0 191 CallNode* call = rgn->as_Call();
aoqi@0 192 rgn = new (C) RegionNode(1);
aoqi@0 193 register_new_node_with_optimizer(rgn);
aoqi@0 194 rgn->add_req(uncommon_proj);
aoqi@0 195 hash_delete(call);
aoqi@0 196 call->set_req(0, rgn);
aoqi@0 197 } else {
aoqi@0 198 // Find region's edge corresponding to uncommon_proj
aoqi@0 199 for (; proj_index < rgn->req(); proj_index++)
aoqi@0 200 if (rgn->in(proj_index) == uncommon_proj) break;
aoqi@0 201 assert(proj_index < rgn->req(), "sanity");
aoqi@0 202 }
aoqi@0 203
aoqi@0 204 // Create new_iff in new location.
aoqi@0 205 IfNode *new_iff = iff->clone()->as_If();
aoqi@0 206 new_iff->set_req(0, new_entry);
aoqi@0 207
aoqi@0 208 register_new_node_with_optimizer(new_iff);
aoqi@0 209 Node *if_cont = new (C) IfTrueNode(new_iff);
aoqi@0 210 Node *if_uct = new (C) IfFalseNode(new_iff);
aoqi@0 211 if (cont_proj->is_IfFalse()) {
aoqi@0 212 // Swap
aoqi@0 213 Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp;
aoqi@0 214 }
aoqi@0 215 register_new_node_with_optimizer(if_cont);
aoqi@0 216 register_new_node_with_optimizer(if_uct);
aoqi@0 217
aoqi@0 218 // if_uct to rgn
aoqi@0 219 hash_delete(rgn);
aoqi@0 220 rgn->add_req(if_uct);
aoqi@0 221
aoqi@0 222 // If rgn has phis add corresponding new edges which has the same
aoqi@0 223 // value as on original uncommon_proj pass.
aoqi@0 224 assert(rgn->in(rgn->req() -1) == if_uct, "new edge should be last");
aoqi@0 225 bool has_phi = false;
aoqi@0 226 for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) {
aoqi@0 227 Node* use = rgn->fast_out(i);
aoqi@0 228 if (use->is_Phi() && use->outcnt() > 0) {
aoqi@0 229 rehash_node_delayed(use);
aoqi@0 230 use->add_req(use->in(proj_index));
aoqi@0 231 has_phi = true;
aoqi@0 232 }
aoqi@0 233 }
aoqi@0 234 assert(!has_phi || rgn->req() > 3, "no phis when region is created");
aoqi@0 235
aoqi@0 236 return if_cont->as_Proj();
aoqi@0 237 }
aoqi@0 238
aoqi@0 239 //--------------------------clone_predicate-----------------------
aoqi@0 240 ProjNode* PhaseIdealLoop::clone_predicate(ProjNode* predicate_proj, Node* new_entry,
aoqi@0 241 Deoptimization::DeoptReason reason,
aoqi@0 242 PhaseIdealLoop* loop_phase,
aoqi@0 243 PhaseIterGVN* igvn) {
aoqi@0 244 ProjNode* new_predicate_proj;
aoqi@0 245 if (loop_phase != NULL) {
aoqi@0 246 new_predicate_proj = loop_phase->create_new_if_for_predicate(predicate_proj, new_entry, reason);
aoqi@0 247 } else {
aoqi@0 248 new_predicate_proj = igvn->create_new_if_for_predicate(predicate_proj, new_entry, reason);
aoqi@0 249 }
aoqi@0 250 IfNode* iff = new_predicate_proj->in(0)->as_If();
aoqi@0 251 Node* ctrl = iff->in(0);
aoqi@0 252
aoqi@0 253 // Match original condition since predicate's projections could be swapped.
aoqi@0 254 assert(predicate_proj->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
aoqi@0 255 Node* opq = new (igvn->C) Opaque1Node(igvn->C, predicate_proj->in(0)->in(1)->in(1)->in(1));
aoqi@0 256 igvn->C->add_predicate_opaq(opq);
aoqi@0 257
aoqi@0 258 Node* bol = new (igvn->C) Conv2BNode(opq);
aoqi@0 259 if (loop_phase != NULL) {
aoqi@0 260 loop_phase->register_new_node(opq, ctrl);
aoqi@0 261 loop_phase->register_new_node(bol, ctrl);
aoqi@0 262 } else {
aoqi@0 263 igvn->register_new_node_with_optimizer(opq);
aoqi@0 264 igvn->register_new_node_with_optimizer(bol);
aoqi@0 265 }
aoqi@0 266 igvn->hash_delete(iff);
aoqi@0 267 iff->set_req(1, bol);
aoqi@0 268 return new_predicate_proj;
aoqi@0 269 }
aoqi@0 270
aoqi@0 271
aoqi@0 272 //--------------------------clone_loop_predicates-----------------------
aoqi@0 273 // Interface from IGVN
aoqi@0 274 Node* PhaseIterGVN::clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) {
aoqi@0 275 return PhaseIdealLoop::clone_loop_predicates(old_entry, new_entry, clone_limit_check, NULL, this);
aoqi@0 276 }
aoqi@0 277
aoqi@0 278 // Interface from PhaseIdealLoop
aoqi@0 279 Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check) {
aoqi@0 280 return clone_loop_predicates(old_entry, new_entry, clone_limit_check, this, &this->_igvn);
aoqi@0 281 }
aoqi@0 282
aoqi@0 283 // Clone loop predicates to cloned loops (peeled, unswitched, split_if).
aoqi@0 284 Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry,
aoqi@0 285 bool clone_limit_check,
aoqi@0 286 PhaseIdealLoop* loop_phase,
aoqi@0 287 PhaseIterGVN* igvn) {
aoqi@0 288 #ifdef ASSERT
aoqi@0 289 if (new_entry == NULL || !(new_entry->is_Proj() || new_entry->is_Region() || new_entry->is_SafePoint())) {
aoqi@0 290 if (new_entry != NULL)
aoqi@0 291 new_entry->dump();
aoqi@0 292 assert(false, "not IfTrue, IfFalse, Region or SafePoint");
aoqi@0 293 }
aoqi@0 294 #endif
aoqi@0 295 // Search original predicates
aoqi@0 296 Node* entry = old_entry;
aoqi@0 297 ProjNode* limit_check_proj = NULL;
aoqi@0 298 if (LoopLimitCheck) {
aoqi@0 299 limit_check_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
aoqi@0 300 if (limit_check_proj != NULL) {
aoqi@0 301 entry = entry->in(0)->in(0);
aoqi@0 302 }
aoqi@0 303 }
aoqi@0 304 if (UseLoopPredicate) {
aoqi@0 305 ProjNode* predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
aoqi@0 306 if (predicate_proj != NULL) { // right pattern that can be used by loop predication
aoqi@0 307 // clone predicate
aoqi@0 308 new_entry = clone_predicate(predicate_proj, new_entry,
aoqi@0 309 Deoptimization::Reason_predicate,
aoqi@0 310 loop_phase, igvn);
aoqi@0 311 assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone predicate");
aoqi@0 312 if (TraceLoopPredicate) {
aoqi@0 313 tty->print("Loop Predicate cloned: ");
aoqi@0 314 debug_only( new_entry->in(0)->dump(); )
aoqi@0 315 }
aoqi@0 316 }
aoqi@0 317 }
aoqi@0 318 if (limit_check_proj != NULL && clone_limit_check) {
aoqi@0 319 // Clone loop limit check last to insert it before loop.
aoqi@0 320 // Don't clone a limit check which was already finalized
aoqi@0 321 // for this counted loop (only one limit check is needed).
aoqi@0 322 new_entry = clone_predicate(limit_check_proj, new_entry,
aoqi@0 323 Deoptimization::Reason_loop_limit_check,
aoqi@0 324 loop_phase, igvn);
aoqi@0 325 assert(new_entry != NULL && new_entry->is_Proj(), "IfTrue or IfFalse after clone limit check");
aoqi@0 326 if (TraceLoopLimitCheck) {
aoqi@0 327 tty->print("Loop Limit Check cloned: ");
aoqi@0 328 debug_only( new_entry->in(0)->dump(); )
aoqi@0 329 }
aoqi@0 330 }
aoqi@0 331 return new_entry;
aoqi@0 332 }
aoqi@0 333
aoqi@0 334 //--------------------------skip_loop_predicates------------------------------
aoqi@0 335 // Skip related predicates.
aoqi@0 336 Node* PhaseIdealLoop::skip_loop_predicates(Node* entry) {
aoqi@0 337 Node* predicate = NULL;
aoqi@0 338 if (LoopLimitCheck) {
aoqi@0 339 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
aoqi@0 340 if (predicate != NULL) {
aoqi@0 341 entry = entry->in(0)->in(0);
aoqi@0 342 }
aoqi@0 343 }
aoqi@0 344 if (UseLoopPredicate) {
aoqi@0 345 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
aoqi@0 346 if (predicate != NULL) { // right pattern that can be used by loop predication
aoqi@0 347 IfNode* iff = entry->in(0)->as_If();
aoqi@0 348 ProjNode* uncommon_proj = iff->proj_out(1 - entry->as_Proj()->_con);
aoqi@0 349 Node* rgn = uncommon_proj->unique_ctrl_out();
aoqi@0 350 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
aoqi@0 351 entry = entry->in(0)->in(0);
aoqi@0 352 while (entry != NULL && entry->is_Proj() && entry->in(0)->is_If()) {
aoqi@0 353 uncommon_proj = entry->in(0)->as_If()->proj_out(1 - entry->as_Proj()->_con);
aoqi@0 354 if (uncommon_proj->unique_ctrl_out() != rgn)
aoqi@0 355 break;
aoqi@0 356 entry = entry->in(0)->in(0);
aoqi@0 357 }
aoqi@0 358 }
aoqi@0 359 }
aoqi@0 360 return entry;
aoqi@0 361 }
aoqi@0 362
aoqi@0 363 //--------------------------find_predicate_insertion_point-------------------
aoqi@0 364 // Find a good location to insert a predicate
aoqi@0 365 ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason) {
aoqi@0 366 if (start_c == NULL || !start_c->is_Proj())
aoqi@0 367 return NULL;
aoqi@0 368 if (start_c->as_Proj()->is_uncommon_trap_if_pattern(reason)) {
aoqi@0 369 return start_c->as_Proj();
aoqi@0 370 }
aoqi@0 371 return NULL;
aoqi@0 372 }
aoqi@0 373
aoqi@0 374 //--------------------------find_predicate------------------------------------
aoqi@0 375 // Find a predicate
aoqi@0 376 Node* PhaseIdealLoop::find_predicate(Node* entry) {
aoqi@0 377 Node* predicate = NULL;
aoqi@0 378 if (LoopLimitCheck) {
aoqi@0 379 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
aoqi@0 380 if (predicate != NULL) { // right pattern that can be used by loop predication
aoqi@0 381 return entry;
aoqi@0 382 }
aoqi@0 383 }
aoqi@0 384 if (UseLoopPredicate) {
aoqi@0 385 predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
aoqi@0 386 if (predicate != NULL) { // right pattern that can be used by loop predication
aoqi@0 387 return entry;
aoqi@0 388 }
aoqi@0 389 }
aoqi@0 390 return NULL;
aoqi@0 391 }
aoqi@0 392
aoqi@0 393 //------------------------------Invariance-----------------------------------
aoqi@0 394 // Helper class for loop_predication_impl to compute invariance on the fly and
aoqi@0 395 // clone invariants.
aoqi@0 396 class Invariance : public StackObj {
aoqi@0 397 VectorSet _visited, _invariant;
aoqi@0 398 Node_Stack _stack;
aoqi@0 399 VectorSet _clone_visited;
aoqi@0 400 Node_List _old_new; // map of old to new (clone)
aoqi@0 401 IdealLoopTree* _lpt;
aoqi@0 402 PhaseIdealLoop* _phase;
aoqi@0 403
aoqi@0 404 // Helper function to set up the invariance for invariance computation
aoqi@0 405 // If n is a known invariant, set up directly. Otherwise, look up the
aoqi@0 406 // the possibility to push n onto the stack for further processing.
aoqi@0 407 void visit(Node* use, Node* n) {
aoqi@0 408 if (_lpt->is_invariant(n)) { // known invariant
aoqi@0 409 _invariant.set(n->_idx);
aoqi@0 410 } else if (!n->is_CFG()) {
aoqi@0 411 Node *n_ctrl = _phase->ctrl_or_self(n);
aoqi@0 412 Node *u_ctrl = _phase->ctrl_or_self(use); // self if use is a CFG
aoqi@0 413 if (_phase->is_dominator(n_ctrl, u_ctrl)) {
aoqi@0 414 _stack.push(n, n->in(0) == NULL ? 1 : 0);
aoqi@0 415 }
aoqi@0 416 }
aoqi@0 417 }
aoqi@0 418
aoqi@0 419 // Compute invariance for "the_node" and (possibly) all its inputs recursively
aoqi@0 420 // on the fly
aoqi@0 421 void compute_invariance(Node* n) {
aoqi@0 422 assert(_visited.test(n->_idx), "must be");
aoqi@0 423 visit(n, n);
aoqi@0 424 while (_stack.is_nonempty()) {
aoqi@0 425 Node* n = _stack.node();
aoqi@0 426 uint idx = _stack.index();
aoqi@0 427 if (idx == n->req()) { // all inputs are processed
aoqi@0 428 _stack.pop();
aoqi@0 429 // n is invariant if it's inputs are all invariant
aoqi@0 430 bool all_inputs_invariant = true;
aoqi@0 431 for (uint i = 0; i < n->req(); i++) {
aoqi@0 432 Node* in = n->in(i);
aoqi@0 433 if (in == NULL) continue;
aoqi@0 434 assert(_visited.test(in->_idx), "must have visited input");
aoqi@0 435 if (!_invariant.test(in->_idx)) { // bad guy
aoqi@0 436 all_inputs_invariant = false;
aoqi@0 437 break;
aoqi@0 438 }
aoqi@0 439 }
aoqi@0 440 if (all_inputs_invariant) {
roland@7859 441 // If n's control is a predicate that was moved out of the
roland@7859 442 // loop, it was marked invariant but n is only invariant if
roland@7859 443 // it depends only on that test. Otherwise, unless that test
roland@7859 444 // is out of the loop, it's not invariant.
roland@7859 445 if (n->is_CFG() || n->depends_only_on_test() || n->in(0) == NULL || !_phase->is_member(_lpt, n->in(0))) {
roland@7859 446 _invariant.set(n->_idx); // I am a invariant too
roland@7859 447 }
aoqi@0 448 }
aoqi@0 449 } else { // process next input
aoqi@0 450 _stack.set_index(idx + 1);
aoqi@0 451 Node* m = n->in(idx);
aoqi@0 452 if (m != NULL && !_visited.test_set(m->_idx)) {
aoqi@0 453 visit(n, m);
aoqi@0 454 }
aoqi@0 455 }
aoqi@0 456 }
aoqi@0 457 }
aoqi@0 458
aoqi@0 459 // Helper function to set up _old_new map for clone_nodes.
aoqi@0 460 // If n is a known invariant, set up directly ("clone" of n == n).
aoqi@0 461 // Otherwise, push n onto the stack for real cloning.
aoqi@0 462 void clone_visit(Node* n) {
aoqi@0 463 assert(_invariant.test(n->_idx), "must be invariant");
aoqi@0 464 if (_lpt->is_invariant(n)) { // known invariant
aoqi@0 465 _old_new.map(n->_idx, n);
aoqi@0 466 } else { // to be cloned
aoqi@0 467 assert(!n->is_CFG(), "should not see CFG here");
aoqi@0 468 _stack.push(n, n->in(0) == NULL ? 1 : 0);
aoqi@0 469 }
aoqi@0 470 }
aoqi@0 471
aoqi@0 472 // Clone "n" and (possibly) all its inputs recursively
aoqi@0 473 void clone_nodes(Node* n, Node* ctrl) {
aoqi@0 474 clone_visit(n);
aoqi@0 475 while (_stack.is_nonempty()) {
aoqi@0 476 Node* n = _stack.node();
aoqi@0 477 uint idx = _stack.index();
aoqi@0 478 if (idx == n->req()) { // all inputs processed, clone n!
aoqi@0 479 _stack.pop();
aoqi@0 480 // clone invariant node
aoqi@0 481 Node* n_cl = n->clone();
aoqi@0 482 _old_new.map(n->_idx, n_cl);
aoqi@0 483 _phase->register_new_node(n_cl, ctrl);
aoqi@0 484 for (uint i = 0; i < n->req(); i++) {
aoqi@0 485 Node* in = n_cl->in(i);
aoqi@0 486 if (in == NULL) continue;
aoqi@0 487 n_cl->set_req(i, _old_new[in->_idx]);
aoqi@0 488 }
aoqi@0 489 } else { // process next input
aoqi@0 490 _stack.set_index(idx + 1);
aoqi@0 491 Node* m = n->in(idx);
aoqi@0 492 if (m != NULL && !_clone_visited.test_set(m->_idx)) {
aoqi@0 493 clone_visit(m); // visit the input
aoqi@0 494 }
aoqi@0 495 }
aoqi@0 496 }
aoqi@0 497 }
aoqi@0 498
aoqi@0 499 public:
aoqi@0 500 Invariance(Arena* area, IdealLoopTree* lpt) :
aoqi@0 501 _lpt(lpt), _phase(lpt->_phase),
aoqi@0 502 _visited(area), _invariant(area), _stack(area, 10 /* guess */),
aoqi@0 503 _clone_visited(area), _old_new(area)
aoqi@0 504 {}
aoqi@0 505
aoqi@0 506 // Map old to n for invariance computation and clone
aoqi@0 507 void map_ctrl(Node* old, Node* n) {
aoqi@0 508 assert(old->is_CFG() && n->is_CFG(), "must be");
aoqi@0 509 _old_new.map(old->_idx, n); // "clone" of old is n
aoqi@0 510 _invariant.set(old->_idx); // old is invariant
aoqi@0 511 _clone_visited.set(old->_idx);
aoqi@0 512 }
aoqi@0 513
aoqi@0 514 // Driver function to compute invariance
aoqi@0 515 bool is_invariant(Node* n) {
aoqi@0 516 if (!_visited.test_set(n->_idx))
aoqi@0 517 compute_invariance(n);
aoqi@0 518 return (_invariant.test(n->_idx) != 0);
aoqi@0 519 }
aoqi@0 520
aoqi@0 521 // Driver function to clone invariant
aoqi@0 522 Node* clone(Node* n, Node* ctrl) {
aoqi@0 523 assert(ctrl->is_CFG(), "must be");
aoqi@0 524 assert(_invariant.test(n->_idx), "must be an invariant");
aoqi@0 525 if (!_clone_visited.test(n->_idx))
aoqi@0 526 clone_nodes(n, ctrl);
aoqi@0 527 return _old_new[n->_idx];
aoqi@0 528 }
aoqi@0 529 };
aoqi@0 530
aoqi@0 531 //------------------------------is_range_check_if -----------------------------------
aoqi@0 532 // Returns true if the predicate of iff is in "scale*iv + offset u< load_range(ptr)" format
aoqi@0 533 // Note: this function is particularly designed for loop predication. We require load_range
aoqi@0 534 // and offset to be loop invariant computed on the fly by "invar"
aoqi@0 535 bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invariance& invar) const {
aoqi@0 536 if (!is_loop_exit(iff)) {
aoqi@0 537 return false;
aoqi@0 538 }
aoqi@0 539 if (!iff->in(1)->is_Bool()) {
aoqi@0 540 return false;
aoqi@0 541 }
aoqi@0 542 const BoolNode *bol = iff->in(1)->as_Bool();
aoqi@0 543 if (bol->_test._test != BoolTest::lt) {
aoqi@0 544 return false;
aoqi@0 545 }
aoqi@0 546 if (!bol->in(1)->is_Cmp()) {
aoqi@0 547 return false;
aoqi@0 548 }
aoqi@0 549 const CmpNode *cmp = bol->in(1)->as_Cmp();
aoqi@0 550 if (cmp->Opcode() != Op_CmpU) {
aoqi@0 551 return false;
aoqi@0 552 }
aoqi@0 553 Node* range = cmp->in(2);
aoqi@0 554 if (range->Opcode() != Op_LoadRange) {
aoqi@0 555 const TypeInt* tint = phase->_igvn.type(range)->isa_int();
aoqi@0 556 if (tint == NULL || tint->empty() || tint->_lo < 0) {
aoqi@0 557 // Allow predication on positive values that aren't LoadRanges.
aoqi@0 558 // This allows optimization of loops where the length of the
aoqi@0 559 // array is a known value and doesn't need to be loaded back
aoqi@0 560 // from the array.
aoqi@0 561 return false;
aoqi@0 562 }
aoqi@0 563 }
aoqi@0 564 if (!invar.is_invariant(range)) {
aoqi@0 565 return false;
aoqi@0 566 }
aoqi@0 567 Node *iv = _head->as_CountedLoop()->phi();
aoqi@0 568 int scale = 0;
aoqi@0 569 Node *offset = NULL;
aoqi@0 570 if (!phase->is_scaled_iv_plus_offset(cmp->in(1), iv, &scale, &offset)) {
aoqi@0 571 return false;
aoqi@0 572 }
aoqi@0 573 if (offset && !invar.is_invariant(offset)) { // offset must be invariant
aoqi@0 574 return false;
aoqi@0 575 }
aoqi@0 576 return true;
aoqi@0 577 }
aoqi@0 578
aoqi@0 579 //------------------------------rc_predicate-----------------------------------
aoqi@0 580 // Create a range check predicate
aoqi@0 581 //
aoqi@0 582 // for (i = init; i < limit; i += stride) {
aoqi@0 583 // a[scale*i+offset]
aoqi@0 584 // }
aoqi@0 585 //
aoqi@0 586 // Compute max(scale*i + offset) for init <= i < limit and build the predicate
aoqi@0 587 // as "max(scale*i + offset) u< a.length".
aoqi@0 588 //
aoqi@0 589 // There are two cases for max(scale*i + offset):
aoqi@0 590 // (1) stride*scale > 0
aoqi@0 591 // max(scale*i + offset) = scale*(limit-stride) + offset
aoqi@0 592 // (2) stride*scale < 0
aoqi@0 593 // max(scale*i + offset) = scale*init + offset
aoqi@0 594 BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl,
aoqi@0 595 int scale, Node* offset,
aoqi@0 596 Node* init, Node* limit, Node* stride,
aoqi@0 597 Node* range, bool upper) {
aoqi@0 598 stringStream* predString = NULL;
aoqi@0 599 if (TraceLoopPredicate) {
aoqi@0 600 predString = new stringStream();
aoqi@0 601 predString->print("rc_predicate ");
aoqi@0 602 }
aoqi@0 603
aoqi@0 604 Node* max_idx_expr = init;
aoqi@0 605 int stride_con = stride->get_int();
aoqi@0 606 if ((stride_con > 0) == (scale > 0) == upper) {
aoqi@0 607 if (LoopLimitCheck) {
aoqi@0 608 // With LoopLimitCheck limit is not exact.
aoqi@0 609 // Calculate exact limit here.
aoqi@0 610 // Note, counted loop's test is '<' or '>'.
aoqi@0 611 limit = exact_limit(loop);
aoqi@0 612 max_idx_expr = new (C) SubINode(limit, stride);
aoqi@0 613 register_new_node(max_idx_expr, ctrl);
aoqi@0 614 if (TraceLoopPredicate) predString->print("(limit - stride) ");
aoqi@0 615 } else {
aoqi@0 616 max_idx_expr = new (C) SubINode(limit, stride);
aoqi@0 617 register_new_node(max_idx_expr, ctrl);
aoqi@0 618 if (TraceLoopPredicate) predString->print("(limit - stride) ");
aoqi@0 619 }
aoqi@0 620 } else {
aoqi@0 621 if (TraceLoopPredicate) predString->print("init ");
aoqi@0 622 }
aoqi@0 623
aoqi@0 624 if (scale != 1) {
aoqi@0 625 ConNode* con_scale = _igvn.intcon(scale);
aoqi@0 626 max_idx_expr = new (C) MulINode(max_idx_expr, con_scale);
aoqi@0 627 register_new_node(max_idx_expr, ctrl);
aoqi@0 628 if (TraceLoopPredicate) predString->print("* %d ", scale);
aoqi@0 629 }
aoqi@0 630
aoqi@0 631 if (offset && (!offset->is_Con() || offset->get_int() != 0)){
aoqi@0 632 max_idx_expr = new (C) AddINode(max_idx_expr, offset);
aoqi@0 633 register_new_node(max_idx_expr, ctrl);
aoqi@0 634 if (TraceLoopPredicate)
aoqi@0 635 if (offset->is_Con()) predString->print("+ %d ", offset->get_int());
aoqi@0 636 else predString->print("+ offset ");
aoqi@0 637 }
aoqi@0 638
aoqi@0 639 CmpUNode* cmp = new (C) CmpUNode(max_idx_expr, range);
aoqi@0 640 register_new_node(cmp, ctrl);
aoqi@0 641 BoolNode* bol = new (C) BoolNode(cmp, BoolTest::lt);
aoqi@0 642 register_new_node(bol, ctrl);
aoqi@0 643
aoqi@0 644 if (TraceLoopPredicate) {
aoqi@0 645 predString->print_cr("<u range");
aoqi@0 646 tty->print("%s", predString->as_string());
aoqi@0 647 }
aoqi@0 648 return bol;
aoqi@0 649 }
aoqi@0 650
aoqi@0 651 //------------------------------ loop_predication_impl--------------------------
aoqi@0 652 // Insert loop predicates for null checks and range checks
aoqi@0 653 bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
aoqi@0 654 if (!UseLoopPredicate) return false;
aoqi@0 655
aoqi@0 656 if (!loop->_head->is_Loop()) {
aoqi@0 657 // Could be a simple region when irreducible loops are present.
aoqi@0 658 return false;
aoqi@0 659 }
aoqi@0 660 LoopNode* head = loop->_head->as_Loop();
aoqi@0 661
aoqi@0 662 if (head->unique_ctrl_out()->Opcode() == Op_NeverBranch) {
aoqi@0 663 // do nothing for infinite loops
aoqi@0 664 return false;
aoqi@0 665 }
aoqi@0 666
aoqi@0 667 CountedLoopNode *cl = NULL;
aoqi@0 668 if (head->is_valid_counted_loop()) {
aoqi@0 669 cl = head->as_CountedLoop();
aoqi@0 670 // do nothing for iteration-splitted loops
aoqi@0 671 if (!cl->is_normal_loop()) return false;
aoqi@0 672 // Avoid RCE if Counted loop's test is '!='.
aoqi@0 673 BoolTest::mask bt = cl->loopexit()->test_trip();
aoqi@0 674 if (bt != BoolTest::lt && bt != BoolTest::gt)
aoqi@0 675 cl = NULL;
aoqi@0 676 }
aoqi@0 677
aoqi@0 678 Node* entry = head->in(LoopNode::EntryControl);
aoqi@0 679 ProjNode *predicate_proj = NULL;
aoqi@0 680 // Loop limit check predicate should be near the loop.
aoqi@0 681 if (LoopLimitCheck) {
aoqi@0 682 predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
aoqi@0 683 if (predicate_proj != NULL)
aoqi@0 684 entry = predicate_proj->in(0)->in(0);
aoqi@0 685 }
aoqi@0 686
aoqi@0 687 predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
aoqi@0 688 if (!predicate_proj) {
aoqi@0 689 #ifndef PRODUCT
aoqi@0 690 if (TraceLoopPredicate) {
aoqi@0 691 tty->print("missing predicate:");
aoqi@0 692 loop->dump_head();
aoqi@0 693 head->dump(1);
aoqi@0 694 }
aoqi@0 695 #endif
aoqi@0 696 return false;
aoqi@0 697 }
aoqi@0 698 ConNode* zero = _igvn.intcon(0);
aoqi@0 699 set_ctrl(zero, C->root());
aoqi@0 700
aoqi@0 701 ResourceArea *area = Thread::current()->resource_area();
aoqi@0 702 Invariance invar(area, loop);
aoqi@0 703
aoqi@0 704 // Create list of if-projs such that a newer proj dominates all older
aoqi@0 705 // projs in the list, and they all dominate loop->tail()
aoqi@0 706 Node_List if_proj_list(area);
aoqi@0 707 Node *current_proj = loop->tail(); //start from tail
aoqi@0 708 while (current_proj != head) {
aoqi@0 709 if (loop == get_loop(current_proj) && // still in the loop ?
aoqi@0 710 current_proj->is_Proj() && // is a projection ?
aoqi@0 711 current_proj->in(0)->Opcode() == Op_If) { // is a if projection ?
aoqi@0 712 if_proj_list.push(current_proj);
aoqi@0 713 }
aoqi@0 714 current_proj = idom(current_proj);
aoqi@0 715 }
aoqi@0 716
aoqi@0 717 bool hoisted = false; // true if at least one proj is promoted
aoqi@0 718 while (if_proj_list.size() > 0) {
aoqi@0 719 // Following are changed to nonnull when a predicate can be hoisted
aoqi@0 720 ProjNode* new_predicate_proj = NULL;
aoqi@0 721
aoqi@0 722 ProjNode* proj = if_proj_list.pop()->as_Proj();
aoqi@0 723 IfNode* iff = proj->in(0)->as_If();
aoqi@0 724
aoqi@0 725 if (!proj->is_uncommon_trap_if_pattern(Deoptimization::Reason_none)) {
aoqi@0 726 if (loop->is_loop_exit(iff)) {
aoqi@0 727 // stop processing the remaining projs in the list because the execution of them
aoqi@0 728 // depends on the condition of "iff" (iff->in(1)).
aoqi@0 729 break;
aoqi@0 730 } else {
aoqi@0 731 // Both arms are inside the loop. There are two cases:
aoqi@0 732 // (1) there is one backward branch. In this case, any remaining proj
aoqi@0 733 // in the if_proj list post-dominates "iff". So, the condition of "iff"
aoqi@0 734 // does not determine the execution the remining projs directly, and we
aoqi@0 735 // can safely continue.
aoqi@0 736 // (2) both arms are forwarded, i.e. a diamond shape. In this case, "proj"
aoqi@0 737 // does not dominate loop->tail(), so it can not be in the if_proj list.
aoqi@0 738 continue;
aoqi@0 739 }
aoqi@0 740 }
aoqi@0 741
aoqi@0 742 Node* test = iff->in(1);
aoqi@0 743 if (!test->is_Bool()){ //Conv2B, ...
aoqi@0 744 continue;
aoqi@0 745 }
aoqi@0 746 BoolNode* bol = test->as_Bool();
aoqi@0 747 if (invar.is_invariant(bol)) {
aoqi@0 748 // Invariant test
aoqi@0 749 new_predicate_proj = create_new_if_for_predicate(predicate_proj, NULL,
aoqi@0 750 Deoptimization::Reason_predicate);
aoqi@0 751 Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0);
aoqi@0 752 BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool();
aoqi@0 753
aoqi@0 754 // Negate test if necessary
aoqi@0 755 bool negated = false;
aoqi@0 756 if (proj->_con != predicate_proj->_con) {
aoqi@0 757 new_predicate_bol = new (C) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate());
aoqi@0 758 register_new_node(new_predicate_bol, ctrl);
aoqi@0 759 negated = true;
aoqi@0 760 }
aoqi@0 761 IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If();
aoqi@0 762 _igvn.hash_delete(new_predicate_iff);
aoqi@0 763 new_predicate_iff->set_req(1, new_predicate_bol);
aoqi@0 764 #ifndef PRODUCT
aoqi@0 765 if (TraceLoopPredicate) {
aoqi@0 766 tty->print("Predicate invariant if%s: %d ", negated ? " negated" : "", new_predicate_iff->_idx);
aoqi@0 767 loop->dump_head();
aoqi@0 768 } else if (TraceLoopOpts) {
aoqi@0 769 tty->print("Predicate IC ");
aoqi@0 770 loop->dump_head();
aoqi@0 771 }
aoqi@0 772 #endif
aoqi@0 773 } else if ((cl != NULL) && (proj->_con == predicate_proj->_con) &&
aoqi@0 774 loop->is_range_check_if(iff, this, invar)) {
aoqi@0 775
aoqi@0 776 // Range check for counted loops
aoqi@0 777 const Node* cmp = bol->in(1)->as_Cmp();
aoqi@0 778 Node* idx = cmp->in(1);
aoqi@0 779 assert(!invar.is_invariant(idx), "index is variant");
aoqi@0 780 Node* rng = cmp->in(2);
aoqi@0 781 assert(rng->Opcode() == Op_LoadRange || _igvn.type(rng)->is_int() >= 0, "must be");
aoqi@0 782 assert(invar.is_invariant(rng), "range must be invariant");
aoqi@0 783 int scale = 1;
aoqi@0 784 Node* offset = zero;
aoqi@0 785 bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset);
aoqi@0 786 assert(ok, "must be index expression");
aoqi@0 787
aoqi@0 788 Node* init = cl->init_trip();
aoqi@0 789 Node* limit = cl->limit();
aoqi@0 790 Node* stride = cl->stride();
aoqi@0 791
aoqi@0 792 // Build if's for the upper and lower bound tests. The
aoqi@0 793 // lower_bound test will dominate the upper bound test and all
aoqi@0 794 // cloned or created nodes will use the lower bound test as
aoqi@0 795 // their declared control.
aoqi@0 796 ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
aoqi@0 797 ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
aoqi@0 798 assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
aoqi@0 799 Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0);
aoqi@0 800
aoqi@0 801 // Perform cloning to keep Invariance state correct since the
aoqi@0 802 // late schedule will place invariant things in the loop.
aoqi@0 803 rng = invar.clone(rng, ctrl);
aoqi@0 804 if (offset && offset != zero) {
aoqi@0 805 assert(invar.is_invariant(offset), "offset must be loop invariant");
aoqi@0 806 offset = invar.clone(offset, ctrl);
aoqi@0 807 }
aoqi@0 808
aoqi@0 809 // Test the lower bound
aoqi@0 810 Node* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false);
aoqi@0 811 IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
aoqi@0 812 _igvn.hash_delete(lower_bound_iff);
aoqi@0 813 lower_bound_iff->set_req(1, lower_bound_bol);
aoqi@0 814 if (TraceLoopPredicate) tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx);
aoqi@0 815
aoqi@0 816 // Test the upper bound
aoqi@0 817 Node* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true);
aoqi@0 818 IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
aoqi@0 819 _igvn.hash_delete(upper_bound_iff);
aoqi@0 820 upper_bound_iff->set_req(1, upper_bound_bol);
aoqi@0 821 if (TraceLoopPredicate) tty->print_cr("upper bound check if: %d", lower_bound_iff->_idx);
aoqi@0 822
aoqi@0 823 // Fall through into rest of the clean up code which will move
aoqi@0 824 // any dependent nodes onto the upper bound test.
aoqi@0 825 new_predicate_proj = upper_bound_proj;
aoqi@0 826
aoqi@0 827 #ifndef PRODUCT
aoqi@0 828 if (TraceLoopOpts && !TraceLoopPredicate) {
aoqi@0 829 tty->print("Predicate RC ");
aoqi@0 830 loop->dump_head();
aoqi@0 831 }
aoqi@0 832 #endif
aoqi@0 833 } else {
aoqi@0 834 // Loop variant check (for example, range check in non-counted loop)
aoqi@0 835 // with uncommon trap.
aoqi@0 836 continue;
aoqi@0 837 }
aoqi@0 838 assert(new_predicate_proj != NULL, "sanity");
aoqi@0 839 // Success - attach condition (new_predicate_bol) to predicate if
aoqi@0 840 invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate
aoqi@0 841
aoqi@0 842 // Eliminate the old If in the loop body
aoqi@0 843 dominated_by( new_predicate_proj, iff, proj->_con != new_predicate_proj->_con );
aoqi@0 844
aoqi@0 845 hoisted = true;
aoqi@0 846 C->set_major_progress();
aoqi@0 847 } // end while
aoqi@0 848
aoqi@0 849 #ifndef PRODUCT
aoqi@0 850 // report that the loop predication has been actually performed
aoqi@0 851 // for this loop
aoqi@0 852 if (TraceLoopPredicate && hoisted) {
aoqi@0 853 tty->print("Loop Predication Performed:");
aoqi@0 854 loop->dump_head();
aoqi@0 855 }
aoqi@0 856 #endif
aoqi@0 857
aoqi@0 858 return hoisted;
aoqi@0 859 }
aoqi@0 860
aoqi@0 861 //------------------------------loop_predication--------------------------------
aoqi@0 862 // driver routine for loop predication optimization
aoqi@0 863 bool IdealLoopTree::loop_predication( PhaseIdealLoop *phase) {
aoqi@0 864 bool hoisted = false;
aoqi@0 865 // Recursively promote predicates
aoqi@0 866 if (_child) {
aoqi@0 867 hoisted = _child->loop_predication( phase);
aoqi@0 868 }
aoqi@0 869
aoqi@0 870 // self
aoqi@0 871 if (!_irreducible && !tail()->is_top()) {
aoqi@0 872 hoisted |= phase->loop_predication_impl(this);
aoqi@0 873 }
aoqi@0 874
aoqi@0 875 if (_next) { //sibling
aoqi@0 876 hoisted |= _next->loop_predication( phase);
aoqi@0 877 }
aoqi@0 878
aoqi@0 879 return hoisted;
aoqi@0 880 }

mercurial