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