annotate src/share/vm/opto/superword.hpp @ 1145:e018e6884bd8

6631166: CMS: better heuristics when combatting fragmentation Summary: Autonomic per-worker free block cache sizing, tunable coalition policies, fixes to per-size block statistics, retuned gain and bandwidth of some feedback loop filters to allow quicker reactivity to abrupt changes in ambient demand, and other heuristics to reduce fragmentation of the CMS old gen. Also tightened some assertions, including those related to locking. Reviewed-by: jmasa
author ysr
date Wed, 23 Dec 2009 09:23:54 -0800
parents bd02caa94611
children c18cbe5936b8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
844
bd02caa94611 6862919: Update copyright year
xdono
parents: 667
diff changeset
2 * Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 */
a61af66fc99e Initial load
duke
parents:
diff changeset
23
a61af66fc99e Initial load
duke
parents:
diff changeset
24 //
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // S U P E R W O R D T R A N S F O R M
a61af66fc99e Initial load
duke
parents:
diff changeset
26 //
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // SuperWords are short, fixed length vectors.
a61af66fc99e Initial load
duke
parents:
diff changeset
28 //
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // Algorithm from:
a61af66fc99e Initial load
duke
parents:
diff changeset
30 //
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // Exploiting SuperWord Level Parallelism with
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // Multimedia Instruction Sets
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // by
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // Samuel Larsen and Saman Amarasighe
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // MIT Laboratory for Computer Science
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // date
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // May 2000
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // published in
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // ACM SIGPLAN Notices
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // Proceedings of ACM PLDI '00, Volume 35 Issue 5
a61af66fc99e Initial load
duke
parents:
diff changeset
41 //
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // Definition 3.1 A Pack is an n-tuple, <s1, ...,sn>, where
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // s1,...,sn are independent isomorphic statements in a basic
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // block.
a61af66fc99e Initial load
duke
parents:
diff changeset
45 //
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // Definition 3.2 A PackSet is a set of Packs.
a61af66fc99e Initial load
duke
parents:
diff changeset
47 //
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // Definition 3.3 A Pair is a Pack of size two, where the
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // first statement is considered the left element, and the
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // second statement is considered the right element.
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 class SWPointer;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 class OrderedPair;
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // ========================= Dependence Graph =====================
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 class DepMem;
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 //------------------------------DepEdge---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // An edge in the dependence graph. The edges incident to a dependence
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // node are threaded through _next_in for incoming edges and _next_out
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // for outgoing edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
63 class DepEdge : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
65 DepMem* _pred;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 DepMem* _succ;
a61af66fc99e Initial load
duke
parents:
diff changeset
67 DepEdge* _next_in; // list of in edges, null terminated
a61af66fc99e Initial load
duke
parents:
diff changeset
68 DepEdge* _next_out; // list of out edges, null terminated
a61af66fc99e Initial load
duke
parents:
diff changeset
69
a61af66fc99e Initial load
duke
parents:
diff changeset
70 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
71 DepEdge(DepMem* pred, DepMem* succ, DepEdge* next_in, DepEdge* next_out) :
a61af66fc99e Initial load
duke
parents:
diff changeset
72 _pred(pred), _succ(succ), _next_in(next_in), _next_out(next_out) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 DepEdge* next_in() { return _next_in; }
a61af66fc99e Initial load
duke
parents:
diff changeset
75 DepEdge* next_out() { return _next_out; }
a61af66fc99e Initial load
duke
parents:
diff changeset
76 DepMem* pred() { return _pred; }
a61af66fc99e Initial load
duke
parents:
diff changeset
77 DepMem* succ() { return _succ; }
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
80 };
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 //------------------------------DepMem---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // A node in the dependence graph. _in_head starts the threaded list of
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // incoming edges, and _out_head starts the list of outgoing edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
85 class DepMem : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
86 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
87 Node* _node; // Corresponding ideal node
a61af66fc99e Initial load
duke
parents:
diff changeset
88 DepEdge* _in_head; // Head of list of in edges, null terminated
a61af66fc99e Initial load
duke
parents:
diff changeset
89 DepEdge* _out_head; // Head of list of out edges, null terminated
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
92 DepMem(Node* node) : _node(node), _in_head(NULL), _out_head(NULL) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 Node* node() { return _node; }
a61af66fc99e Initial load
duke
parents:
diff changeset
95 DepEdge* in_head() { return _in_head; }
a61af66fc99e Initial load
duke
parents:
diff changeset
96 DepEdge* out_head() { return _out_head; }
a61af66fc99e Initial load
duke
parents:
diff changeset
97 void set_in_head(DepEdge* hd) { _in_head = hd; }
a61af66fc99e Initial load
duke
parents:
diff changeset
98 void set_out_head(DepEdge* hd) { _out_head = hd; }
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 int in_cnt(); // Incoming edge count
a61af66fc99e Initial load
duke
parents:
diff changeset
101 int out_cnt(); // Outgoing edge count
a61af66fc99e Initial load
duke
parents:
diff changeset
102
a61af66fc99e Initial load
duke
parents:
diff changeset
103 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
104 };
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 //------------------------------DepGraph---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
107 class DepGraph VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
109 Arena* _arena;
a61af66fc99e Initial load
duke
parents:
diff changeset
110 GrowableArray<DepMem*> _map;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 DepMem* _root;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 DepMem* _tail;
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
115 DepGraph(Arena* a) : _arena(a), _map(a, 8, 0, NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 _root = new (_arena) DepMem(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 _tail = new (_arena) DepMem(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
119
a61af66fc99e Initial load
duke
parents:
diff changeset
120 DepMem* root() { return _root; }
a61af66fc99e Initial load
duke
parents:
diff changeset
121 DepMem* tail() { return _tail; }
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // Return dependence node corresponding to an ideal node
a61af66fc99e Initial load
duke
parents:
diff changeset
124 DepMem* dep(Node* node) { return _map.at(node->_idx); }
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // Make a new dependence graph node for an ideal node.
a61af66fc99e Initial load
duke
parents:
diff changeset
127 DepMem* make_node(Node* node);
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // Make a new dependence graph edge dprec->dsucc
a61af66fc99e Initial load
duke
parents:
diff changeset
130 DepEdge* make_edge(DepMem* dpred, DepMem* dsucc);
a61af66fc99e Initial load
duke
parents:
diff changeset
131
a61af66fc99e Initial load
duke
parents:
diff changeset
132 DepEdge* make_edge(Node* pred, Node* succ) { return make_edge(dep(pred), dep(succ)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
133 DepEdge* make_edge(DepMem* pred, Node* succ) { return make_edge(pred, dep(succ)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
134 DepEdge* make_edge(Node* pred, DepMem* succ) { return make_edge(dep(pred), succ); }
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 void init() { _map.clear(); } // initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 void print(Node* n) { dep(n)->print(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
139 void print(DepMem* d) { d->print(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
140 };
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 //------------------------------DepPreds---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // Iterator over predecessors in the dependence graph and
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // non-memory-graph inputs of ideal nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
145 class DepPreds : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
146 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
147 Node* _n;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 int _next_idx, _end_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 DepEdge* _dep_next;
a61af66fc99e Initial load
duke
parents:
diff changeset
150 Node* _current;
a61af66fc99e Initial load
duke
parents:
diff changeset
151 bool _done;
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
154 DepPreds(Node* n, DepGraph& dg);
a61af66fc99e Initial load
duke
parents:
diff changeset
155 Node* current() { return _current; }
a61af66fc99e Initial load
duke
parents:
diff changeset
156 bool done() { return _done; }
a61af66fc99e Initial load
duke
parents:
diff changeset
157 void next();
a61af66fc99e Initial load
duke
parents:
diff changeset
158 };
a61af66fc99e Initial load
duke
parents:
diff changeset
159
a61af66fc99e Initial load
duke
parents:
diff changeset
160 //------------------------------DepSuccs---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // Iterator over successors in the dependence graph and
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // non-memory-graph outputs of ideal nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
163 class DepSuccs : public StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
165 Node* _n;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 int _next_idx, _end_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 DepEdge* _dep_next;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 Node* _current;
a61af66fc99e Initial load
duke
parents:
diff changeset
169 bool _done;
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
172 DepSuccs(Node* n, DepGraph& dg);
a61af66fc99e Initial load
duke
parents:
diff changeset
173 Node* current() { return _current; }
a61af66fc99e Initial load
duke
parents:
diff changeset
174 bool done() { return _done; }
a61af66fc99e Initial load
duke
parents:
diff changeset
175 void next();
a61af66fc99e Initial load
duke
parents:
diff changeset
176 };
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // ========================= SuperWord =====================
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // -----------------------------SWNodeInfo---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // Per node info needed by SuperWord
a61af66fc99e Initial load
duke
parents:
diff changeset
183 class SWNodeInfo VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
185 int _alignment; // memory alignment for a node
a61af66fc99e Initial load
duke
parents:
diff changeset
186 int _depth; // Max expression (DAG) depth from block start
a61af66fc99e Initial load
duke
parents:
diff changeset
187 const Type* _velt_type; // vector element type
a61af66fc99e Initial load
duke
parents:
diff changeset
188 Node_List* _my_pack; // pack containing this node
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 SWNodeInfo() : _alignment(-1), _depth(0), _velt_type(NULL), _my_pack(NULL) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
191 static const SWNodeInfo initial;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 };
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // -----------------------------SuperWord---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // Transforms scalar operations into packed (superword) operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
196 class SuperWord : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
198 PhaseIdealLoop* _phase;
a61af66fc99e Initial load
duke
parents:
diff changeset
199 Arena* _arena;
a61af66fc99e Initial load
duke
parents:
diff changeset
200 PhaseIterGVN &_igvn;
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 enum consts { top_align = -1, bottom_align = -666 };
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 GrowableArray<Node_List*> _packset; // Packs for the current block
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 GrowableArray<int> _bb_idx; // Map from Node _idx to index within block
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 GrowableArray<Node*> _block; // Nodes in current block
a61af66fc99e Initial load
duke
parents:
diff changeset
209 GrowableArray<Node*> _data_entry; // Nodes with all inputs from outside
a61af66fc99e Initial load
duke
parents:
diff changeset
210 GrowableArray<Node*> _mem_slice_head; // Memory slice head nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
211 GrowableArray<Node*> _mem_slice_tail; // Memory slice tail nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 GrowableArray<SWNodeInfo> _node_info; // Info needed per node
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 MemNode* _align_to_ref; // Memory reference that pre-loop will align to
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 GrowableArray<OrderedPair> _disjoint_ptrs; // runtime disambiguated pointer pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
218
a61af66fc99e Initial load
duke
parents:
diff changeset
219 DepGraph _dg; // Dependence graph
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 // Scratch pads
a61af66fc99e Initial load
duke
parents:
diff changeset
222 VectorSet _visited; // Visited set
a61af66fc99e Initial load
duke
parents:
diff changeset
223 VectorSet _post_visited; // Post-visited set
a61af66fc99e Initial load
duke
parents:
diff changeset
224 Node_Stack _n_idx_list; // List of (node,index) pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
225 GrowableArray<Node*> _nlist; // List of nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
226 GrowableArray<Node*> _stk; // Stack of nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
229 SuperWord(PhaseIdealLoop* phase);
a61af66fc99e Initial load
duke
parents:
diff changeset
230
a61af66fc99e Initial load
duke
parents:
diff changeset
231 void transform_loop(IdealLoopTree* lpt);
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 // Accessors for SWPointer
a61af66fc99e Initial load
duke
parents:
diff changeset
234 PhaseIdealLoop* phase() { return _phase; }
a61af66fc99e Initial load
duke
parents:
diff changeset
235 IdealLoopTree* lpt() { return _lpt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
236 PhiNode* iv() { return _iv; }
a61af66fc99e Initial load
duke
parents:
diff changeset
237
a61af66fc99e Initial load
duke
parents:
diff changeset
238 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
239 IdealLoopTree* _lpt; // Current loop tree node
a61af66fc99e Initial load
duke
parents:
diff changeset
240 LoopNode* _lp; // Current LoopNode
a61af66fc99e Initial load
duke
parents:
diff changeset
241 Node* _bb; // Current basic block
a61af66fc99e Initial load
duke
parents:
diff changeset
242 PhiNode* _iv; // Induction var
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
245 Arena* arena() { return _arena; }
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 Node* bb() { return _bb; }
a61af66fc99e Initial load
duke
parents:
diff changeset
248 void set_bb(Node* bb) { _bb = bb; }
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 void set_lpt(IdealLoopTree* lpt) { _lpt = lpt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 LoopNode* lp() { return _lp; }
a61af66fc99e Initial load
duke
parents:
diff changeset
253 void set_lp(LoopNode* lp) { _lp = lp;
a61af66fc99e Initial load
duke
parents:
diff changeset
254 _iv = lp->as_CountedLoop()->phi()->as_Phi(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
255 int iv_stride() { return lp()->as_CountedLoop()->stride_con(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 int vector_width_in_bytes() { return Matcher::vector_width_in_bytes(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
258
a61af66fc99e Initial load
duke
parents:
diff changeset
259 MemNode* align_to_ref() { return _align_to_ref; }
a61af66fc99e Initial load
duke
parents:
diff changeset
260 void set_align_to_ref(MemNode* m) { _align_to_ref = m; }
a61af66fc99e Initial load
duke
parents:
diff changeset
261
a61af66fc99e Initial load
duke
parents:
diff changeset
262 Node* ctrl(Node* n) const { return _phase->has_ctrl(n) ? _phase->get_ctrl(n) : n; }
a61af66fc99e Initial load
duke
parents:
diff changeset
263
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // block accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
265 bool in_bb(Node* n) { return n != NULL && n->outcnt() > 0 && ctrl(n) == _bb; }
a61af66fc99e Initial load
duke
parents:
diff changeset
266 int bb_idx(Node* n) { assert(in_bb(n), "must be"); return _bb_idx.at(n->_idx); }
a61af66fc99e Initial load
duke
parents:
diff changeset
267 void set_bb_idx(Node* n, int i) { _bb_idx.at_put_grow(n->_idx, i); }
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // visited set accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
270 void visited_clear() { _visited.Clear(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
271 void visited_set(Node* n) { return _visited.set(bb_idx(n)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
272 int visited_test(Node* n) { return _visited.test(bb_idx(n)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
273 int visited_test_set(Node* n) { return _visited.test_set(bb_idx(n)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
274 void post_visited_clear() { _post_visited.Clear(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
275 void post_visited_set(Node* n) { return _post_visited.set(bb_idx(n)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
276 int post_visited_test(Node* n) { return _post_visited.test(bb_idx(n)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // Ensure node_info contains element "i"
a61af66fc99e Initial load
duke
parents:
diff changeset
279 void grow_node_info(int i) { if (i >= _node_info.length()) _node_info.at_put_grow(i, SWNodeInfo::initial); }
a61af66fc99e Initial load
duke
parents:
diff changeset
280
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // memory alignment for a node
a61af66fc99e Initial load
duke
parents:
diff changeset
282 int alignment(Node* n) { return _node_info.adr_at(bb_idx(n))->_alignment; }
a61af66fc99e Initial load
duke
parents:
diff changeset
283 void set_alignment(Node* n, int a) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_alignment = a; }
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // Max expression (DAG) depth from beginning of the block for each node
a61af66fc99e Initial load
duke
parents:
diff changeset
286 int depth(Node* n) { return _node_info.adr_at(bb_idx(n))->_depth; }
a61af66fc99e Initial load
duke
parents:
diff changeset
287 void set_depth(Node* n, int d) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_depth = d; }
a61af66fc99e Initial load
duke
parents:
diff changeset
288
a61af66fc99e Initial load
duke
parents:
diff changeset
289 // vector element type
a61af66fc99e Initial load
duke
parents:
diff changeset
290 const Type* velt_type(Node* n) { return _node_info.adr_at(bb_idx(n))->_velt_type; }
a61af66fc99e Initial load
duke
parents:
diff changeset
291 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; }
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // my_pack
a61af66fc99e Initial load
duke
parents:
diff changeset
294 Node_List* my_pack(Node* n) { return !in_bb(n) ? NULL : _node_info.adr_at(bb_idx(n))->_my_pack; }
a61af66fc99e Initial load
duke
parents:
diff changeset
295 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; }
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // methods
a61af66fc99e Initial load
duke
parents:
diff changeset
298
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // Extract the superword level parallelism
a61af66fc99e Initial load
duke
parents:
diff changeset
300 void SLP_extract();
a61af66fc99e Initial load
duke
parents:
diff changeset
301 // Find the adjacent memory references and create pack pairs for them.
a61af66fc99e Initial load
duke
parents:
diff changeset
302 void find_adjacent_refs();
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // Find a memory reference to align the loop induction variable to.
a61af66fc99e Initial load
duke
parents:
diff changeset
304 void find_align_to_ref(Node_List &memops);
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // Can the preloop align the reference to position zero in the vector?
a61af66fc99e Initial load
duke
parents:
diff changeset
306 bool ref_is_alignable(SWPointer& p);
a61af66fc99e Initial load
duke
parents:
diff changeset
307 // Construct dependency graph.
a61af66fc99e Initial load
duke
parents:
diff changeset
308 void dependence_graph();
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // Return a memory slice (node list) in predecessor order starting at "start"
a61af66fc99e Initial load
duke
parents:
diff changeset
310 void mem_slice_preds(Node* start, Node* stop, GrowableArray<Node*> &preds);
605
98cb887364d3 6810672: Comment typos
twisti
parents: 0
diff changeset
311 // Can s1 and s2 be in a pack with s1 immediately preceding s2 and s1 aligned at "align"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
312 bool stmts_can_pack(Node* s1, Node* s2, int align);
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // Does s exist in a pack at position pos?
a61af66fc99e Initial load
duke
parents:
diff changeset
314 bool exists_at(Node* s, uint pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // Is s1 immediately before s2 in memory?
a61af66fc99e Initial load
duke
parents:
diff changeset
316 bool are_adjacent_refs(Node* s1, Node* s2);
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // Are s1 and s2 similar?
a61af66fc99e Initial load
duke
parents:
diff changeset
318 bool isomorphic(Node* s1, Node* s2);
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // Is there no data path from s1 to s2 or s2 to s1?
a61af66fc99e Initial load
duke
parents:
diff changeset
320 bool independent(Node* s1, Node* s2);
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // Helper for independent
a61af66fc99e Initial load
duke
parents:
diff changeset
322 bool independent_path(Node* shallow, Node* deep, uint dp=0);
a61af66fc99e Initial load
duke
parents:
diff changeset
323 void set_alignment(Node* s1, Node* s2, int align);
a61af66fc99e Initial load
duke
parents:
diff changeset
324 int data_size(Node* s);
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // Extend packset by following use->def and def->use links from pack members.
a61af66fc99e Initial load
duke
parents:
diff changeset
326 void extend_packlist();
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // Extend the packset by visiting operand definitions of nodes in pack p
a61af66fc99e Initial load
duke
parents:
diff changeset
328 bool follow_use_defs(Node_List* p);
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // Extend the packset by visiting uses of nodes in pack p
a61af66fc99e Initial load
duke
parents:
diff changeset
330 bool follow_def_uses(Node_List* p);
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // Estimate the savings from executing s1 and s2 as a pack
a61af66fc99e Initial load
duke
parents:
diff changeset
332 int est_savings(Node* s1, Node* s2);
a61af66fc99e Initial load
duke
parents:
diff changeset
333 int adjacent_profit(Node* s1, Node* s2);
a61af66fc99e Initial load
duke
parents:
diff changeset
334 int pack_cost(int ct);
a61af66fc99e Initial load
duke
parents:
diff changeset
335 int unpack_cost(int ct);
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // Combine packs A and B with A.last == B.first into A.first..,A.last,B.second,..B.last
a61af66fc99e Initial load
duke
parents:
diff changeset
337 void combine_packs();
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // Construct the map from nodes to packs.
a61af66fc99e Initial load
duke
parents:
diff changeset
339 void construct_my_pack_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // Remove packs that are not implemented or not profitable.
a61af66fc99e Initial load
duke
parents:
diff changeset
341 void filter_packs();
a61af66fc99e Initial load
duke
parents:
diff changeset
342 // Adjust the memory graph for the packed operations
a61af66fc99e Initial load
duke
parents:
diff changeset
343 void schedule();
667
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 605
diff changeset
344 // Remove "current" from its current position in the memory graph and insert
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 605
diff changeset
345 // it after the appropriate insert points (lip or uip);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 605
diff changeset
346 void remove_and_insert(MemNode *current, MemNode *prev, MemNode *lip, Node *uip, Unique_Node_List &schd_before);
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 605
diff changeset
347 // Within a store pack, schedule stores together by moving out the sandwiched memory ops according
78af5ae8e731 6636138: UseSuperWord enabled failure
cfang
parents: 605
diff changeset
348 // to dependence info; and within a load pack, move loads down to the last executed load.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
349 void co_locate_pack(Node_List* p);
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // Convert packs into vector node operations
a61af66fc99e Initial load
duke
parents:
diff changeset
351 void output();
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // Create a vector operand for the nodes in pack p for operand: in(opd_idx)
a61af66fc99e Initial load
duke
parents:
diff changeset
353 VectorNode* vector_opd(Node_List* p, int opd_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // Can code be generated for pack p?
a61af66fc99e Initial load
duke
parents:
diff changeset
355 bool implemented(Node_List* p);
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // For pack p, are all operands and all uses (with in the block) vector?
a61af66fc99e Initial load
duke
parents:
diff changeset
357 bool profitable(Node_List* p);
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // If a use of pack p is not a vector use, then replace the use with an extract operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
359 void insert_extracts(Node_List* p);
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // Is use->in(u_idx) a vector use?
a61af66fc99e Initial load
duke
parents:
diff changeset
361 bool is_vector_use(Node* use, int u_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // Construct reverse postorder list of block members
a61af66fc99e Initial load
duke
parents:
diff changeset
363 void construct_bb();
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // Initialize per node info
a61af66fc99e Initial load
duke
parents:
diff changeset
365 void initialize_bb();
a61af66fc99e Initial load
duke
parents:
diff changeset
366 // Insert n into block after pos
a61af66fc99e Initial load
duke
parents:
diff changeset
367 void bb_insert_after(Node* n, int pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // Compute max depth for expressions from beginning of block
a61af66fc99e Initial load
duke
parents:
diff changeset
369 void compute_max_depth();
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // Compute necessary vector element type for expressions
a61af66fc99e Initial load
duke
parents:
diff changeset
371 void compute_vector_element_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
372 // Are s1 and s2 in a pack pair and ordered as s1,s2?
a61af66fc99e Initial load
duke
parents:
diff changeset
373 bool in_packset(Node* s1, Node* s2);
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // Is s in pack p?
a61af66fc99e Initial load
duke
parents:
diff changeset
375 Node_List* in_pack(Node* s, Node_List* p);
a61af66fc99e Initial load
duke
parents:
diff changeset
376 // Remove the pack at position pos in the packset
a61af66fc99e Initial load
duke
parents:
diff changeset
377 void remove_pack_at(int pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // Return the node executed first in pack p.
a61af66fc99e Initial load
duke
parents:
diff changeset
379 Node* executed_first(Node_List* p);
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // Return the node executed last in pack p.
a61af66fc99e Initial load
duke
parents:
diff changeset
381 Node* executed_last(Node_List* p);
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // Alignment within a vector memory reference
a61af66fc99e Initial load
duke
parents:
diff changeset
383 int memory_alignment(MemNode* s, int iv_adjust_in_bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
384 // (Start, end] half-open range defining which operands are vector
a61af66fc99e Initial load
duke
parents:
diff changeset
385 void vector_opd_range(Node* n, uint* start, uint* end);
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // Smallest type containing range of values
a61af66fc99e Initial load
duke
parents:
diff changeset
387 static const Type* container_type(const Type* t);
a61af66fc99e Initial load
duke
parents:
diff changeset
388 // Adjust pre-loop limit so that in main loop, a load/store reference
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // to align_to_ref will be a position zero in the vector.
a61af66fc99e Initial load
duke
parents:
diff changeset
390 void align_initial_loop_index(MemNode* align_to_ref);
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // Find pre loop end from main loop. Returns null if none.
a61af66fc99e Initial load
duke
parents:
diff changeset
392 CountedLoopEndNode* get_pre_loop_end(CountedLoopNode *cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
393 // Is the use of d1 in u1 at the same operand position as d2 in u2?
a61af66fc99e Initial load
duke
parents:
diff changeset
394 bool opnd_positions_match(Node* d1, Node* u1, Node* d2, Node* u2);
a61af66fc99e Initial load
duke
parents:
diff changeset
395 void init();
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // print methods
a61af66fc99e Initial load
duke
parents:
diff changeset
398 void print_packset();
a61af66fc99e Initial load
duke
parents:
diff changeset
399 void print_pack(Node_List* p);
a61af66fc99e Initial load
duke
parents:
diff changeset
400 void print_bb();
a61af66fc99e Initial load
duke
parents:
diff changeset
401 void print_stmt(Node* s);
a61af66fc99e Initial load
duke
parents:
diff changeset
402 char* blank(uint depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
403 };
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 //------------------------------SWPointer---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
407 // Information about an address for dependence checking and vector alignment
a61af66fc99e Initial load
duke
parents:
diff changeset
408 class SWPointer VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
409 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
410 MemNode* _mem; // My memory reference node
a61af66fc99e Initial load
duke
parents:
diff changeset
411 SuperWord* _slp; // SuperWord class
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 Node* _base; // NULL if unsafe nonheap reference
a61af66fc99e Initial load
duke
parents:
diff changeset
414 Node* _adr; // address pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
415 jint _scale; // multipler for iv (in bytes), 0 if no loop iv
a61af66fc99e Initial load
duke
parents:
diff changeset
416 jint _offset; // constant offset (in bytes)
a61af66fc99e Initial load
duke
parents:
diff changeset
417 Node* _invar; // invariant offset (in bytes), NULL if none
a61af66fc99e Initial load
duke
parents:
diff changeset
418 bool _negate_invar; // if true then use: (0 - _invar)
a61af66fc99e Initial load
duke
parents:
diff changeset
419
a61af66fc99e Initial load
duke
parents:
diff changeset
420 PhaseIdealLoop* phase() { return _slp->phase(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
421 IdealLoopTree* lpt() { return _slp->lpt(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
422 PhiNode* iv() { return _slp->iv(); } // Induction var
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 bool invariant(Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
425 Node *n_c = phase()->get_ctrl(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
426 return !lpt()->is_member(phase()->get_loop(n_c));
a61af66fc99e Initial load
duke
parents:
diff changeset
427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
428
a61af66fc99e Initial load
duke
parents:
diff changeset
429 // Match: k*iv + offset
a61af66fc99e Initial load
duke
parents:
diff changeset
430 bool scaled_iv_plus_offset(Node* n);
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // Match: k*iv where k is a constant that's not zero
a61af66fc99e Initial load
duke
parents:
diff changeset
432 bool scaled_iv(Node* n);
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // Match: offset is (k [+/- invariant])
a61af66fc99e Initial load
duke
parents:
diff changeset
434 bool offset_plus_k(Node* n, bool negate = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
437 enum CMP {
a61af66fc99e Initial load
duke
parents:
diff changeset
438 Less = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
439 Greater = 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
440 Equal = 4,
a61af66fc99e Initial load
duke
parents:
diff changeset
441 NotEqual = (Less | Greater),
a61af66fc99e Initial load
duke
parents:
diff changeset
442 NotComparable = (Less | Greater | Equal)
a61af66fc99e Initial load
duke
parents:
diff changeset
443 };
a61af66fc99e Initial load
duke
parents:
diff changeset
444
a61af66fc99e Initial load
duke
parents:
diff changeset
445 SWPointer(MemNode* mem, SuperWord* slp);
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // Following is used to create a temporary object during
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // the pattern match of an address expression.
a61af66fc99e Initial load
duke
parents:
diff changeset
448 SWPointer(SWPointer* p);
a61af66fc99e Initial load
duke
parents:
diff changeset
449
a61af66fc99e Initial load
duke
parents:
diff changeset
450 bool valid() { return _adr != NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
451 bool has_iv() { return _scale != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
452
a61af66fc99e Initial load
duke
parents:
diff changeset
453 Node* base() { return _base; }
a61af66fc99e Initial load
duke
parents:
diff changeset
454 Node* adr() { return _adr; }
a61af66fc99e Initial load
duke
parents:
diff changeset
455 int scale_in_bytes() { return _scale; }
a61af66fc99e Initial load
duke
parents:
diff changeset
456 Node* invar() { return _invar; }
a61af66fc99e Initial load
duke
parents:
diff changeset
457 bool negate_invar() { return _negate_invar; }
a61af66fc99e Initial load
duke
parents:
diff changeset
458 int offset_in_bytes() { return _offset; }
a61af66fc99e Initial load
duke
parents:
diff changeset
459 int memory_size() { return _mem->memory_size(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // Comparable?
a61af66fc99e Initial load
duke
parents:
diff changeset
462 int cmp(SWPointer& q) {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 if (valid() && q.valid() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
464 (_adr == q._adr || _base == _adr && q._base == q._adr) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
465 _scale == q._scale &&
a61af66fc99e Initial load
duke
parents:
diff changeset
466 _invar == q._invar &&
a61af66fc99e Initial load
duke
parents:
diff changeset
467 _negate_invar == q._negate_invar) {
a61af66fc99e Initial load
duke
parents:
diff changeset
468 bool overlap = q._offset < _offset + memory_size() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
469 _offset < q._offset + q.memory_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
470 return overlap ? Equal : (_offset < q._offset ? Less : Greater);
a61af66fc99e Initial load
duke
parents:
diff changeset
471 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 return NotComparable;
a61af66fc99e Initial load
duke
parents:
diff changeset
473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
475
a61af66fc99e Initial load
duke
parents:
diff changeset
476 bool not_equal(SWPointer& q) { return not_equal(cmp(q)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
477 bool equal(SWPointer& q) { return equal(cmp(q)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
478 bool comparable(SWPointer& q) { return comparable(cmp(q)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
479 static bool not_equal(int cmp) { return cmp <= NotEqual; }
a61af66fc99e Initial load
duke
parents:
diff changeset
480 static bool equal(int cmp) { return cmp == Equal; }
a61af66fc99e Initial load
duke
parents:
diff changeset
481 static bool comparable(int cmp) { return cmp < NotComparable; }
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
484 };
a61af66fc99e Initial load
duke
parents:
diff changeset
485
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 //------------------------------OrderedPair---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
488 // Ordered pair of Node*.
a61af66fc99e Initial load
duke
parents:
diff changeset
489 class OrderedPair VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
490 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
491 Node* _p1;
a61af66fc99e Initial load
duke
parents:
diff changeset
492 Node* _p2;
a61af66fc99e Initial load
duke
parents:
diff changeset
493 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
494 OrderedPair() : _p1(NULL), _p2(NULL) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
495 OrderedPair(Node* p1, Node* p2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
496 if (p1->_idx < p2->_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 _p1 = p1; _p2 = p2;
a61af66fc99e Initial load
duke
parents:
diff changeset
498 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
499 _p1 = p2; _p2 = p1;
a61af66fc99e Initial load
duke
parents:
diff changeset
500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
502
a61af66fc99e Initial load
duke
parents:
diff changeset
503 bool operator==(const OrderedPair &rhs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
504 return _p1 == rhs._p1 && _p2 == rhs._p2;
a61af66fc99e Initial load
duke
parents:
diff changeset
505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
506 void print() { tty->print(" (%d, %d)", _p1->_idx, _p2->_idx); }
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508 static const OrderedPair initial;
a61af66fc99e Initial load
duke
parents:
diff changeset
509 };