annotate src/share/vm/opto/node.hpp @ 1941:79d04223b8a5

Added caching for resolved types and resolved fields. This is crucial, because the local load elimination will lead to wrong results, if field equality (of two RiField objects with the same object and the same RiType) is not given. The caching makes sure that the default equals implementation is sufficient.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Tue, 28 Dec 2010 18:33:26 +0100
parents c18cbe5936b8
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1100
diff changeset
2 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. 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 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1100
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1100
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1100
diff changeset
21 * questions.
0
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 // Portions of code courtesy of Clifford Click
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // Optimization - Graph Style
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29
a61af66fc99e Initial load
duke
parents:
diff changeset
30 class AbstractLockNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 class AddNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
32 class AddPNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
33 class AliasInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
34 class AllocateArrayNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
35 class AllocateNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
36 class Block;
a61af66fc99e Initial load
duke
parents:
diff changeset
37 class Block_Array;
a61af66fc99e Initial load
duke
parents:
diff changeset
38 class BoolNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 class BoxLockNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 class CMoveNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 class CallDynamicJavaNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
42 class CallJavaNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
43 class CallLeafNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
44 class CallNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 class CallRuntimeNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 class CallStaticJavaNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
47 class CatchNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 class CatchProjNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 class CheckCastPPNode;
1100
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
50 class ClearArrayNode;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
51 class CmpNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 class CodeBuffer;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 class ConstraintCastNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
54 class ConNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 class CountedLoopNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
56 class CountedLoopEndNode;
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 128
diff changeset
57 class DecodeNNode;
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 128
diff changeset
58 class EncodePNode;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
59 class FastLockNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
60 class FastUnlockNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
61 class IfNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
62 class InitializeNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
63 class JVMState;
a61af66fc99e Initial load
duke
parents:
diff changeset
64 class JumpNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
65 class JumpProjNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 class LoadNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
67 class LoadStoreNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
68 class LockNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 class LoopNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
70 class MachCallDynamicJavaNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 class MachCallJavaNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
72 class MachCallLeafNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
73 class MachCallNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 class MachCallRuntimeNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
75 class MachCallStaticJavaNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
76 class MachIfNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
77 class MachNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 class MachNullCheckNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
79 class MachReturnNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
80 class MachSafePointNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 class MachSpillCopyNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
82 class MachTempNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
83 class Matcher;
a61af66fc99e Initial load
duke
parents:
diff changeset
84 class MemBarNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 class MemNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
86 class MergeMemNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
87 class MulNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
88 class MultiNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
89 class MultiBranchNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
90 class NeverBranchNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
91 class Node;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 class Node_Array;
a61af66fc99e Initial load
duke
parents:
diff changeset
93 class Node_List;
a61af66fc99e Initial load
duke
parents:
diff changeset
94 class Node_Stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
95 class NullCheckNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
96 class OopMap;
33
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
97 class ParmNode;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
98 class PCTableNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 class PhaseCCP;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 class PhaseGVN;
a61af66fc99e Initial load
duke
parents:
diff changeset
101 class PhaseIterGVN;
a61af66fc99e Initial load
duke
parents:
diff changeset
102 class PhaseRegAlloc;
a61af66fc99e Initial load
duke
parents:
diff changeset
103 class PhaseTransform;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 class PhaseValues;
a61af66fc99e Initial load
duke
parents:
diff changeset
105 class PhiNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
106 class Pipeline;
a61af66fc99e Initial load
duke
parents:
diff changeset
107 class ProjNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
108 class RegMask;
a61af66fc99e Initial load
duke
parents:
diff changeset
109 class RegionNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
110 class RootNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 class SafePointNode;
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 40
diff changeset
112 class SafePointScalarObjectNode;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
113 class StartNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
114 class State;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 class StoreNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 class SubNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
117 class Type;
a61af66fc99e Initial load
duke
parents:
diff changeset
118 class TypeNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
119 class UnlockNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
120 class VectorSet;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 class IfTrueNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
122 class IfFalseNode;
a61af66fc99e Initial load
duke
parents:
diff changeset
123 typedef void (*NFunc)(Node&,void*);
a61af66fc99e Initial load
duke
parents:
diff changeset
124 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
125 typedef int (*C_sort_func_t)(const void *, const void *);
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // The type of all node counts and indexes.
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // It must hold at least 16 bits, but must also be fast to load and store.
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // This type, if less than 32 bits, could limit the number of possible nodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // (To make this type platform-specific, move to globalDefinitions_xxx.hpp.)
a61af66fc99e Initial load
duke
parents:
diff changeset
132 typedef unsigned int node_idx_t;
a61af66fc99e Initial load
duke
parents:
diff changeset
133
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 #ifndef OPTO_DU_ITERATOR_ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
136 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
137 #define OPTO_DU_ITERATOR_ASSERT 1
a61af66fc99e Initial load
duke
parents:
diff changeset
138 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
139 #define OPTO_DU_ITERATOR_ASSERT 0
a61af66fc99e Initial load
duke
parents:
diff changeset
140 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
141 #endif //OPTO_DU_ITERATOR_ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 #if OPTO_DU_ITERATOR_ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
144 class DUIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
145 class DUIterator_Fast;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 class DUIterator_Last;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
148 typedef uint DUIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 typedef Node** DUIterator_Fast;
a61af66fc99e Initial load
duke
parents:
diff changeset
150 typedef Node** DUIterator_Last;
a61af66fc99e Initial load
duke
parents:
diff changeset
151 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // Node Sentinel
a61af66fc99e Initial load
duke
parents:
diff changeset
154 #define NodeSentinel (Node*)-1
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // Unknown count frequency
a61af66fc99e Initial load
duke
parents:
diff changeset
157 #define COUNT_UNKNOWN (-1.0f)
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159 //------------------------------Node-------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // Nodes define actions in the program. They create values, which have types.
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // They are both vertices in a directed graph and program primitives. Nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // are labeled; the label is the "opcode", the primitive function in the lambda
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // calculus sense that gives meaning to the Node. Node inputs are ordered (so
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // that "a-b" is different from "b-a"). The inputs to a Node are the inputs to
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // the Node's function. These inputs also define a Type equation for the Node.
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // Solving these Type equations amounts to doing dataflow analysis.
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // Control and data are uniformly represented in the graph. Finally, Nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // have a unique dense integer index which is used to index into side arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // whenever I have phase-specific information.
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 class Node {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // Lots of restrictions on cloning Nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
173 Node(const Node&); // not defined; linker error to use these
a61af66fc99e Initial load
duke
parents:
diff changeset
174 Node &operator=(const Node &rhs);
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
177 friend class Compile;
a61af66fc99e Initial load
duke
parents:
diff changeset
178 #if OPTO_DU_ITERATOR_ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
179 friend class DUIterator_Common;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 friend class DUIterator;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 friend class DUIterator_Fast;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 friend class DUIterator_Last;
a61af66fc99e Initial load
duke
parents:
diff changeset
183 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // Because Nodes come and go, I define an Arena of Node structures to pull
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // from. This should allow fast access to node creation & deletion. This
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // field is a local cache of a value defined in some "program fragment" for
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // which these Nodes are just a part of.
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // New Operator that takes a Compile pointer, this will eventually
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // be the "new" New operator.
a61af66fc99e Initial load
duke
parents:
diff changeset
192 inline void* operator new( size_t x, Compile* C) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 Node* n = (Node*)C->node_arena()->Amalloc_D(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
195 n->_in = (Node**)n; // magic cookie for assertion check
a61af66fc99e Initial load
duke
parents:
diff changeset
196 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
197 n->_out = (Node**)C;
a61af66fc99e Initial load
duke
parents:
diff changeset
198 return (void*)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // New Operator that takes a Compile pointer, this will eventually
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // be the "new" New operator.
a61af66fc99e Initial load
duke
parents:
diff changeset
203 inline void* operator new( size_t x, Compile* C, int y) {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 Node* n = (Node*)C->node_arena()->Amalloc_D(x + y*sizeof(void*));
a61af66fc99e Initial load
duke
parents:
diff changeset
205 n->_in = (Node**)(((char*)n) + x);
a61af66fc99e Initial load
duke
parents:
diff changeset
206 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
207 n->_in[y-1] = n; // magic cookie for assertion check
a61af66fc99e Initial load
duke
parents:
diff changeset
208 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
209 n->_out = (Node**)C;
a61af66fc99e Initial load
duke
parents:
diff changeset
210 return (void*)n;
a61af66fc99e Initial load
duke
parents:
diff changeset
211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // Delete is a NOP
a61af66fc99e Initial load
duke
parents:
diff changeset
214 void operator delete( void *ptr ) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // Fancy destructor; eagerly attempt to reclaim Node numberings and storage
a61af66fc99e Initial load
duke
parents:
diff changeset
216 void destruct();
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // Create a new Node. Required is the number is of inputs required for
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // semantic correctness.
a61af66fc99e Initial load
duke
parents:
diff changeset
220 Node( uint required );
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // Create a new Node with given input edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
223 // This version requires use of the "edge-count" new.
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // E.g. new (C,3) FooNode( C, NULL, left, right );
a61af66fc99e Initial load
duke
parents:
diff changeset
225 Node( Node *n0 );
a61af66fc99e Initial load
duke
parents:
diff changeset
226 Node( Node *n0, Node *n1 );
a61af66fc99e Initial load
duke
parents:
diff changeset
227 Node( Node *n0, Node *n1, Node *n2 );
a61af66fc99e Initial load
duke
parents:
diff changeset
228 Node( Node *n0, Node *n1, Node *n2, Node *n3 );
a61af66fc99e Initial load
duke
parents:
diff changeset
229 Node( Node *n0, Node *n1, Node *n2, Node *n3, Node *n4 );
a61af66fc99e Initial load
duke
parents:
diff changeset
230 Node( Node *n0, Node *n1, Node *n2, Node *n3, Node *n4, Node *n5 );
a61af66fc99e Initial load
duke
parents:
diff changeset
231 Node( Node *n0, Node *n1, Node *n2, Node *n3,
a61af66fc99e Initial load
duke
parents:
diff changeset
232 Node *n4, Node *n5, Node *n6 );
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // Clone an inherited Node given only the base Node type.
a61af66fc99e Initial load
duke
parents:
diff changeset
235 Node* clone() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // Clone a Node, immediately supplying one or two new edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // The first and second arguments, if non-null, replace in(1) and in(2),
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // respectively.
a61af66fc99e Initial load
duke
parents:
diff changeset
240 Node* clone_with_data_edge(Node* in1, Node* in2 = NULL) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
241 Node* nn = clone();
a61af66fc99e Initial load
duke
parents:
diff changeset
242 if (in1 != NULL) nn->set_req(1, in1);
a61af66fc99e Initial load
duke
parents:
diff changeset
243 if (in2 != NULL) nn->set_req(2, in2);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 return nn;
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
248 // Shared setup for the above constructors.
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // Handles all interactions with Compile::current.
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // Puts initial values in all Node fields except _idx.
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // Returns the initial value for _idx, which cannot
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // be initialized by assignment.
a61af66fc99e Initial load
duke
parents:
diff changeset
253 inline int Init(int req, Compile* C);
a61af66fc99e Initial load
duke
parents:
diff changeset
254
a61af66fc99e Initial load
duke
parents:
diff changeset
255 //----------------- input edge handling
a61af66fc99e Initial load
duke
parents:
diff changeset
256 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
257 friend class PhaseCFG; // Access to address of _in array elements
a61af66fc99e Initial load
duke
parents:
diff changeset
258 Node **_in; // Array of use-def references to Nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
259 Node **_out; // Array of def-use references to Nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
260
605
98cb887364d3 6810672: Comment typos
twisti
parents: 400
diff changeset
261 // Input edges are split into two categories. Required edges are required
0
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // for semantic correctness; order is important and NULLs are allowed.
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // Precedence edges are used to help determine execution order and are
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // added, e.g., for scheduling purposes. They are unordered and not
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // duplicated; they have no embedded NULLs. Edges from 0 to _cnt-1
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // are required, from _cnt to _max-1 are precedence edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
267 node_idx_t _cnt; // Total number of required Node inputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269 node_idx_t _max; // Actual length of input array.
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // Output edges are an unordered list of def-use edges which exactly
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // correspond to required input edges which point from other nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
273 // to this one. Thus the count of the output edges is the number of
a61af66fc99e Initial load
duke
parents:
diff changeset
274 // users of this node.
a61af66fc99e Initial load
duke
parents:
diff changeset
275 node_idx_t _outcnt; // Total number of Node outputs.
a61af66fc99e Initial load
duke
parents:
diff changeset
276
a61af66fc99e Initial load
duke
parents:
diff changeset
277 node_idx_t _outmax; // Actual length of output array.
a61af66fc99e Initial load
duke
parents:
diff changeset
278
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // Grow the actual input array to the next larger power-of-2 bigger than len.
a61af66fc99e Initial load
duke
parents:
diff changeset
280 void grow( uint len );
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // Grow the output array to the next larger power-of-2 bigger than len.
a61af66fc99e Initial load
duke
parents:
diff changeset
282 void out_grow( uint len );
a61af66fc99e Initial load
duke
parents:
diff changeset
283
a61af66fc99e Initial load
duke
parents:
diff changeset
284 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // Each Node is assigned a unique small/dense number. This number is used
a61af66fc99e Initial load
duke
parents:
diff changeset
286 // to index into auxiliary arrays of data and bitvectors.
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // It is declared const to defend against inadvertant assignment,
a61af66fc99e Initial load
duke
parents:
diff changeset
288 // since it is used by clients as a naked field.
a61af66fc99e Initial load
duke
parents:
diff changeset
289 const node_idx_t _idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
290
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // Get the (read-only) number of input edges
a61af66fc99e Initial load
duke
parents:
diff changeset
292 uint req() const { return _cnt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
293 uint len() const { return _max; }
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // Get the (read-only) number of output edges
a61af66fc99e Initial load
duke
parents:
diff changeset
295 uint outcnt() const { return _outcnt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297 #if OPTO_DU_ITERATOR_ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // Iterate over the out-edges of this node. Deletions are illegal.
a61af66fc99e Initial load
duke
parents:
diff changeset
299 inline DUIterator outs() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // Use this when the out array might have changed to suppress asserts.
a61af66fc99e Initial load
duke
parents:
diff changeset
301 inline DUIterator& refresh_out_pos(DUIterator& i) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
302 // Does the node have an out at this position? (Used for iteration.)
a61af66fc99e Initial load
duke
parents:
diff changeset
303 inline bool has_out(DUIterator& i) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
304 inline Node* out(DUIterator& i) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // Iterate over the out-edges of this node. All changes are illegal.
a61af66fc99e Initial load
duke
parents:
diff changeset
306 inline DUIterator_Fast fast_outs(DUIterator_Fast& max) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
307 inline Node* fast_out(DUIterator_Fast& i) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // Iterate over the out-edges of this node, deleting one at a time.
a61af66fc99e Initial load
duke
parents:
diff changeset
309 inline DUIterator_Last last_outs(DUIterator_Last& min) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
310 inline Node* last_out(DUIterator_Last& i) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // The inline bodies of all these methods are after the iterator definitions.
a61af66fc99e Initial load
duke
parents:
diff changeset
312 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // Iterate over the out-edges of this node. Deletions are illegal.
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // This iteration uses integral indexes, to decouple from array reallocations.
a61af66fc99e Initial load
duke
parents:
diff changeset
315 DUIterator outs() const { return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
316 // Use this when the out array might have changed to suppress asserts.
a61af66fc99e Initial load
duke
parents:
diff changeset
317 DUIterator refresh_out_pos(DUIterator i) const { return i; }
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // Reference to the i'th output Node. Error if out of bounds.
a61af66fc99e Initial load
duke
parents:
diff changeset
320 Node* out(DUIterator i) const { assert(i < _outcnt, "oob"); return _out[i]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // Does the node have an out at this position? (Used for iteration.)
a61af66fc99e Initial load
duke
parents:
diff changeset
322 bool has_out(DUIterator i) const { return i < _outcnt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // Iterate over the out-edges of this node. All changes are illegal.
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // This iteration uses a pointer internal to the out array.
a61af66fc99e Initial load
duke
parents:
diff changeset
326 DUIterator_Fast fast_outs(DUIterator_Fast& max) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 Node** out = _out;
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // Assign a limit pointer to the reference argument:
a61af66fc99e Initial load
duke
parents:
diff changeset
329 max = out + (ptrdiff_t)_outcnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // Return the base pointer:
a61af66fc99e Initial load
duke
parents:
diff changeset
331 return out;
a61af66fc99e Initial load
duke
parents:
diff changeset
332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
333 Node* fast_out(DUIterator_Fast i) const { return *i; }
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // Iterate over the out-edges of this node, deleting one at a time.
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // This iteration uses a pointer internal to the out array.
a61af66fc99e Initial load
duke
parents:
diff changeset
336 DUIterator_Last last_outs(DUIterator_Last& min) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
337 Node** out = _out;
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // Assign a limit pointer to the reference argument:
a61af66fc99e Initial load
duke
parents:
diff changeset
339 min = out;
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // Return the pointer to the start of the iteration:
a61af66fc99e Initial load
duke
parents:
diff changeset
341 return out + (ptrdiff_t)_outcnt - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343 Node* last_out(DUIterator_Last i) const { return *i; }
a61af66fc99e Initial load
duke
parents:
diff changeset
344 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // Reference to the i'th input Node. Error if out of bounds.
a61af66fc99e Initial load
duke
parents:
diff changeset
347 Node* in(uint i) const { assert(i < _max,"oob"); return _in[i]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // Reference to the i'th output Node. Error if out of bounds.
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // Use this accessor sparingly. We are going trying to use iterators instead.
a61af66fc99e Initial load
duke
parents:
diff changeset
350 Node* raw_out(uint i) const { assert(i < _outcnt,"oob"); return _out[i]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
351 // Return the unique out edge.
a61af66fc99e Initial load
duke
parents:
diff changeset
352 Node* unique_out() const { assert(_outcnt==1,"not unique"); return _out[0]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // Delete out edge at position 'i' by moving last out edge to position 'i'
a61af66fc99e Initial load
duke
parents:
diff changeset
354 void raw_del_out(uint i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 assert(i < _outcnt,"oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
356 assert(_outcnt > 0,"oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
357 #if OPTO_DU_ITERATOR_ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // Record that a change happened here.
a61af66fc99e Initial load
duke
parents:
diff changeset
359 debug_only(_last_del = _out[i]; ++_del_tick);
a61af66fc99e Initial load
duke
parents:
diff changeset
360 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
361 _out[i] = _out[--_outcnt];
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // Smash the old edge so it can't be used accidentally.
a61af66fc99e Initial load
duke
parents:
diff changeset
363 debug_only(_out[_outcnt] = (Node *)(uintptr_t)0xdeadbeef);
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
367 bool is_dead() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
368 #define is_not_dead(n) ((n) == NULL || !VerifyIterativeGVN || !((n)->is_dead()))
a61af66fc99e Initial load
duke
parents:
diff changeset
369 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // Set a required input edge, also updates corresponding output edge
a61af66fc99e Initial load
duke
parents:
diff changeset
372 void add_req( Node *n ); // Append a NEW required input
a61af66fc99e Initial load
duke
parents:
diff changeset
373 void add_req_batch( Node* n, uint m ); // Append m NEW required inputs (all n).
a61af66fc99e Initial load
duke
parents:
diff changeset
374 void del_req( uint idx ); // Delete required edge & compact
a61af66fc99e Initial load
duke
parents:
diff changeset
375 void ins_req( uint i, Node *n ); // Insert a NEW required input
a61af66fc99e Initial load
duke
parents:
diff changeset
376 void set_req( uint i, Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
377 assert( is_not_dead(n), "can not use dead node");
a61af66fc99e Initial load
duke
parents:
diff changeset
378 assert( i < _cnt, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
379 assert( !VerifyHashTableKeys || _hash_lock == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
380 "remove node from hash table before modifying it");
a61af66fc99e Initial load
duke
parents:
diff changeset
381 Node** p = &_in[i]; // cache this._in, across the del_out call
a61af66fc99e Initial load
duke
parents:
diff changeset
382 if (*p != NULL) (*p)->del_out((Node *)this);
a61af66fc99e Initial load
duke
parents:
diff changeset
383 (*p) = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
384 if (n != NULL) n->add_out((Node *)this);
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // Light version of set_req() to init inputs after node creation.
a61af66fc99e Initial load
duke
parents:
diff changeset
387 void init_req( uint i, Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 assert( i == 0 && this == n ||
a61af66fc99e Initial load
duke
parents:
diff changeset
389 is_not_dead(n), "can not use dead node");
a61af66fc99e Initial load
duke
parents:
diff changeset
390 assert( i < _cnt, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
391 assert( !VerifyHashTableKeys || _hash_lock == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
392 "remove node from hash table before modifying it");
a61af66fc99e Initial load
duke
parents:
diff changeset
393 assert( _in[i] == NULL, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
394 _in[i] = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
395 if (n != NULL) n->add_out((Node *)this);
a61af66fc99e Initial load
duke
parents:
diff changeset
396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
397 // Find first occurrence of n among my edges:
a61af66fc99e Initial load
duke
parents:
diff changeset
398 int find_edge(Node* n);
a61af66fc99e Initial load
duke
parents:
diff changeset
399 int replace_edge(Node* old, Node* neww);
a61af66fc99e Initial load
duke
parents:
diff changeset
400 // NULL out all inputs to eliminate incoming Def-Use edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
401 // Return the number of edges between 'n' and 'this'
a61af66fc99e Initial load
duke
parents:
diff changeset
402 int disconnect_inputs(Node *n);
a61af66fc99e Initial load
duke
parents:
diff changeset
403
a61af66fc99e Initial load
duke
parents:
diff changeset
404 // Quickly, return true if and only if I am Compile::current()->top().
a61af66fc99e Initial load
duke
parents:
diff changeset
405 bool is_top() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
406 assert((this == (Node*) Compile::current()->top()) == (_out == NULL), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
407 return (_out == NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // Reaffirm invariants for is_top. (Only from Compile::set_cached_top_node.)
a61af66fc99e Initial load
duke
parents:
diff changeset
410 void setup_is_top();
a61af66fc99e Initial load
duke
parents:
diff changeset
411
a61af66fc99e Initial load
duke
parents:
diff changeset
412 // Strip away casting. (It is depth-limited.)
a61af66fc99e Initial load
duke
parents:
diff changeset
413 Node* uncast() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
414
a61af66fc99e Initial load
duke
parents:
diff changeset
415 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
416 static Node* uncast_helper(const Node* n);
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // Add an output edge to the end of the list
a61af66fc99e Initial load
duke
parents:
diff changeset
419 void add_out( Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
420 if (is_top()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
421 if( _outcnt == _outmax ) out_grow(_outcnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
422 _out[_outcnt++] = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
423 }
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // Delete an output edge
a61af66fc99e Initial load
duke
parents:
diff changeset
425 void del_out( Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
426 if (is_top()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
427 Node** outp = &_out[_outcnt];
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // Find and remove n
a61af66fc99e Initial load
duke
parents:
diff changeset
429 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
430 assert(outp > _out, "Missing Def-Use edge");
a61af66fc99e Initial load
duke
parents:
diff changeset
431 } while (*--outp != n);
a61af66fc99e Initial load
duke
parents:
diff changeset
432 *outp = _out[--_outcnt];
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // Smash the old edge so it can't be used accidentally.
a61af66fc99e Initial load
duke
parents:
diff changeset
434 debug_only(_out[_outcnt] = (Node *)(uintptr_t)0xdeadbeef);
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // Record that a change happened here.
a61af66fc99e Initial load
duke
parents:
diff changeset
436 #if OPTO_DU_ITERATOR_ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
437 debug_only(_last_del = n; ++_del_tick);
a61af66fc99e Initial load
duke
parents:
diff changeset
438 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
440
a61af66fc99e Initial load
duke
parents:
diff changeset
441 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // Globally replace this node by a given new node, updating all uses.
a61af66fc99e Initial load
duke
parents:
diff changeset
443 void replace_by(Node* new_node);
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 128
diff changeset
444 // Globally replace this node by a given new node, updating all uses
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 128
diff changeset
445 // and cutting input edges of old node.
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 128
diff changeset
446 void subsume_by(Node* new_node) {
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 128
diff changeset
447 replace_by(new_node);
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 128
diff changeset
448 disconnect_inputs(NULL);
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 128
diff changeset
449 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
450 void set_req_X( uint i, Node *n, PhaseIterGVN *igvn );
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // Find the one non-null required input. RegionNode only
a61af66fc99e Initial load
duke
parents:
diff changeset
452 Node *nonnull_req() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
453 // Add or remove precedence edges
a61af66fc99e Initial load
duke
parents:
diff changeset
454 void add_prec( Node *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
455 void rm_prec( uint i );
a61af66fc99e Initial load
duke
parents:
diff changeset
456 void set_prec( uint i, Node *n ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
457 assert( is_not_dead(n), "can not use dead node");
a61af66fc99e Initial load
duke
parents:
diff changeset
458 assert( i >= _cnt, "not a precedence edge");
a61af66fc99e Initial load
duke
parents:
diff changeset
459 if (_in[i] != NULL) _in[i]->del_out((Node *)this);
a61af66fc99e Initial load
duke
parents:
diff changeset
460 _in[i] = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
461 if (n != NULL) n->add_out((Node *)this);
a61af66fc99e Initial load
duke
parents:
diff changeset
462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // Set this node's index, used by cisc_version to replace current node
a61af66fc99e Initial load
duke
parents:
diff changeset
464 void set_idx(uint new_idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
465 const node_idx_t* ref = &_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
466 *(node_idx_t*)ref = new_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // Swap input edge order. (Edge indexes i1 and i2 are usually 1 and 2.)
a61af66fc99e Initial load
duke
parents:
diff changeset
469 void swap_edges(uint i1, uint i2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
470 debug_only(uint check_hash = (VerifyHashTableKeys && _hash_lock) ? hash() : NO_HASH);
a61af66fc99e Initial load
duke
parents:
diff changeset
471 // Def-Use info is unchanged
a61af66fc99e Initial load
duke
parents:
diff changeset
472 Node* n1 = in(i1);
a61af66fc99e Initial load
duke
parents:
diff changeset
473 Node* n2 = in(i2);
a61af66fc99e Initial load
duke
parents:
diff changeset
474 _in[i1] = n2;
a61af66fc99e Initial load
duke
parents:
diff changeset
475 _in[i2] = n1;
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // If this node is in the hash table, make sure it doesn't need a rehash.
a61af66fc99e Initial load
duke
parents:
diff changeset
477 assert(check_hash == NO_HASH || check_hash == hash(), "edge swap must preserve hash code");
a61af66fc99e Initial load
duke
parents:
diff changeset
478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // Iterators over input Nodes for a Node X are written as:
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // for( i = 0; i < X.req(); i++ ) ... X[i] ...
a61af66fc99e Initial load
duke
parents:
diff changeset
482 // NOTE: Required edges can contain embedded NULL pointers.
a61af66fc99e Initial load
duke
parents:
diff changeset
483
a61af66fc99e Initial load
duke
parents:
diff changeset
484 //----------------- Other Node Properties
a61af66fc99e Initial load
duke
parents:
diff changeset
485
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // Generate class id for some ideal nodes to avoid virtual query
a61af66fc99e Initial load
duke
parents:
diff changeset
487 // methods is_<Node>().
a61af66fc99e Initial load
duke
parents:
diff changeset
488 // Class id is the set of bits corresponded to the node class and all its
a61af66fc99e Initial load
duke
parents:
diff changeset
489 // super classes so that queries for super classes are also valid.
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // Subclasses of the same super class have different assigned bit
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // (the third parameter in the macro DEFINE_CLASS_ID).
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // Classes with deeper hierarchy are declared first.
a61af66fc99e Initial load
duke
parents:
diff changeset
493 // Classes with the same hierarchy depth are sorted by usage frequency.
a61af66fc99e Initial load
duke
parents:
diff changeset
494 //
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // The query method masks the bits to cut off bits of subclasses
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // and then compare the result with the class id
a61af66fc99e Initial load
duke
parents:
diff changeset
497 // (see the macro DEFINE_CLASS_QUERY below).
a61af66fc99e Initial load
duke
parents:
diff changeset
498 //
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // Class_MachCall=30, ClassMask_MachCall=31
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // 12 8 4 0
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // 0 0 0 0 0 0 0 0 1 1 1 1 0
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // | | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // | | | Bit_Mach=2
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // | | Bit_MachReturn=4
a61af66fc99e Initial load
duke
parents:
diff changeset
505 // | Bit_MachSafePoint=8
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // Bit_MachCall=16
a61af66fc99e Initial load
duke
parents:
diff changeset
507 //
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // Class_CountedLoop=56, ClassMask_CountedLoop=63
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // 12 8 4 0
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // 0 0 0 0 0 0 0 1 1 1 0 0 0
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // | | |
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // | | Bit_Region=8
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // | Bit_Loop=16
a61af66fc99e Initial load
duke
parents:
diff changeset
514 // Bit_CountedLoop=32
a61af66fc99e Initial load
duke
parents:
diff changeset
515
a61af66fc99e Initial load
duke
parents:
diff changeset
516 #define DEFINE_CLASS_ID(cl, supcl, subn) \
a61af66fc99e Initial load
duke
parents:
diff changeset
517 Bit_##cl = (Class_##supcl == 0) ? 1 << subn : (Bit_##supcl) << (1 + subn) , \
a61af66fc99e Initial load
duke
parents:
diff changeset
518 Class_##cl = Class_##supcl + Bit_##cl , \
a61af66fc99e Initial load
duke
parents:
diff changeset
519 ClassMask_##cl = ((Bit_##cl << 1) - 1) ,
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // This enum is used only for C2 ideal and mach nodes with is_<node>() methods
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // so that it's values fits into 16 bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
523 enum NodeClasses {
a61af66fc99e Initial load
duke
parents:
diff changeset
524 Bit_Node = 0x0000,
a61af66fc99e Initial load
duke
parents:
diff changeset
525 Class_Node = 0x0000,
a61af66fc99e Initial load
duke
parents:
diff changeset
526 ClassMask_Node = 0xFFFF,
a61af66fc99e Initial load
duke
parents:
diff changeset
527
a61af66fc99e Initial load
duke
parents:
diff changeset
528 DEFINE_CLASS_ID(Multi, Node, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
529 DEFINE_CLASS_ID(SafePoint, Multi, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
530 DEFINE_CLASS_ID(Call, SafePoint, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
531 DEFINE_CLASS_ID(CallJava, Call, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
532 DEFINE_CLASS_ID(CallStaticJava, CallJava, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
533 DEFINE_CLASS_ID(CallDynamicJava, CallJava, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
534 DEFINE_CLASS_ID(CallRuntime, Call, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
535 DEFINE_CLASS_ID(CallLeaf, CallRuntime, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
536 DEFINE_CLASS_ID(Allocate, Call, 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
537 DEFINE_CLASS_ID(AllocateArray, Allocate, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
538 DEFINE_CLASS_ID(AbstractLock, Call, 3)
a61af66fc99e Initial load
duke
parents:
diff changeset
539 DEFINE_CLASS_ID(Lock, AbstractLock, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
540 DEFINE_CLASS_ID(Unlock, AbstractLock, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
541 DEFINE_CLASS_ID(MultiBranch, Multi, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
542 DEFINE_CLASS_ID(PCTable, MultiBranch, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
543 DEFINE_CLASS_ID(Catch, PCTable, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
544 DEFINE_CLASS_ID(Jump, PCTable, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
545 DEFINE_CLASS_ID(If, MultiBranch, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
546 DEFINE_CLASS_ID(CountedLoopEnd, If, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
547 DEFINE_CLASS_ID(NeverBranch, MultiBranch, 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
548 DEFINE_CLASS_ID(Start, Multi, 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
549 DEFINE_CLASS_ID(MemBar, Multi, 3)
a61af66fc99e Initial load
duke
parents:
diff changeset
550 DEFINE_CLASS_ID(Initialize, MemBar, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
551
a61af66fc99e Initial load
duke
parents:
diff changeset
552 DEFINE_CLASS_ID(Mach, Node, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
553 DEFINE_CLASS_ID(MachReturn, Mach, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
554 DEFINE_CLASS_ID(MachSafePoint, MachReturn, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
555 DEFINE_CLASS_ID(MachCall, MachSafePoint, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
556 DEFINE_CLASS_ID(MachCallJava, MachCall, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
557 DEFINE_CLASS_ID(MachCallStaticJava, MachCallJava, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
558 DEFINE_CLASS_ID(MachCallDynamicJava, MachCallJava, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
559 DEFINE_CLASS_ID(MachCallRuntime, MachCall, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
560 DEFINE_CLASS_ID(MachCallLeaf, MachCallRuntime, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
561 DEFINE_CLASS_ID(MachSpillCopy, Mach, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
562 DEFINE_CLASS_ID(MachNullCheck, Mach, 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
563 DEFINE_CLASS_ID(MachIf, Mach, 3)
a61af66fc99e Initial load
duke
parents:
diff changeset
564 DEFINE_CLASS_ID(MachTemp, Mach, 4)
a61af66fc99e Initial load
duke
parents:
diff changeset
565
a61af66fc99e Initial load
duke
parents:
diff changeset
566 DEFINE_CLASS_ID(Proj, Node, 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
567 DEFINE_CLASS_ID(CatchProj, Proj, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
568 DEFINE_CLASS_ID(JumpProj, Proj, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
569 DEFINE_CLASS_ID(IfTrue, Proj, 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
570 DEFINE_CLASS_ID(IfFalse, Proj, 3)
33
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
571 DEFINE_CLASS_ID(Parm, Proj, 4)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
572
a61af66fc99e Initial load
duke
parents:
diff changeset
573 DEFINE_CLASS_ID(Region, Node, 3)
a61af66fc99e Initial load
duke
parents:
diff changeset
574 DEFINE_CLASS_ID(Loop, Region, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
575 DEFINE_CLASS_ID(Root, Loop, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
576 DEFINE_CLASS_ID(CountedLoop, Loop, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
577
a61af66fc99e Initial load
duke
parents:
diff changeset
578 DEFINE_CLASS_ID(Sub, Node, 4)
a61af66fc99e Initial load
duke
parents:
diff changeset
579 DEFINE_CLASS_ID(Cmp, Sub, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
580 DEFINE_CLASS_ID(FastLock, Cmp, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
581 DEFINE_CLASS_ID(FastUnlock, Cmp, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
582
a61af66fc99e Initial load
duke
parents:
diff changeset
583 DEFINE_CLASS_ID(Type, Node, 5)
a61af66fc99e Initial load
duke
parents:
diff changeset
584 DEFINE_CLASS_ID(Phi, Type, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
585 DEFINE_CLASS_ID(ConstraintCast, Type, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
586 DEFINE_CLASS_ID(CheckCastPP, Type, 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
587 DEFINE_CLASS_ID(CMove, Type, 3)
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 40
diff changeset
588 DEFINE_CLASS_ID(SafePointScalarObject, Type, 4)
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 128
diff changeset
589 DEFINE_CLASS_ID(DecodeN, Type, 5)
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 128
diff changeset
590 DEFINE_CLASS_ID(EncodeP, Type, 6)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
591
a61af66fc99e Initial load
duke
parents:
diff changeset
592 DEFINE_CLASS_ID(Mem, Node, 6)
a61af66fc99e Initial load
duke
parents:
diff changeset
593 DEFINE_CLASS_ID(Load, Mem, 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
594 DEFINE_CLASS_ID(Store, Mem, 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
595 DEFINE_CLASS_ID(LoadStore, Mem, 2)
a61af66fc99e Initial load
duke
parents:
diff changeset
596
a61af66fc99e Initial load
duke
parents:
diff changeset
597 DEFINE_CLASS_ID(MergeMem, Node, 7)
a61af66fc99e Initial load
duke
parents:
diff changeset
598 DEFINE_CLASS_ID(Bool, Node, 8)
a61af66fc99e Initial load
duke
parents:
diff changeset
599 DEFINE_CLASS_ID(AddP, Node, 9)
a61af66fc99e Initial load
duke
parents:
diff changeset
600 DEFINE_CLASS_ID(BoxLock, Node, 10)
a61af66fc99e Initial load
duke
parents:
diff changeset
601 DEFINE_CLASS_ID(Add, Node, 11)
a61af66fc99e Initial load
duke
parents:
diff changeset
602 DEFINE_CLASS_ID(Mul, Node, 12)
1100
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
603 DEFINE_CLASS_ID(ClearArray, Node, 13)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
604
1100
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
605 _max_classes = ClassMask_ClearArray
0
a61af66fc99e Initial load
duke
parents:
diff changeset
606 };
a61af66fc99e Initial load
duke
parents:
diff changeset
607 #undef DEFINE_CLASS_ID
a61af66fc99e Initial load
duke
parents:
diff changeset
608
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // Flags are sorted by usage frequency.
a61af66fc99e Initial load
duke
parents:
diff changeset
610 enum NodeFlags {
a61af66fc99e Initial load
duke
parents:
diff changeset
611 Flag_is_Copy = 0x01, // should be first bit to avoid shift
a61af66fc99e Initial load
duke
parents:
diff changeset
612 Flag_is_Call = Flag_is_Copy << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
613 Flag_rematerialize = Flag_is_Call << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
614 Flag_needs_anti_dependence_check = Flag_rematerialize << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
615 Flag_is_macro = Flag_needs_anti_dependence_check << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
616 Flag_is_Con = Flag_is_macro << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
617 Flag_is_cisc_alternate = Flag_is_Con << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
618 Flag_is_Branch = Flag_is_cisc_alternate << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
619 Flag_is_block_start = Flag_is_Branch << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
620 Flag_is_Goto = Flag_is_block_start << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
621 Flag_is_dead_loop_safe = Flag_is_Goto << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
622 Flag_may_be_short_branch = Flag_is_dead_loop_safe << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
623 Flag_is_safepoint_node = Flag_may_be_short_branch << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
624 Flag_is_pc_relative = Flag_is_safepoint_node << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
625 Flag_is_Vector = Flag_is_pc_relative << 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
626 _max_flags = (Flag_is_Vector << 1) - 1 // allow flags combination
a61af66fc99e Initial load
duke
parents:
diff changeset
627 };
a61af66fc99e Initial load
duke
parents:
diff changeset
628
a61af66fc99e Initial load
duke
parents:
diff changeset
629 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
630 jushort _class_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
631 jushort _flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
632
a61af66fc99e Initial load
duke
parents:
diff changeset
633 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // These methods should be called from constructors only.
a61af66fc99e Initial load
duke
parents:
diff changeset
635 void init_class_id(jushort c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
636 assert(c <= _max_classes, "invalid node class");
a61af66fc99e Initial load
duke
parents:
diff changeset
637 _class_id = c; // cast out const
a61af66fc99e Initial load
duke
parents:
diff changeset
638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
639 void init_flags(jushort fl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
640 assert(fl <= _max_flags, "invalid node flag");
a61af66fc99e Initial load
duke
parents:
diff changeset
641 _flags |= fl;
a61af66fc99e Initial load
duke
parents:
diff changeset
642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
643 void clear_flag(jushort fl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
644 assert(fl <= _max_flags, "invalid node flag");
a61af66fc99e Initial load
duke
parents:
diff changeset
645 _flags &= ~fl;
a61af66fc99e Initial load
duke
parents:
diff changeset
646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
649 const jushort class_id() const { return _class_id; }
a61af66fc99e Initial load
duke
parents:
diff changeset
650
a61af66fc99e Initial load
duke
parents:
diff changeset
651 const jushort flags() const { return _flags; }
a61af66fc99e Initial load
duke
parents:
diff changeset
652
a61af66fc99e Initial load
duke
parents:
diff changeset
653 // Return a dense integer opcode number
a61af66fc99e Initial load
duke
parents:
diff changeset
654 virtual int Opcode() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
655
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // Virtual inherited Node size
a61af66fc99e Initial load
duke
parents:
diff changeset
657 virtual uint size_of() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
658
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // Other interesting Node properties
a61af66fc99e Initial load
duke
parents:
diff changeset
660
a61af66fc99e Initial load
duke
parents:
diff changeset
661 // Special case: is_Call() returns true for both CallNode and MachCallNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
662 bool is_Call() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
663 return (_flags & Flag_is_Call) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
665
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
666 CallNode* isa_Call() const {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
667 return is_Call() ? as_Call() : NULL;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
668 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
669
0
a61af66fc99e Initial load
duke
parents:
diff changeset
670 CallNode *as_Call() const { // Only for CallNode (not for MachCallNode)
a61af66fc99e Initial load
duke
parents:
diff changeset
671 assert((_class_id & ClassMask_Call) == Class_Call, "invalid node class");
a61af66fc99e Initial load
duke
parents:
diff changeset
672 return (CallNode*)this;
a61af66fc99e Initial load
duke
parents:
diff changeset
673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
674
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
675 #define DEFINE_CLASS_QUERY(type) \
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
676 bool is_##type() const { \
0
a61af66fc99e Initial load
duke
parents:
diff changeset
677 return ((_class_id & ClassMask_##type) == Class_##type); \
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
678 } \
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
679 type##Node *as_##type() const { \
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
680 assert(is_##type(), "invalid node class"); \
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
681 return (type##Node*)this; \
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
682 } \
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
683 type##Node* isa_##type() const { \
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
684 return (is_##type()) ? as_##type() : NULL; \
0
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686
a61af66fc99e Initial load
duke
parents:
diff changeset
687 DEFINE_CLASS_QUERY(AbstractLock)
a61af66fc99e Initial load
duke
parents:
diff changeset
688 DEFINE_CLASS_QUERY(Add)
a61af66fc99e Initial load
duke
parents:
diff changeset
689 DEFINE_CLASS_QUERY(AddP)
a61af66fc99e Initial load
duke
parents:
diff changeset
690 DEFINE_CLASS_QUERY(Allocate)
a61af66fc99e Initial load
duke
parents:
diff changeset
691 DEFINE_CLASS_QUERY(AllocateArray)
a61af66fc99e Initial load
duke
parents:
diff changeset
692 DEFINE_CLASS_QUERY(Bool)
a61af66fc99e Initial load
duke
parents:
diff changeset
693 DEFINE_CLASS_QUERY(BoxLock)
a61af66fc99e Initial load
duke
parents:
diff changeset
694 DEFINE_CLASS_QUERY(CallDynamicJava)
a61af66fc99e Initial load
duke
parents:
diff changeset
695 DEFINE_CLASS_QUERY(CallJava)
a61af66fc99e Initial load
duke
parents:
diff changeset
696 DEFINE_CLASS_QUERY(CallLeaf)
a61af66fc99e Initial load
duke
parents:
diff changeset
697 DEFINE_CLASS_QUERY(CallRuntime)
a61af66fc99e Initial load
duke
parents:
diff changeset
698 DEFINE_CLASS_QUERY(CallStaticJava)
a61af66fc99e Initial load
duke
parents:
diff changeset
699 DEFINE_CLASS_QUERY(Catch)
a61af66fc99e Initial load
duke
parents:
diff changeset
700 DEFINE_CLASS_QUERY(CatchProj)
a61af66fc99e Initial load
duke
parents:
diff changeset
701 DEFINE_CLASS_QUERY(CheckCastPP)
a61af66fc99e Initial load
duke
parents:
diff changeset
702 DEFINE_CLASS_QUERY(ConstraintCast)
1100
f96a1a986f7b 6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents: 1080
diff changeset
703 DEFINE_CLASS_QUERY(ClearArray)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
704 DEFINE_CLASS_QUERY(CMove)
a61af66fc99e Initial load
duke
parents:
diff changeset
705 DEFINE_CLASS_QUERY(Cmp)
a61af66fc99e Initial load
duke
parents:
diff changeset
706 DEFINE_CLASS_QUERY(CountedLoop)
a61af66fc99e Initial load
duke
parents:
diff changeset
707 DEFINE_CLASS_QUERY(CountedLoopEnd)
168
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 128
diff changeset
708 DEFINE_CLASS_QUERY(DecodeN)
7793bd37a336 6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents: 128
diff changeset
709 DEFINE_CLASS_QUERY(EncodeP)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
710 DEFINE_CLASS_QUERY(FastLock)
a61af66fc99e Initial load
duke
parents:
diff changeset
711 DEFINE_CLASS_QUERY(FastUnlock)
a61af66fc99e Initial load
duke
parents:
diff changeset
712 DEFINE_CLASS_QUERY(If)
a61af66fc99e Initial load
duke
parents:
diff changeset
713 DEFINE_CLASS_QUERY(IfFalse)
a61af66fc99e Initial load
duke
parents:
diff changeset
714 DEFINE_CLASS_QUERY(IfTrue)
a61af66fc99e Initial load
duke
parents:
diff changeset
715 DEFINE_CLASS_QUERY(Initialize)
a61af66fc99e Initial load
duke
parents:
diff changeset
716 DEFINE_CLASS_QUERY(Jump)
a61af66fc99e Initial load
duke
parents:
diff changeset
717 DEFINE_CLASS_QUERY(JumpProj)
a61af66fc99e Initial load
duke
parents:
diff changeset
718 DEFINE_CLASS_QUERY(Load)
a61af66fc99e Initial load
duke
parents:
diff changeset
719 DEFINE_CLASS_QUERY(LoadStore)
a61af66fc99e Initial load
duke
parents:
diff changeset
720 DEFINE_CLASS_QUERY(Lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
721 DEFINE_CLASS_QUERY(Loop)
a61af66fc99e Initial load
duke
parents:
diff changeset
722 DEFINE_CLASS_QUERY(Mach)
a61af66fc99e Initial load
duke
parents:
diff changeset
723 DEFINE_CLASS_QUERY(MachCall)
a61af66fc99e Initial load
duke
parents:
diff changeset
724 DEFINE_CLASS_QUERY(MachCallDynamicJava)
a61af66fc99e Initial load
duke
parents:
diff changeset
725 DEFINE_CLASS_QUERY(MachCallJava)
a61af66fc99e Initial load
duke
parents:
diff changeset
726 DEFINE_CLASS_QUERY(MachCallLeaf)
a61af66fc99e Initial load
duke
parents:
diff changeset
727 DEFINE_CLASS_QUERY(MachCallRuntime)
a61af66fc99e Initial load
duke
parents:
diff changeset
728 DEFINE_CLASS_QUERY(MachCallStaticJava)
a61af66fc99e Initial load
duke
parents:
diff changeset
729 DEFINE_CLASS_QUERY(MachIf)
a61af66fc99e Initial load
duke
parents:
diff changeset
730 DEFINE_CLASS_QUERY(MachNullCheck)
a61af66fc99e Initial load
duke
parents:
diff changeset
731 DEFINE_CLASS_QUERY(MachReturn)
a61af66fc99e Initial load
duke
parents:
diff changeset
732 DEFINE_CLASS_QUERY(MachSafePoint)
a61af66fc99e Initial load
duke
parents:
diff changeset
733 DEFINE_CLASS_QUERY(MachSpillCopy)
a61af66fc99e Initial load
duke
parents:
diff changeset
734 DEFINE_CLASS_QUERY(MachTemp)
a61af66fc99e Initial load
duke
parents:
diff changeset
735 DEFINE_CLASS_QUERY(Mem)
a61af66fc99e Initial load
duke
parents:
diff changeset
736 DEFINE_CLASS_QUERY(MemBar)
a61af66fc99e Initial load
duke
parents:
diff changeset
737 DEFINE_CLASS_QUERY(MergeMem)
a61af66fc99e Initial load
duke
parents:
diff changeset
738 DEFINE_CLASS_QUERY(Mul)
a61af66fc99e Initial load
duke
parents:
diff changeset
739 DEFINE_CLASS_QUERY(Multi)
a61af66fc99e Initial load
duke
parents:
diff changeset
740 DEFINE_CLASS_QUERY(MultiBranch)
33
3288958bf319 6667580: Optimize CmpP for allocations
kvn
parents: 0
diff changeset
741 DEFINE_CLASS_QUERY(Parm)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
742 DEFINE_CLASS_QUERY(PCTable)
a61af66fc99e Initial load
duke
parents:
diff changeset
743 DEFINE_CLASS_QUERY(Phi)
a61af66fc99e Initial load
duke
parents:
diff changeset
744 DEFINE_CLASS_QUERY(Proj)
a61af66fc99e Initial load
duke
parents:
diff changeset
745 DEFINE_CLASS_QUERY(Region)
a61af66fc99e Initial load
duke
parents:
diff changeset
746 DEFINE_CLASS_QUERY(Root)
a61af66fc99e Initial load
duke
parents:
diff changeset
747 DEFINE_CLASS_QUERY(SafePoint)
63
eac007780a58 6671807: (Escape Analysis) Add new ideal node to represent the state of a scalarized object at a safepoint
kvn
parents: 40
diff changeset
748 DEFINE_CLASS_QUERY(SafePointScalarObject)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
749 DEFINE_CLASS_QUERY(Start)
a61af66fc99e Initial load
duke
parents:
diff changeset
750 DEFINE_CLASS_QUERY(Store)
a61af66fc99e Initial load
duke
parents:
diff changeset
751 DEFINE_CLASS_QUERY(Sub)
a61af66fc99e Initial load
duke
parents:
diff changeset
752 DEFINE_CLASS_QUERY(Type)
a61af66fc99e Initial load
duke
parents:
diff changeset
753 DEFINE_CLASS_QUERY(Unlock)
a61af66fc99e Initial load
duke
parents:
diff changeset
754
a61af66fc99e Initial load
duke
parents:
diff changeset
755 #undef DEFINE_CLASS_QUERY
a61af66fc99e Initial load
duke
parents:
diff changeset
756
a61af66fc99e Initial load
duke
parents:
diff changeset
757 // duplicate of is_MachSpillCopy()
a61af66fc99e Initial load
duke
parents:
diff changeset
758 bool is_SpillCopy () const {
a61af66fc99e Initial load
duke
parents:
diff changeset
759 return ((_class_id & ClassMask_MachSpillCopy) == Class_MachSpillCopy);
a61af66fc99e Initial load
duke
parents:
diff changeset
760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
761
a61af66fc99e Initial load
duke
parents:
diff changeset
762 bool is_Con () const { return (_flags & Flag_is_Con) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
763 bool is_Goto() const { return (_flags & Flag_is_Goto) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
764 // The data node which is safe to leave in dead loop during IGVN optimization.
a61af66fc99e Initial load
duke
parents:
diff changeset
765 bool is_dead_loop_safe() const {
126
72f4a668df19 6625997: CastPP, CheckCastPP and Proj nodes are not dead loop safe
kvn
parents: 119
diff changeset
766 return is_Phi() || (is_Proj() && in(0) == NULL) ||
72f4a668df19 6625997: CastPP, CheckCastPP and Proj nodes are not dead loop safe
kvn
parents: 119
diff changeset
767 ((_flags & (Flag_is_dead_loop_safe | Flag_is_Con)) != 0 &&
72f4a668df19 6625997: CastPP, CheckCastPP and Proj nodes are not dead loop safe
kvn
parents: 119
diff changeset
768 (!is_Proj() || !in(0)->is_Allocate()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // is_Copy() returns copied edge index (0 or 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
772 uint is_Copy() const { return (_flags & Flag_is_Copy); }
a61af66fc99e Initial load
duke
parents:
diff changeset
773
a61af66fc99e Initial load
duke
parents:
diff changeset
774 virtual bool is_CFG() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
775
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // If this node is control-dependent on a test, can it be
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // rerouted to a dominating equivalent test? This is usually
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // true of non-CFG nodes, but can be false for operations which
a61af66fc99e Initial load
duke
parents:
diff changeset
779 // depend for their correct sequencing on more than one test.
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // (In that case, hoisting to a dominating test may silently
a61af66fc99e Initial load
duke
parents:
diff changeset
781 // skip some other important test.)
a61af66fc99e Initial load
duke
parents:
diff changeset
782 virtual bool depends_only_on_test() const { assert(!is_CFG(), ""); return true; };
a61af66fc99e Initial load
duke
parents:
diff changeset
783
a61af66fc99e Initial load
duke
parents:
diff changeset
784 // defined for MachNodes that match 'If' | 'Goto' | 'CountedLoopEnd'
a61af66fc99e Initial load
duke
parents:
diff changeset
785 bool is_Branch() const { return (_flags & Flag_is_Branch) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
786
a61af66fc99e Initial load
duke
parents:
diff changeset
787 // When building basic blocks, I need to have a notion of block beginning
a61af66fc99e Initial load
duke
parents:
diff changeset
788 // Nodes, next block selector Nodes (block enders), and next block
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // projections. These calls need to work on their machine equivalents. The
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // Ideal beginning Nodes are RootNode, RegionNode and StartNode.
a61af66fc99e Initial load
duke
parents:
diff changeset
791 bool is_block_start() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
792 if ( is_Region() )
a61af66fc99e Initial load
duke
parents:
diff changeset
793 return this == (const Node*)in(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
794 else
a61af66fc99e Initial load
duke
parents:
diff changeset
795 return (_flags & Flag_is_block_start) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
796 }
a61af66fc99e Initial load
duke
parents:
diff changeset
797
a61af66fc99e Initial load
duke
parents:
diff changeset
798 // The Ideal control projection Nodes are IfTrue/IfFalse, JumpProjNode, Root,
a61af66fc99e Initial load
duke
parents:
diff changeset
799 // Goto and Return. This call also returns the block ending Node.
a61af66fc99e Initial load
duke
parents:
diff changeset
800 virtual const Node *is_block_proj() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
801
a61af66fc99e Initial load
duke
parents:
diff changeset
802 // The node is a "macro" node which needs to be expanded before matching
a61af66fc99e Initial load
duke
parents:
diff changeset
803 bool is_macro() const { return (_flags & Flag_is_macro) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 // Value is a vector of primitive values
a61af66fc99e Initial load
duke
parents:
diff changeset
806 bool is_Vector() const { return (_flags & Flag_is_Vector) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
807
a61af66fc99e Initial load
duke
parents:
diff changeset
808 //----------------- Optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
809
a61af66fc99e Initial load
duke
parents:
diff changeset
810 // Get the worst-case Type output for this Node.
a61af66fc99e Initial load
duke
parents:
diff changeset
811 virtual const class Type *bottom_type() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
812
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // If we find a better type for a node, try to record it permanently.
a61af66fc99e Initial load
duke
parents:
diff changeset
814 // Return true if this node actually changed.
a61af66fc99e Initial load
duke
parents:
diff changeset
815 // Be sure to do the hash_delete game in the "rehash" variant.
a61af66fc99e Initial load
duke
parents:
diff changeset
816 void raise_bottom_type(const Type* new_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
817
a61af66fc99e Initial load
duke
parents:
diff changeset
818 // Get the address type with which this node uses and/or defs memory,
a61af66fc99e Initial load
duke
parents:
diff changeset
819 // or NULL if none. The address type is conservatively wide.
a61af66fc99e Initial load
duke
parents:
diff changeset
820 // Returns non-null for calls, membars, loads, stores, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
821 // Returns TypePtr::BOTTOM if the node touches memory "broadly".
a61af66fc99e Initial load
duke
parents:
diff changeset
822 virtual const class TypePtr *adr_type() const { return NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 // Return an existing node which computes the same function as this node.
a61af66fc99e Initial load
duke
parents:
diff changeset
825 // The optimistic combined algorithm requires this to return a Node which
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // is a small number of steps away (e.g., one of my inputs).
a61af66fc99e Initial load
duke
parents:
diff changeset
827 virtual Node *Identity( PhaseTransform *phase );
a61af66fc99e Initial load
duke
parents:
diff changeset
828
a61af66fc99e Initial load
duke
parents:
diff changeset
829 // Return the set of values this Node can take on at runtime.
a61af66fc99e Initial load
duke
parents:
diff changeset
830 virtual const Type *Value( PhaseTransform *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
831
a61af66fc99e Initial load
duke
parents:
diff changeset
832 // Return a node which is more "ideal" than the current node.
a61af66fc99e Initial load
duke
parents:
diff changeset
833 // The invariants on this call are subtle. If in doubt, read the
a61af66fc99e Initial load
duke
parents:
diff changeset
834 // treatise in node.cpp above the default implemention AND TEST WITH
a61af66fc99e Initial load
duke
parents:
diff changeset
835 // +VerifyIterativeGVN!
a61af66fc99e Initial load
duke
parents:
diff changeset
836 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
837
a61af66fc99e Initial load
duke
parents:
diff changeset
838 // Some nodes have specific Ideal subgraph transformations only if they are
a61af66fc99e Initial load
duke
parents:
diff changeset
839 // unique users of specific nodes. Such nodes should be put on IGVN worklist
a61af66fc99e Initial load
duke
parents:
diff changeset
840 // for the transformations to happen.
a61af66fc99e Initial load
duke
parents:
diff changeset
841 bool has_special_unique_user() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
842
119
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
843 // Skip Proj and CatchProj nodes chains. Check for Null and Top.
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
844 Node* find_exact_control(Node* ctrl);
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
845
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
846 // Check if 'this' node dominates or equal to 'sub'.
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
847 bool dominates(Node* sub, Node_List &nlist);
d1a5218d7eaf 6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents: 113
diff changeset
848
0
a61af66fc99e Initial load
duke
parents:
diff changeset
849 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
850 bool remove_dead_region(PhaseGVN *phase, bool can_reshape);
a61af66fc99e Initial load
duke
parents:
diff changeset
851 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
852
a61af66fc99e Initial load
duke
parents:
diff changeset
853 // Idealize graph, using DU info. Done after constant propagation
a61af66fc99e Initial load
duke
parents:
diff changeset
854 virtual Node *Ideal_DU_postCCP( PhaseCCP *ccp );
a61af66fc99e Initial load
duke
parents:
diff changeset
855
a61af66fc99e Initial load
duke
parents:
diff changeset
856 // See if there is valid pipeline info
a61af66fc99e Initial load
duke
parents:
diff changeset
857 static const Pipeline *pipeline_class();
a61af66fc99e Initial load
duke
parents:
diff changeset
858 virtual const Pipeline *pipeline() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
859
a61af66fc99e Initial load
duke
parents:
diff changeset
860 // Compute the latency from the def to this instruction of the ith input node
a61af66fc99e Initial load
duke
parents:
diff changeset
861 uint latency(uint i);
a61af66fc99e Initial load
duke
parents:
diff changeset
862
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // Hash & compare functions, for pessimistic value numbering
a61af66fc99e Initial load
duke
parents:
diff changeset
864
a61af66fc99e Initial load
duke
parents:
diff changeset
865 // If the hash function returns the special sentinel value NO_HASH,
a61af66fc99e Initial load
duke
parents:
diff changeset
866 // the node is guaranteed never to compare equal to any other node.
605
98cb887364d3 6810672: Comment typos
twisti
parents: 400
diff changeset
867 // If we accidentally generate a hash with value NO_HASH the node
0
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // won't go into the table and we'll lose a little optimization.
a61af66fc99e Initial load
duke
parents:
diff changeset
869 enum { NO_HASH = 0 };
a61af66fc99e Initial load
duke
parents:
diff changeset
870 virtual uint hash() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
871 virtual uint cmp( const Node &n ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
872
a61af66fc99e Initial load
duke
parents:
diff changeset
873 // Operation appears to be iteratively computed (such as an induction variable)
a61af66fc99e Initial load
duke
parents:
diff changeset
874 // It is possible for this operation to return false for a loop-varying
a61af66fc99e Initial load
duke
parents:
diff changeset
875 // value, if it appears (by local graph inspection) to be computed by a simple conditional.
a61af66fc99e Initial load
duke
parents:
diff changeset
876 bool is_iteratively_computed();
a61af66fc99e Initial load
duke
parents:
diff changeset
877
a61af66fc99e Initial load
duke
parents:
diff changeset
878 // Determine if a node is Counted loop induction variable.
a61af66fc99e Initial load
duke
parents:
diff changeset
879 // The method is defined in loopnode.cpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
880 const Node* is_loop_iv() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // Return a node with opcode "opc" and same inputs as "this" if one can
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // be found; Otherwise return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
884 Node* find_similar(int opc);
a61af66fc99e Initial load
duke
parents:
diff changeset
885
a61af66fc99e Initial load
duke
parents:
diff changeset
886 // Return the unique control out if only one. Null if none or more than one.
a61af66fc99e Initial load
duke
parents:
diff changeset
887 Node* unique_ctrl_out();
a61af66fc99e Initial load
duke
parents:
diff changeset
888
a61af66fc99e Initial load
duke
parents:
diff changeset
889 //----------------- Code Generation
a61af66fc99e Initial load
duke
parents:
diff changeset
890
a61af66fc99e Initial load
duke
parents:
diff changeset
891 // Ideal register class for Matching. Zero means unmatched instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // (these are cloned instead of converted to machine nodes).
a61af66fc99e Initial load
duke
parents:
diff changeset
893 virtual uint ideal_reg() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
894
a61af66fc99e Initial load
duke
parents:
diff changeset
895 static const uint NotAMachineReg; // must be > max. machine register
a61af66fc99e Initial load
duke
parents:
diff changeset
896
a61af66fc99e Initial load
duke
parents:
diff changeset
897 // Do we Match on this edge index or not? Generally false for Control
a61af66fc99e Initial load
duke
parents:
diff changeset
898 // and true for everything else. Weird for calls & returns.
a61af66fc99e Initial load
duke
parents:
diff changeset
899 virtual uint match_edge(uint idx) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901 // Register class output is returned in
a61af66fc99e Initial load
duke
parents:
diff changeset
902 virtual const RegMask &out_RegMask() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // Register class input is expected in
a61af66fc99e Initial load
duke
parents:
diff changeset
904 virtual const RegMask &in_RegMask(uint) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
905 // Should we clone rather than spill this instruction?
a61af66fc99e Initial load
duke
parents:
diff changeset
906 bool rematerialize() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 // Return JVM State Object if this Node carries debug info, or NULL otherwise
a61af66fc99e Initial load
duke
parents:
diff changeset
909 virtual JVMState* jvms() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
910
a61af66fc99e Initial load
duke
parents:
diff changeset
911 // Print as assembly
a61af66fc99e Initial load
duke
parents:
diff changeset
912 virtual void format( PhaseRegAlloc *, outputStream* st = tty ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
913 // Emit bytes starting at parameter 'ptr'
a61af66fc99e Initial load
duke
parents:
diff changeset
914 // Bump 'ptr' by the number of output bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
915 virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
916 // Size of instruction in bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
917 virtual uint size(PhaseRegAlloc *ra_) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
918
a61af66fc99e Initial load
duke
parents:
diff changeset
919 // Convenience function to extract an integer constant from a node.
a61af66fc99e Initial load
duke
parents:
diff changeset
920 // If it is not an integer constant (either Con, CastII, or Mach),
a61af66fc99e Initial load
duke
parents:
diff changeset
921 // return value_if_unknown.
a61af66fc99e Initial load
duke
parents:
diff changeset
922 jint find_int_con(jint value_if_unknown) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
923 const TypeInt* t = find_int_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
924 return (t != NULL && t->is_con()) ? t->get_con() : value_if_unknown;
a61af66fc99e Initial load
duke
parents:
diff changeset
925 }
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // Return the constant, knowing it is an integer constant already
a61af66fc99e Initial load
duke
parents:
diff changeset
927 jint get_int() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
928 const TypeInt* t = find_int_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
929 guarantee(t != NULL, "must be con");
a61af66fc99e Initial load
duke
parents:
diff changeset
930 return t->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
932 // Here's where the work is done. Can produce non-constant int types too.
a61af66fc99e Initial load
duke
parents:
diff changeset
933 const TypeInt* find_int_type() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
934
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // Same thing for long (and intptr_t, via type.hpp):
a61af66fc99e Initial load
duke
parents:
diff changeset
936 jlong get_long() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
937 const TypeLong* t = find_long_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
938 guarantee(t != NULL, "must be con");
a61af66fc99e Initial load
duke
parents:
diff changeset
939 return t->get_con();
a61af66fc99e Initial load
duke
parents:
diff changeset
940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
941 jlong find_long_con(jint value_if_unknown) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
942 const TypeLong* t = find_long_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
943 return (t != NULL && t->is_con()) ? t->get_con() : value_if_unknown;
a61af66fc99e Initial load
duke
parents:
diff changeset
944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
945 const TypeLong* find_long_type() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 // These guys are called by code generated by ADLC:
a61af66fc99e Initial load
duke
parents:
diff changeset
948 intptr_t get_ptr() const;
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 65
diff changeset
949 intptr_t get_narrowcon() const;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
950 jdouble getd() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
951 jfloat getf() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
952
a61af66fc99e Initial load
duke
parents:
diff changeset
953 // Nodes which are pinned into basic blocks
a61af66fc99e Initial load
duke
parents:
diff changeset
954 virtual bool pinned() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
955
a61af66fc99e Initial load
duke
parents:
diff changeset
956 // Nodes which use memory without consuming it, hence need antidependences
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // More specifically, needs_anti_dependence_check returns true iff the node
a61af66fc99e Initial load
duke
parents:
diff changeset
958 // (a) does a load, and (b) does not perform a store (except perhaps to a
a61af66fc99e Initial load
duke
parents:
diff changeset
959 // stack slot or some other unaliased location).
a61af66fc99e Initial load
duke
parents:
diff changeset
960 bool needs_anti_dependence_check() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
961
a61af66fc99e Initial load
duke
parents:
diff changeset
962 // Return which operand this instruction may cisc-spill. In other words,
a61af66fc99e Initial load
duke
parents:
diff changeset
963 // return operand position that can convert from reg to memory access
a61af66fc99e Initial load
duke
parents:
diff changeset
964 virtual int cisc_operand() const { return AdlcVMDeps::Not_cisc_spillable; }
a61af66fc99e Initial load
duke
parents:
diff changeset
965 bool is_cisc_alternate() const { return (_flags & Flag_is_cisc_alternate) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
966
a61af66fc99e Initial load
duke
parents:
diff changeset
967 //----------------- Graph walking
a61af66fc99e Initial load
duke
parents:
diff changeset
968 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // Walk and apply member functions recursively.
a61af66fc99e Initial load
duke
parents:
diff changeset
970 // Supplied (this) pointer is root.
a61af66fc99e Initial load
duke
parents:
diff changeset
971 void walk(NFunc pre, NFunc post, void *env);
a61af66fc99e Initial load
duke
parents:
diff changeset
972 static void nop(Node &, void*); // Dummy empty function
a61af66fc99e Initial load
duke
parents:
diff changeset
973 static void packregion( Node &n, void* );
a61af66fc99e Initial load
duke
parents:
diff changeset
974 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
975 void walk_(NFunc pre, NFunc post, void *env, VectorSet &visited);
a61af66fc99e Initial load
duke
parents:
diff changeset
976
a61af66fc99e Initial load
duke
parents:
diff changeset
977 //----------------- Printing, etc
a61af66fc99e Initial load
duke
parents:
diff changeset
978 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
979 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
980 Node* find(int idx) const; // Search the graph for the given idx.
a61af66fc99e Initial load
duke
parents:
diff changeset
981 Node* find_ctrl(int idx) const; // Search control ancestors for the given idx.
a61af66fc99e Initial load
duke
parents:
diff changeset
982 void dump() const; // Print this node,
a61af66fc99e Initial load
duke
parents:
diff changeset
983 void dump(int depth) const; // Print this node, recursively to depth d
a61af66fc99e Initial load
duke
parents:
diff changeset
984 void dump_ctrl(int depth) const; // Print control nodes, to depth d
a61af66fc99e Initial load
duke
parents:
diff changeset
985 virtual void dump_req() const; // Print required-edge info
a61af66fc99e Initial load
duke
parents:
diff changeset
986 virtual void dump_prec() const; // Print precedence-edge info
a61af66fc99e Initial load
duke
parents:
diff changeset
987 virtual void dump_out() const; // Print the output edge info
a61af66fc99e Initial load
duke
parents:
diff changeset
988 virtual void dump_spec(outputStream *st) const {}; // Print per-node info
a61af66fc99e Initial load
duke
parents:
diff changeset
989 void verify_edges(Unique_Node_List &visited); // Verify bi-directional edges
a61af66fc99e Initial load
duke
parents:
diff changeset
990 void verify() const; // Check Def-Use info for my subgraph
a61af66fc99e Initial load
duke
parents:
diff changeset
991 static void verify_recur(const Node *n, int verify_depth, VectorSet &old_space, VectorSet &new_space);
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 // This call defines a class-unique string used to identify class instances
a61af66fc99e Initial load
duke
parents:
diff changeset
994 virtual const char *Name() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
995
a61af66fc99e Initial load
duke
parents:
diff changeset
996 void dump_format(PhaseRegAlloc *ra) const; // debug access to MachNode::format(...)
a61af66fc99e Initial load
duke
parents:
diff changeset
997 // RegMask Print Functions
a61af66fc99e Initial load
duke
parents:
diff changeset
998 void dump_in_regmask(int idx) { in_RegMask(idx).dump(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
999 void dump_out_regmask() { out_RegMask().dump(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 static int _in_dump_cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 static bool in_dump() { return _in_dump_cnt > 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 void fast_dump() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 tty->print("%4d: %-17s", _idx, Name());
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 for (uint i = 0; i < len(); i++)
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 if (in(i))
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 tty->print(" %4d", in(i)->_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 tty->print(" NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 tty->print("\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 void verify_construction();
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 bool verify_jvms(const JVMState* jvms) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 int _debug_idx; // Unique value assigned to every node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 int debug_idx() const { return _debug_idx; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 void set_debug_idx( int debug_idx ) { _debug_idx = debug_idx; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1018
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 Node* _debug_orig; // Original version of this, if any.
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 Node* debug_orig() const { return _debug_orig; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 void set_debug_orig(Node* orig); // _debug_orig = orig
a61af66fc99e Initial load
duke
parents:
diff changeset
1022
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 int _hash_lock; // Barrier to modifications of nodes in the hash table
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 void enter_hash_lock() { ++_hash_lock; assert(_hash_lock < 99, "in too many hash tables?"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 void exit_hash_lock() { --_hash_lock; assert(_hash_lock >= 0, "mispaired hash locks"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1026
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 static void init_NodeProperty();
a61af66fc99e Initial load
duke
parents:
diff changeset
1028
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 #if OPTO_DU_ITERATOR_ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 const Node* _last_del; // The last deleted node.
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 uint _del_tick; // Bumped when a deletion happens..
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1035
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 //-----------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 // Iterators over DU info, and associated Node functions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1038
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 #if OPTO_DU_ITERATOR_ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1040
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 // Common code for assertion checking on DU iterators.
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 class DUIterator_Common VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 bool _vdui; // cached value of VerifyDUIterators
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 const Node* _node; // the node containing the _out array
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 uint _outcnt; // cached node->_outcnt
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 uint _del_tick; // cached node->_del_tick
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 Node* _last; // last value produced by the iterator
a61af66fc99e Initial load
duke
parents:
diff changeset
1050
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 void sample(const Node* node); // used by c'tor to set up for verifies
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 void verify(const Node* node, bool at_end_ok = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 void verify_resync();
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 void reset(const DUIterator_Common& that);
a61af66fc99e Initial load
duke
parents:
diff changeset
1055
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 // The VDUI_ONLY macro protects code conditionalized on VerifyDUIterators
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 #define I_VDUI_ONLY(i,x) { if ((i)._vdui) { x; } }
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 #define I_VDUI_ONLY(i,x) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 #endif //ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1062
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 #define VDUI_ONLY(x) I_VDUI_ONLY(*this, x)
a61af66fc99e Initial load
duke
parents:
diff changeset
1064
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 // Default DU iterator. Allows appends onto the out array.
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 // Allows deletion from the out array only at the current point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 // Usage:
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 // for (DUIterator i = x->outs(); x->has_out(i); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 // Node* y = x->out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 // Compiles in product mode to a unsigned integer index, which indexes
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 // onto a repeatedly reloaded base pointer of x->_out. The loop predicate
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 // also reloads x->_outcnt. If you delete, you must perform "--i" just
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 // before continuing the loop. You must delete only the last-produced
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 // edge. You must delete only a single copy of the last-produced edge,
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 // or else you must delete all copies at once (the first time the edge
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // is produced by the iterator).
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 class DUIterator : public DUIterator_Common {
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 friend class Node;
a61af66fc99e Initial load
duke
parents:
diff changeset
1081
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 // This is the index which provides the product-mode behavior.
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 // Whatever the product-mode version of the system does to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 // DUI index is done to this index. All other fields in
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 // this class are used only for assertion checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 uint _idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1087
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 uint _refresh_tick; // Records the refresh activity.
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 void sample(const Node* node); // Initialize _refresh_tick etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 void verify(const Node* node, bool at_end_ok = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 void verify_increment(); // Verify an increment operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 void verify_resync(); // Verify that we can back up over a deletion.
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 void verify_finish(); // Verify that the loop terminated properly.
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 void refresh(); // Resample verification info.
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 void reset(const DUIterator& that); // Resample after assignment.
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1099
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 DUIterator(const Node* node, int dummy_to_avoid_conversion)
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 { _idx = 0; debug_only(sample(node)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1102
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 // initialize to garbage; clear _vdui to disable asserts
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 DUIterator()
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 { /*initialize to garbage*/ debug_only(_vdui = false); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1107
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 void operator++(int dummy_to_specify_postfix_op)
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 { _idx++; VDUI_ONLY(verify_increment()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1110
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 void operator--()
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 { VDUI_ONLY(verify_resync()); --_idx; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1113
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 ~DUIterator()
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 { VDUI_ONLY(verify_finish()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1116
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 void operator=(const DUIterator& that)
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 { _idx = that._idx; debug_only(reset(that)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1120
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 DUIterator Node::outs() const
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 { return DUIterator(this, 0); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 DUIterator& Node::refresh_out_pos(DUIterator& i) const
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 { I_VDUI_ONLY(i, i.refresh()); return i; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 bool Node::has_out(DUIterator& i) const
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 { I_VDUI_ONLY(i, i.verify(this,true));return i._idx < _outcnt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 Node* Node::out(DUIterator& i) const
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 { I_VDUI_ONLY(i, i.verify(this)); return debug_only(i._last=) _out[i._idx]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1129
a61af66fc99e Initial load
duke
parents:
diff changeset
1130
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // Faster DU iterator. Disallows insertions into the out array.
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 // Allows deletion from the out array only at the current point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 // Usage:
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 // for (DUIterator_Fast imax, i = x->fast_outs(imax); i < imax; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 // Node* y = x->fast_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // Compiles in product mode to raw Node** pointer arithmetic, with
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // no reloading of pointers from the original node x. If you delete,
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // you must perform "--i; --imax" just before continuing the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 // If you delete multiple copies of the same edge, you must decrement
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // imax, but not i, multiple times: "--i, imax -= num_edges".
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 class DUIterator_Fast : public DUIterator_Common {
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 friend class Node;
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 friend class DUIterator_Last;
a61af66fc99e Initial load
duke
parents:
diff changeset
1146
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 // This is the pointer which provides the product-mode behavior.
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 // Whatever the product-mode version of the system does to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 // DUI pointer is done to this pointer. All other fields in
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 // this class are used only for assertion checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 Node** _outp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1152
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 void verify(const Node* node, bool at_end_ok = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 void verify_limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 void verify_resync();
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 void verify_relimit(uint n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 void reset(const DUIterator_Fast& that);
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // Note: offset must be signed, since -1 is sometimes passed
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 DUIterator_Fast(const Node* node, ptrdiff_t offset)
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 { _outp = node->_out + offset; debug_only(sample(node)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1164
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 // initialize to garbage; clear _vdui to disable asserts
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 DUIterator_Fast()
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 { /*initialize to garbage*/ debug_only(_vdui = false); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1169
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 void operator++(int dummy_to_specify_postfix_op)
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 { _outp++; VDUI_ONLY(verify(_node, true)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1172
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 void operator--()
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 { VDUI_ONLY(verify_resync()); --_outp; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1175
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 void operator-=(uint n) // applied to the limit only
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 { _outp -= n; VDUI_ONLY(verify_relimit(n)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1178
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 bool operator<(DUIterator_Fast& limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 I_VDUI_ONLY(*this, this->verify(_node, true));
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 I_VDUI_ONLY(limit, limit.verify_limit());
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 return _outp < limit._outp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1184
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 void operator=(const DUIterator_Fast& that)
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 { _outp = that._outp; debug_only(reset(that)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1188
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 DUIterator_Fast Node::fast_outs(DUIterator_Fast& imax) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 // Assign a limit pointer to the reference argument:
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 imax = DUIterator_Fast(this, (ptrdiff_t)_outcnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 // Return the base pointer:
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 return DUIterator_Fast(this, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 Node* Node::fast_out(DUIterator_Fast& i) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 I_VDUI_ONLY(i, i.verify(this));
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 return debug_only(i._last=) *i._outp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1199
a61af66fc99e Initial load
duke
parents:
diff changeset
1200
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 // Faster DU iterator. Requires each successive edge to be removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 // Does not allow insertion of any edges.
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 // Usage:
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 // for (DUIterator_Last imin, i = x->last_outs(imin); i >= imin; i -= num_edges) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 // Node* y = x->last_out(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 // Compiles in product mode to raw Node** pointer arithmetic, with
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 // no reloading of pointers from the original node x.
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 class DUIterator_Last : private DUIterator_Fast {
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 friend class Node;
a61af66fc99e Initial load
duke
parents:
diff changeset
1212
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 void verify(const Node* node, bool at_end_ok = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 void verify_limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 void verify_step(uint num_edges);
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1218
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // Note: offset must be signed, since -1 is sometimes passed
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 DUIterator_Last(const Node* node, ptrdiff_t offset)
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 : DUIterator_Fast(node, offset) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1222
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 void operator++(int dummy_to_specify_postfix_op) {} // do not use
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 void operator<(int) {} // do not use
a61af66fc99e Initial load
duke
parents:
diff changeset
1225
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 DUIterator_Last() { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 // initialize to garbage
a61af66fc99e Initial load
duke
parents:
diff changeset
1229
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 void operator--()
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 { _outp--; VDUI_ONLY(verify_step(1)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1232
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 void operator-=(uint n)
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 { _outp -= n; VDUI_ONLY(verify_step(n)); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1235
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 bool operator>=(DUIterator_Last& limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 I_VDUI_ONLY(*this, this->verify(_node, true));
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 I_VDUI_ONLY(limit, limit.verify_limit());
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 return _outp >= limit._outp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1241
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 void operator=(const DUIterator_Last& that)
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 { DUIterator_Fast::operator=(that); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1245
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 DUIterator_Last Node::last_outs(DUIterator_Last& imin) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 // Assign a limit pointer to the reference argument:
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 imin = DUIterator_Last(this, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 // Return the initial pointer:
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 return DUIterator_Last(this, (ptrdiff_t)_outcnt - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 Node* Node::last_out(DUIterator_Last& i) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 I_VDUI_ONLY(i, i.verify(this));
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 return debug_only(i._last=) *i._outp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1256
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 #endif //OPTO_DU_ITERATOR_ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1258
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 #undef I_VDUI_ONLY
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 #undef VDUI_ONLY
a61af66fc99e Initial load
duke
parents:
diff changeset
1261
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1262 // An Iterator that truly follows the iterator pattern. Doesn't
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1263 // support deletion but could be made to.
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1264 //
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1265 // for (SimpleDUIterator i(n); i.has_next(); i.next()) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1266 // Node* m = i.get();
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1267 //
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1268 class SimpleDUIterator : public StackObj {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1269 private:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1270 Node* node;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1271 DUIterator_Fast i;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1272 DUIterator_Fast imax;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1273 public:
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1274 SimpleDUIterator(Node* n): node(n), i(n->fast_outs(imax)) {}
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1275 bool has_next() { return i < imax; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1276 void next() { i++; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1277 Node* get() { return node->fast_out(i); }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1278 };
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1279
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1280
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 //-----------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // Map dense integer indices to Nodes. Uses classic doubling-array trick.
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // Abstractly provides an infinite array of Node*'s, initialized to NULL.
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // Note that the constructor just zeros things, and since I use Arena
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // allocation I do not need a destructor to reclaim storage.
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 class Node_Array : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 Arena *_a; // Arena to allocate in
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 uint _max;
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 Node **_nodes;
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 void grow( uint i ); // Grow array node to fit
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 Node_Array(Arena *a) : _a(a), _max(OptoNodeListSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 _nodes = NEW_ARENA_ARRAY( a, Node *, OptoNodeListSize );
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 for( int i = 0; i < OptoNodeListSize; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 _nodes[i] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1299
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 Node_Array(Node_Array *na) : _a(na->_a), _max(na->_max), _nodes(na->_nodes) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 Node *operator[] ( uint i ) const // Lookup, or NULL for not mapped
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 { return (i<_max) ? _nodes[i] : (Node*)NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 Node *at( uint i ) const { assert(i<_max,"oob"); return _nodes[i]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 Node **adr() { return _nodes; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // Extend the mapping: index i maps to Node *n.
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 void map( uint i, Node *n ) { if( i>=_max ) grow(i); _nodes[i] = n; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 void insert( uint i, Node *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 void remove( uint i ); // Remove, preserving order
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 void sort( C_sort_func_t func);
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 void reset( Arena *new_a ); // Zap mapping to empty; reclaim storage
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 void clear(); // Set all entries to NULL, keep storage
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 uint Size() const { return _max; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 void dump() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1315
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 class Node_List : public Node_Array {
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 uint _cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 Node_List() : Node_Array(Thread::current()->resource_area()), _cnt(0) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 Node_List(Arena *a) : Node_Array(a), _cnt(0) {}
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1321 bool contains(Node* n) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1322 for (uint e = 0; e < size(); e++) {
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1323 if (at(e) == n) return true;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1324 }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1325 return false;
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 605
diff changeset
1326 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 void insert( uint i, Node *n ) { Node_Array::insert(i,n); _cnt++; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 void remove( uint i ) { Node_Array::remove(i); _cnt--; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 void push( Node *b ) { map(_cnt++,b); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 void yank( Node *n ); // Find and remove
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 Node *pop() { return _nodes[--_cnt]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 Node *rpop() { Node *b = _nodes[0]; _nodes[0]=_nodes[--_cnt]; return b;}
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 void clear() { _cnt = 0; Node_Array::clear(); } // retain storage
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 uint size() const { return _cnt; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 void dump() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1337
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 //------------------------------Unique_Node_List-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 class Unique_Node_List : public Node_List {
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 VectorSet _in_worklist;
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 uint _clock_index; // Index in list where to pop from next
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 Unique_Node_List() : Node_List(), _in_worklist(Thread::current()->resource_area()), _clock_index(0) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 Unique_Node_List(Arena *a) : Node_List(a), _in_worklist(a), _clock_index(0) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
1345
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 void remove( Node *n );
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 bool member( Node *n ) { return _in_worklist.test(n->_idx) != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 VectorSet &member_set(){ return _in_worklist; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1349
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 void push( Node *b ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 if( !_in_worklist.test_set(b->_idx) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 Node_List::push(b);
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 Node *pop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 if( _clock_index >= size() ) _clock_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 Node *b = at(_clock_index);
400
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 247
diff changeset
1357 map( _clock_index, Node_List::pop());
cc80376deb0c 6667595: Set probability FAIR for pre-, post- loops and ALWAYS for main loop
kvn
parents: 247
diff changeset
1358 if (size() != 0) _clock_index++; // Always start from 0
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 _in_worklist >>= b->_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 return b;
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 Node *remove( uint i ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 Node *b = Node_List::at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 _in_worklist >>= b->_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 map(i,Node_List::pop());
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 return b;
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 void yank( Node *n ) { _in_worklist >>= n->_idx; Node_List::yank(n); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 void clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 _in_worklist.Clear(); // Discards storage but grows automatically
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 Node_List::clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 _clock_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1374
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 // Used after parsing to remove useless nodes before Iterative GVN
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 void remove_useless_nodes(VectorSet &useful);
a61af66fc99e Initial load
duke
parents:
diff changeset
1377
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 void print_set() const { _in_worklist.print(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1382
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 // Inline definition of Compile::record_for_igvn must be deferred to this point.
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 inline void Compile::record_for_igvn(Node* n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 _for_igvn->push(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1387
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 //------------------------------Node_Stack-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 class Node_Stack {
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 struct INode {
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 Node *node; // Processed node
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 uint indx; // Index of next node's child
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 INode *_inode_top; // tos, stack grows up
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 INode *_inode_max; // End of _inodes == _inodes + _max
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 INode *_inodes; // Array storage for the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 Arena *_a; // Arena to allocate in
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 void grow();
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 Node_Stack(int size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 size_t max = (size > OptoNodeListSize) ? size : OptoNodeListSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 _a = Thread::current()->resource_area();
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 _inodes = NEW_ARENA_ARRAY( _a, INode, max );
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 _inode_max = _inodes + max;
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 _inode_top = _inodes - 1; // stack is empty
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1408
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 Node_Stack(Arena *a, int size) : _a(a) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 size_t max = (size > OptoNodeListSize) ? size : OptoNodeListSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 _inodes = NEW_ARENA_ARRAY( _a, INode, max );
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 _inode_max = _inodes + max;
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 _inode_top = _inodes - 1; // stack is empty
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1415
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 void pop() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 assert(_inode_top >= _inodes, "node stack underflow");
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 --_inode_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 void push(Node *n, uint i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 ++_inode_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 if (_inode_top >= _inode_max) grow();
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 INode *top = _inode_top; // optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 top->node = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 top->indx = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 Node *node() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 return _inode_top->node;
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 Node* node_at(uint i) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 assert(_inodes + i <= _inode_top, "in range");
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 return _inodes[i].node;
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 uint index() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 return _inode_top->indx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 }
247
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 196
diff changeset
1437 uint index_at(uint i) const {
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 196
diff changeset
1438 assert(_inodes + i <= _inode_top, "in range");
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 196
diff changeset
1439 return _inodes[i].indx;
02a35ad4adf8 6723160: Nightly failure: Error: meet not symmetric
kvn
parents: 196
diff changeset
1440 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 void set_node(Node *n) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 _inode_top->node = n;
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 void set_index(uint i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 _inode_top->indx = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 uint size_max() const { return (uint)pointer_delta(_inode_max, _inodes, sizeof(INode)); } // Max size
40
7c1f32ae4a20 6670459: Fix Node::dump() performance
kvn
parents: 33
diff changeset
1448 uint size() const { return (uint)pointer_delta((_inode_top+1), _inodes, sizeof(INode)); } // Current size
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 bool is_nonempty() const { return (_inode_top >= _inodes); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 bool is_empty() const { return (_inode_top < _inodes); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 void clear() { _inode_top = _inodes - 1; } // retain storage
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1453
a61af66fc99e Initial load
duke
parents:
diff changeset
1454
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 //-----------------------------Node_Notes--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 // Debugging or profiling annotations loosely and sparsely associated
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 // with some nodes. See Compile::node_notes_at for the accessor.
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 class Node_Notes VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 JVMState* _jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
1460
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 Node_Notes(JVMState* jvms = NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 _jvms = jvms;
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1465
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 JVMState* jvms() { return _jvms; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 void set_jvms(JVMState* x) { _jvms = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1468
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 // True if there is nothing here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 bool is_clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 return (_jvms == NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1473
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 // Make there be nothing here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 void clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 _jvms = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1478
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // Make a new, clean node notes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 static Node_Notes* make(Compile* C) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 Node_Notes* nn = NEW_ARENA_ARRAY(C->comp_arena(), Node_Notes, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 nn->clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 return nn;
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1485
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 Node_Notes* clone(Compile* C) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 Node_Notes* nn = NEW_ARENA_ARRAY(C->comp_arena(), Node_Notes, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 (*nn) = (*this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 return nn;
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1491
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 // Absorb any information from source.
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 bool update_from(Node_Notes* source) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 bool changed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 if (source != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 if (source->jvms() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 set_jvms(source->jvms());
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 changed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 return changed;
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1504
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 // Inlined accessors for Compile::node_nodes that require the preceding class:
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 inline Node_Notes*
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 Compile::locate_node_notes(GrowableArray<Node_Notes*>* arr,
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 int idx, bool can_grow) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 assert(idx >= 0, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 int block_idx = (idx >> _log2_node_notes_block_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 int grow_by = (block_idx - (arr == NULL? 0: arr->length()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 if (grow_by >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 if (!can_grow) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 grow_node_notes(arr, grow_by + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 // (Every element of arr is a sub-array of length _node_notes_block_size.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 return arr->at(block_idx) + (idx & (_node_notes_block_size-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1519
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 inline bool
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 Compile::set_node_notes_at(int idx, Node_Notes* value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 if (value == NULL || value->is_clear())
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 return false; // nothing to write => write nothing
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 Node_Notes* loc = locate_node_notes(_node_note_array, idx, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 assert(loc != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 return loc->update_from(value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1528
a61af66fc99e Initial load
duke
parents:
diff changeset
1529
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 //------------------------------TypeNode---------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 // Node with a Type constant.
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 class TypeNode : public Node {
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 virtual uint hash() const; // Check the type
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 virtual uint cmp( const Node &n ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 virtual uint size_of() const; // Size is bigger
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 const Type* const _type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 void set_type(const Type* t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 assert(t != NULL, "sanity");
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 debug_only(uint check_hash = (VerifyHashTableKeys && _hash_lock) ? hash() : NO_HASH);
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 *(const Type**)&_type = t; // cast away const-ness
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 // If this node is in the hash table, make sure it doesn't need a rehash.
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 assert(check_hash == NO_HASH || check_hash == hash(), "type change must preserve hash code");
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 const Type* type() const { assert(_type != NULL, "sanity"); return _type; };
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 TypeNode( const Type *t, uint required ) : Node(required), _type(t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 init_class_id(Class_Type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 virtual const Type *Value( PhaseTransform *phase ) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 virtual const Type *bottom_type() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 virtual uint ideal_reg() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 virtual void dump_spec(outputStream *st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 };