hotspot/src/share/vm/opto/chaitin.hpp
author coleenp
Mon, 14 Jan 2013 11:01:39 -0500
changeset 15194 a35093d73168
parent 13520 a1ba7784ef54
child 15944 095248beb690
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
/*
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
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: 3678
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 3678
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: 3678
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: 5547
diff changeset
    25
#ifndef SHARE_VM_OPTO_CHAITIN_HPP
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    26
#define SHARE_VM_OPTO_CHAITIN_HPP
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    27
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "code/vmreg.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    29
#include "libadt/port.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    30
#include "memory/resourceArea.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    31
#include "opto/connode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    32
#include "opto/live.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    33
#include "opto/matcher.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    34
#include "opto/phase.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    35
#include "opto/regalloc.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    36
#include "opto/regmask.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    37
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
class LoopTree;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
class MachCallNode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
class MachSafePointNode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
class Matcher;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
class PhaseCFG;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
class PhaseLive;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
class PhaseRegAlloc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
class   PhaseChaitin;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
#define OPTO_DEBUG_SPLIT_FREQ  BLOCK_FREQUENCY(0.001)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
#define OPTO_LRG_HIGH_FREQ     BLOCK_FREQUENCY(0.25)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
//------------------------------LRG--------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
// Live-RanGe structure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
class LRG : public ResourceObj {
10547
ea4a2ec31ae2 7088955: add C2 IR support to the SA
never
parents: 10542
diff changeset
    53
  friend class VMStructs;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  enum { SPILL_REG=29999 };     // Register number of a spilled LRG
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  double _cost;                 // 2 for loads/1 for stores times block freq
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  double _area;                 // Sum of all simultaneously live values
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  double score() const;         // Compute score from cost and area
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  double _maxfreq;              // Maximum frequency of any def or use
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  Node *_def;                   // Check for multi-def live ranges
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  GrowableArray<Node*>* _defs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  uint _risk_bias;              // Index of LRG which we want to avoid color
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  uint _copy_bias;              // Index of LRG which we want to share color
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  uint _next;                   // Index of next LRG in linked list
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  uint _prev;                   // Index of prev LRG in linked list
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  uint _reg;                    // Chosen register; undefined if mask is plural
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  // Return chosen register for this LRG.  Error if the LRG is not bound to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  // a single register.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  OptoReg::Name reg() const { return OptoReg::Name(_reg); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  void set_reg( OptoReg::Name r ) { _reg = r; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  uint _eff_degree;             // Effective degree: Sum of neighbors _num_regs
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  int degree() const { assert( _degree_valid, "" ); return _eff_degree; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  // Degree starts not valid and any change to the IFG neighbor
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  // set makes it not valid.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  void set_degree( uint degree ) { _eff_degree = degree; debug_only(_degree_valid = 1;) }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  // Made a change that hammered degree
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  void invalid_degree() { debug_only(_degree_valid=0;) }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  // Incrementally modify degree.  If it was correct, it should remain correct
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  void inc_degree( uint mod ) { _eff_degree += mod; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
  // Compute the degree between 2 live ranges
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  int compute_degree( LRG &l ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  RegMask _mask;                // Allowed registers for this LRG
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  uint _mask_size;              // cache of _mask.Size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  int compute_mask_size() const { return _mask.is_AllStack() ? 65535 : _mask.Size(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  void set_mask_size( int size ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
    assert((size == 65535) || (size == (int)_mask.Size()), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
    _mask_size = size;
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   102
#ifdef ASSERT
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   103
    _msize_valid=1;
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   104
    if (_is_vector) {
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   105
      assert(!_fat_proj, "sanity");
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   106
      _mask.verify_sets(_num_regs);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   107
    } else if (_num_regs == 2 && !_fat_proj) {
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   108
      _mask.verify_pairs();
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   109
    }
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   110
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  void compute_set_mask_size() { set_mask_size(compute_mask_size()); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  int mask_size() const { assert( _msize_valid, "mask size not valid" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
                          return _mask_size; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  // Get the last mask size computed, even if it does not match the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  // count of bits in the current mask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  int get_invalid_mask_size() const { return _mask_size; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  const RegMask &mask() const { return _mask; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  void set_mask( const RegMask &rm ) { _mask = rm; debug_only(_msize_valid=0;)}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  void AND( const RegMask &rm ) { _mask.AND(rm); debug_only(_msize_valid=0;)}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  void SUBTRACT( const RegMask &rm ) { _mask.SUBTRACT(rm); debug_only(_msize_valid=0;)}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  void Clear()   { _mask.Clear()  ; debug_only(_msize_valid=1); _mask_size = 0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  void Set_All() { _mask.Set_All(); debug_only(_msize_valid=1); _mask_size = RegMask::CHUNK_SIZE; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  void Insert( OptoReg::Name reg ) { _mask.Insert(reg);  debug_only(_msize_valid=0;) }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  void Remove( OptoReg::Name reg ) { _mask.Remove(reg);  debug_only(_msize_valid=0;) }
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   126
  void clear_to_pairs() { _mask.clear_to_pairs(); debug_only(_msize_valid=0;) }
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   127
  void clear_to_sets()  { _mask.clear_to_sets(_num_regs); debug_only(_msize_valid=0;) }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  // Number of registers this live range uses when it colors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  uint8 _num_regs;              // 2 for Longs and Doubles, 1 for all else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
                                // except _num_regs is kill count for fat_proj
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  int num_regs() const { return _num_regs; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  void set_num_regs( int reg ) { assert( _num_regs == reg || !_num_regs, "" ); _num_regs = reg; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  // Number of physical registers this live range uses when it colors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  // Architecture and register-set dependent
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  uint8 _reg_pressure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  void set_reg_pressure(int i)  { _reg_pressure = i; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  int      reg_pressure() const { return _reg_pressure; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  // How much 'wiggle room' does this live range have?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  // How many color choices can it make (scaled by _num_regs)?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  int degrees_of_freedom() const { return mask_size() - _num_regs; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  // Bound LRGs have ZERO degrees of freedom.  We also count
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  // must_spill as bound.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  bool is_bound  () const { return _is_bound; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  // Negative degrees-of-freedom; even with no neighbors this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  // live range must spill.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  bool not_free() const { return degrees_of_freedom() <  0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  // Is this live range of "low-degree"?  Trivially colorable?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  bool lo_degree () const { return degree() <= degrees_of_freedom(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  // Is this live range just barely "low-degree"?  Trivially colorable?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  bool just_lo_degree () const { return degree() == degrees_of_freedom(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  uint   _is_oop:1,             // Live-range holds an oop
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
         _is_float:1,           // True if in float registers
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 11444
diff changeset
   161
         _is_vector:1,          // True if in vector registers
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
         _was_spilled1:1,       // True if prior spilling on def
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
         _was_spilled2:1,       // True if twice prior spilling on def
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
         _is_bound:1,           // live range starts life with no
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
                                // degrees of freedom.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
         _direct_conflict:1,    // True if def and use registers in conflict
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
         _must_spill:1,         // live range has lost all degrees of freedom
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
    // If _fat_proj is set, live range does NOT require aligned, adjacent
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
    // registers and has NO interferences.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    // If _fat_proj is clear, live range requires num_regs() to be a power of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
    // 2, and it requires registers to form an aligned, adjacent set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
         _fat_proj:1,           //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
         _was_lo:1,             // Was lo-degree prior to coalesce
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
         _msize_valid:1,        // _mask_size cache valid
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
         _degree_valid:1,       // _degree cache valid
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
         _has_copy:1,           // Adjacent to some copy instruction
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
         _at_risk:1;            // Simplify says this guy is at risk to spill
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  // Alive if non-zero, dead if zero
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  bool alive() const { return _def != NULL; }
1057
44220ef9a775 6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents: 670
diff changeset
   182
  bool is_multidef() const { return _def == NodeSentinel; }
44220ef9a775 6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents: 670
diff changeset
   183
  bool is_singledef() const { return _def != NodeSentinel; }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  void dump( ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
//------------------------------LRG_List---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
// Map Node indices to Live RanGe indices.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
// Array lookup in the optimized case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
class LRG_List : public ResourceObj {
10547
ea4a2ec31ae2 7088955: add C2 IR support to the SA
never
parents: 10542
diff changeset
   194
  friend class VMStructs;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  uint _cnt, _max;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  uint* _lidxs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  ReallocMark _nesting;         // assertion check for reallocations
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  LRG_List( uint max );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  uint lookup( uint nidx ) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    return _lidxs[nidx];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  uint operator[] (uint nidx) const { return lookup(nidx); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  void map( uint nidx, uint lidx ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
    assert( nidx < _cnt, "oob" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
    _lidxs[nidx] = lidx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  void extend( uint nidx, uint lidx );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  uint Size() const { return _cnt; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
//------------------------------IFG--------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
//                         InterFerence Graph
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
// An undirected graph implementation.  Created with a fixed number of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
// vertices.  Edges can be added & tested.  Vertices can be removed, then
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
// added back later with all edges intact.  Can add edges between one vertex
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
// and a list of other vertices.  Can union vertices (and their edges)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
// together.  The IFG needs to be really really fast, and also fairly
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
// abstract!  It needs abstraction so I can fiddle with the implementation to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
// get even more speed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
class PhaseIFG : public Phase {
10547
ea4a2ec31ae2 7088955: add C2 IR support to the SA
never
parents: 10542
diff changeset
   225
  friend class VMStructs;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  // Current implementation: a triangular adjacency list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  // Array of adjacency-lists, indexed by live-range number
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  IndexSet *_adjs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  // Assertion bit for proper use of Squaring
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  bool _is_square;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  // Live range structure goes here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  LRG *_lrgs;                   // Array of LRG structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  // Largest live-range number
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  uint _maxlrg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  Arena *_arena;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  // Keep track of inserted and deleted Nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  VectorSet *_yanked;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  PhaseIFG( Arena *arena );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  void init( uint maxlrg );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  // Add edge between a and b.  Returns true if actually addded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  int add_edge( uint a, uint b );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  // Add edge between a and everything in the vector
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  void add_vector( uint a, IndexSet *vec );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  // Test for edge existance
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  int test_edge( uint a, uint b ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  // Square-up matrix for faster Union
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  void SquareUp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
  // Return number of LRG neighbors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  uint neighbor_cnt( uint a ) const { return _adjs[a].count(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  // Union edges of b into a on Squared-up matrix
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  void Union( uint a, uint b );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  // Test for edge in Squared-up matrix
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  int test_edge_sq( uint a, uint b ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
  // Yank a Node and all connected edges from the IFG.  Be prepared to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  // re-insert the yanked Node in reverse order of yanking.  Return a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  // list of neighbors (edges) yanked.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
  IndexSet *remove_node( uint a );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
  // Reinsert a yanked Node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
  void re_insert( uint a );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
  // Return set of neighbors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
  IndexSet *neighbors( uint a ) const { return &_adjs[a]; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  // Dump the IFG
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  void dump() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  void stats() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  void verify( const PhaseChaitin * ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  //--------------- Live Range Accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
  LRG &lrgs(uint idx) const { assert(idx < _maxlrg, "oob"); return _lrgs[idx]; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  // Compute and set effective degree.  Might be folded into SquareUp().
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  void Compute_Effective_Degree();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  // Compute effective degree as the sum of neighbors' _sizes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  int effective_degree( uint lidx ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
// TEMPORARILY REPLACED WITH COMMAND LINE FLAG
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
//// !!!!! Magic Constants need to move into ad file
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
#ifdef SPARC
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
//#define FLOAT_PRESSURE 30  /*     SFLT_REG_mask.Size() - 1 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
//#define INT_PRESSURE   23  /* NOTEMP_I_REG_mask.Size() - 1 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
#define FLOAT_INCREMENT(regs) regs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
//#define FLOAT_PRESSURE 6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
//#define INT_PRESSURE   6
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
#define FLOAT_INCREMENT(regs) 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
//------------------------------Chaitin----------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
// Briggs-Chaitin style allocation, mostly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
class PhaseChaitin : public PhaseRegAlloc {
10547
ea4a2ec31ae2 7088955: add C2 IR support to the SA
never
parents: 10542
diff changeset
   309
  friend class VMStructs;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  int _trip_cnt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  int _alternate;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
  uint _maxlrg;                 // Max live range number
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  LRG &lrgs(uint idx) const { return _ifg->lrgs(idx); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
  PhaseLive *_live;             // Liveness, used in the interference graph
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  PhaseIFG *_ifg;               // Interference graph (for original chunk)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  Node_List **_lrg_nodes;       // Array of node; lists for lrgs which spill
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  VectorSet _spilled_once;      // Nodes that have been spilled
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  VectorSet _spilled_twice;     // Nodes that have been spilled twice
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  LRG_List _names;              // Map from Nodes to Live RanGes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  // Union-find map.  Declared as a short for speed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  // Indexed by live-range number, it returns the compacted live-range number
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  LRG_List _uf_map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  // Reset the Union-Find map to identity
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  void reset_uf_map( uint maxlrg );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  // Remove the need for the Union-Find mapping
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  void compress_uf_map_for_nodes( );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  // Combine the Live Range Indices for these 2 Nodes into a single live
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  // range.  Future requests for any Node in either live range will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  // return the live range index for the combined live range.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  void Union( const Node *src, const Node *dst );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  void new_lrg( const Node *x, uint lrg );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  // Compact live ranges, removing unused ones.  Return new maxlrg.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  void compact();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  uint _lo_degree;              // Head of lo-degree LRGs list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  uint _lo_stk_degree;          // Head of lo-stk-degree LRGs list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  uint _hi_degree;              // Head of hi-degree LRGs list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  uint _simplified;             // Linked list head of simplified LRGs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  // Helper functions for Split()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
  uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray<uint> splits, int slidx );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  int clone_projs( Block *b, uint idx, Node *con, Node *copy, uint &maxlrg );
1057
44220ef9a775 6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents: 670
diff changeset
   351
  Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits,
44220ef9a775 6732194: Data corruption dependent on -server/-client/-Xbatch
never
parents: 670
diff changeset
   352
                            int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  // True if lidx is used before any real register is def'd in the block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  bool prompt_use( Block *b, uint lidx );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  Node *get_spillcopy_wide( Node *def, Node *use, uint uidx );
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 2030
diff changeset
   356
  // Insert the spill at chosen location.  Skip over any intervening Proj's or
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  // Phis.  Skip over a CatchNode and projs, inserting in the fall-through block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  // instead.  Update high-pressure indices.  Create a new live range.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
  void insert_proj( Block *b, uint i, Node *spill, uint maxlrg );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
  bool is_high_pressure( Block *b, LRG *lrg, uint insidx );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  uint _oldphi;                 // Node index which separates pre-allocation nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
  Block **_blks;                // Array of blocks sorted by frequency for coalescing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
2340
cb47f8209cd8 6810845: Performance regression in mpegaudio on x64
kvn
parents: 2154
diff changeset
   367
  float _high_frequency_lrg;    // Frequency at which LRG will be spilled for debug info
cb47f8209cd8 6810845: Performance regression in mpegaudio on x64
kvn
parents: 2154
diff changeset
   368
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  bool _trace_spilling;
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
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  PhaseChaitin( uint unique, PhaseCFG &cfg, Matcher &matcher );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  ~PhaseChaitin() {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  // Convert a Node into a Live Range Index - a lidx
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
  uint Find( const Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
    uint lidx = n2lidx(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
    uint uf_lidx = _uf_map[lidx];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
    return (uf_lidx == lidx) ? uf_lidx : Find_compress(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
  uint Find_const( uint lrg ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
  uint Find_const( const Node *n ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  // Do all the real work of allocate
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  void Register_Allocate();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  uint n2lidx( const Node *n ) const { return _names[n->_idx]; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
2340
cb47f8209cd8 6810845: Performance regression in mpegaudio on x64
kvn
parents: 2154
diff changeset
   391
  float high_frequency_lrg() const { return _high_frequency_lrg; }
cb47f8209cd8 6810845: Performance regression in mpegaudio on x64
kvn
parents: 2154
diff changeset
   392
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  bool trace_spilling() const { return _trace_spilling; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  // De-SSA the world.  Assign registers to Nodes.  Use the same register for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  // all inputs to a PhiNode, effectively coalescing live ranges.  Insert
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  // copies as needed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  void de_ssa();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  uint Find_compress( const Node *n );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  uint Find( uint lidx ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
    uint uf_lidx = _uf_map[lidx];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
    return (uf_lidx == lidx) ? uf_lidx : Find_compress(lidx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  uint Find_compress( uint lidx );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
  uint Find_id( const Node *n ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
    uint retval = n2lidx(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
    assert(retval == Find(n),"Invalid node to lidx mapping");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
    return retval;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  // Add edge between reg and everything in the vector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  // Same as _ifg->add_vector(reg,live) EXCEPT use the RegMask
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  // information to trim the set of interferences.  Return the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  // count of edges added.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  void interfere_with_live( uint reg, IndexSet *live );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  // Count register pressure for asserts
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
  uint count_int_pressure( IndexSet *liveout );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  uint count_float_pressure( IndexSet *liveout );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
  // Build the interference graph using virtual registers only.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
  // Used for aggressive coalescing.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
  void build_ifg_virtual( );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
  // Build the interference graph using physical registers when available.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  // That is, if 2 live ranges are simultaneously alive but in their
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
  // acceptable register sets do not overlap, then they do not interfere.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  uint build_ifg_physical( ResourceArea *a );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  // Gather LiveRanGe information, including register masks and base pointer/
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  // derived pointer relationships.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  void gather_lrg_masks( bool mod_cisc_masks );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
  // Force the bases of derived pointers to be alive at GC points.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  bool stretch_base_pointer_live_ranges( ResourceArea *a );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
  // Helper to stretch above; recursively discover the base Node for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  // a given derived Node.  Easy for AddP-related machine nodes, but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  // needs to be recursive for derived Phis.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  Node *find_base_for_derived( Node **derived_base_map, Node *derived, uint &maxlrg );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  // Set the was-lo-degree bit.  Conservative coalescing should not change the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  // colorability of the graph.  If any live range was of low-degree before
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
  // coalescing, it should Simplify.  This call sets the was-lo-degree bit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
  void set_was_low();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  // Split live-ranges that must spill due to register conflicts (as opposed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  // to capacity spills).  Typically these are things def'd in a register
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  // and used on the stack or vice-versa.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  void pre_spill();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  // Init LRG caching of degree, numregs.  Init lo_degree list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  void cache_lrg_info( );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  // Simplify the IFG by removing LRGs of low degree with no copies
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  void Pre_Simplify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
  // Simplify the IFG by removing LRGs of low degree
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
  void Simplify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  // Select colors by re-inserting edges into the IFG.
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 2030
diff changeset
   464
  // Return TRUE if any spills occurred.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  uint Select( );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  // Helper function for select which allows biased coloring
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  OptoReg::Name choose_color( LRG &lrg, int chunk );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
  // Helper function which implements biasing heuristic
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  OptoReg::Name bias_color( LRG &lrg, int chunk );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  // Split uncolorable live ranges
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  // Return new number of live ranges
13520
a1ba7784ef54 7148109: C2 compiler consumes too much heap resources
kvn
parents: 13104
diff changeset
   473
  uint Split(uint maxlrg, ResourceArea* split_arena);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
  // Copy 'was_spilled'-edness from one Node to another.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
  void copy_was_spilled( Node *src, Node *dst );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
  // Set the 'spilled_once' or 'spilled_twice' flag on a node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  void set_was_spilled( Node *n );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
  // Convert ideal spill-nodes into machine loads & stores
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  // Set C->failing when fixup spills could not complete, node limit exceeded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
  void fixup_spills();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  // Post-Allocation peephole copy removal
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  void post_allocate_copy_removal();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  Node *skip_copies( Node *c );
3678
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2340
diff changeset
   487
  // Replace the old node with the current live version of that value
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2340
diff changeset
   488
  // and yank the old value if it's dead.
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2340
diff changeset
   489
  int replace_and_yank_if_dead( Node *old, OptoReg::Name nreg,
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2340
diff changeset
   490
                                Block *current_block, Node_List& value, Node_List& regnd ) {
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2340
diff changeset
   491
    Node* v = regnd[nreg];
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2340
diff changeset
   492
    assert(v->outcnt() != 0, "no dead values");
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2340
diff changeset
   493
    old->replace_by(v);
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2340
diff changeset
   494
    return yank_if_dead(old, current_block, &value, &regnd);
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2340
diff changeset
   495
  }
d797d97552e4 6862863: C2 compiler fails in elide_copy()
never
parents: 2340
diff changeset
   496
11444
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10547
diff changeset
   497
  int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) {
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10547
diff changeset
   498
    return yank_if_dead_recurse(old, old, current_block, value, regnd);
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10547
diff changeset
   499
  }
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10547
diff changeset
   500
  int yank_if_dead_recurse(Node *old, Node *orig_old, Block *current_block,
8a2619fd3fca 7110824: ctw/jarfiles/GUI3rdParty_jar/ob_mask_DateField crashes VM
kvn
parents: 10547
diff changeset
   501
                           Node_List *value, Node_List *regnd);
10542
93e6f995c75c 7087453: PhaseChaitin::yank_if_dead() should handle MachTemp inputs
roland
parents: 7441
diff changeset
   502
  int yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
  int elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List &regnd, bool can_change_regs );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List &regnd );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  bool may_be_copy_of_callee( Node *def ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
  // If nreg already contains the same constant as val then eliminate it
243
79b67a7a584a 6661247: Internal bug in 32-bit HotSpot optimizer while bit manipulations
never
parents: 1
diff changeset
   508
  bool eliminate_copy_of_constant(Node* val, Node* n,
79b67a7a584a 6661247: Internal bug in 32-bit HotSpot optimizer while bit manipulations
never
parents: 1
diff changeset
   509
                                  Block *current_block, Node_List& value, Node_List &regnd,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
                                  OptoReg::Name nreg, OptoReg::Name nreg2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  // Extend the node to LRG mapping
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  void add_reference( const Node *node, const Node *old_node);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  static int _final_loads, _final_stores, _final_copies, _final_memoves;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  static double _final_load_cost, _final_store_cost, _final_copy_cost, _final_memove_cost;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  static int _conserv_coalesce, _conserv_coalesce_pair;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  static int _conserv_coalesce_trie, _conserv_coalesce_quad;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  static int _post_alloc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  static int _lost_opp_pp_coalesce, _lost_opp_cflow_coalesce;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  static int _used_cisc_instructions, _unused_cisc_instructions;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  static int _allocator_attempts, _allocator_successes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  static uint _high_pressure, _low_pressure;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  void dump() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  void dump( const Node *n ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  void dump( const Block * b ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  void dump_degree_lists() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  void dump_simplified() const;
7441
47ea904dba6a 7004940: CTW: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG
never
parents: 7397
diff changeset
   533
  void dump_lrg( uint lidx, bool defs_only) const;
47ea904dba6a 7004940: CTW: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG
never
parents: 7397
diff changeset
   534
  void dump_lrg( uint lidx) const {
47ea904dba6a 7004940: CTW: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG
never
parents: 7397
diff changeset
   535
    // dump defs and uses by default
47ea904dba6a 7004940: CTW: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG
never
parents: 7397
diff changeset
   536
    dump_lrg(lidx, false);
47ea904dba6a 7004940: CTW: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG
never
parents: 7397
diff changeset
   537
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
  void dump_bb( uint pre_order ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
  // Verify that base pointers and derived pointers are still sane
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  void verify_base_ptrs( ResourceArea *a ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
2030
39d55e4534b4 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 1057
diff changeset
   543
  void verify( ResourceArea *a, bool verify_ifg = false ) const;
39d55e4534b4 6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly")
kvn
parents: 1057
diff changeset
   544
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  void dump_for_spill_split_recycle() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
  void dump_frame() const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  char *dump_register( const Node *n, char *buf  ) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
  static void print_chaitin_statistics();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  friend class PhaseCoalesce;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
  friend class PhaseAggressiveCoalesce;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  friend class PhaseConservativeCoalesce;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
};
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
   557
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
   558
#endif // SHARE_VM_OPTO_CHAITIN_HPP