hotspot/src/share/vm/opto/phaseX.hpp
author coleenp
Mon, 14 Jan 2013 11:01:39 -0500
changeset 15194 a35093d73168
parent 13974 791cba24758f
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: 13397
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: 5402
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5402
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: 5402
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: 5901
diff changeset
    25
#ifndef SHARE_VM_OPTO_PHASEX_HPP
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5901
diff changeset
    26
#define SHARE_VM_OPTO_PHASEX_HPP
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5901
diff changeset
    27
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5901
diff changeset
    28
#include "libadt/dict.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5901
diff changeset
    29
#include "libadt/vectset.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5901
diff changeset
    30
#include "memory/resourceArea.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5901
diff changeset
    31
#include "opto/memnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5901
diff changeset
    32
#include "opto/node.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5901
diff changeset
    33
#include "opto/phase.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5901
diff changeset
    34
#include "opto/type.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5901
diff changeset
    35
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
class Compile;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
class ConINode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
class ConLNode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
class Node;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
class Type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
class PhaseTransform;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
class   PhaseGVN;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
class     PhaseIterGVN;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
class       PhaseCCP;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
class   PhasePeephole;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
class   PhaseRegAlloc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
//-----------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
// Expandable closed hash-table of nodes, initialized to NULL.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
// Note that the constructor just zeros things
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
// Storage is reclaimed when the Arena's lifetime is over.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
class NodeHash : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  Arena *_a;                    // Arena to allocate in
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  uint   _max;                  // Size of table (power of 2)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  uint   _inserts;              // For grow and debug, count of hash_inserts
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  uint   _insert_limit;         // 'grow' when _inserts reaches _insert_limit
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  Node **_table;                // Hash table of Node pointers
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  Node  *_sentinel;             // Replaces deleted entries in hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  NodeHash(uint est_max_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  NodeHash(Arena *arena, uint est_max_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  NodeHash(NodeHash *use_this_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  ~NodeHash();                  // Unlock all nodes upon destruction of table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  void operator=(const NodeHash&); // Unlock all nodes upon replacement of table.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  Node  *hash_find(const Node*);// Find an equivalent version in hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  Node  *hash_find_insert(Node*);// If not in table insert else return found node
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  void   hash_insert(Node*);    // Insert into hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  bool   hash_delete(const Node*);// Replace with _sentinel in hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  void   check_grow() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
    _inserts++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
    if( _inserts == _insert_limit ) { grow(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
    assert( _inserts <= _insert_limit, "hash table overflow");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
    assert( _inserts < _max, "hash table overflow" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  static uint round_up(uint);   // Round up to nearest power of 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  void   grow();                // Grow _table to next power of 2 and rehash
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  // Return 75% of _max, rounded up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  uint   insert_limit() const { return _max - (_max>>2); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  void   clear();               // Set all entries to NULL, keep storage.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  // Size of hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  uint   size()         const { return _max; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  // Return Node* at index in table
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  Node  *at(uint table_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
    assert(table_index < _max, "Must be within table");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    return _table[table_index];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  void   remove_useless_nodes(VectorSet &useful); // replace with sentinel
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  Node  *sentinel() { return _sentinel; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  Node  *find_index(uint idx);  // For debugging
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  void   dump();                // For debugging, dump statistics
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  uint   _grows;                // For debugging, count of table grow()s
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  uint   _look_probes;          // For debugging, count of hash probes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  uint   _lookup_hits;          // For debugging, count of hash_finds
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  uint   _lookup_misses;        // For debugging, count of hash_finds
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  uint   _insert_probes;        // For debugging, count of hash probes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  uint   _delete_probes;        // For debugging, count of hash probes for deletes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  uint   _delete_hits;          // For debugging, count of hash probes for deletes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  uint   _delete_misses;        // For debugging, count of hash probes for deletes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  uint   _total_inserts;        // For debugging, total inserts into hash table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  uint   _total_insert_probes;  // For debugging, total probes while inserting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
//-----------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
// Map dense integer indices to Types.  Uses classic doubling-array trick.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
// Abstractly provides an infinite array of Type*'s, initialized to NULL.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
// Note that the constructor just zeros things, and since I use Arena
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
// allocation I do not need a destructor to reclaim storage.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
// Despite the general name, this class is customized for use by PhaseTransform.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
class Type_Array : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  Arena *_a;                    // Arena to allocate in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  uint   _max;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  const Type **_types;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  void grow( uint i );          // Grow array node to fit
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  const Type *operator[] ( uint i ) const // Lookup, or NULL for not mapped
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  { return (i<_max) ? _types[i] : (Type*)NULL; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  friend class PhaseTransform;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  Type_Array(Arena *a) : _a(a), _max(0), _types(0) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  Type_Array(Type_Array *ta) : _a(ta->_a), _max(ta->_max), _types(ta->_types) { }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  const Type *fast_lookup(uint i) const{assert(i<_max,"oob");return _types[i];}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  // Extend the mapping: index i maps to Type *n.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  void map( uint i, const Type *n ) { if( i>=_max ) grow(i); _types[i] = n; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  uint Size() const { return _max; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  void dump() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
//------------------------------PhaseRemoveUseless-----------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
// Remove useless nodes from GVN hash-table, worklist, and graph
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
class PhaseRemoveUseless : public Phase {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  Unique_Node_List _useful;   // Nodes reachable from root
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
                              // list is allocated from current resource area
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  PhaseRemoveUseless( PhaseGVN *gvn, Unique_Node_List *worklist );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  Unique_Node_List *get_useful() { return &_useful; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
//------------------------------PhaseTransform---------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
// Phases that analyze, then transform.  Constructing the Phase object does any
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
// global or slow analysis.  The results are cached later for a fast
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
// transformation pass.  When the Phase object is deleted the cached analysis
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
// results are deleted.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
class PhaseTransform : public Phase {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  Arena*     _arena;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  Node_Array _nodes;           // Map old node indices to new nodes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  Type_Array _types;           // Map old node indices to Types.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  // ConNode caches:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  enum { _icon_min = -1 * HeapWordSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
         _icon_max = 16 * HeapWordSize,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
         _lcon_min = _icon_min,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
         _lcon_max = _icon_max,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
         _zcon_max = (uint)T_CONFLICT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  ConINode* _icons[_icon_max - _icon_min + 1];   // cached jint constant nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  ConLNode* _lcons[_lcon_max - _lcon_min + 1];   // cached jlong constant nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  ConNode*  _zcons[_zcon_max + 1];               // cached is_zero_type nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  void init_con_caches();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  // Support both int and long caches because either might be an intptr_t,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  // so they show up frequently in address computations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  PhaseTransform( PhaseNumber pnum );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  PhaseTransform( Arena *arena, PhaseNumber pnum );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  PhaseTransform( PhaseTransform *phase, PhaseNumber pnum );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  Arena*      arena()   { return _arena; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  Type_Array& types()   { return _types; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  // _nodes is used in varying ways by subclasses, which define local accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  // Get a previously recorded type for the node n.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  // This type must already have been recorded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  // If you want the type of a very new (untransformed) node,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  // you must use type_or_null, and test the result for NULL.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  const Type* type(const Node* n) const {
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 12958
diff changeset
   196
    assert(n != NULL, "must not be null");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    const Type* t = _types.fast_lookup(n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
    assert(t != NULL, "must set before get");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    return t;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  // Get a previously recorded type for the node n,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  // or else return NULL if there is none.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  const Type* type_or_null(const Node* n) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
    return _types.fast_lookup(n->_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  // Record a type for a node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  void    set_type(const Node* n, const Type *t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
    assert(t != NULL, "type must not be null");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    _types.map(n->_idx, t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  // Record an initial type for a node, the node's bottom type.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  void    set_type_bottom(const Node* n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
    // Use this for initialization when bottom_type() (or better) is not handy.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
    // Usually the initialization shoudl be to n->Value(this) instead,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
    // or a hand-optimized value like Type::MEMORY or Type::CONTROL.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
    assert(_types[n->_idx] == NULL, "must set the initial type just once");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
    _types.map(n->_idx, n->bottom_type());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  // Make sure the types array is big enough to record a size for the node n.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  // (In product builds, we never want to do range checks on the types array!)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  void ensure_type_or_null(const Node* n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
    if (n->_idx >= _types.Size())
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
      _types.map(n->_idx, NULL);   // Grow the types array as needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  // Utility functions:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  const TypeInt*  find_int_type( Node* n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  const TypeLong* find_long_type(Node* n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  jint  find_int_con( Node* n, jint  value_if_unknown) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
    const TypeInt* t = find_int_type(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
    return (t != NULL && t->is_con()) ? t->get_con() : value_if_unknown;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  jlong find_long_con(Node* n, jlong value_if_unknown) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
    const TypeLong* t = find_long_type(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
    return (t != NULL && t->is_con()) ? t->get_con() : value_if_unknown;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  // Make an idealized constant, i.e., one of ConINode, ConPNode, ConFNode, etc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  // Same as transform(ConNode::make(t)).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  ConNode* makecon(const Type* t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  virtual ConNode* uncached_makecon(const Type* t)  // override in PhaseValues
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  { ShouldNotCallThis(); return NULL; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  // Fast int or long constant.  Same as TypeInt::make(i) or TypeLong::make(l).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  ConINode* intcon(jint i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  ConLNode* longcon(jlong l);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  // Fast zero or null constant.  Same as makecon(Type::get_zero_type(bt)).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  ConNode* zerocon(BasicType bt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  // Return a node which computes the same function as this node, but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  // in a faster or cheaper fashion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  virtual Node *transform( Node *n ) = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  // Return whether two Nodes are equivalent.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  // Must not be recursive, since the recursive version is built from this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  // For pessimistic optimizations this is simply pointer equivalence.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  bool eqv(const Node* n1, const Node* n2) const { return n1 == n2; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  // For pessimistic passes, the return type must monotonically narrow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  // For optimistic  passes, the return type must monotonically widen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  // It is possible to get into a "death march" in either type of pass,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  // where the types are continually moving but it will take 2**31 or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  // more steps to converge.  This doesn't happen on most normal loops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  // Here is an example of a deadly loop for an optimistic pass, along
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
  // with a partial trace of inferred types:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  //    x = phi(0,x'); L: x' = x+1; if (x' >= 0) goto L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  //    0                 1                join([0..max], 1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
  //    [0..1]            [1..2]           join([0..max], [1..2])
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
  //    [0..2]            [1..3]           join([0..max], [1..3])
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
  //      ... ... ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
  //    [0..max]          [min]u[1..max]   join([0..max], [min..max])
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
  //    [0..max] ==> fixpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  // We would have proven, the hard way, that the iteration space is all
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  // non-negative ints, with the loop terminating due to 32-bit overflow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  // Here is the corresponding example for a pessimistic pass:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  //    x = phi(0,x'); L: x' = x-1; if (x' >= 0) goto L;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  //    int               int              join([0..max], int)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  //    [0..max]          [-1..max-1]      join([0..max], [-1..max-1])
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  //    [0..max-1]        [-1..max-2]      join([0..max], [-1..max-2])
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  //      ... ... ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  //    [0..1]            [-1..0]          join([0..max], [-1..0])
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  //    0                 -1               join([0..max], -1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  //    0 == fixpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  // We would have proven, the hard way, that the iteration space is {0}.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  // (Usually, other optimizations will make the "if (x >= 0)" fold up
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  // before we get into trouble.  But not always.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  // It's a pleasant thing to observe that the pessimistic pass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  // will make short work of the optimistic pass's deadly loop,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  // and vice versa.  That is a good example of the complementary
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  // purposes of the CCP (optimistic) vs. GVN (pessimistic) phases.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  // In any case, only widen or narrow a few times before going to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  // correct flavor of top or bottom.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  // This call only needs to be made once as the data flows around any
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
  // given cycle.  We do it at Phis, and nowhere else.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  // The types presented are the new type of a phi (computed by PhiNode::Value)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
  // and the previously computed type, last time the phi was visited.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
  // The third argument is upper limit for the saturated value,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
  // if the phase wishes to widen the new_type.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  // If the phase is narrowing, the old type provides a lower limit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  // Caller guarantees that old_type and new_type are no higher than limit_type.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  virtual const Type* saturate(const Type* new_type, const Type* old_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
                               const Type* limit_type) const
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  { ShouldNotCallThis(); return NULL; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
  void dump_old2new_map() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
  void dump_new( uint new_lidx ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  void dump_types() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
  void dump_nodes_and_types(const Node *root, uint depth, bool only_ctrl = true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  void dump_nodes_and_types_recur( const Node *n, uint depth, bool only_ctrl, VectorSet &visited);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  uint   _count_progress;       // For profiling, count transforms that make progress
5402
c51fd0c1d005 6888953: some calls to function-like macros are missing semicolons
jcoomes
parents: 4450
diff changeset
   320
  void   set_progress()        { ++_count_progress; assert( allow_progress(),"No progress allowed during verification"); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
  void   clear_progress()      { _count_progress = 0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  uint   made_progress() const { return _count_progress; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  uint   _count_transforms;     // For profiling, count transforms performed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  void   set_transforms()      { ++_count_transforms; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  void   clear_transforms()    { _count_transforms = 0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  uint   made_transforms() const{ return _count_transforms; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  bool   _allow_progress;      // progress not allowed during verification pass
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  void   set_allow_progress(bool allow) { _allow_progress = allow; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  bool   allow_progress()               { return _allow_progress; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
//------------------------------PhaseValues------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
// Phase infrastructure to support values
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
class PhaseValues : public PhaseTransform {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  NodeHash  _table;             // Hash table for value-numbering
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  PhaseValues( Arena *arena, uint est_max_size );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  PhaseValues( PhaseValues *pt );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  PhaseValues( PhaseValues *ptv, const char *dummy );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  NOT_PRODUCT( ~PhaseValues(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  virtual PhaseIterGVN *is_IterGVN() { return 0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
  // Some Ideal and other transforms delete --> modify --> insert values
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  bool   hash_delete(Node *n)     { return _table.hash_delete(n); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  void   hash_insert(Node *n)     { _table.hash_insert(n); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  Node  *hash_find_insert(Node *n){ return _table.hash_find_insert(n); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  Node  *hash_find(const Node *n) { return _table.hash_find(n); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  // Used after parsing to eliminate values that are no longer in program
4450
6d700b859b3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 3795
diff changeset
   355
  void   remove_useless_nodes(VectorSet &useful) {
6d700b859b3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 3795
diff changeset
   356
    _table.remove_useless_nodes(useful);
6d700b859b3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 3795
diff changeset
   357
    // this may invalidate cached cons so reset the cache
6d700b859b3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 3795
diff changeset
   358
    init_con_caches();
6d700b859b3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 3795
diff changeset
   359
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
  virtual ConNode* uncached_makecon(const Type* t);  // override from PhaseTransform
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  virtual const Type* saturate(const Type* new_type, const Type* old_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
                               const Type* limit_type) const
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
  { return new_type; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
  uint   _count_new_values;     // For profiling, count new values produced
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  void    inc_new_values()        { ++_count_new_values; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  void    clear_new_values()      { _count_new_values = 0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  uint    made_new_values() const { return _count_new_values; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
//------------------------------PhaseGVN---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
// Phase for performing local, pessimistic GVN-style optimizations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
class PhaseGVN : public PhaseValues {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
  PhaseGVN( Arena *arena, uint est_max_size ) : PhaseValues( arena, est_max_size ) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
  PhaseGVN( PhaseGVN *gvn ) : PhaseValues( gvn ) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  PhaseGVN( PhaseGVN *gvn, const char *dummy ) : PhaseValues( gvn, dummy ) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
  // Return a node which computes the same function as this node, but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
  // in a faster or cheaper fashion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  Node  *transform( Node *n );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  Node  *transform_no_reclaim( Node *n );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  // Check for a simple dead loop when a data node references itself.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  DEBUG_ONLY(void dead_loop_check(Node *n);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
//------------------------------PhaseIterGVN-----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
// Phase for iteratively performing local, pessimistic GVN-style optimizations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
// and ideal transformations on the graph.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
class PhaseIterGVN : public PhaseGVN {
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 246
diff changeset
   397
 private:
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 246
diff changeset
   398
  bool _delay_transform;  // When true simply register the node when calling transform
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 246
diff changeset
   399
                          // instead of actually optimizing it
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 246
diff changeset
   400
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  // Idealize old Node 'n' with respect to its inputs and its value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  virtual Node *transform_old( Node *a_node );
5901
c046f8e9c52b 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 5547
diff changeset
   403
c046f8e9c52b 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 5547
diff changeset
   404
  // Subsume users of node 'old' into node 'nn'
c046f8e9c52b 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 5547
diff changeset
   405
  void subsume_node( Node *old, Node *nn );
c046f8e9c52b 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 5547
diff changeset
   406
13312
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 12958
diff changeset
   407
  Node_Stack _stack;      // Stack used to avoid recursion
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 12958
diff changeset
   408
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  // Idealize new Node 'n' with respect to its inputs and its value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
  virtual Node *transform( Node *a_node );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  // Warm up hash table, type table and initial worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  void init_worklist( Node *a_root );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  virtual const Type* saturate(const Type* new_type, const Type* old_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
                               const Type* limit_type) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  // Usually returns new_type.  Returns old_type if new_type is only a slight
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  // improvement, such that it would take many (>>10) steps to reach 2**32.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
  PhaseIterGVN( PhaseIterGVN *igvn ); // Used by CCP constructor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  PhaseIterGVN( PhaseGVN *gvn ); // Used after Parser
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  PhaseIterGVN( PhaseIterGVN *igvn, const char *dummy ); // Used after +VerifyOpto
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  virtual PhaseIterGVN *is_IterGVN() { return this; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  Unique_Node_List _worklist;       // Iterative worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  // Given def-use info and an initial worklist, apply Node::Ideal,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  // Node::Value, Node::Identity, hash-based value numbering, Node::Ideal_DU
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  // and dominator info to a fixed point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  void optimize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  // Register a new node with the iter GVN pass without transforming it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
  // Used when we need to restructure a Region/Phi area and all the Regions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  // and Phis need to complete this one big transform before any other
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
  // transforms can be triggered on the region.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  // Optional 'orig' is an earlier version of this node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  // It is significant only for debugging and profiling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  Node* register_new_node_with_optimizer(Node* n, Node* orig = NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
13312
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 12958
diff changeset
   444
  // Kill a globally dead Node.  All uses are also globally dead and are
a8e45429e01e 7147464: Java crashed while executing method with over 8k of dneg operations
dlong
parents: 12958
diff changeset
   445
  // aggressively trimmed.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
  void remove_globally_dead_node( Node *dead );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
  // Kill all inputs to a dead node, recursively making more dead nodes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  // The Node must be dead locally, i.e., have no uses.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  void remove_dead_node( Node *dead ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
    assert(dead->outcnt() == 0 && !dead->is_top(), "node must be dead");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
    remove_globally_dead_node(dead);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  // Add users of 'n' to worklist
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
  void add_users_to_worklist0( Node *n );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  void add_users_to_worklist ( Node *n );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
246
b029af7e69d3 6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents: 1
diff changeset
   459
  // Replace old node with new one.
b029af7e69d3 6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents: 1
diff changeset
   460
  void replace_node( Node *old, Node *nn ) {
b029af7e69d3 6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents: 1
diff changeset
   461
    add_users_to_worklist(old);
5901
c046f8e9c52b 6677629: PhaseIterGVN::subsume_node() should call hash_delete() and add_users_to_worklist()
kvn
parents: 5547
diff changeset
   462
    hash_delete(old); // Yank from hash before hacking edges
246
b029af7e69d3 6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents: 1
diff changeset
   463
    subsume_node(old, nn);
b029af7e69d3 6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents: 1
diff changeset
   464
  }
b029af7e69d3 6259129: (Escape Analysis) scalar replacement for not escaping objects
kvn
parents: 1
diff changeset
   465
12958
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   466
  // Delayed node rehash: remove a node from the hash table and rehash it during
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   467
  // next optimizing pass
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   468
  void rehash_node_delayed(Node* n) {
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   469
    hash_delete(n);
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   470
    _worklist.push(n);
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   471
  }
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   472
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   473
  // Replace ith edge of "n" with "in"
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   474
  void replace_input_of(Node* n, int i, Node* in) {
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   475
    rehash_node_delayed(n);
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   476
    n->set_req(i, in);
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   477
  }
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   478
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   479
  // Delete ith edge of "n"
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   480
  void delete_input_of(Node* n, int i) {
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   481
    rehash_node_delayed(n);
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   482
    n->del_req(i);
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   483
  }
009b6c9586d8 7173340: C2: code cleanup: use PhaseIterGVN::replace_edge(Node*, int, Node*) where applicable
kvn
parents: 11446
diff changeset
   484
3268
f034e0c86895 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 670
diff changeset
   485
  bool delay_transform() const { return _delay_transform; }
f034e0c86895 6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents: 670
diff changeset
   486
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 246
diff changeset
   487
  void set_delay_transform(bool delay) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 246
diff changeset
   488
    _delay_transform = delay;
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 246
diff changeset
   489
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 246
diff changeset
   490
9101
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 7397
diff changeset
   491
  // Clone loop predicates. Defined in loopTransform.cpp.
9446
748a37b25d10 5091921: Sign flip issues in loop optimizer
kvn
parents: 9101
diff changeset
   492
  Node* clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check);
9101
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 7397
diff changeset
   493
  // Create a new if below new_entry for the predicate to be cloned
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 7397
diff changeset
   494
  ProjNode* create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 7397
diff changeset
   495
                                        Deoptimization::DeoptReason reason);
ff58f9a8e31c 7004535: Clone loop predicate during loop unswitch
kvn
parents: 7397
diff changeset
   496
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  // Sub-quadratic implementation of VerifyIterativeGVN.
13967
bf7c8dfb5121 8000313: C2 should use jlong for 64bit values
vlivanov
parents: 13397
diff changeset
   500
  julong _verify_counter;
bf7c8dfb5121 8000313: C2 should use jlong for 64bit values
vlivanov
parents: 13397
diff changeset
   501
  julong _verify_full_passes;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
  enum { _verify_window_size = 30 };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
  Node* _verify_window[_verify_window_size];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  void verify_step(Node* n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
//------------------------------PhaseCCP---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
// Phase for performing global Conditional Constant Propagation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
// Should be replaced with combined CCP & GVN someday.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
class PhaseCCP : public PhaseIterGVN {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  // Non-recursive.  Use analysis to transform single Node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  virtual Node *transform_once( Node *n );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  PhaseCCP( PhaseIterGVN *igvn ); // Compute conditional constants
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  NOT_PRODUCT( ~PhaseCCP(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  // Worklist algorithm identifies constants
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  void analyze();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  // Recursive traversal of program.  Used analysis to modify program.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  virtual Node *transform( Node *n );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  // Do any transformation after analysis
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  void          do_transform();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  virtual const Type* saturate(const Type* new_type, const Type* old_type,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
                               const Type* limit_type) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  // Returns new_type->widen(old_type), which increments the widen bits until
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  // giving up with TypeInt::INT or TypeLong::LONG.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  // Result is clipped to limit_type if necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  static uint _total_invokes;    // For profiling, count invocations
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
  void    inc_invokes()          { ++PhaseCCP::_total_invokes; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  static uint _total_constants;  // For profiling, count constants found
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
  uint   _count_constants;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
  void    clear_constants()      { _count_constants = 0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  void    inc_constants()        { ++_count_constants; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
  uint    count_constants() const { return _count_constants; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
  static void print_statistics();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
//------------------------------PhasePeephole----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
// Phase for performing peephole optimizations on register allocated basic blocks.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
class PhasePeephole : public PhaseTransform {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
  PhaseRegAlloc *_regalloc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
  PhaseCFG     &_cfg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  // Recursive traversal of program.  Pure function is unused in this phase
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  virtual Node *transform( Node *n );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
  PhasePeephole( PhaseRegAlloc *regalloc, PhaseCFG &cfg );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
  NOT_PRODUCT( ~PhasePeephole(); )
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  // Do any transformation after analysis
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  void          do_transform();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  static uint _total_peepholes;  // For profiling, count peephole rules applied
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
  uint   _count_peepholes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
  void    clear_peepholes()      { _count_peepholes = 0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  void    inc_peepholes()        { ++_count_peepholes; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  uint    count_peepholes() const { return _count_peepholes; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
  static void print_statistics();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
};
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5901
diff changeset
   572
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5901
diff changeset
   573
#endif // SHARE_VM_OPTO_PHASEX_HPP