annotate src/share/vm/opto/node.hpp @ 1994:6cd6d394f280

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