Mercurial > hg > graal-compiler
annotate src/share/vm/opto/idealKit.hpp @ 10185:d50cc62e94ff
8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
Summary: In graphKit INT operations were generated to access PtrQueue::_index which has type size_t. This is 64 bit on 64-bit machines. No problems occur on little endian machines as long as the index fits into 32 bit, but on big endian machines the upper part is read, which is zero. This leads to unnecessary branches to the slow path in the runtime.
Reviewed-by: twisti, johnc
Contributed-by: Martin Doerr <martin.doerr@sap.com>
author | johnc |
---|---|
date | Wed, 24 Apr 2013 14:48:43 -0700 |
parents | 30f42e691e70 |
children | de6a9e811145 2113136690bc |
rev | line source |
---|---|
0 | 1 /* |
6842
b9a9ed0f8eeb
7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents:
6804
diff
changeset
|
2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1000
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1000
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:
1000
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_OPTO_IDEALKIT_HPP |
26 #define SHARE_VM_OPTO_IDEALKIT_HPP | |
27 | |
28 #include "opto/addnode.hpp" | |
29 #include "opto/cfgnode.hpp" | |
30 #include "opto/connode.hpp" | |
31 #include "opto/divnode.hpp" | |
2383
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
32 #include "opto/graphKit.hpp" |
1972 | 33 #include "opto/mulnode.hpp" |
34 #include "opto/phaseX.hpp" | |
35 #include "opto/subnode.hpp" | |
36 #include "opto/type.hpp" | |
37 | |
0 | 38 //----------------------------------------------------------------------------- |
39 //----------------------------IdealKit----------------------------------------- | |
40 // Set of utilities for creating control flow and scalar SSA data flow. | |
41 // Control: | |
42 // if_then(left, relop, right) | |
43 // else_ (optional) | |
44 // end_if | |
45 // loop(iv variable, initial, relop, limit) | |
46 // - sets iv to initial for first trip | |
47 // - exits when relation on limit is true | |
48 // - the values of initial and limit should be loop invariant | |
49 // - no increment, must be explicitly coded | |
50 // - final value of iv is available after end_loop (until dead()) | |
51 // end_loop | |
52 // make_label(number of gotos) | |
53 // goto_(label) | |
54 // bind(label) | |
55 // Data: | |
56 // ConI(integer constant) - create an integer constant | |
57 // set(variable, value) - assignment | |
58 // value(variable) - reference value | |
59 // dead(variable) - variable's value is no longer live | |
60 // increment(variable, value) - increment variable by value | |
61 // simple operations: AddI, SubI, AndI, LShiftI, etc. | |
62 // Example: | |
63 // Node* limit = ?? | |
64 // IdealVariable i(kit), j(kit); | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
0
diff
changeset
|
65 // declarations_done(); |
0 | 66 // Node* exit = make_label(1); // 1 goto |
67 // set(j, ConI(0)); | |
68 // loop(i, ConI(0), BoolTest::lt, limit); { | |
69 // if_then(value(i), BoolTest::gt, ConI(5)) { | |
70 // set(j, ConI(1)); | |
71 // goto_(exit); dead(i); | |
72 // } end_if(); | |
73 // increment(i, ConI(1)); | |
74 // } end_loop(); dead(i); | |
75 // bind(exit); | |
76 // | |
77 // See string_indexOf for a more complete example. | |
78 | |
79 class IdealKit; | |
80 | |
81 // Variable definition for IdealKit | |
82 class IdealVariable: public StackObj { | |
83 friend class IdealKit; | |
84 private: | |
85 int _id; | |
86 void set_id(int id) { _id = id; } | |
87 public: | |
88 IdealVariable(IdealKit &k); | |
89 int id() { assert(has_id(),"uninitialized id"); return _id; } | |
90 bool has_id() { return _id >= 0; } | |
91 }; | |
92 | |
93 class IdealKit: public StackObj { | |
94 friend class IdealVariable; | |
95 // The main state (called a cvstate for Control and Variables) | |
96 // contains both the current values of the variables and the | |
97 // current set of predecessor control edges. The variable values | |
98 // are managed via a Node [in(1)..in(_var_ct)], and the predecessor | |
99 // control edges managed via a RegionNode. The in(0) of the Node | |
100 // for variables points to the RegionNode for the control edges. | |
101 protected: | |
102 Compile * const C; | |
103 PhaseGVN &_gvn; | |
104 GrowableArray<Node*>* _pending_cvstates; // stack of cvstates | |
105 Node* _cvstate; // current cvstate (control, memory and variables) | |
106 uint _var_ct; // number of variables | |
107 bool _delay_all_transforms; // flag forcing all transforms to be delayed | |
108 Node* _initial_ctrl; // saves initial control until variables declared | |
109 Node* _initial_memory; // saves initial memory until variables declared | |
2444
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
110 Node* _initial_i_o; // saves initial i_o until variables declared |
0 | 111 |
112 PhaseGVN& gvn() const { return _gvn; } | |
113 // Create a new cvstate filled with nulls | |
114 Node* new_cvstate(); // Create a new cvstate | |
115 Node* cvstate() { return _cvstate; } // current cvstate | |
116 Node* copy_cvstate(); // copy current cvstate | |
117 | |
118 void set_memory(Node* mem, uint alias_idx ); | |
119 void do_memory_merge(Node* merging, Node* join); | |
120 void clear(Node* m); // clear a cvstate | |
121 void stop() { clear(_cvstate); } // clear current cvstate | |
122 Node* delay_transform(Node* n); | |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
6842
diff
changeset
|
123 Node* transform(Node* n); // gvn.transform or skip it |
0 | 124 Node* promote_to_phi(Node* n, Node* reg);// Promote "n" to a phi on region "reg" |
125 bool was_promoted_to_phi(Node* n, Node* reg) { | |
126 return (n->is_Phi() && n->in(0) == reg); | |
127 } | |
128 void declare(IdealVariable* v) { v->set_id(_var_ct++); } | |
129 // This declares the position where vars are kept in the cvstate | |
130 // For some degree of consistency we use the TypeFunc enum to | |
131 // soak up spots in the inputs even though we only use early Control | |
132 // and Memory slots. (So far.) | |
133 static const uint first_var; // = TypeFunc::Parms + 1; | |
134 | |
135 #ifdef ASSERT | |
136 enum State { NullS=0, BlockS=1, LoopS=2, IfThenS=4, ElseS=8, EndifS= 16 }; | |
137 GrowableArray<int>* _state; | |
138 State state() { return (State)(_state->top()); } | |
139 #endif | |
140 | |
141 // Users should not care about slices only MergedMem so no access for them. | |
142 Node* memory(uint alias_idx); | |
143 | |
144 public: | |
2444
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
145 IdealKit(GraphKit* gkit, bool delay_all_transforms = false, bool has_declarations = false); |
0 | 146 ~IdealKit() { |
147 stop(); | |
148 } | |
2444
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
149 void sync_kit(GraphKit* gkit); |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
150 |
0 | 151 // Control |
152 Node* ctrl() { return _cvstate->in(TypeFunc::Control); } | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
0
diff
changeset
|
153 void set_ctrl(Node* ctrl) { _cvstate->set_req(TypeFunc::Control, ctrl); } |
0 | 154 Node* top() { return C->top(); } |
155 MergeMemNode* merged_memory() { return _cvstate->in(TypeFunc::Memory)->as_MergeMem(); } | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
0
diff
changeset
|
156 void set_all_memory(Node* mem) { _cvstate->set_req(TypeFunc::Memory, mem); } |
2444
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
157 Node* i_o() { return _cvstate->in(TypeFunc::I_O); } |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
158 void set_i_o(Node* c) { _cvstate->set_req(TypeFunc::I_O, c); } |
0 | 159 void set(IdealVariable& v, Node* rhs) { _cvstate->set_req(first_var + v.id(), rhs); } |
160 Node* value(IdealVariable& v) { return _cvstate->in(first_var + v.id()); } | |
161 void dead(IdealVariable& v) { set(v, (Node*)NULL); } | |
162 void if_then(Node* left, BoolTest::mask relop, Node* right, | |
163 float prob = PROB_FAIR, float cnt = COUNT_UNKNOWN, | |
164 bool push_new_state = true); | |
165 void else_(); | |
166 void end_if(); | |
2383
9dc311b8473e
7008866: Missing loop predicate for loop with multiple entries
kvn
parents:
1972
diff
changeset
|
167 void loop(GraphKit* gkit, int nargs, IdealVariable& iv, Node* init, BoolTest::mask cmp, Node* limit, |
0 | 168 float prob = PROB_LIKELY(0.9), float cnt = COUNT_UNKNOWN); |
169 void end_loop(); | |
170 Node* make_label(int goto_ct); | |
171 void bind(Node* lab); | |
172 void goto_(Node* lab, bool bind = false); | |
851
fc4be448891f
6851742: (EA) allocation elimination doesn't work with UseG1GC
kvn
parents:
0
diff
changeset
|
173 void declarations_done(); |
0 | 174 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
175 Node* IfTrue(IfNode* iff) { return transform(new (C) IfTrueNode(iff)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
176 Node* IfFalse(IfNode* iff) { return transform(new (C) IfFalseNode(iff)); } |
0 | 177 |
178 // Data | |
179 Node* ConI(jint k) { return (Node*)gvn().intcon(k); } | |
180 Node* makecon(const Type *t) const { return _gvn.makecon(t); } | |
181 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
182 Node* AddI(Node* l, Node* r) { return transform(new (C) AddINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
183 Node* SubI(Node* l, Node* r) { return transform(new (C) SubINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
184 Node* AndI(Node* l, Node* r) { return transform(new (C) AndINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
185 Node* MaxI(Node* l, Node* r) { return transform(new (C) MaxINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
186 Node* LShiftI(Node* l, Node* r) { return transform(new (C) LShiftINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
187 Node* CmpI(Node* l, Node* r) { return transform(new (C) CmpINode(l, r)); } |
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
188 Node* Bool(Node* cmp, BoolTest::mask relop) { return transform(new (C) BoolNode(cmp, relop)); } |
0 | 189 void increment(IdealVariable& v, Node* j) { set(v, AddI(value(v), j)); } |
190 void decrement(IdealVariable& v, Node* j) { set(v, SubI(value(v), j)); } | |
191 | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
192 Node* CmpL(Node* l, Node* r) { return transform(new (C) CmpLNode(l, r)); } |
0 | 193 |
194 // TLS | |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
195 Node* thread() { return gvn().transform(new (C) ThreadLocalNode()); } |
0 | 196 |
197 // Pointers | |
8868
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
6842
diff
changeset
|
198 |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
6842
diff
changeset
|
199 // Raw address should be transformed regardless 'delay_transform' flag |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
6842
diff
changeset
|
200 // to produce canonical form CastX2P(offset). |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
6842
diff
changeset
|
201 Node* AddP(Node *base, Node *ptr, Node *off) { return _gvn.transform(new (C) AddPNode(base, ptr, off)); } |
30f42e691e70
8004640: C2 assert failure in memnode.cpp: NULL+offs not RAW address
kvn
parents:
6842
diff
changeset
|
202 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
203 Node* CmpP(Node* l, Node* r) { return transform(new (C) CmpPNode(l, r)); } |
0 | 204 #ifdef _LP64 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
205 Node* XorX(Node* l, Node* r) { return transform(new (C) XorLNode(l, r)); } |
0 | 206 #else // _LP64 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
207 Node* XorX(Node* l, Node* r) { return transform(new (C) XorINode(l, r)); } |
0 | 208 #endif // _LP64 |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
209 Node* URShiftX(Node* l, Node* r) { return transform(new (C) URShiftXNode(l, r)); } |
0 | 210 Node* ConX(jint k) { return (Node*)gvn().MakeConX(k); } |
6804
e626685e9f6c
7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents:
2468
diff
changeset
|
211 Node* CastPX(Node* ctl, Node* p) { return transform(new (C) CastP2XNode(ctl, p)); } |
0 | 212 |
213 // Memory operations | |
214 | |
215 // This is the base version which is given an alias index. | |
216 Node* load(Node* ctl, | |
217 Node* adr, | |
218 const Type* t, | |
219 BasicType bt, | |
220 int adr_idx, | |
221 bool require_atomic_access = false); | |
222 | |
223 // Return the new StoreXNode | |
224 Node* store(Node* ctl, | |
225 Node* adr, | |
226 Node* val, | |
227 BasicType bt, | |
228 int adr_idx, | |
229 bool require_atomic_access = false); | |
230 | |
231 // Store a card mark ordered after store_oop | |
232 Node* storeCM(Node* ctl, | |
233 Node* adr, | |
234 Node* val, | |
235 Node* oop_store, | |
985
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
851
diff
changeset
|
236 int oop_adr_idx, |
0 | 237 BasicType bt, |
238 int adr_idx); | |
239 | |
240 // Trivial call | |
241 void make_leaf_call(const TypeFunc *slow_call_type, | |
242 address slow_call, | |
243 const char *leaf_name, | |
244 Node* parm0, | |
245 Node* parm1 = NULL, | |
2444
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
246 Node* parm2 = NULL, |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
247 Node* parm3 = NULL); |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
248 |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
249 void make_leaf_call_no_fp(const TypeFunc *slow_call_type, |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
250 address slow_call, |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
251 const char *leaf_name, |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
252 const TypePtr* adr_type, |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
253 Node* parm0, |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
254 Node* parm1, |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
255 Node* parm2, |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
256 Node* parm3); |
07acc51c1d2a
7032314: Allow to generate CallLeafNoFPNode in IdealKit
kvn
parents:
2383
diff
changeset
|
257 |
0 | 258 }; |
1972 | 259 |
260 #endif // SHARE_VM_OPTO_IDEALKIT_HPP |