hotspot/src/share/vm/c1/c1_ValueMap.hpp
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 1 489c9b5090e2
child 1612 2488b45ded37
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
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
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
class ValueMapEntry: public CompilationResourceObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
  intx           _hash;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
  Value          _value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
  int            _nesting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
  ValueMapEntry* _next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
  ValueMapEntry(intx hash, Value value, int nesting, ValueMapEntry* next)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
    : _hash(hash)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
    , _value(value)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
    , _nesting(nesting)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
    , _next(next)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
  intx           hash()      { return _hash; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
  Value          value()     { return _value; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  int            nesting()   { return _nesting; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  ValueMapEntry* next()      { return _next; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
  void set_next(ValueMapEntry* next) { _next = next; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
define_array(ValueMapEntryArray, ValueMapEntry*)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
define_stack(ValueMapEntryList, ValueMapEntryArray)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
// ValueMap implements nested hash tables for value numbering.  It
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
// maintains a set _killed_values which represents the instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
// which have been killed so far and an array of linked lists of
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
// ValueMapEntries names _entries.  Each ValueMapEntry has a nesting
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
// which indicates what ValueMap nesting it belongs to.  Higher
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
// nesting values are always before lower values in the linked list.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
// This allows cloning of parent ValueMaps by simply copying the heads
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
// of the list.  _entry_count represents the number of reachable
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
// entries in the ValueMap.  A ValueMap is only allowed to mutate
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
// ValueMapEntries with the same nesting level.  Adding or removing
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
// entries at the current nesting level requires updating
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
// _entry_count.  Elements in the parent's list that get killed can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
// skipped if they are at the head of the list by simply moving to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
// next element in the list and decrementing _entry_count.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
class ValueMap: public CompilationResourceObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  int           _nesting;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  ValueMapEntryArray _entries;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  ValueSet      _killed_values;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  int           _entry_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  int           nesting()                        { return _nesting; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  bool          is_local_value_numbering()       { return _nesting == 0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  bool          is_global_value_numbering()      { return _nesting > 0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  int           entry_count()                    { return _entry_count; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  int           size()                           { return _entries.length(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  ValueMapEntry* entry_at(int i)                 { return _entries.at(i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  // calculates the index of a hash value in a hash table of size n
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  int           entry_index(intx hash, int n)    { return (unsigned int)hash % n; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  // if entry_count > size_threshold, the size of the hash table is increased
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  int           size_threshold()                 { return size(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  // management of the killed-bitset for global value numbering
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  void          kill_value(Value v)              { if (is_global_value_numbering()) _killed_values.put(v); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  bool          is_killed(Value v)               { if (is_global_value_numbering()) return _killed_values.contains(v); else return false; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  // helper functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  void          increase_table_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  static int _number_of_finds;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  static int _number_of_hits;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  static int _number_of_kills;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  // creation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  ValueMap();                // empty value map
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  ValueMap(ValueMap* old);   // value map with increased nesting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  // manipulation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  Value find_insert(Value x);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  void kill_memory();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  void kill_field(ciField* field);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  void kill_array(ValueType* type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
  void kill_exception();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  void kill_map(ValueMap* map);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  void kill_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  // debugging/printing
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  void print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  static void reset_statistics();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  static void print_statistics();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
define_array(ValueMapArray, ValueMap*)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
class ValueNumberingVisitor: public InstructionVisitor {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
 protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  // called by visitor functions for instructions that kill values
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  virtual void kill_memory() = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  virtual void kill_field(ciField* field) = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  virtual void kill_array(ValueType* type) = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  // visitor functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  void do_StoreField     (StoreField*      x) { kill_field(x->field()); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  void do_StoreIndexed   (StoreIndexed*    x) { kill_array(x->type()); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  void do_MonitorEnter   (MonitorEnter*    x) { kill_memory(); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  void do_MonitorExit    (MonitorExit*     x) { kill_memory(); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  void do_Invoke         (Invoke*          x) { kill_memory(); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  void do_UnsafePutRaw   (UnsafePutRaw*    x) { kill_memory(); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  void do_Intrinsic      (Intrinsic*       x) { if (!x->preserves_state()) kill_memory(); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  void do_Phi            (Phi*             x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  void do_Local          (Local*           x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  void do_Constant       (Constant*        x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  void do_LoadField      (LoadField*       x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  void do_ArrayLength    (ArrayLength*     x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  void do_LoadIndexed    (LoadIndexed*     x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  void do_NegateOp       (NegateOp*        x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  void do_ArithmeticOp   (ArithmeticOp*    x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  void do_ShiftOp        (ShiftOp*         x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  void do_LogicOp        (LogicOp*         x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  void do_CompareOp      (CompareOp*       x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  void do_IfOp           (IfOp*            x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  void do_Convert        (Convert*         x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  void do_NullCheck      (NullCheck*       x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  void do_NewInstance    (NewInstance*     x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  void do_NewTypeArray   (NewTypeArray*    x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  void do_NewObjectArray (NewObjectArray*  x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  void do_NewMultiArray  (NewMultiArray*   x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  void do_CheckCast      (CheckCast*       x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  void do_InstanceOf     (InstanceOf*      x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  void do_BlockBegin     (BlockBegin*      x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  void do_Goto           (Goto*            x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  void do_If             (If*              x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  void do_IfInstanceOf   (IfInstanceOf*    x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  void do_TableSwitch    (TableSwitch*     x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  void do_LookupSwitch   (LookupSwitch*    x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  void do_Return         (Return*          x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  void do_Throw          (Throw*           x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  void do_Base           (Base*            x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  void do_OsrEntry       (OsrEntry*        x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  void do_RoundFP        (RoundFP*         x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  void do_UnsafeGetRaw   (UnsafeGetRaw*    x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  void do_UnsafePrefetchRead (UnsafePrefetchRead*  x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  void do_ProfileCall    (ProfileCall*     x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
  void do_ProfileCounter (ProfileCounter*  x) { /* nothing to do */ };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
class GlobalValueNumbering: public ValueNumberingVisitor {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  ValueMap*     _current_map;     // value map of current block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  ValueMapArray _value_maps;      // list of value maps for all blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  // accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  ValueMap*     current_map()                    { return _current_map; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  ValueMap*     value_map_of(BlockBegin* block)  { return _value_maps.at(block->linear_scan_number()); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  void          set_value_map_of(BlockBegin* block, ValueMap* map)   { assert(value_map_of(block) == NULL, ""); _value_maps.at_put(block->linear_scan_number(), map); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  // implementation for abstract methods of ValueNumberingVisitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  void          kill_memory()                    { current_map()->kill_memory(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  void          kill_field(ciField* field)       { current_map()->kill_field(field); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  void          kill_array(ValueType* type)      { current_map()->kill_array(type); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  // main entry point that performs global value numbering
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  GlobalValueNumbering(IR* ir);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
};