hotspot/src/share/vm/opto/superword.hpp
author coleenp
Mon, 14 Jan 2013 11:01:39 -0500
changeset 15194 a35093d73168
parent 13885 6b056026ecad
child 15755 c54cbfb4b37f
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: 10255
diff changeset
     2
 * Copyright (c) 2007, 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: 3261
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 3261
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: 3261
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    24
#ifndef SHARE_VM_OPTO_SUPERWORD_HPP
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#define SHARE_VM_OPTO_SUPERWORD_HPP
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    26
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    27
#include "opto/connode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "opto/loopnode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    29
#include "opto/node.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    30
#include "opto/phaseX.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    31
#include "opto/vectornode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    32
#include "utilities/growableArray.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    33
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
//                  S U P E R W O R D   T R A N S F O R M
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
// SuperWords are short, fixed length vectors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
// Algorithm from:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
// Exploiting SuperWord Level Parallelism with
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
//   Multimedia Instruction Sets
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
// by
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
//   Samuel Larsen and Saman Amarasighe
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
//   MIT Laboratory for Computer Science
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
// date
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
//   May 2000
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
// published in
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
//   ACM SIGPLAN Notices
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
//   Proceedings of ACM PLDI '00,  Volume 35 Issue 5
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
// Definition 3.1 A Pack is an n-tuple, <s1, ...,sn>, where
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
// s1,...,sn are independent isomorphic statements in a basic
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
// block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
// Definition 3.2 A PackSet is a set of Packs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
// Definition 3.3 A Pair is a Pack of size two, where the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
// first statement is considered the left element, and the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
// second statement is considered the right element.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
class SWPointer;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
class OrderedPair;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
// ========================= Dependence Graph =====================
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
class DepMem;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
//------------------------------DepEdge---------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
// An edge in the dependence graph.  The edges incident to a dependence
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
// node are threaded through _next_in for incoming edges and _next_out
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
// for outgoing edges.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
class DepEdge : public ResourceObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
 protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  DepMem* _pred;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  DepMem* _succ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  DepEdge* _next_in;   // list of in edges, null terminated
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  DepEdge* _next_out;  // list of out edges, null terminated
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  DepEdge(DepMem* pred, DepMem* succ, DepEdge* next_in, DepEdge* next_out) :
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
    _pred(pred), _succ(succ), _next_in(next_in), _next_out(next_out) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  DepEdge* next_in()  { return _next_in; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  DepEdge* next_out() { return _next_out; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  DepMem*  pred()     { return _pred; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  DepMem*  succ()     { return _succ; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  void print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
//------------------------------DepMem---------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
// A node in the dependence graph.  _in_head starts the threaded list of
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
// incoming edges, and _out_head starts the list of outgoing edges.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
class DepMem : public ResourceObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
 protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  Node*    _node;     // Corresponding ideal node
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  DepEdge* _in_head;  // Head of list of in edges, null terminated
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
  DepEdge* _out_head; // Head of list of out edges, null terminated
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
  DepMem(Node* node) : _node(node), _in_head(NULL), _out_head(NULL) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  Node*    node()                { return _node;     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  DepEdge* in_head()             { return _in_head;  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  DepEdge* out_head()            { return _out_head; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  void set_in_head(DepEdge* hd)  { _in_head = hd;    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  void set_out_head(DepEdge* hd) { _out_head = hd;   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  int in_cnt();  // Incoming edge count
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
  int out_cnt(); // Outgoing edge count
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  void print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
//------------------------------DepGraph---------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
class DepGraph VALUE_OBJ_CLASS_SPEC {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
 protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  Arena* _arena;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  GrowableArray<DepMem*> _map;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  DepMem* _root;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  DepMem* _tail;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  DepGraph(Arena* a) : _arena(a), _map(a, 8,  0, NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
    _root = new (_arena) DepMem(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
    _tail = new (_arena) DepMem(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  DepMem* root() { return _root; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  DepMem* tail() { return _tail; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  // Return dependence node corresponding to an ideal node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  DepMem* dep(Node* node) { return _map.at(node->_idx); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  // Make a new dependence graph node for an ideal node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  DepMem* make_node(Node* node);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  // Make a new dependence graph edge dprec->dsucc
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
  DepEdge* make_edge(DepMem* dpred, DepMem* dsucc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  DepEdge* make_edge(Node* pred,   Node* succ)   { return make_edge(dep(pred), dep(succ)); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  DepEdge* make_edge(DepMem* pred, Node* succ)   { return make_edge(pred,      dep(succ)); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  DepEdge* make_edge(Node* pred,   DepMem* succ) { return make_edge(dep(pred), succ);      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  void init() { _map.clear(); } // initialize
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  void print(Node* n)   { dep(n)->print(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  void print(DepMem* d) { d->print(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
//------------------------------DepPreds---------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
// Iterator over predecessors in the dependence graph and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
// non-memory-graph inputs of ideal nodes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
class DepPreds : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  Node*    _n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
  int      _next_idx, _end_idx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  DepEdge* _dep_next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  Node*    _current;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  bool     _done;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  DepPreds(Node* n, DepGraph& dg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  Node* current() { return _current; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  bool  done()    { return _done; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  void  next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
//------------------------------DepSuccs---------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
// Iterator over successors in the dependence graph and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
// non-memory-graph outputs of ideal nodes.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
class DepSuccs : public StackObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  Node*    _n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  int      _next_idx, _end_idx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  DepEdge* _dep_next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  Node*    _current;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  bool     _done;
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
  DepSuccs(Node* n, DepGraph& dg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  Node* current() { return _current; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  bool  done()    { return _done; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  void  next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
// ========================= SuperWord =====================
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
// -----------------------------SWNodeInfo---------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
// Per node info needed by SuperWord
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
class SWNodeInfo VALUE_OBJ_CLASS_SPEC {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  int         _alignment; // memory alignment for a node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  int         _depth;     // Max expression (DAG) depth from block start
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  const Type* _velt_type; // vector element type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  Node_List*  _my_pack;   // pack containing this node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  SWNodeInfo() : _alignment(-1), _depth(0), _velt_type(NULL), _my_pack(NULL) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  static const SWNodeInfo initial;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
// -----------------------------SuperWord---------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
// Transforms scalar operations into packed (superword) operations.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
class SuperWord : public ResourceObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  PhaseIdealLoop* _phase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  Arena*          _arena;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  PhaseIterGVN   &_igvn;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  enum consts { top_align = -1, bottom_align = -666 };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  GrowableArray<Node_List*> _packset;    // Packs for the current block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  GrowableArray<int> _bb_idx;            // Map from Node _idx to index within block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  GrowableArray<Node*> _block;           // Nodes in current block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  GrowableArray<Node*> _data_entry;      // Nodes with all inputs from outside
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  GrowableArray<Node*> _mem_slice_head;  // Memory slice head nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  GrowableArray<Node*> _mem_slice_tail;  // Memory slice tail nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  GrowableArray<SWNodeInfo> _node_info;  // Info needed per node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  MemNode* _align_to_ref;                // Memory reference that pre-loop will align to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  GrowableArray<OrderedPair> _disjoint_ptrs; // runtime disambiguated pointer pairs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  DepGraph _dg; // Dependence graph
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  // Scratch pads
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  VectorSet    _visited;       // Visited set
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  VectorSet    _post_visited;  // Post-visited set
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  Node_Stack   _n_idx_list;    // List of (node,index) pairs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  GrowableArray<Node*> _nlist; // List of nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
  GrowableArray<Node*> _stk;   // Stack of nodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
  SuperWord(PhaseIdealLoop* phase);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  void transform_loop(IdealLoopTree* lpt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  // Accessors for SWPointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
  PhaseIdealLoop* phase()          { return _phase; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
  IdealLoopTree* lpt()             { return _lpt; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
  PhiNode* iv()                    { return _iv; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  IdealLoopTree* _lpt;             // Current loop tree node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  LoopNode*      _lp;              // Current LoopNode
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  Node*          _bb;              // Current basic block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
  PhiNode*       _iv;              // Induction var
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
  // Accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  Arena* arena()                   { return _arena; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  Node* bb()                       { return _bb; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  void  set_bb(Node* bb)           { _bb = bb; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  void set_lpt(IdealLoopTree* lpt) { _lpt = lpt; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  LoopNode* lp()                   { return _lp; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
  void      set_lp(LoopNode* lp)   { _lp = lp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
                                     _iv = lp->as_CountedLoop()->phi()->as_Phi(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  int      iv_stride()             { return lp()->as_CountedLoop()->stride_con(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
13108
6d27f658925c 7177923: SIGBUS on sparc in compiled code for java.util.Calendar.clear()
kvn
parents: 13104
diff changeset
   267
  int vector_width(Node* n) {
6d27f658925c 7177923: SIGBUS on sparc in compiled code for java.util.Calendar.clear()
kvn
parents: 13104
diff changeset
   268
    BasicType bt = velt_basic_type(n);
6d27f658925c 7177923: SIGBUS on sparc in compiled code for java.util.Calendar.clear()
kvn
parents: 13104
diff changeset
   269
    return MIN2(ABS(iv_stride()), Matcher::max_vector_size(bt));
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 10255
diff changeset
   270
  }
13108
6d27f658925c 7177923: SIGBUS on sparc in compiled code for java.util.Calendar.clear()
kvn
parents: 13104
diff changeset
   271
  int vector_width_in_bytes(Node* n) {
6d27f658925c 7177923: SIGBUS on sparc in compiled code for java.util.Calendar.clear()
kvn
parents: 13104
diff changeset
   272
    BasicType bt = velt_basic_type(n);
6d27f658925c 7177923: SIGBUS on sparc in compiled code for java.util.Calendar.clear()
kvn
parents: 13104
diff changeset
   273
    return vector_width(n)*type2aelembytes(bt);
6d27f658925c 7177923: SIGBUS on sparc in compiled code for java.util.Calendar.clear()
kvn
parents: 13104
diff changeset
   274
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  MemNode* align_to_ref()            { return _align_to_ref; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
  void  set_align_to_ref(MemNode* m) { _align_to_ref = m; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  Node* ctrl(Node* n) const { return _phase->has_ctrl(n) ? _phase->get_ctrl(n) : n; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
  // block accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  bool in_bb(Node* n)      { return n != NULL && n->outcnt() > 0 && ctrl(n) == _bb; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  int  bb_idx(Node* n)     { assert(in_bb(n), "must be"); return _bb_idx.at(n->_idx); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  void set_bb_idx(Node* n, int i) { _bb_idx.at_put_grow(n->_idx, i); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  // visited set accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  void visited_clear()           { _visited.Clear(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  void visited_set(Node* n)      { return _visited.set(bb_idx(n)); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  int visited_test(Node* n)      { return _visited.test(bb_idx(n)); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
  int visited_test_set(Node* n)  { return _visited.test_set(bb_idx(n)); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  void post_visited_clear()      { _post_visited.Clear(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  void post_visited_set(Node* n) { return _post_visited.set(bb_idx(n)); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  int post_visited_test(Node* n) { return _post_visited.test(bb_idx(n)); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  // Ensure node_info contains element "i"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  void grow_node_info(int i) { if (i >= _node_info.length()) _node_info.at_put_grow(i, SWNodeInfo::initial); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  // memory alignment for a node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  int alignment(Node* n)                     { return _node_info.adr_at(bb_idx(n))->_alignment; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  void set_alignment(Node* n, int a)         { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_alignment = a; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  // Max expression (DAG) depth from beginning of the block for each node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
  int depth(Node* n)                         { return _node_info.adr_at(bb_idx(n))->_depth; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
  void set_depth(Node* n, int d)             { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_depth = d; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
  // vector element type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
  const Type* velt_type(Node* n)             { return _node_info.adr_at(bb_idx(n))->_velt_type; }
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 10255
diff changeset
   307
  BasicType velt_basic_type(Node* n)         { return velt_type(n)->array_element_basic_type(); }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  void set_velt_type(Node* n, const Type* t) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_velt_type = t; }
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 10255
diff changeset
   309
  bool same_velt_type(Node* n1, Node* n2);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  // my_pack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  Node_List* my_pack(Node* n)                { return !in_bb(n) ? NULL : _node_info.adr_at(bb_idx(n))->_my_pack; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
  void set_my_pack(Node* n, Node_List* p)    { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_my_pack = p; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  // methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
  // Extract the superword level parallelism
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  void SLP_extract();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  // Find the adjacent memory references and create pack pairs for them.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  void find_adjacent_refs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
  // Find a memory reference to align the loop induction variable to.
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 10255
diff changeset
   322
  MemNode* find_align_to_ref(Node_List &memops);
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 10255
diff changeset
   323
  // Calculate loop's iv adjustment for this memory ops.
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 10255
diff changeset
   324
  int get_iv_adjustment(MemNode* mem);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  // Can the preloop align the reference to position zero in the vector?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  bool ref_is_alignable(SWPointer& p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  // Construct dependency graph.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  void dependence_graph();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  // Return a memory slice (node list) in predecessor order starting at "start"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  void mem_slice_preds(Node* start, Node* stop, GrowableArray<Node*> &preds);
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1
diff changeset
   331
  // Can s1 and s2 be in a pack with s1 immediately preceding s2 and  s1 aligned at "align"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  bool stmts_can_pack(Node* s1, Node* s2, int align);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  // Does s exist in a pack at position pos?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  bool exists_at(Node* s, uint pos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  // Is s1 immediately before s2 in memory?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  bool are_adjacent_refs(Node* s1, Node* s2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  // Are s1 and s2 similar?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
  bool isomorphic(Node* s1, Node* s2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  // Is there no data path from s1 to s2 or s2 to s1?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  bool independent(Node* s1, Node* s2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  // Helper for independent
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  bool independent_path(Node* shallow, Node* deep, uint dp=0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  void set_alignment(Node* s1, Node* s2, int align);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  int data_size(Node* s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  // Extend packset by following use->def and def->use links from pack members.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  void extend_packlist();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  // Extend the packset by visiting operand definitions of nodes in pack p
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
  bool follow_use_defs(Node_List* p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  // Extend the packset by visiting uses of nodes in pack p
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
  bool follow_def_uses(Node_List* p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  // Estimate the savings from executing s1 and s2 as a pack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  int est_savings(Node* s1, Node* s2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  int adjacent_profit(Node* s1, Node* s2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  int pack_cost(int ct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  int unpack_cost(int ct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  // Combine packs A and B with A.last == B.first into A.first..,A.last,B.second,..B.last
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  void combine_packs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  // Construct the map from nodes to packs.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
  void construct_my_pack_map();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
  // Remove packs that are not implemented or not profitable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
  void filter_packs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
  // Adjust the memory graph for the packed operations
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  void schedule();
2334
742b05aeec42 6636138: UseSuperWord enabled failure
cfang
parents: 2131
diff changeset
   364
  // Remove "current" from its current position in the memory graph and insert
742b05aeec42 6636138: UseSuperWord enabled failure
cfang
parents: 2131
diff changeset
   365
  // it after the appropriate insert points (lip or uip);
742b05aeec42 6636138: UseSuperWord enabled failure
cfang
parents: 2131
diff changeset
   366
  void remove_and_insert(MemNode *current, MemNode *prev, MemNode *lip, Node *uip, Unique_Node_List &schd_before);
742b05aeec42 6636138: UseSuperWord enabled failure
cfang
parents: 2131
diff changeset
   367
  // Within a store pack, schedule stores together by moving out the sandwiched memory ops according
742b05aeec42 6636138: UseSuperWord enabled failure
cfang
parents: 2131
diff changeset
   368
  // to dependence info; and within a load pack, move loads down to the last executed load.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  void co_locate_pack(Node_List* p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
  // Convert packs into vector node operations
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
  void output();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
  // Create a vector operand for the nodes in pack p for operand: in(opd_idx)
10255
bab46e6f7661 7069452: Cleanup NodeFlags
kvn
parents: 7397
diff changeset
   373
  Node* vector_opd(Node_List* p, int opd_idx);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  // Can code be generated for pack p?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  bool implemented(Node_List* p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  // For pack p, are all operands and all uses (with in the block) vector?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  bool profitable(Node_List* p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
  // If a use of pack p is not a vector use, then replace the use with an extract operation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
  void insert_extracts(Node_List* p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
  // Is use->in(u_idx) a vector use?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
  bool is_vector_use(Node* use, int u_idx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  // Construct reverse postorder list of block members
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
  void construct_bb();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
  // Initialize per node info
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
  void initialize_bb();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  // Insert n into block after pos
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  void bb_insert_after(Node* n, int pos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  // Compute max depth for expressions from beginning of block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
  void compute_max_depth();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
  // Compute necessary vector element type for expressions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  void compute_vector_element_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  // Are s1 and s2 in a pack pair and ordered as s1,s2?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  bool in_packset(Node* s1, Node* s2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
  // Is s in pack p?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  Node_List* in_pack(Node* s, Node_List* p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  // Remove the pack at position pos in the packset
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  void remove_pack_at(int pos);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  // Return the node executed first in pack p.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  Node* executed_first(Node_List* p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  // Return the node executed last in pack p.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  Node* executed_last(Node_List* p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  // Alignment within a vector memory reference
13885
6b056026ecad 7199010: incorrect vector alignment
kvn
parents: 13108
diff changeset
   403
  int memory_alignment(MemNode* s, int iv_adjust);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  // (Start, end] half-open range defining which operands are vector
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
  void vector_opd_range(Node* n, uint* start, uint* end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
  // Smallest type containing range of values
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 10255
diff changeset
   407
  const Type* container_type(Node* n);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  // Adjust pre-loop limit so that in main loop, a load/store reference
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
  // to align_to_ref will be a position zero in the vector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  void align_initial_loop_index(MemNode* align_to_ref);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  // Find pre loop end from main loop.  Returns null if none.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
  CountedLoopEndNode* get_pre_loop_end(CountedLoopNode *cl);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
  // Is the use of d1 in u1 at the same operand position as d2 in u2?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  bool opnd_positions_match(Node* d1, Node* u1, Node* d2, Node* u2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
  void init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  // print methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  void print_packset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
  void print_pack(Node_List* p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  void print_bb();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
  void print_stmt(Node* s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  char* blank(uint depth);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
//------------------------------SWPointer---------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
// Information about an address for dependence checking and vector alignment
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
class SWPointer VALUE_OBJ_CLASS_SPEC {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
 protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
  MemNode*   _mem;     // My memory reference node
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  SuperWord* _slp;     // SuperWord class
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  Node* _base;         // NULL if unsafe nonheap reference
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  Node* _adr;          // address pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  jint  _scale;        // multipler for iv (in bytes), 0 if no loop iv
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  jint  _offset;       // constant offset (in bytes)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
  Node* _invar;        // invariant offset (in bytes), NULL if none
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
  bool  _negate_invar; // if true then use: (0 - _invar)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  PhaseIdealLoop* phase() { return _slp->phase(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
  IdealLoopTree*  lpt()   { return _slp->lpt(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
  PhiNode*        iv()    { return _slp->iv();  } // Induction var
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  bool invariant(Node* n) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
    Node *n_c = phase()->get_ctrl(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
    return !lpt()->is_member(phase()->get_loop(n_c));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  // Match: k*iv + offset
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
  bool scaled_iv_plus_offset(Node* n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  // Match: k*iv where k is a constant that's not zero
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
  bool scaled_iv(Node* n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
  // Match: offset is (k [+/- invariant])
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
  bool offset_plus_k(Node* n, bool negate = false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  enum CMP {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    Less          = 1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
    Greater       = 2,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
    Equal         = 4,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
    NotEqual      = (Less | Greater),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
    NotComparable = (Less | Greater | Equal)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
  SWPointer(MemNode* mem, SuperWord* slp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
  // Following is used to create a temporary object during
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  // the pattern match of an address expression.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
  SWPointer(SWPointer* p);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
  bool valid()  { return _adr != NULL; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  bool has_iv() { return _scale != 0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
  Node* base()            { return _base; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
  Node* adr()             { return _adr; }
13104
657b387034fb 7119644: Increase superword's vector size up to 256 bits
kvn
parents: 10255
diff changeset
   475
  MemNode* mem()          { return _mem; }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
  int   scale_in_bytes()  { return _scale; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
  Node* invar()           { return _invar; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  bool  negate_invar()    { return _negate_invar; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  int   offset_in_bytes() { return _offset; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
  int   memory_size()     { return _mem->memory_size(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
  // Comparable?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  int cmp(SWPointer& q) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
    if (valid() && q.valid() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
        (_adr == q._adr || _base == _adr && q._base == q._adr) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
        _scale == q._scale   &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
        _invar == q._invar   &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
        _negate_invar == q._negate_invar) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
      bool overlap = q._offset <   _offset +   memory_size() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
                       _offset < q._offset + q.memory_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
      return overlap ? Equal : (_offset < q._offset ? Less : Greater);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
      return NotComparable;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
  bool not_equal(SWPointer& q)    { return not_equal(cmp(q)); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
  bool equal(SWPointer& q)        { return equal(cmp(q)); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  bool comparable(SWPointer& q)   { return comparable(cmp(q)); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
  static bool not_equal(int cmp)  { return cmp <= NotEqual; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
  static bool equal(int cmp)      { return cmp == Equal; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
  static bool comparable(int cmp) { return cmp < NotComparable; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  void print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
//------------------------------OrderedPair---------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
// Ordered pair of Node*.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
class OrderedPair VALUE_OBJ_CLASS_SPEC {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
 protected:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  Node* _p1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  Node* _p2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  OrderedPair() : _p1(NULL), _p2(NULL) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  OrderedPair(Node* p1, Node* p2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
    if (p1->_idx < p2->_idx) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
      _p1 = p1; _p2 = p2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
      _p1 = p2; _p2 = p1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  bool operator==(const OrderedPair &rhs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
    return _p1 == rhs._p1 && _p2 == rhs._p2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  void print() { tty->print("  (%d, %d)", _p1->_idx, _p2->_idx); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  static const OrderedPair initial;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
};
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
   531
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
   532
#endif // SHARE_VM_OPTO_SUPERWORD_HPP