hotspot/src/share/vm/opto/phaseX.cpp
author coleenp
Mon, 14 Jan 2013 11:01:39 -0500
changeset 15194 a35093d73168
parent 14623 70c4c1be0a14
child 15113 823590505eb4
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:
1
489c9b5090e2 Initial load
duke
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) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4020
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4020
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 4020
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    26
#include "memory/allocation.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    27
#include "opto/block.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    28
#include "opto/callnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    29
#include "opto/cfgnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    30
#include "opto/connode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    31
#include "opto/idealGraphPrinter.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    32
#include "opto/loopnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    33
#include "opto/machnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    34
#include "opto/opcodes.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    35
#include "opto/phaseX.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    36
#include "opto/regalloc.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6752
diff changeset
    37
#include "opto/rootnode.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
#define NODE_HASH_MINIMUM_SIZE    255
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
//------------------------------NodeHash---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
NodeHash::NodeHash(uint est_max_size) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  _max( round_up(est_max_size < NODE_HASH_MINIMUM_SIZE ? NODE_HASH_MINIMUM_SIZE : est_max_size) ),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  _a(Thread::current()->resource_area()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
  _table( NEW_ARENA_ARRAY( _a , Node* , _max ) ), // (Node**)_a->Amalloc(_max * sizeof(Node*)) ),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
  _inserts(0), _insert_limit( insert_limit() ),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  _look_probes(0), _lookup_hits(0), _lookup_misses(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  _total_insert_probes(0), _total_inserts(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  _insert_probes(0), _grows(0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  // _sentinel must be in the current node space
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13312
diff changeset
    51
  _sentinel = new (Compile::current()) ProjNode(NULL, TypeFunc::Control);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  memset(_table,0,sizeof(Node*)*_max);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
//------------------------------NodeHash---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
NodeHash::NodeHash(Arena *arena, uint est_max_size) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  _max( round_up(est_max_size < NODE_HASH_MINIMUM_SIZE ? NODE_HASH_MINIMUM_SIZE : est_max_size) ),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  _a(arena),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  _table( NEW_ARENA_ARRAY( _a , Node* , _max ) ),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  _inserts(0), _insert_limit( insert_limit() ),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  _look_probes(0), _lookup_hits(0), _lookup_misses(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  _delete_probes(0), _delete_hits(0), _delete_misses(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  _total_insert_probes(0), _total_inserts(0),
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  _insert_probes(0), _grows(0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  // _sentinel must be in the current node space
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13312
diff changeset
    66
  _sentinel = new (Compile::current()) ProjNode(NULL, TypeFunc::Control);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  memset(_table,0,sizeof(Node*)*_max);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
//------------------------------NodeHash---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
NodeHash::NodeHash(NodeHash *nh) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  debug_only(_table = (Node**)badAddress);   // interact correctly w/ operator=
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  // just copy in all the fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  *this = *nh;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  // nh->_sentinel must be in the current node space
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
//------------------------------hash_find--------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
// Find in hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
Node *NodeHash::hash_find( const Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  // ((Node*)n)->set_hash( n->hash() );
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  uint hash = n->hash();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  if (hash == Node::NO_HASH) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
    debug_only( _lookup_misses++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  uint key = hash & (_max-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  uint stride = key | 0x01;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  debug_only( _look_probes++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  Node *k = _table[key];        // Get hashed value
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  if( !k ) {                    // ?Miss?
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
    debug_only( _lookup_misses++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
    return NULL;                // Miss!
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  int op = n->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  uint req = n->req();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  while( 1 ) {                  // While probing hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    if( k->req() == req &&      // Same count of inputs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
        k->Opcode() == op ) {   // Same Opcode
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
      for( uint i=0; i<req; i++ )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
        if( n->in(i)!=k->in(i)) // Different inputs?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
          goto collision;       // "goto" is a speed hack...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
      if( n->cmp(*k) ) {        // Check for any special bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
        debug_only( _lookup_hits++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
        return k;               // Hit!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  collision:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
    debug_only( _look_probes++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
    key = (key + stride/*7*/) & (_max-1); // Stride through table with relative prime
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
    k = _table[key];            // Get hashed value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
    if( !k ) {                  // ?Miss?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
      debug_only( _lookup_misses++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
      return NULL;              // Miss!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
//------------------------------hash_find_insert-------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
// Find in hash table, insert if not already present
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
// Used to preserve unique entries in hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
Node *NodeHash::hash_find_insert( Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  // n->set_hash( );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  uint hash = n->hash();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  if (hash == Node::NO_HASH) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
    debug_only( _lookup_misses++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  uint key = hash & (_max-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  uint stride = key | 0x01;     // stride must be relatively prime to table siz
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  uint first_sentinel = 0;      // replace a sentinel if seen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  debug_only( _look_probes++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  Node *k = _table[key];        // Get hashed value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  if( !k ) {                    // ?Miss?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
    debug_only( _lookup_misses++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
    _table[key] = n;            // Insert into table!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
    debug_only(n->enter_hash_lock()); // Lock down the node while in the table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
    check_grow();               // Grow table if insert hit limit
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
    return NULL;                // Miss!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  else if( k == _sentinel ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
    first_sentinel = key;      // Can insert here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  int op = n->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  uint req = n->req();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  while( 1 ) {                  // While probing hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    if( k->req() == req &&      // Same count of inputs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
        k->Opcode() == op ) {   // Same Opcode
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
      for( uint i=0; i<req; i++ )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
        if( n->in(i)!=k->in(i)) // Different inputs?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
          goto collision;       // "goto" is a speed hack...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
      if( n->cmp(*k) ) {        // Check for any special bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
        debug_only( _lookup_hits++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
        return k;               // Hit!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  collision:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
    debug_only( _look_probes++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
    key = (key + stride) & (_max-1); // Stride through table w/ relative prime
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
    k = _table[key];            // Get hashed value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    if( !k ) {                  // ?Miss?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
      debug_only( _lookup_misses++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
      key = (first_sentinel == 0) ? key : first_sentinel; // ?saw sentinel?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
      _table[key] = n;          // Insert into table!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
      debug_only(n->enter_hash_lock()); // Lock down the node while in the table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
      check_grow();             // Grow table if insert hit limit
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
      return NULL;              // Miss!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    else if( first_sentinel == 0 && k == _sentinel ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
      first_sentinel = key;    // Can insert here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
//------------------------------hash_insert------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
// Insert into hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
void NodeHash::hash_insert( Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  // // "conflict" comments -- print nodes that conflict
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  // bool conflict = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  // n->set_hash();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  uint hash = n->hash();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  if (hash == Node::NO_HASH) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  check_grow();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  uint key = hash & (_max-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  uint stride = key | 0x01;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  while( 1 ) {                  // While probing hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    debug_only( _insert_probes++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
    Node *k = _table[key];      // Get hashed value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    if( !k || (k == _sentinel) ) break;       // Found a slot
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
    assert( k != n, "already inserted" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
    // if( PrintCompilation && PrintOptoStatistics && Verbose ) { tty->print("  conflict: "); k->dump(); conflict = true; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    key = (key + stride) & (_max-1); // Stride through table w/ relative prime
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  _table[key] = n;              // Insert into table!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  debug_only(n->enter_hash_lock()); // Lock down the node while in the table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  // if( conflict ) { n->dump(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
//------------------------------hash_delete------------------------------------
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1067
diff changeset
   210
// Replace in hash table with sentinel
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
bool NodeHash::hash_delete( const Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  Node *k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  uint hash = n->hash();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  if (hash == Node::NO_HASH) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
    debug_only( _delete_misses++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  uint key = hash & (_max-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  uint stride = key | 0x01;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  debug_only( uint counter = 0; );
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1067
diff changeset
   221
  for( ; /* (k != NULL) && (k != _sentinel) */; ) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
    debug_only( counter++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
    debug_only( _delete_probes++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
    k = _table[key];            // Get hashed value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
    if( !k ) {                  // Miss?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
      debug_only( _delete_misses++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
      if( VerifyOpto ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
        for( uint i=0; i < _max; i++ )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
          assert( _table[i] != n, "changed edges with rehashing" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
      return false;             // Miss! Not in chain
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
    else if( n == k ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
      debug_only( _delete_hits++ );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
      _table[key] = _sentinel;  // Hit! Label as deleted entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
      debug_only(((Node*)n)->exit_hash_lock()); // Unlock the node upon removal from table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
    else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
      // collision: move through table with prime offset
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
      key = (key + stride/*7*/) & (_max-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
      assert( counter <= _insert_limit, "Cycle in hash-table");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
//------------------------------round_up---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
// Round up to nearest power of 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
uint NodeHash::round_up( uint x ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  x += (x>>2);                  // Add 25% slop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  if( x <16 ) return 16;        // Small stuff
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  uint i=16;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  while( i < x ) i <<= 1;       // Double to fit
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  return i;                     // Return hash table size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
//------------------------------grow-------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
// Grow _table to next power of 2 and insert old entries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
void  NodeHash::grow() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  // Record old state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  uint   old_max   = _max;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  Node **old_table = _table;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
  // Construct new table with twice the space
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  _grows++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  _total_inserts       += _inserts;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
  _total_insert_probes += _insert_probes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
  _inserts         = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
  _insert_probes   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
  _max     = _max << 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
  _table   = NEW_ARENA_ARRAY( _a , Node* , _max ); // (Node**)_a->Amalloc( _max * sizeof(Node*) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  memset(_table,0,sizeof(Node*)*_max);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  _insert_limit = insert_limit();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  // Insert old entries into the new table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  for( uint i = 0; i < old_max; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
    Node *m = *old_table++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    if( !m || m == _sentinel ) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
    debug_only(m->exit_hash_lock()); // Unlock the node upon removal from old table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
    hash_insert(m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
//------------------------------clear------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
// Clear all entries in _table to NULL but keep storage
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
void  NodeHash::clear() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  // Unlock all nodes upon removal from table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  for (uint i = 0; i < _max; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
    Node* n = _table[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
    if (!n || n == _sentinel)  continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
    n->exit_hash_lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  memset( _table, 0, _max * sizeof(Node*) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
//-----------------------remove_useless_nodes----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
// Remove useless nodes from value table,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
// implementation does not depend on hash function
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
void NodeHash::remove_useless_nodes(VectorSet &useful) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  // Dead nodes in the hash table inherited from GVN should not replace
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  // existing nodes, remove dead nodes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  uint max = size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
  Node *sentinel_node = sentinel();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  for( uint i = 0; i < max; ++i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
    Node *n = at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
    if(n != NULL && n != sentinel_node && !useful.test(n->_idx)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
      debug_only(n->exit_hash_lock()); // Unlock the node when removed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
      _table[i] = sentinel_node;       // Replace with placeholder
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
//------------------------------dump-------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
// Dump statistics for the hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
void NodeHash::dump() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
  _total_inserts       += _inserts;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  _total_insert_probes += _insert_probes;
10988
a3b2bd43ef4f 7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents: 10563
diff changeset
   325
  if (PrintCompilation && PrintOptoStatistics && Verbose && (_inserts > 0)) {
a3b2bd43ef4f 7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents: 10563
diff changeset
   326
    if (WizardMode) {
a3b2bd43ef4f 7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents: 10563
diff changeset
   327
      for (uint i=0; i<_max; i++) {
a3b2bd43ef4f 7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents: 10563
diff changeset
   328
        if (_table[i])
a3b2bd43ef4f 7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents: 10563
diff changeset
   329
          tty->print("%d/%d/%d ",i,_table[i]->hash()&(_max-1),_table[i]->_idx);
a3b2bd43ef4f 7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents: 10563
diff changeset
   330
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    tty->print("\nGVN Hash stats:  %d grows to %d max_size\n", _grows, _max);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
    tty->print("  %d/%d (%8.1f%% full)\n", _inserts, _max, (double)_inserts/_max*100.0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
    tty->print("  %dp/(%dh+%dm) (%8.2f probes/lookup)\n", _look_probes, _lookup_hits, _lookup_misses, (double)_look_probes/(_lookup_hits+_lookup_misses));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
    tty->print("  %dp/%di (%8.2f probes/insert)\n", _total_insert_probes, _total_inserts, (double)_total_insert_probes/_total_inserts);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
    // sentinels increase lookup cost, but not insert cost
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
    assert((_lookup_misses+_lookup_hits)*4+100 >= _look_probes, "bad hash function");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
    assert( _inserts+(_inserts>>3) < _max, "table too full" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
    assert( _inserts*3+100 >= _insert_probes, "bad hash function" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
Node *NodeHash::find_index(uint idx) { // For debugging
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  // Find an entry by its index value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  for( uint i = 0; i < _max; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
    Node *m = _table[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
    if( !m || m == _sentinel ) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
    if( m->_idx == (uint)idx ) return m;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
NodeHash::~NodeHash() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  // Unlock all nodes upon destruction of table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  if (_table != (Node**)badAddress)  clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
void NodeHash::operator=(const NodeHash& nh) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
  // Unlock all nodes upon replacement of table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
  if (&nh == this)  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  if (_table != (Node**)badAddress)  clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
  memcpy(this, &nh, sizeof(*this));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
  // Do not increment hash_lock counts again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
  // Instead, be sure we never again use the source table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
  ((NodeHash*)&nh)->_table = (Node**)badAddress;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
//------------------------------PhaseRemoveUseless-----------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
// 1) Use a breadthfirst walk to collect useful nodes reachable from root.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
PhaseRemoveUseless::PhaseRemoveUseless( PhaseGVN *gvn, Unique_Node_List *worklist ) : Phase(Remove_Useless),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
  _useful(Thread::current()->resource_area()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
  // Implementation requires 'UseLoopSafepoints == true' and an edge from root
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
  // to each SafePointNode at a backward branch.  Inserted in add_safepoint().
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  if( !UseLoopSafepoints || !OptoRemoveUseless ) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
  // Identify nodes that are reachable from below, useful.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
  C->identify_useful_nodes(_useful);
14623
70c4c1be0a14 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 13963
diff changeset
   386
  // Update dead node list
70c4c1be0a14 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 13963
diff changeset
   387
  C->update_dead_node_list(_useful);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  // Remove all useless nodes from PhaseValues' recorded types
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  // Must be done before disconnecting nodes to preserve hash-table-invariant
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  gvn->remove_useless_nodes(_useful.member_set());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  // Remove all useless nodes from future worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  worklist->remove_useless_nodes(_useful.member_set());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  // Disconnect 'useless' nodes that are adjacent to useful nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  C->remove_useless_nodes(_useful);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  // Remove edges from "root" to each SafePoint at a backward branch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  // They were inserted during parsing (see add_safepoint()) to make infinite
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  // loops without calls or exceptions visible to root, i.e., useful.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  Node *root = C->root();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  if( root != NULL ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
    for( uint i = root->req(); i < root->len(); ++i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
      Node *n = root->in(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
      if( n != NULL && n->is_SafePoint() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
        root->rm_prec(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
        --i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
//------------------------------PhaseTransform---------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
PhaseTransform::PhaseTransform( PhaseNumber pnum ) : Phase(pnum),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  _arena(Thread::current()->resource_area()),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  _nodes(_arena),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  _types(_arena)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  init_con_caches();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  clear_progress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  clear_transforms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  set_allow_progress(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  // Force allocation for currently existing nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  _types.map(C->unique(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
//------------------------------PhaseTransform---------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
PhaseTransform::PhaseTransform( Arena *arena, PhaseNumber pnum ) : Phase(pnum),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  _arena(arena),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  _nodes(arena),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  _types(arena)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  init_con_caches();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  clear_progress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  clear_transforms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  set_allow_progress(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  // Force allocation for currently existing nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  _types.map(C->unique(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
//------------------------------PhaseTransform---------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
// Initialize with previously generated type information
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
PhaseTransform::PhaseTransform( PhaseTransform *pt, PhaseNumber pnum ) : Phase(pnum),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  _arena(pt->_arena),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  _nodes(pt->_nodes),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  _types(pt->_types)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  init_con_caches();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  clear_progress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  clear_transforms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
  set_allow_progress(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
void PhaseTransform::init_con_caches() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
  memset(_icons,0,sizeof(_icons));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  memset(_lcons,0,sizeof(_lcons));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  memset(_zcons,0,sizeof(_zcons));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
//--------------------------------find_int_type--------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
const TypeInt* PhaseTransform::find_int_type(Node* n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  if (n == NULL)  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  // Call type_or_null(n) to determine node's type since we might be in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  // parse phase and call n->Value() may return wrong type.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
  // (For example, a phi node at the beginning of loop parsing is not ready.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
  const Type* t = type_or_null(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
  if (t == NULL)  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  return t->isa_int();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
//-------------------------------find_long_type--------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
const TypeLong* PhaseTransform::find_long_type(Node* n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  if (n == NULL)  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  // (See comment above on type_or_null.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  const Type* t = type_or_null(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  if (t == NULL)  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
  return t->isa_long();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
void PhaseTransform::dump_old2new_map() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
  _nodes.dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
void PhaseTransform::dump_new( uint nidx ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
  for( uint i=0; i<_nodes.Size(); i++ )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
    if( _nodes[i] && _nodes[i]->_idx == nidx ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
      _nodes[i]->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
      tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
      tty->print_cr("Old index= %d",i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  tty->print_cr("Node %d not found in the new indices", nidx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
//------------------------------dump_types-------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
void PhaseTransform::dump_types( ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  _types.dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
//------------------------------dump_nodes_and_types---------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
void PhaseTransform::dump_nodes_and_types(const Node *root, uint depth, bool only_ctrl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  VectorSet visited(Thread::current()->resource_area());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  dump_nodes_and_types_recur( root, depth, only_ctrl, visited );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
//------------------------------dump_nodes_and_types_recur---------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
void PhaseTransform::dump_nodes_and_types_recur( const Node *n, uint depth, bool only_ctrl, VectorSet &visited) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  if( !n ) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  if( depth == 0 ) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  if( visited.test_set(n->_idx) ) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  for( uint i=0; i<n->len(); i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
    if( only_ctrl && !(n->is_Region()) && i != TypeFunc::Control ) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
    dump_nodes_and_types_recur( n->in(i), depth-1, only_ctrl, visited );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  n->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  if (type_or_null(n) != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
    tty->print("      "); type(n)->dump(); tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
//------------------------------PhaseValues------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
// Set minimum table size to "255"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
PhaseValues::PhaseValues( Arena *arena, uint est_max_size ) : PhaseTransform(arena, GVN), _table(arena, est_max_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  NOT_PRODUCT( clear_new_values(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
//------------------------------PhaseValues------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
// Set minimum table size to "255"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
PhaseValues::PhaseValues( PhaseValues *ptv ) : PhaseTransform( ptv, GVN ),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  _table(&ptv->_table) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
  NOT_PRODUCT( clear_new_values(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
//------------------------------PhaseValues------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
// Used by +VerifyOpto.  Clear out hash table but copy _types array.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
PhaseValues::PhaseValues( PhaseValues *ptv, const char *dummy ) : PhaseTransform( ptv, GVN ),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
  _table(ptv->arena(),ptv->_table.size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  NOT_PRODUCT( clear_new_values(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
//------------------------------~PhaseValues-----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
PhaseValues::~PhaseValues() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  _table.dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  // Statistics for value progress and efficiency
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
  if( PrintCompilation && Verbose && WizardMode ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
    tty->print("\n%sValues: %d nodes ---> %d/%d (%d)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
      is_IterGVN() ? "Iter" : "    ", C->unique(), made_progress(), made_transforms(), made_new_values());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
    if( made_transforms() != 0 ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
      tty->print_cr("  ratio %f", made_progress()/(float)made_transforms() );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
      tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
//------------------------------makecon----------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
ConNode* PhaseTransform::makecon(const Type *t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  assert(t->singleton(), "must be a constant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  assert(!t->empty() || t == Type::TOP, "must not be vacuous range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  switch (t->base()) {  // fast paths
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
  case Type::Half:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  case Type::Top:  return (ConNode*) C->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
  case Type::Int:  return intcon( t->is_int()->get_con() );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
  case Type::Long: return longcon( t->is_long()->get_con() );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
  if (t->is_zero_type())
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
    return zerocon(t->basic_type());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
  return uncached_makecon(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
//--------------------------uncached_makecon-----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
// Make an idealized constant - one of ConINode, ConPNode, etc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
ConNode* PhaseValues::uncached_makecon(const Type *t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
  assert(t->singleton(), "must be a constant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  ConNode* x = ConNode::make(C, t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
  ConNode* k = (ConNode*)hash_find_insert(x); // Value numbering
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
  if (k == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
    set_type(x, t);             // Missed, provide type mapping
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
    GrowableArray<Node_Notes*>* nna = C->node_note_array();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
    if (nna != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
      Node_Notes* loc = C->locate_node_notes(nna, x->_idx, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
      loc->clear(); // do not put debug info on constants
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
    x->destruct();              // Hit, destroy duplicate constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
    x = k;                      // use existing constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
  return x;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
//------------------------------intcon-----------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
// Fast integer constant.  Same as "transform(new ConINode(TypeInt::make(i)))"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
ConINode* PhaseTransform::intcon(int i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
  // Small integer?  Check cache! Check that cached node is not dead
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
  if (i >= _icon_min && i <= _icon_max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
    ConINode* icon = _icons[i-_icon_min];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
    if (icon != NULL && icon->in(TypeFunc::Control) != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
      return icon;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
  ConINode* icon = (ConINode*) uncached_makecon(TypeInt::make(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
  assert(icon->is_Con(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  if (i >= _icon_min && i <= _icon_max)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
    _icons[i-_icon_min] = icon;   // Cache small integers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
  return icon;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
//------------------------------longcon----------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
// Fast long constant.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
ConLNode* PhaseTransform::longcon(jlong l) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
  // Small integer?  Check cache! Check that cached node is not dead
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
  if (l >= _lcon_min && l <= _lcon_max) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
    ConLNode* lcon = _lcons[l-_lcon_min];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
    if (lcon != NULL && lcon->in(TypeFunc::Control) != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
      return lcon;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
  ConLNode* lcon = (ConLNode*) uncached_makecon(TypeLong::make(l));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
  assert(lcon->is_Con(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
  if (l >= _lcon_min && l <= _lcon_max)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
    _lcons[l-_lcon_min] = lcon;      // Cache small integers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
  return lcon;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
//------------------------------zerocon-----------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
// Fast zero or null constant. Same as "transform(ConNode::make(Type::get_zero_type(bt)))"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
ConNode* PhaseTransform::zerocon(BasicType bt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
  assert((uint)bt <= _zcon_max, "domain check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
  ConNode* zcon = _zcons[bt];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
  if (zcon != NULL && zcon->in(TypeFunc::Control) != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
    return zcon;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
  zcon = (ConNode*) uncached_makecon(Type::get_zero_type(bt));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
  _zcons[bt] = zcon;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
  return zcon;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
//------------------------------transform--------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
// Return a node which computes the same function as this node, but in a
214
c5d9b4456687 6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents: 1
diff changeset
   660
// faster or cheaper fashion.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
Node *PhaseGVN::transform( Node *n ) {
214
c5d9b4456687 6667605: (Escape Analysis) inline java constructors when EA is on
kvn
parents: 1
diff changeset
   662
  return transform_no_reclaim(n);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
//------------------------------transform--------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
// Return a node which computes the same function as this node, but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
// in a faster or cheaper fashion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
Node *PhaseGVN::transform_no_reclaim( Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
  NOT_PRODUCT( set_transforms(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
  // Apply the Ideal call in a loop until it no longer applies
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
  Node *k = n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
  NOT_PRODUCT( uint loop_count = 0; )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
  while( 1 ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
    Node *i = k->Ideal(this, /*can_reshape=*/false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
    if( !i ) break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
    assert( i->_idx >= k->_idx, "Idealize should return new nodes, use Identity to return old nodes" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
    k = i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
    assert(loop_count++ < K, "infinite loop in PhaseGVN::transform");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
  NOT_PRODUCT( if( loop_count != 0 ) { set_progress(); } )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
  // If brand new node, make space in type array.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
  ensure_type_or_null(k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
  // Since I just called 'Value' to compute the set of run-time values
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
  // for this Node, and 'Value' is non-local (and therefore expensive) I'll
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
  // cache Value.  Later requests for the local phase->type of this Node can
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
  // use the cached Value instead of suffering with 'bottom_type'.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
  const Type *t = k->Value(this); // Get runtime Value set
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
  assert(t != NULL, "value sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
  if (type_or_null(k) != t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
    // Do not count initial visit to node as a transformation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
    if (type_or_null(k) == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
      inc_new_values();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
      set_progress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
    set_type(k, t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
    // If k is a TypeNode, capture any more-precise type permanently into Node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
    k->raise_bottom_type(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
  if( t->singleton() && !k->is_Con() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
    NOT_PRODUCT( set_progress(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
    return makecon(t);          // Turn into a constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
  // Now check for Identities
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
  Node *i = k->Identity(this);  // Look for a nearby replacement
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
  if( i != k ) {                // Found? Return replacement!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
    NOT_PRODUCT( set_progress(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
    return i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
  // Global Value Numbering
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
  i = hash_find_insert(k);      // Insert if new
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
  if( i && (i != k) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
    // Return the pre-existing node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
    NOT_PRODUCT( set_progress(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
    return i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
  // Return Idealized original
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
  return k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
//------------------------------dead_loop_check--------------------------------
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1067
diff changeset
   732
// Check for a simple dead loop when a data node references itself directly
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
// or through an other data node excluding cons and phis.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
void PhaseGVN::dead_loop_check( Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  // Phi may reference itself in a loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
  if (n != NULL && !n->is_dead_loop_safe() && !n->is_CFG()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
    // Do 2 levels check and only data inputs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
    bool no_dead_loop = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
    uint cnt = n->req();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
    for (uint i = 1; i < cnt && no_dead_loop; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
      Node *in = n->in(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
      if (in == n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
        no_dead_loop = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
      } else if (in != NULL && !in->is_dead_loop_safe()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
        uint icnt = in->req();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
        for (uint j = 1; j < icnt && no_dead_loop; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
          if (in->in(j) == n || in->in(j) == in)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
            no_dead_loop = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
    if (!no_dead_loop) n->dump(3);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
    assert(no_dead_loop, "dead loop detected");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
//------------------------------PhaseIterGVN-----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
// Initialize hash table to fresh and clean for +VerifyOpto
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 238
diff changeset
   761
PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn, const char *dummy ) : PhaseGVN(igvn,dummy), _worklist( ),
13312
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
   762
                                                                      _stack(C->unique() >> 1),
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 238
diff changeset
   763
                                                                      _delay_transform(false) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
//------------------------------PhaseIterGVN-----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
// Initialize with previous PhaseIterGVN info; used by PhaseCCP
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn ) : PhaseGVN(igvn),
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 238
diff changeset
   769
                                                   _worklist( igvn->_worklist ),
13312
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
   770
                                                   _stack( igvn->_stack ),
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 238
diff changeset
   771
                                                   _delay_transform(igvn->_delay_transform)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
//------------------------------PhaseIterGVN-----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
// Initialize with previous PhaseGVN info from Parser
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
PhaseIterGVN::PhaseIterGVN( PhaseGVN *gvn ) : PhaseGVN(gvn),
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 238
diff changeset
   778
                                              _worklist(*C->for_igvn()),
13312
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
   779
                                              _stack(C->unique() >> 1),
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 238
diff changeset
   780
                                              _delay_transform(false)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
  uint max;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
  // Dead nodes in the hash table inherited from GVN were not treated as
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
  // roots during def-use info creation; hence they represent an invisible
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
  // use.  Clear them out.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
  max = _table.size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
  for( uint i = 0; i < max; ++i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
    Node *n = _table.at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
    if(n != NULL && n != _table.sentinel() && n->outcnt() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
      if( n->is_top() ) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
      assert( false, "Parse::remove_useless_nodes missed this node");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
      hash_delete(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
  // Any Phis or Regions on the worklist probably had uses that could not
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
  // make more progress because the uses were made while the Phis and Regions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
  // were in half-built states.  Put all uses of Phis and Regions on worklist.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
  max = _worklist.size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
  for( uint j = 0; j < max; j++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
    Node *n = _worklist.at(j);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
    uint uop = n->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
    if( uop == Op_Phi || uop == Op_Region ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
        n->is_Type() ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
        n->is_Mem() )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
      add_users_to_worklist(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
void PhaseIterGVN::verify_step(Node* n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
  _verify_window[_verify_counter % _verify_window_size] = n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
  ++_verify_counter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
  ResourceArea *area = Thread::current()->resource_area();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
  VectorSet old_space(area), new_space(area);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
  if (C->unique() < 1000 ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
      0 == _verify_counter % (C->unique() < 10000 ? 10 : 100)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
    ++_verify_full_passes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
    Node::verify_recur(C->root(), -1, old_space, new_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
  const int verify_depth = 4;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
  for ( int i = 0; i < _verify_window_size; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
    Node* n = _verify_window[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
    if ( n == NULL )  continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
    if( n->in(0) == NodeSentinel ) {  // xform_idom
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
      _verify_window[i] = n->in(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
      --i; continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
    // Typical fanout is 1-2, so this call visits about 6 nodes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
    Node::verify_recur(n, verify_depth, old_space, new_space);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
//------------------------------init_worklist----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
// Initialize worklist for each node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
void PhaseIterGVN::init_worklist( Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
  if( _worklist.member(n) ) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
  _worklist.push(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
  uint cnt = n->req();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
  for( uint i =0 ; i < cnt; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
    Node *m = n->in(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
    if( m ) init_worklist(m);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
//------------------------------optimize---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
void PhaseIterGVN::optimize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
  debug_only(uint num_processed  = 0;);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
    _verify_counter = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
    _verify_full_passes = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
    for ( int i = 0; i < _verify_window_size; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
      _verify_window[i] = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
6752
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   864
#ifdef ASSERT
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   865
  Node* prev = NULL;
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   866
  uint rep_cnt = 0;
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   867
#endif
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   868
  uint loop_count = 0;
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   869
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
  // Pull from worklist; transform node;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
  // If node has changed: update edge info and put uses on worklist.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
  while( _worklist.size() ) {
10563
b9b82ff9f0e9 7081842: assert(Compile::current()->unique() < (uint)MaxNodeLimit) failed: Node limit exceeded
kvn
parents: 7397
diff changeset
   873
    if (C->check_node_count(NodeLimitFudgeFactor * 2,
b9b82ff9f0e9 7081842: assert(Compile::current()->unique() < (uint)MaxNodeLimit) failed: Node limit exceeded
kvn
parents: 7397
diff changeset
   874
                            "out of nodes optimizing method")) {
b9b82ff9f0e9 7081842: assert(Compile::current()->unique() < (uint)MaxNodeLimit) failed: Node limit exceeded
kvn
parents: 7397
diff changeset
   875
      return;
b9b82ff9f0e9 7081842: assert(Compile::current()->unique() < (uint)MaxNodeLimit) failed: Node limit exceeded
kvn
parents: 7397
diff changeset
   876
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
    Node *n  = _worklist.pop();
6752
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   878
    if (++loop_count >= K * C->unique()) {
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   879
      debug_only(n->dump(4);)
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   880
      assert(false, "infinite loop in PhaseIterGVN::optimize");
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   881
      C->record_method_not_compilable("infinite loop in PhaseIterGVN::optimize");
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   882
      return;
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   883
    }
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   884
#ifdef ASSERT
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   885
    if (n == prev) {
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   886
      if (++rep_cnt > 3) {
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   887
        n->dump(4);
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   888
        assert(false, "loop in Ideal transformation");
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   889
      }
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   890
    } else {
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   891
      rep_cnt = 0;
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   892
    }
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   893
    prev = n;
9a3b09fd5745 6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents: 5901
diff changeset
   894
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
    if (TraceIterativeGVN && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
      tty->print("  Pop ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
      NOT_PRODUCT( n->dump(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
      debug_only(if( (num_processed++ % 100) == 0 ) _worklist.print_set();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
    if (n->outcnt() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
      uint wlsize = _worklist.size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
      const Type* oldtype = type_or_null(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
#endif //PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
      Node *nn = transform_old(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
      if (TraceIterativeGVN) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
        const Type* newtype = type_or_null(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
        if (nn != n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
          // print old node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
          tty->print("< ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
          if (oldtype != newtype && oldtype != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
            oldtype->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
          do { tty->print("\t"); } while (tty->position() < 16);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
          tty->print("<");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
          n->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
        if (oldtype != newtype || nn != n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
          // print new node and/or new type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
          if (oldtype == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
            tty->print("* ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
          } else if (nn != n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
            tty->print("> ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
            tty->print("= ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
          if (newtype == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
            tty->print("null");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
            newtype->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
          do { tty->print("\t"); } while (tty->position() < 16);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
          nn->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
        if (Verbose && wlsize < _worklist.size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
          tty->print("  Push {");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
          while (wlsize != _worklist.size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
            Node* pushed = _worklist.at(wlsize++);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
            tty->print(" %d", pushed->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
          tty->print_cr(" }");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
      if( VerifyIterativeGVN && nn != n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
        verify_step((Node*) NULL);  // ignore n, it might be subsumed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
    } else if (!n->is_top()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
      remove_dead_node(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
  C->verify_graph_edges();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
  if( VerifyOpto && allow_progress() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
    // Must turn off allow_progress to enable assert and break recursion
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
    C->root()->verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
    { // Check if any progress was missed using IterGVN
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
      // Def-Use info enables transformations not attempted in wash-pass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
      // e.g. Region/Phi cleanup, ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
      // Null-check elision -- may not have reached fixpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
      //                       do not propagate to dominated nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
      ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
      PhaseIterGVN igvn2(this,"Verify"); // Fresh and clean!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
      // Fill worklist completely
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
      igvn2.init_worklist(C->root());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
      igvn2.set_allow_progress(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
      igvn2.optimize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
      igvn2.set_allow_progress(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
  if ( VerifyIterativeGVN && PrintOpto ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
    if ( _verify_counter == _verify_full_passes )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
      tty->print_cr("VerifyIterativeGVN: %d transforms and verify passes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
                    _verify_full_passes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
    else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
      tty->print_cr("VerifyIterativeGVN: %d transforms, %d full verify passes",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
                  _verify_counter, _verify_full_passes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
//------------------register_new_node_with_optimizer---------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
// Register a new node with the optimizer.  Update the types array, the def-use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
// info.  Put on worklist.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
Node* PhaseIterGVN::register_new_node_with_optimizer(Node* n, Node* orig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
  set_type_bottom(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
  _worklist.push(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
  if (orig != NULL)  C->copy_node_notes_to(n, orig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
  return n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
//------------------------------transform--------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
// Non-recursive: idealize Node 'n' with respect to its inputs and its value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
Node *PhaseIterGVN::transform( Node *n ) {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 238
diff changeset
  1003
  if (_delay_transform) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 238
diff changeset
  1004
    // Register the node but don't optimize for now
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 238
diff changeset
  1005
    register_new_node_with_optimizer(n);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 238
diff changeset
  1006
    return n;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 238
diff changeset
  1007
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 238
diff changeset
  1008
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
  // If brand new node, make space in type array, and give it a type.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
  ensure_type_or_null(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
  if (type_or_null(n) == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
    set_type_bottom(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
  return transform_old(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
//------------------------------transform_old----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
Node *PhaseIterGVN::transform_old( Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
  debug_only(uint loop_count = 0;);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
  set_transforms();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
  // Remove 'n' from hash table in case it gets modified
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
  _table.hash_delete(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
  if( VerifyIterativeGVN ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
   assert( !_table.find_index(n->_idx), "found duplicate entry in table");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
  // Apply the Ideal call in a loop until it no longer applies
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
  Node *k = n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
  DEBUG_ONLY(dead_loop_check(k);)
1067
f82e0a8cd438 6736417: Fastdebug C2 crashes in StoreBNode::Ideal
kvn
parents: 670
diff changeset
  1033
  DEBUG_ONLY(bool is_new = (k->outcnt() == 0);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
  Node *i = k->Ideal(this, /*can_reshape=*/true);
1067
f82e0a8cd438 6736417: Fastdebug C2 crashes in StoreBNode::Ideal
kvn
parents: 670
diff changeset
  1035
  assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
  if( VerifyIterativeGVN )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
    verify_step(k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
  if( i && VerifyOpto ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
    if( !allow_progress() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
      if (i->is_Add() && i->outcnt() == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
        // Switched input to left side because this is the only use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
      } else if( i->is_If() && (i->in(0) == NULL) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
        // This IF is dead because it is dominated by an equivalent IF When
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
        // dominating if changed, info is not propagated sparsely to 'this'
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
        // Propagating this info further will spuriously identify other
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
        // progress.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
        return i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
      } else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
        set_progress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
    } else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
      set_progress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
  while( i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
    debug_only( if( loop_count >= K ) i->dump(4); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
    assert(loop_count < K, "infinite loop in PhaseIterGVN::transform");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
    debug_only( loop_count++; )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
    assert((i->_idx >= k->_idx) || i->is_top(), "Idealize should return new nodes, use Identity to return old nodes");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
    // Made a change; put users of original Node on worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
    add_users_to_worklist( k );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
    // Replacing root of transform tree?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
    if( k != i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
      // Make users of old Node now use new.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
      subsume_node( k, i );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
      k = i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
    DEBUG_ONLY(dead_loop_check(k);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
    // Try idealizing again
1067
f82e0a8cd438 6736417: Fastdebug C2 crashes in StoreBNode::Ideal
kvn
parents: 670
diff changeset
  1073
    DEBUG_ONLY(is_new = (k->outcnt() == 0);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
    i = k->Ideal(this, /*can_reshape=*/true);
1067
f82e0a8cd438 6736417: Fastdebug C2 crashes in StoreBNode::Ideal
kvn
parents: 670
diff changeset
  1075
    assert(i != k || is_new || i->outcnt() > 0, "don't return dead nodes");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
    if( VerifyIterativeGVN )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
      verify_step(k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
    if( i && VerifyOpto ) set_progress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
  // If brand new node, make space in type array.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
  ensure_type_or_null(k);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
  // See what kind of values 'k' takes on at runtime
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
  const Type *t = k->Value(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
  assert(t != NULL, "value sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
  // Since I just called 'Value' to compute the set of run-time values
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
  // for this Node, and 'Value' is non-local (and therefore expensive) I'll
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
  // cache Value.  Later requests for the local phase->type of this Node can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
  // use the cached Value instead of suffering with 'bottom_type'.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
  if (t != type_or_null(k)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
    NOT_PRODUCT( set_progress(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
    NOT_PRODUCT( inc_new_values();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
    set_type(k, t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
    // If k is a TypeNode, capture any more-precise type permanently into Node
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
    k->raise_bottom_type(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
    // Move users of node to worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
    add_users_to_worklist( k );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
  // If 'k' computes a constant, replace it with a constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
  if( t->singleton() && !k->is_Con() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
    NOT_PRODUCT( set_progress(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
    Node *con = makecon(t);     // Make a constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
    add_users_to_worklist( k );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
    subsume_node( k, con );     // Everybody using k now uses con
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
    return con;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
  // Now check for Identities
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
  i = k->Identity(this);        // Look for a nearby replacement
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
  if( i != k ) {                // Found? Return replacement!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
    NOT_PRODUCT( set_progress(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
    add_users_to_worklist( k );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
    subsume_node( k, i );       // Everybody using k now uses i
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
    return i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
  // Global Value Numbering
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
  i = hash_find_insert(k);      // Check for pre-existing node
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
  if( i && (i != k) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
    // Return the pre-existing node if it isn't dead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
    NOT_PRODUCT( set_progress(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
    add_users_to_worklist( k );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
    subsume_node( k, i );       // Everybody using k now uses i
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
    return i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
  // Return Idealized original
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
  return k;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
//---------------------------------saturate------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
const Type* PhaseIterGVN::saturate(const Type* new_type, const Type* old_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
                                   const Type* limit_type) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
  return new_type->narrow(old_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
//------------------------------remove_globally_dead_node----------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
// Kill a globally dead Node.  All uses are also globally dead and are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
// aggressively trimmed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
void PhaseIterGVN::remove_globally_dead_node( Node *dead ) {
13312
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1146
  enum DeleteProgress {
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1147
    PROCESS_INPUTS,
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1148
    PROCESS_OUTPUTS
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1149
  };
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1150
  assert(_stack.is_empty(), "not empty");
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1151
  _stack.push(dead, PROCESS_INPUTS);
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1152
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1153
  while (_stack.is_nonempty()) {
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1154
    dead = _stack.node();
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1155
    uint progress_state = _stack.index();
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1156
    assert(dead != C->root(), "killing root, eh?");
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1157
    assert(!dead->is_top(), "add check for top when pushing");
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1158
    NOT_PRODUCT( set_progress(); )
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1159
    if (progress_state == PROCESS_INPUTS) {
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1160
      // After following inputs, continue to outputs
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1161
      _stack.set_index(PROCESS_OUTPUTS);
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1162
      // Remove from iterative worklist
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1163
      _worklist.remove(dead);
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1164
      if (!dead->is_Con()) { // Don't kill cons but uses
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1165
        bool recurse = false;
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1166
        // Remove from hash table
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1167
        _table.hash_delete( dead );
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1168
        // Smash all inputs to 'dead', isolating him completely
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1169
        for( uint i = 0; i < dead->req(); i++ ) {
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1170
          Node *in = dead->in(i);
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1171
          if( in ) {                 // Points to something?
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1172
            dead->set_req(i,NULL);  // Kill the edge
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1173
            if (in->outcnt() == 0 && in != C->top()) {// Made input go dead?
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1174
              _stack.push(in, PROCESS_INPUTS); // Recursively remove
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1175
              recurse = true;
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1176
            } else if (in->outcnt() == 1 &&
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1177
                       in->has_special_unique_user()) {
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1178
              _worklist.push(in->unique_out());
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1179
            } else if (in->outcnt() <= 2 && dead->is_Phi()) {
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1180
              if( in->Opcode() == Op_Region )
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1181
                _worklist.push(in);
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1182
              else if( in->is_Store() ) {
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1183
                DUIterator_Fast imax, i = in->fast_outs(imax);
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1184
                _worklist.push(in->fast_out(i));
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1185
                i++;
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1186
                if(in->outcnt() == 2) {
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1187
                  _worklist.push(in->fast_out(i));
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1188
                  i++;
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1189
                }
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1190
                assert(!(i < imax), "sanity");
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1191
              }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
        }
14623
70c4c1be0a14 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 13963
diff changeset
  1195
        C->record_dead_node(dead->_idx);
13312
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1196
        if (dead->is_macro()) {
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1197
          C->remove_macro_node(dead);
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1198
        }
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1199
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1200
        if (recurse) {
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1201
          continue;
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1202
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
      }
14623
70c4c1be0a14 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 13963
diff changeset
  1204
      // Constant node that has no out-edges and has only one in-edge from
70c4c1be0a14 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 13963
diff changeset
  1205
      // root is usually dead. However, sometimes reshaping walk makes
70c4c1be0a14 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 13963
diff changeset
  1206
      // it reachable by adding use edges. So, we will NOT count Con nodes
70c4c1be0a14 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 13963
diff changeset
  1207
      // as dead to be conservative about the dead node count at any
70c4c1be0a14 7092905: C2: Keep track of the number of dead nodes
bharadwaj
parents: 13963
diff changeset
  1208
      // given time.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1209
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
13312
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1211
    // Aggressively kill globally dead uses
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1212
    // (Rather than pushing all the outs at once, we push one at a time,
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1213
    // plus the parent to resume later, because of the indefinite number
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1214
    // of edge deletions per loop trip.)
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1215
    if (dead->outcnt() > 0) {
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1216
      // Recursively remove
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1217
      _stack.push(dead->raw_out(0), PROCESS_INPUTS);
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1218
    } else {
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 10988
diff changeset
  1219
      _stack.pop();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
//------------------------------subsume_node-----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
// Remove users from node 'old' and add them to node 'nn'.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
void PhaseIterGVN::subsume_node( Node *old, Node *nn ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
  assert( old != hash_find(old), "should already been removed" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
  assert( old != C->top(), "cannot subsume top node");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
  // Copy debug or profile information to the new version:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
  C->copy_node_notes_to(nn, old);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
  // Move users of node 'old' to node 'nn'
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
  for (DUIterator_Last imin, i = old->last_outs(imin); i >= imin; ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
    Node* use = old->last_out(i);  // for each use...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
    // use might need re-hashing (but it won't if it's a new node)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
    bool is_in_table = _table.hash_delete( use );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
    // Update use-def info as well
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
    // We remove all occurrences of old within use->in,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
    // so as to avoid rehashing any node more than once.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
    // The hash table probe swamps any outer loop overhead.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
    uint num_edges = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
    for (uint jmax = use->len(), j = 0; j < jmax; j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
      if (use->in(j) == old) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
        use->set_req(j, nn);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
        ++num_edges;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
    // Insert into GVN hash table if unique
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
    // If a duplicate, 'use' will be cleaned up when pulled off worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
    if( is_in_table ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
      hash_find_insert(use);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
    i -= num_edges;    // we deleted 1 or more copies of this edge
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
  // Smash all inputs to 'old', isolating him completely
13895
f6dfe4123709 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 13312
diff changeset
  1256
  Node *temp = new (C) Node(1);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
  temp->init_req(0,nn);     // Add a use to nn to prevent him from dying
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
  remove_dead_node( old );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
  temp->del_req(0);         // Yank bogus edge
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
  if( VerifyIterativeGVN ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
    for ( int i = 0; i < _verify_window_size; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
      if ( _verify_window[i] == old )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
        _verify_window[i] = nn;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
  _worklist.remove(temp);   // this can be necessary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
  temp->destruct();         // reuse the _idx of this little guy
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
//------------------------------add_users_to_worklist--------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
void PhaseIterGVN::add_users_to_worklist0( Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
  for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
    _worklist.push(n->fast_out(i));  // Push on worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
void PhaseIterGVN::add_users_to_worklist( Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
  add_users_to_worklist0(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
  // Move users of node to worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
  for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
    Node* use = n->fast_out(i); // Get use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
    if( use->is_Multi() ||      // Multi-definer?  Push projs on worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
        use->is_Store() )       // Enable store/load same address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
      add_users_to_worklist0(use);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
    // If we changed the receiver type to a call, we need to revisit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
    // the Catch following the call.  It's looking for a non-NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
    // receiver to know when to enable the regular fall-through path
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
    // in addition to the NullPtrException path.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
    if (use->is_CallDynamicJava() && n == use->in(TypeFunc::Parms)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
      Node* p = use->as_CallDynamicJava()->proj_out(TypeFunc::Control);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
      if (p != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
        add_users_to_worklist0(p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
    if( use->is_Cmp() ) {       // Enable CMP/BOOL optimization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
      add_users_to_worklist(use); // Put Bool on worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
      // Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
      // phi merging either 0 or 1 onto the worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
      if (use->outcnt() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
        Node* bol = use->raw_out(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
        if (bol->outcnt() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
          Node* iff = bol->raw_out(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
          if (iff->outcnt() == 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
            Node* ifproj0 = iff->raw_out(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
            Node* ifproj1 = iff->raw_out(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
            if (ifproj0->outcnt() > 0 && ifproj1->outcnt() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
              Node* region0 = ifproj0->raw_out(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
              Node* region1 = ifproj1->raw_out(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
              if( region0 == region1 )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
                add_users_to_worklist0(region0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
    uint use_op = use->Opcode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
    // If changed Cast input, check Phi users for simple cycles
238
803c80713999 6674588: (Escape Analysis) Improve Escape Analysis code
kvn
parents: 214
diff changeset
  1325
    if( use->is_ConstraintCast() || use->is_CheckCastPP() ) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
      for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
        Node* u = use->fast_out(i2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
        if (u->is_Phi())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
          _worklist.push(u);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
    // If changed LShift inputs, check RShift users for useless sign-ext
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
    if( use_op == Op_LShiftI ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
      for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
        Node* u = use->fast_out(i2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
        if (u->Opcode() == Op_RShiftI)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
          _worklist.push(u);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
    // If changed AddP inputs, check Stores for loop invariant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
    if( use_op == Op_AddP ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
      for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
        Node* u = use->fast_out(i2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
        if (u->is_Mem())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
          _worklist.push(u);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
    // If changed initialization activity, check dependent Stores
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1349
    if (use_op == Op_Allocate || use_op == Op_AllocateArray) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
      InitializeNode* init = use->as_Allocate()->initialization();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1351
      if (init != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
        Node* imem = init->proj_out(TypeFunc::Memory);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
        if (imem != NULL)  add_users_to_worklist0(imem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
    if (use_op == Op_Initialize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
      Node* imem = use->as_Initialize()->proj_out(TypeFunc::Memory);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
      if (imem != NULL)  add_users_to_worklist0(imem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
uint PhaseCCP::_total_invokes   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
uint PhaseCCP::_total_constants = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
//------------------------------PhaseCCP---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
// Conditional Constant Propagation, ala Wegman & Zadeck
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
PhaseCCP::PhaseCCP( PhaseIterGVN *igvn ) : PhaseIterGVN(igvn) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
  NOT_PRODUCT( clear_constants(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
  assert( _worklist.size() == 0, "" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
  // Clear out _nodes from IterGVN.  Must be clear to transform call.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
  _nodes.clear();               // Clear out from IterGVN
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
  analyze();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
//------------------------------~PhaseCCP--------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
PhaseCCP::~PhaseCCP() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
  inc_invokes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  _total_constants += count_constants();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
static bool ccp_type_widens(const Type* t, const Type* t0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
  assert(t->meet(t0) == t, "Not monotonic");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
  switch (t->base() == t0->base() ? t->base() : Type::Top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
  case Type::Int:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
    assert(t0->isa_int()->_widen <= t->isa_int()->_widen, "widen increases");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
  case Type::Long:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
    assert(t0->isa_long()->_widen <= t->isa_long()->_widen, "widen increases");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
#endif //ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
//------------------------------analyze----------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
void PhaseCCP::analyze() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
  // Initialize all types to TOP, optimistic analysis
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
  for (int i = C->unique() - 1; i >= 0; i--)  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
    _types.map(i,Type::TOP);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
  // Push root onto worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
  Unique_Node_List worklist;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
  worklist.push(C->root());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
  // Pull from worklist; compute new value; push changes out.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
  // This loop is the meat of CCP.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
  while( worklist.size() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
    Node *n = worklist.pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
    const Type *t = n->Value(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
    if (t != type(n)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
      assert(ccp_type_widens(t, type(n)), "ccp type must widen");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
      if( TracePhaseCCP ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
        t->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
        do { tty->print("\t"); } while (tty->position() < 16);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
        n->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
      set_type(n, t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
      for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
        Node* m = n->fast_out(i);   // Get user
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
        if( m->is_Region() ) {  // New path to Region?  Must recheck Phis too
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
          for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
            Node* p = m->fast_out(i2); // Propagate changes to uses
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
            if( p->bottom_type() != type(p) ) // If not already bottomed out
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
              worklist.push(p); // Propagate change to user
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
        }
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1067
diff changeset
  1437
        // If we changed the receiver type to a call, we need to revisit
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
        // the Catch following the call.  It's looking for a non-NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
        // receiver to know when to enable the regular fall-through path
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
        // in addition to the NullPtrException path
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
        if (m->is_Call()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
          for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
            Node* p = m->fast_out(i2);  // Propagate changes to uses
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
            if (p->is_Proj() && p->as_Proj()->_con == TypeFunc::Control && p->outcnt() == 1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
              worklist.push(p->unique_out());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
        if( m->bottom_type() != type(m) ) // If not already bottomed out
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
          worklist.push(m);     // Propagate change to user
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
//------------------------------do_transform-----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
// Top level driver for the recursive transformer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
void PhaseCCP::do_transform() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
  // Correct leaves of new-space Nodes; they point to old-space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
  C->set_root( transform(C->root())->as_Root() );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
  assert( C->top(),  "missing TOP node" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
  assert( C->root(), "missing root" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
//------------------------------transform--------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
// Given a Node in old-space, clone him into new-space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
// Convert any of his old-space children into new-space children.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
Node *PhaseCCP::transform( Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
  Node *new_node = _nodes[n->_idx]; // Check for transformed node
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
  if( new_node != NULL )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
    return new_node;                // Been there, done that, return old answer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
  new_node = transform_once(n);     // Check for constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
  _nodes.map( n->_idx, new_node );  // Flag as having been cloned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
  // Allocate stack of size _nodes.Size()/2 to avoid frequent realloc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
  GrowableArray <Node *> trstack(C->unique() >> 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
  trstack.push(new_node);           // Process children of cloned node
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
  while ( trstack.is_nonempty() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
    Node *clone = trstack.pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
    uint cnt = clone->req();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
    for( uint i = 0; i < cnt; i++ ) {          // For all inputs do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
      Node *input = clone->in(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
      if( input != NULL ) {                    // Ignore NULLs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
        Node *new_input = _nodes[input->_idx]; // Check for cloned input node
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
        if( new_input == NULL ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
          new_input = transform_once(input);   // Check for constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
          _nodes.map( input->_idx, new_input );// Flag as having been cloned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
          trstack.push(new_input);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
        assert( new_input == clone->in(i), "insanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
  return new_node;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
//------------------------------transform_once---------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
// For PhaseCCP, transformation is IDENTITY unless Node computed a constant.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
Node *PhaseCCP::transform_once( Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
  const Type *t = type(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
  // Constant?  Use constant Node instead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
  if( t->singleton() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
    Node *nn = n;               // Default is to return the original constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
    if( t == Type::TOP ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
      // cache my top node on the Compile instance
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
      if( C->cached_top_node() == NULL || C->cached_top_node()->in(0) == NULL ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
        C->set_cached_top_node( ConNode::make(C, Type::TOP) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
        set_type(C->top(), Type::TOP);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
      nn = C->top();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
    if( !n->is_Con() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1514
      if( t != Type::TOP ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
        nn = makecon(t);        // ConNode::make(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
        NOT_PRODUCT( inc_constants(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
      } else if( n->is_Region() ) { // Unreachable region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
        // Note: nn == C->top()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1519
        n->set_req(0, NULL);        // Cut selfreference
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1520
        // Eagerly remove dead phis to avoid phis copies creation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
        for (DUIterator i = n->outs(); n->has_out(i); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
          Node* m = n->out(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
          if( m->is_Phi() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
            assert(type(m) == Type::TOP, "Unreachable region should not have live phis.");
5901
c046f8e9c52b 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 5547
diff changeset
  1525
            replace_node(m, nn);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
            --i; // deleted this phi; rescan starting with next position
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
      }
5901
c046f8e9c52b 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 5547
diff changeset
  1530
      replace_node(n,nn);       // Update DefUse edges for new constant
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
    return nn;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
  // If x is a TypeNode, capture any more-precise type permanently into Node
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
  if (t != n->bottom_type()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
    hash_delete(n);             // changing bottom type may force a rehash
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
    n->raise_bottom_type(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
    _worklist.push(n);          // n re-enters the hash table via the worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
  // Idealize graph using DU info.  Must clone() into new-space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
  // DU info is generally used to show profitability, progress or safety
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
  // (but generally not needed for correctness).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
  Node *nn = n->Ideal_DU_postCCP(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
  // TEMPORARY fix to ensure that 2nd GVN pass eliminates NULL checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
  switch( n->Opcode() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
  case Op_FastLock:      // Revisit FastLocks for lock coarsening
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
  case Op_If:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
  case Op_CountedLoopEnd:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
  case Op_Region:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
  case Op_Loop:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
  case Op_CountedLoop:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
  case Op_Conv2B:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
  case Op_Opaque1:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
  case Op_Opaque2:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
    _worklist.push(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
  if( nn ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
    _worklist.push(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
    // Put users of 'n' onto worklist for second igvn transform
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
    add_users_to_worklist(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
    return nn;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
  return  n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
//---------------------------------saturate------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
const Type* PhaseCCP::saturate(const Type* new_type, const Type* old_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
                               const Type* limit_type) const {
4012
579b7bad9983 6885584: A particular class structure causes large allocation spike for jit
never
parents: 3682
diff changeset
  1576
  const Type* wide_type = new_type->widen(old_type, limit_type);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
  if (wide_type != new_type) {          // did we widen?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
    // If so, we may have widened beyond the limit type.  Clip it back down.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
    new_type = wide_type->filter(limit_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1580
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1581
  return new_type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1582
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1584
//------------------------------print_statistics-------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1585
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1586
void PhaseCCP::print_statistics() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1587
  tty->print_cr("CCP: %d  constants found: %d", _total_invokes, _total_constants);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1589
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1590
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1592
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1593
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
uint PhasePeephole::_total_peepholes = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
//------------------------------PhasePeephole----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
// Conditional Constant Propagation, ala Wegman & Zadeck
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
PhasePeephole::PhasePeephole( PhaseRegAlloc *regalloc, PhaseCFG &cfg )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
  : PhaseTransform(Peephole), _regalloc(regalloc), _cfg(cfg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
  NOT_PRODUCT( clear_peepholes(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
//------------------------------~PhasePeephole---------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
PhasePeephole::~PhasePeephole() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1606
  _total_peepholes += count_peepholes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
//------------------------------transform--------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
Node *PhasePeephole::transform( Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
  ShouldNotCallThis();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
//------------------------------do_transform-----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
void PhasePeephole::do_transform() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
  bool method_name_not_printed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1620
  // Examine each basic block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1621
  for( uint block_number = 1; block_number < _cfg._num_blocks; ++block_number ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
    Block *block = _cfg._blocks[block_number];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
    bool block_not_printed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1624
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
    // and each instruction within a block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1626
    uint end_index = block->_nodes.size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
    // block->end_idx() not valid after PhaseRegAlloc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
    for( uint instruction_index = 1; instruction_index < end_index; ++instruction_index ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
      Node     *n = block->_nodes.at(instruction_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
      if( n->is_Mach() ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
        MachNode *m = n->as_Mach();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
        int deleted_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
        // check for peephole opportunities
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
        MachNode *m2 = m->peephole( block, instruction_index, _regalloc, deleted_count, C );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
        if( m2 != NULL ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1637
          if( PrintOptoPeephole ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
            // Print method, first time only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
            if( C->method() && method_name_not_printed ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
              C->method()->print_short_name(); tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
              method_name_not_printed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
            // Print this block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
            if( Verbose && block_not_printed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
              tty->print_cr("in block");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
              block->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
              block_not_printed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
            // Print instructions being deleted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
            for( int i = (deleted_count - 1); i >= 0; --i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
              block->_nodes.at(instruction_index-i)->as_Mach()->format(_regalloc); tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
            tty->print_cr("replaced with");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
            // Print new instruction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
            m2->format(_regalloc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
            tty->print("\n\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
          // Remove old nodes from basic block and update instruction_index
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
          // (old nodes still exist and may have edges pointing to them
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
          //  as register allocation info is stored in the allocator using
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
          //  the node index to live range mappings.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
          uint safe_instruction_index = (instruction_index - deleted_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
          for( ; (instruction_index > safe_instruction_index); --instruction_index ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
            block->_nodes.remove( instruction_index );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
          // install new node after safe_instruction_index
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
          block->_nodes.insert( safe_instruction_index + 1, m2 );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
          end_index = block->_nodes.size() - 1; // Recompute new block size
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
          NOT_PRODUCT( inc_peepholes(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
//------------------------------print_statistics-------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
void PhasePeephole::print_statistics() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
  tty->print_cr("Peephole: peephole rules applied: %d",  _total_peepholes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
//------------------------------set_req_X--------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
void Node::set_req_X( uint i, Node *n, PhaseIterGVN *igvn ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
  assert( is_not_dead(n), "can not use dead node");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
  assert( igvn->hash_find(this) != this, "Need to remove from hash before changing edges" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
  Node *old = in(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
  set_req(i, n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
  // old goes dead?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
  if( old ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
    switch (old->outcnt()) {
3682
42de755d7d6e 6866651: Regression: simple int sum crashes jvm (build 1.6.0_14-b08 and 1.7.0-ea-b59)
cfang
parents: 2131
diff changeset
  1696
    case 0:
42de755d7d6e 6866651: Regression: simple int sum crashes jvm (build 1.6.0_14-b08 and 1.7.0-ea-b59)
cfang
parents: 2131
diff changeset
  1697
      // Put into the worklist to kill later. We do not kill it now because the
42de755d7d6e 6866651: Regression: simple int sum crashes jvm (build 1.6.0_14-b08 and 1.7.0-ea-b59)
cfang
parents: 2131
diff changeset
  1698
      // recursive kill will delete the current node (this) if dead-loop exists
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
      if (!old->is_top())
3682
42de755d7d6e 6866651: Regression: simple int sum crashes jvm (build 1.6.0_14-b08 and 1.7.0-ea-b59)
cfang
parents: 2131
diff changeset
  1700
        igvn->_worklist.push( old );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
    case 1:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
      if( old->is_Store() || old->has_special_unique_user() )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
        igvn->add_users_to_worklist( old );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
    case 2:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
      if( old->is_Store() )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
        igvn->add_users_to_worklist( old );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
      if( old->Opcode() == Op_Region )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
        igvn->_worklist.push(old);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
    case 3:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
      if( old->Opcode() == Op_Region ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
        igvn->_worklist.push(old);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
        igvn->add_users_to_worklist( old );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
//-------------------------------replace_by-----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
// Using def-use info, replace one node for another.  Follow the def-use info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
// to all users of the OLD node.  Then make all uses point to the NEW node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
void Node::replace_by(Node *new_node) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
  assert(!is_top(), "top node has no DU info");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
  for (DUIterator_Last imin, i = last_outs(imin); i >= imin; ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
    Node* use = last_out(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
    uint uses_found = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
    for (uint j = 0; j < use->len(); j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
      if (use->in(j) == this) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
        if (j < use->req())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
              use->set_req(j, new_node);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
        else  use->set_prec(j, new_node);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
        uses_found++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
    i -= uses_found;    // we deleted 1 or more copies of this edge
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
//=============================================================================
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
//-----------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
void Type_Array::grow( uint i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
  if( !_max ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
    _max = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
    _types = (const Type**)_a->Amalloc( _max * sizeof(Type*) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
    _types[0] = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
  uint old = _max;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
  while( i >= _max ) _max <<= 1;        // Double to fit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
  _types = (const Type**)_a->Arealloc( _types, old*sizeof(Type*),_max*sizeof(Type*));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
  memset( &_types[old], 0, (_max-old)*sizeof(Type*) );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
//------------------------------dump-------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
void Type_Array::dump() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
  uint max = Size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
  for( uint i = 0; i < max; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
    if( _types[i] != NULL ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
      tty->print("  %d\t== ", i); _types[i]->dump(); tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
#endif