Mercurial > hg > truffle
annotate src/share/vm/opto/memnode.cpp @ 4710:41406797186b
7113012: G1: rename not-fully-young GCs as "mixed"
Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets).
Reviewed-by: johnc, brutisso
author | tonyp |
---|---|
date | Fri, 16 Dec 2011 02:14:27 -0500 |
parents | f745b2be3737 |
children | 069ab3f976d3 |
rev | line source |
---|---|
0 | 1 /* |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
2 * Copyright (c) 1997, 2011, 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:
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 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "compiler/compileLog.hpp" | |
28 #include "memory/allocation.inline.hpp" | |
29 #include "oops/objArrayKlass.hpp" | |
30 #include "opto/addnode.hpp" | |
31 #include "opto/cfgnode.hpp" | |
32 #include "opto/compile.hpp" | |
33 #include "opto/connode.hpp" | |
34 #include "opto/loopnode.hpp" | |
35 #include "opto/machnode.hpp" | |
36 #include "opto/matcher.hpp" | |
37 #include "opto/memnode.hpp" | |
38 #include "opto/mulnode.hpp" | |
39 #include "opto/phaseX.hpp" | |
40 #include "opto/regmask.hpp" | |
41 | |
0 | 42 // Portions of code courtesy of Clifford Click |
43 | |
44 // Optimization - Graph Style | |
45 | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
46 static Node *step_through_mergemem(PhaseGVN *phase, MergeMemNode *mmem, const TypePtr *tp, const TypePtr *adr_check, outputStream *st); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
47 |
0 | 48 //============================================================================= |
49 uint MemNode::size_of() const { return sizeof(*this); } | |
50 | |
51 const TypePtr *MemNode::adr_type() const { | |
52 Node* adr = in(Address); | |
53 const TypePtr* cross_check = NULL; | |
54 DEBUG_ONLY(cross_check = _adr_type); | |
55 return calculate_adr_type(adr->bottom_type(), cross_check); | |
56 } | |
57 | |
58 #ifndef PRODUCT | |
59 void MemNode::dump_spec(outputStream *st) const { | |
60 if (in(Address) == NULL) return; // node is dead | |
61 #ifndef ASSERT | |
62 // fake the missing field | |
63 const TypePtr* _adr_type = NULL; | |
64 if (in(Address) != NULL) | |
65 _adr_type = in(Address)->bottom_type()->isa_ptr(); | |
66 #endif | |
67 dump_adr_type(this, _adr_type, st); | |
68 | |
69 Compile* C = Compile::current(); | |
70 if( C->alias_type(_adr_type)->is_volatile() ) | |
71 st->print(" Volatile!"); | |
72 } | |
73 | |
74 void MemNode::dump_adr_type(const Node* mem, const TypePtr* adr_type, outputStream *st) { | |
75 st->print(" @"); | |
76 if (adr_type == NULL) { | |
77 st->print("NULL"); | |
78 } else { | |
79 adr_type->dump_on(st); | |
80 Compile* C = Compile::current(); | |
81 Compile::AliasType* atp = NULL; | |
82 if (C->have_alias_type(adr_type)) atp = C->alias_type(adr_type); | |
83 if (atp == NULL) | |
84 st->print(", idx=?\?;"); | |
85 else if (atp->index() == Compile::AliasIdxBot) | |
86 st->print(", idx=Bot;"); | |
87 else if (atp->index() == Compile::AliasIdxTop) | |
88 st->print(", idx=Top;"); | |
89 else if (atp->index() == Compile::AliasIdxRaw) | |
90 st->print(", idx=Raw;"); | |
91 else { | |
92 ciField* field = atp->field(); | |
93 if (field) { | |
94 st->print(", name="); | |
95 field->print_name_on(st); | |
96 } | |
97 st->print(", idx=%d;", atp->index()); | |
98 } | |
99 } | |
100 } | |
101 | |
102 extern void print_alias_types(); | |
103 | |
104 #endif | |
105 | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
106 Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
107 const TypeOopPtr *tinst = t_adr->isa_oopptr(); |
223 | 108 if (tinst == NULL || !tinst->is_known_instance_field()) |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
109 return mchain; // don't try to optimize non-instance types |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
110 uint instance_id = tinst->instance_id(); |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
111 Node *start_mem = phase->C->start()->proj_out(TypeFunc::Memory); |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
112 Node *prev = NULL; |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
113 Node *result = mchain; |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
114 while (prev != result) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
115 prev = result; |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
116 if (result == start_mem) |
605 | 117 break; // hit one of our sentinels |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
118 // skip over a call which does not affect this memory slice |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
119 if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
120 Node *proj_in = result->in(0); |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
121 if (proj_in->is_Allocate() && proj_in->_idx == instance_id) { |
605 | 122 break; // hit one of our sentinels |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
123 } else if (proj_in->is_Call()) { |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
124 CallNode *call = proj_in->as_Call(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
125 if (!call->may_modify(t_adr, phase)) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
126 result = call->in(TypeFunc::Memory); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
127 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
128 } else if (proj_in->is_Initialize()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
129 AllocateNode* alloc = proj_in->as_Initialize()->allocation(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
130 // Stop if this is the initialization for the object instance which |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
131 // which contains this memory slice, otherwise skip over it. |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
132 if (alloc != NULL && alloc->_idx != instance_id) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
133 result = proj_in->in(TypeFunc::Memory); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
134 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
135 } else if (proj_in->is_MemBar()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
136 result = proj_in->in(TypeFunc::Memory); |
253
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
137 } else { |
b0fe4deeb9fb
6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.")
kvn
parents:
247
diff
changeset
|
138 assert(false, "unexpected projection"); |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
139 } |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
140 } else if (result->is_ClearArray()) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
141 if (!ClearArrayNode::step_through(&result, instance_id, phase)) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
142 // Can not bypass initialization of the instance |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
143 // we are looking for. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
144 break; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
145 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
146 // Otherwise skip it (the call updated 'result' value). |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
147 } else if (result->is_MergeMem()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
148 result = step_through_mergemem(phase, result->as_MergeMem(), t_adr, NULL, tty); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
149 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
150 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
151 return result; |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
152 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
153 |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
154 Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
155 const TypeOopPtr *t_oop = t_adr->isa_oopptr(); |
223 | 156 bool is_instance = (t_oop != NULL) && t_oop->is_known_instance_field(); |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
157 PhaseIterGVN *igvn = phase->is_IterGVN(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
158 Node *result = mchain; |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
159 result = optimize_simple_memory_chain(result, t_adr, phase); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
160 if (is_instance && igvn != NULL && result->is_Phi()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
161 PhiNode *mphi = result->as_Phi(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
162 assert(mphi->bottom_type() == Type::MEMORY, "memory phi required"); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
163 const TypePtr *t = mphi->adr_type(); |
163 | 164 if (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM || |
223 | 165 t->isa_oopptr() && !t->is_oopptr()->is_known_instance() && |
247 | 166 t->is_oopptr()->cast_to_exactness(true) |
167 ->is_oopptr()->cast_to_ptr_type(t_oop->ptr()) | |
168 ->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop) { | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
169 // clone the Phi with our address type |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
170 result = mphi->split_out_instance(t_adr, igvn); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
171 } else { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
172 assert(phase->C->get_alias_index(t) == phase->C->get_alias_index(t_adr), "correct memory chain"); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
173 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
174 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
175 return result; |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
176 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
177 |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
178 static Node *step_through_mergemem(PhaseGVN *phase, MergeMemNode *mmem, const TypePtr *tp, const TypePtr *adr_check, outputStream *st) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
179 uint alias_idx = phase->C->get_alias_index(tp); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
180 Node *mem = mmem; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
181 #ifdef ASSERT |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
182 { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
183 // Check that current type is consistent with the alias index used during graph construction |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
184 assert(alias_idx >= Compile::AliasIdxRaw, "must not be a bad alias_idx"); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
185 bool consistent = adr_check == NULL || adr_check->empty() || |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
186 phase->C->must_alias(adr_check, alias_idx ); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
187 // Sometimes dead array references collapse to a[-1], a[-2], or a[-3] |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
188 if( !consistent && adr_check != NULL && !adr_check->empty() && |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
189 tp->isa_aryptr() && tp->offset() == Type::OffsetBot && |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
190 adr_check->isa_aryptr() && adr_check->offset() != Type::OffsetBot && |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
191 ( adr_check->offset() == arrayOopDesc::length_offset_in_bytes() || |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
192 adr_check->offset() == oopDesc::klass_offset_in_bytes() || |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
193 adr_check->offset() == oopDesc::mark_offset_in_bytes() ) ) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
194 // don't assert if it is dead code. |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
195 consistent = true; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
196 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
197 if( !consistent ) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
198 st->print("alias_idx==%d, adr_check==", alias_idx); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
199 if( adr_check == NULL ) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
200 st->print("NULL"); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
201 } else { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
202 adr_check->dump(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
203 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
204 st->cr(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
205 print_alias_types(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
206 assert(consistent, "adr_check must match alias idx"); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
207 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
208 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
209 #endif |
1815 | 210 // TypeOopPtr::NOTNULL+any is an OOP with unknown offset - generally |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
211 // means an array I have not precisely typed yet. Do not do any |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
212 // alias stuff with it any time soon. |
1815 | 213 const TypeOopPtr *toop = tp->isa_oopptr(); |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
214 if( tp->base() != Type::AnyPtr && |
1815 | 215 !(toop && |
216 toop->klass() != NULL && | |
217 toop->klass()->is_java_lang_Object() && | |
218 toop->offset() == Type::OffsetBot) ) { | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
219 // compress paths and change unreachable cycles to TOP |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
220 // If not, we can update the input infinitely along a MergeMem cycle |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
221 // Equivalent code in PhiNode::Ideal |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
222 Node* m = phase->transform(mmem); |
605 | 223 // If transformed to a MergeMem, get the desired slice |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
224 // Otherwise the returned node represents memory for every slice |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
225 mem = (m->is_MergeMem())? m->as_MergeMem()->memory_at(alias_idx) : m; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
226 // Update input if it is progress over what we have now |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
227 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
228 return mem; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
229 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
230 |
0 | 231 //--------------------------Ideal_common--------------------------------------- |
232 // Look for degenerate control and memory inputs. Bypass MergeMem inputs. | |
233 // Unhook non-raw memories from complete (macro-expanded) initializations. | |
234 Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) { | |
235 // If our control input is a dead region, kill all below the region | |
236 Node *ctl = in(MemNode::Control); | |
237 if (ctl && remove_dead_region(phase, can_reshape)) | |
238 return this; | |
305 | 239 ctl = in(MemNode::Control); |
240 // Don't bother trying to transform a dead node | |
241 if( ctl && ctl->is_top() ) return NodeSentinel; | |
0 | 242 |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
243 PhaseIterGVN *igvn = phase->is_IterGVN(); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
244 // Wait if control on the worklist. |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
245 if (ctl && can_reshape && igvn != NULL) { |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
246 Node* bol = NULL; |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
247 Node* cmp = NULL; |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
248 if (ctl->in(0)->is_If()) { |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
249 assert(ctl->is_IfTrue() || ctl->is_IfFalse(), "sanity"); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
250 bol = ctl->in(0)->in(1); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
251 if (bol->is_Bool()) |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
252 cmp = ctl->in(0)->in(1)->in(1); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
253 } |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
254 if (igvn->_worklist.member(ctl) || |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
255 (bol != NULL && igvn->_worklist.member(bol)) || |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
256 (cmp != NULL && igvn->_worklist.member(cmp)) ) { |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
257 // This control path may be dead. |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
258 // Delay this memory node transformation until the control is processed. |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
259 phase->is_IterGVN()->_worklist.push(this); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
260 return NodeSentinel; // caller will return NULL |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
261 } |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
262 } |
0 | 263 // Ignore if memory is dead, or self-loop |
264 Node *mem = in(MemNode::Memory); | |
265 if( phase->type( mem ) == Type::TOP ) return NodeSentinel; // caller will return NULL | |
266 assert( mem != this, "dead loop in MemNode::Ideal" ); | |
267 | |
4124
f745b2be3737
7117282: assert(base == NULL || t_adr->isa_rawptr() || !phase->type(base)
kvn
parents:
4115
diff
changeset
|
268 if (can_reshape && igvn != NULL && igvn->_worklist.member(mem)) { |
f745b2be3737
7117282: assert(base == NULL || t_adr->isa_rawptr() || !phase->type(base)
kvn
parents:
4115
diff
changeset
|
269 // This memory slice may be dead. |
f745b2be3737
7117282: assert(base == NULL || t_adr->isa_rawptr() || !phase->type(base)
kvn
parents:
4115
diff
changeset
|
270 // Delay this mem node transformation until the memory is processed. |
f745b2be3737
7117282: assert(base == NULL || t_adr->isa_rawptr() || !phase->type(base)
kvn
parents:
4115
diff
changeset
|
271 phase->is_IterGVN()->_worklist.push(this); |
f745b2be3737
7117282: assert(base == NULL || t_adr->isa_rawptr() || !phase->type(base)
kvn
parents:
4115
diff
changeset
|
272 return NodeSentinel; // caller will return NULL |
f745b2be3737
7117282: assert(base == NULL || t_adr->isa_rawptr() || !phase->type(base)
kvn
parents:
4115
diff
changeset
|
273 } |
f745b2be3737
7117282: assert(base == NULL || t_adr->isa_rawptr() || !phase->type(base)
kvn
parents:
4115
diff
changeset
|
274 |
0 | 275 Node *address = in(MemNode::Address); |
276 const Type *t_adr = phase->type( address ); | |
277 if( t_adr == Type::TOP ) return NodeSentinel; // caller will return NULL | |
278 | |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
279 if( can_reshape && igvn != NULL && |
1826
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1815
diff
changeset
|
280 (igvn->_worklist.member(address) || |
56601ef83436
6916062: assert(_inserts <= _insert_limit,"hash table overflow") in NodeHash::hash_insert
kvn
parents:
1815
diff
changeset
|
281 igvn->_worklist.size() > 0 && (phase->type(address) != adr_type())) ) { |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
282 // The address's base and type may change when the address is processed. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
283 // Delay this mem node transformation until the address is processed. |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
284 phase->is_IterGVN()->_worklist.push(this); |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
285 return NodeSentinel; // caller will return NULL |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
286 } |
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
366
diff
changeset
|
287 |
1062
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
288 // Do NOT remove or optimize the next lines: ensure a new alias index |
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
289 // is allocated for an oop pointer type before Escape Analysis. |
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
290 // Note: C++ will not remove it since the call has side effect. |
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
291 if ( t_adr->isa_oopptr() ) { |
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
292 int alias_idx = phase->C->get_alias_index(t_adr->is_ptr()); |
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
293 } |
dcdcc8c16e20
6896352: CTW fails hotspot/src/share/vm/opto/escape.cpp:1155
kvn
parents:
986
diff
changeset
|
294 |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
295 #ifdef ASSERT |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
296 Node* base = NULL; |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
297 if (address->is_AddP()) |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
298 base = address->in(AddPNode::Base); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
299 assert(base == NULL || t_adr->isa_rawptr() || |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
300 !phase->type(base)->higher_equal(TypePtr::NULL_PTR), "NULL+offs not RAW address?"); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
301 #endif |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
302 |
0 | 303 // Avoid independent memory operations |
304 Node* old_mem = mem; | |
305 | |
36 | 306 // The code which unhooks non-raw memories from complete (macro-expanded) |
307 // initializations was removed. After macro-expansion all stores catched | |
308 // by Initialize node became raw stores and there is no information | |
309 // which memory slices they modify. So it is unsafe to move any memory | |
310 // operation above these stores. Also in most cases hooked non-raw memories | |
311 // were already unhooked by using information from detect_ptr_independence() | |
312 // and find_previous_store(). | |
0 | 313 |
314 if (mem->is_MergeMem()) { | |
315 MergeMemNode* mmem = mem->as_MergeMem(); | |
316 const TypePtr *tp = t_adr->is_ptr(); | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
317 |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
318 mem = step_through_mergemem(phase, mmem, tp, adr_type(), tty); |
0 | 319 } |
320 | |
321 if (mem != old_mem) { | |
322 set_req(MemNode::Memory, mem); | |
305 | 323 if (phase->type( mem ) == Type::TOP) return NodeSentinel; |
0 | 324 return this; |
325 } | |
326 | |
327 // let the subclass continue analyzing... | |
328 return NULL; | |
329 } | |
330 | |
331 // Helper function for proving some simple control dominations. | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
332 // Attempt to prove that all control inputs of 'dom' dominate 'sub'. |
0 | 333 // Already assumes that 'dom' is available at 'sub', and that 'sub' |
334 // is not a constant (dominated by the method's StartNode). | |
335 // Used by MemNode::find_previous_store to prove that the | |
336 // control input of a memory operation predates (dominates) | |
337 // an allocation it wants to look past. | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
338 bool MemNode::all_controls_dominate(Node* dom, Node* sub) { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
339 if (dom == NULL || dom->is_top() || sub == NULL || sub->is_top()) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
340 return false; // Conservative answer for dead code |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
341 |
193
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
342 // Check 'dom'. Skip Proj and CatchProj nodes. |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
343 dom = dom->find_exact_control(dom); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
344 if (dom == NULL || dom->is_top()) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
345 return false; // Conservative answer for dead code |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
346 |
193
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
347 if (dom == sub) { |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
348 // For the case when, for example, 'sub' is Initialize and the original |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
349 // 'dom' is Proj node of the 'sub'. |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
350 return false; |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
351 } |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
352 |
155
723be81c1212
6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents:
128
diff
changeset
|
353 if (dom->is_Con() || dom->is_Start() || dom->is_Root() || dom == sub) |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
354 return true; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
355 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
356 // 'dom' dominates 'sub' if its control edge and control edges |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
357 // of all its inputs dominate or equal to sub's control edge. |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
358 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
359 // Currently 'sub' is either Allocate, Initialize or Start nodes. |
163 | 360 // Or Region for the check in LoadNode::Ideal(); |
361 // 'sub' should have sub->in(0) != NULL. | |
362 assert(sub->is_Allocate() || sub->is_Initialize() || sub->is_Start() || | |
363 sub->is_Region(), "expecting only these nodes"); | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
364 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
365 // Get control edge of 'sub'. |
193
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
366 Node* orig_sub = sub; |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
367 sub = sub->find_exact_control(sub->in(0)); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
368 if (sub == NULL || sub->is_top()) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
369 return false; // Conservative answer for dead code |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
370 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
371 assert(sub->is_CFG(), "expecting control"); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
372 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
373 if (sub == dom) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
374 return true; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
375 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
376 if (sub->is_Start() || sub->is_Root()) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
377 return false; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
378 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
379 { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
380 // Check all control edges of 'dom'. |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
381 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
382 ResourceMark rm; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
383 Arena* arena = Thread::current()->resource_area(); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
384 Node_List nlist(arena); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
385 Unique_Node_List dom_list(arena); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
386 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
387 dom_list.push(dom); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
388 bool only_dominating_controls = false; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
389 |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
390 for (uint next = 0; next < dom_list.size(); next++) { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
391 Node* n = dom_list.at(next); |
193
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
392 if (n == orig_sub) |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
393 return false; // One of dom's inputs dominated by sub. |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
394 if (!n->is_CFG() && n->pinned()) { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
395 // Check only own control edge for pinned non-control nodes. |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
396 n = n->find_exact_control(n->in(0)); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
397 if (n == NULL || n->is_top()) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
398 return false; // Conservative answer for dead code |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
399 assert(n->is_CFG(), "expecting control"); |
193
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
400 dom_list.push(n); |
44a553b2809d
6714406: Node::dominates() does not always check for TOP
kvn
parents:
169
diff
changeset
|
401 } else if (n->is_Con() || n->is_Start() || n->is_Root()) { |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
402 only_dominating_controls = true; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
403 } else if (n->is_CFG()) { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
404 if (n->dominates(sub, nlist)) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
405 only_dominating_controls = true; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
406 else |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
407 return false; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
408 } else { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
409 // First, own control edge. |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
410 Node* m = n->find_exact_control(n->in(0)); |
155
723be81c1212
6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents:
128
diff
changeset
|
411 if (m != NULL) { |
723be81c1212
6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents:
128
diff
changeset
|
412 if (m->is_top()) |
723be81c1212
6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents:
128
diff
changeset
|
413 return false; // Conservative answer for dead code |
723be81c1212
6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents:
128
diff
changeset
|
414 dom_list.push(m); |
723be81c1212
6701887: JDK7 server VM in endless loop in Node::dominates
kvn
parents:
128
diff
changeset
|
415 } |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
416 // Now, the rest of edges. |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
417 uint cnt = n->req(); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
418 for (uint i = 1; i < cnt; i++) { |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
419 m = n->find_exact_control(n->in(i)); |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
420 if (m == NULL || m->is_top()) |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
421 continue; |
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
422 dom_list.push(m); |
0 | 423 } |
424 } | |
425 } | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
426 return only_dominating_controls; |
0 | 427 } |
428 } | |
429 | |
430 //---------------------detect_ptr_independence--------------------------------- | |
431 // Used by MemNode::find_previous_store to prove that two base | |
432 // pointers are never equal. | |
433 // The pointers are accompanied by their associated allocations, | |
434 // if any, which have been previously discovered by the caller. | |
435 bool MemNode::detect_ptr_independence(Node* p1, AllocateNode* a1, | |
436 Node* p2, AllocateNode* a2, | |
437 PhaseTransform* phase) { | |
438 // Attempt to prove that these two pointers cannot be aliased. | |
439 // They may both manifestly be allocations, and they should differ. | |
440 // Or, if they are not both allocations, they can be distinct constants. | |
441 // Otherwise, one is an allocation and the other a pre-existing value. | |
442 if (a1 == NULL && a2 == NULL) { // neither an allocation | |
443 return (p1 != p2) && p1->is_Con() && p2->is_Con(); | |
444 } else if (a1 != NULL && a2 != NULL) { // both allocations | |
445 return (a1 != a2); | |
446 } else if (a1 != NULL) { // one allocation a1 | |
447 // (Note: p2->is_Con implies p2->in(0)->is_Root, which dominates.) | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
448 return all_controls_dominate(p2, a1); |
0 | 449 } else { //(a2 != NULL) // one allocation a2 |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
450 return all_controls_dominate(p1, a2); |
0 | 451 } |
452 return false; | |
453 } | |
454 | |
455 | |
456 // The logic for reordering loads and stores uses four steps: | |
457 // (a) Walk carefully past stores and initializations which we | |
458 // can prove are independent of this load. | |
459 // (b) Observe that the next memory state makes an exact match | |
460 // with self (load or store), and locate the relevant store. | |
461 // (c) Ensure that, if we were to wire self directly to the store, | |
462 // the optimizer would fold it up somehow. | |
463 // (d) Do the rewiring, and return, depending on some other part of | |
464 // the optimizer to fold up the load. | |
465 // This routine handles steps (a) and (b). Steps (c) and (d) are | |
466 // specific to loads and stores, so they are handled by the callers. | |
467 // (Currently, only LoadNode::Ideal has steps (c), (d). More later.) | |
468 // | |
469 Node* MemNode::find_previous_store(PhaseTransform* phase) { | |
470 Node* ctrl = in(MemNode::Control); | |
471 Node* adr = in(MemNode::Address); | |
472 intptr_t offset = 0; | |
473 Node* base = AddPNode::Ideal_base_and_offset(adr, phase, offset); | |
474 AllocateNode* alloc = AllocateNode::Ideal_allocation(base, phase); | |
475 | |
476 if (offset == Type::OffsetBot) | |
477 return NULL; // cannot unalias unless there are precise offsets | |
478 | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
479 const TypeOopPtr *addr_t = adr->bottom_type()->isa_oopptr(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
480 |
0 | 481 intptr_t size_in_bytes = memory_size(); |
482 | |
483 Node* mem = in(MemNode::Memory); // start searching here... | |
484 | |
485 int cnt = 50; // Cycle limiter | |
486 for (;;) { // While we can dance past unrelated stores... | |
487 if (--cnt < 0) break; // Caught in cycle or a complicated dance? | |
488 | |
489 if (mem->is_Store()) { | |
490 Node* st_adr = mem->in(MemNode::Address); | |
491 intptr_t st_offset = 0; | |
492 Node* st_base = AddPNode::Ideal_base_and_offset(st_adr, phase, st_offset); | |
493 if (st_base == NULL) | |
494 break; // inscrutable pointer | |
495 if (st_offset != offset && st_offset != Type::OffsetBot) { | |
496 const int MAX_STORE = BytesPerLong; | |
497 if (st_offset >= offset + size_in_bytes || | |
498 st_offset <= offset - MAX_STORE || | |
499 st_offset <= offset - mem->as_Store()->memory_size()) { | |
500 // Success: The offsets are provably independent. | |
501 // (You may ask, why not just test st_offset != offset and be done? | |
502 // The answer is that stores of different sizes can co-exist | |
503 // in the same sequence of RawMem effects. We sometimes initialize | |
504 // a whole 'tile' of array elements with a single jint or jlong.) | |
505 mem = mem->in(MemNode::Memory); | |
506 continue; // (a) advance through independent store memory | |
507 } | |
508 } | |
509 if (st_base != base && | |
510 detect_ptr_independence(base, alloc, | |
511 st_base, | |
512 AllocateNode::Ideal_allocation(st_base, phase), | |
513 phase)) { | |
514 // Success: The bases are provably independent. | |
515 mem = mem->in(MemNode::Memory); | |
516 continue; // (a) advance through independent store memory | |
517 } | |
518 | |
519 // (b) At this point, if the bases or offsets do not agree, we lose, | |
520 // since we have not managed to prove 'this' and 'mem' independent. | |
521 if (st_base == base && st_offset == offset) { | |
522 return mem; // let caller handle steps (c), (d) | |
523 } | |
524 | |
525 } else if (mem->is_Proj() && mem->in(0)->is_Initialize()) { | |
526 InitializeNode* st_init = mem->in(0)->as_Initialize(); | |
527 AllocateNode* st_alloc = st_init->allocation(); | |
528 if (st_alloc == NULL) | |
529 break; // something degenerated | |
530 bool known_identical = false; | |
531 bool known_independent = false; | |
532 if (alloc == st_alloc) | |
533 known_identical = true; | |
534 else if (alloc != NULL) | |
535 known_independent = true; | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
536 else if (all_controls_dominate(this, st_alloc)) |
0 | 537 known_independent = true; |
538 | |
539 if (known_independent) { | |
540 // The bases are provably independent: Either they are | |
541 // manifestly distinct allocations, or else the control | |
542 // of this load dominates the store's allocation. | |
543 int alias_idx = phase->C->get_alias_index(adr_type()); | |
544 if (alias_idx == Compile::AliasIdxRaw) { | |
545 mem = st_alloc->in(TypeFunc::Memory); | |
546 } else { | |
547 mem = st_init->memory(alias_idx); | |
548 } | |
549 continue; // (a) advance through independent store memory | |
550 } | |
551 | |
552 // (b) at this point, if we are not looking at a store initializing | |
553 // the same allocation we are loading from, we lose. | |
554 if (known_identical) { | |
555 // From caller, can_see_stored_value will consult find_captured_store. | |
556 return mem; // let caller handle steps (c), (d) | |
557 } | |
558 | |
223 | 559 } else if (addr_t != NULL && addr_t->is_known_instance_field()) { |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
560 // Can't use optimize_simple_memory_chain() since it needs PhaseGVN. |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
561 if (mem->is_Proj() && mem->in(0)->is_Call()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
562 CallNode *call = mem->in(0)->as_Call(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
563 if (!call->may_modify(addr_t, phase)) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
564 mem = call->in(TypeFunc::Memory); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
565 continue; // (a) advance through independent call memory |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
566 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
567 } else if (mem->is_Proj() && mem->in(0)->is_MemBar()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
568 mem = mem->in(0)->in(TypeFunc::Memory); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
569 continue; // (a) advance through independent MemBar memory |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
570 } else if (mem->is_ClearArray()) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
571 if (ClearArrayNode::step_through(&mem, (uint)addr_t->instance_id(), phase)) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
572 // (the call updated 'mem' value) |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
573 continue; // (a) advance through independent allocation memory |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
574 } else { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
575 // Can not bypass initialization of the instance |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
576 // we are looking for. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
577 return mem; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
578 } |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
579 } else if (mem->is_MergeMem()) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
580 int alias_idx = phase->C->get_alias_index(adr_type()); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
581 mem = mem->as_MergeMem()->memory_at(alias_idx); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
582 continue; // (a) advance through independent MergeMem memory |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
583 } |
0 | 584 } |
585 | |
586 // Unless there is an explicit 'continue', we must bail out here, | |
587 // because 'mem' is an inscrutable memory state (e.g., a call). | |
588 break; | |
589 } | |
590 | |
591 return NULL; // bail out | |
592 } | |
593 | |
594 //----------------------calculate_adr_type------------------------------------- | |
595 // Helper function. Notices when the given type of address hits top or bottom. | |
596 // Also, asserts a cross-check of the type against the expected address type. | |
597 const TypePtr* MemNode::calculate_adr_type(const Type* t, const TypePtr* cross_check) { | |
598 if (t == Type::TOP) return NULL; // does not touch memory any more? | |
599 #ifdef PRODUCT | |
600 cross_check = NULL; | |
601 #else | |
602 if (!VerifyAliases || is_error_reported() || Node::in_dump()) cross_check = NULL; | |
603 #endif | |
604 const TypePtr* tp = t->isa_ptr(); | |
605 if (tp == NULL) { | |
606 assert(cross_check == NULL || cross_check == TypePtr::BOTTOM, "expected memory type must be wide"); | |
607 return TypePtr::BOTTOM; // touches lots of memory | |
608 } else { | |
609 #ifdef ASSERT | |
610 // %%%% [phh] We don't check the alias index if cross_check is | |
611 // TypeRawPtr::BOTTOM. Needs to be investigated. | |
612 if (cross_check != NULL && | |
613 cross_check != TypePtr::BOTTOM && | |
614 cross_check != TypeRawPtr::BOTTOM) { | |
615 // Recheck the alias index, to see if it has changed (due to a bug). | |
616 Compile* C = Compile::current(); | |
617 assert(C->get_alias_index(cross_check) == C->get_alias_index(tp), | |
618 "must stay in the original alias category"); | |
619 // The type of the address must be contained in the adr_type, | |
620 // disregarding "null"-ness. | |
621 // (We make an exception for TypeRawPtr::BOTTOM, which is a bit bucket.) | |
622 const TypePtr* tp_notnull = tp->join(TypePtr::NOTNULL)->is_ptr(); | |
623 assert(cross_check->meet(tp_notnull) == cross_check, | |
624 "real address must not escape from expected memory type"); | |
625 } | |
626 #endif | |
627 return tp; | |
628 } | |
629 } | |
630 | |
631 //------------------------adr_phi_is_loop_invariant---------------------------- | |
632 // A helper function for Ideal_DU_postCCP to check if a Phi in a counted | |
633 // loop is loop invariant. Make a quick traversal of Phi and associated | |
634 // CastPP nodes, looking to see if they are a closed group within the loop. | |
635 bool MemNode::adr_phi_is_loop_invariant(Node* adr_phi, Node* cast) { | |
636 // The idea is that the phi-nest must boil down to only CastPP nodes | |
637 // with the same data. This implies that any path into the loop already | |
638 // includes such a CastPP, and so the original cast, whatever its input, | |
639 // must be covered by an equivalent cast, with an earlier control input. | |
640 ResourceMark rm; | |
641 | |
642 // The loop entry input of the phi should be the unique dominating | |
643 // node for every Phi/CastPP in the loop. | |
644 Unique_Node_List closure; | |
645 closure.push(adr_phi->in(LoopNode::EntryControl)); | |
646 | |
647 // Add the phi node and the cast to the worklist. | |
648 Unique_Node_List worklist; | |
649 worklist.push(adr_phi); | |
650 if( cast != NULL ){ | |
651 if( !cast->is_ConstraintCast() ) return false; | |
652 worklist.push(cast); | |
653 } | |
654 | |
655 // Begin recursive walk of phi nodes. | |
656 while( worklist.size() ){ | |
657 // Take a node off the worklist | |
658 Node *n = worklist.pop(); | |
659 if( !closure.member(n) ){ | |
660 // Add it to the closure. | |
661 closure.push(n); | |
662 // Make a sanity check to ensure we don't waste too much time here. | |
663 if( closure.size() > 20) return false; | |
664 // This node is OK if: | |
665 // - it is a cast of an identical value | |
666 // - or it is a phi node (then we add its inputs to the worklist) | |
667 // Otherwise, the node is not OK, and we presume the cast is not invariant | |
668 if( n->is_ConstraintCast() ){ | |
669 worklist.push(n->in(1)); | |
670 } else if( n->is_Phi() ) { | |
671 for( uint i = 1; i < n->req(); i++ ) { | |
672 worklist.push(n->in(i)); | |
673 } | |
674 } else { | |
675 return false; | |
676 } | |
677 } | |
678 } | |
679 | |
680 // Quit when the worklist is empty, and we've found no offending nodes. | |
681 return true; | |
682 } | |
683 | |
684 //------------------------------Ideal_DU_postCCP------------------------------- | |
685 // Find any cast-away of null-ness and keep its control. Null cast-aways are | |
686 // going away in this pass and we need to make this memory op depend on the | |
687 // gating null check. | |
163 | 688 Node *MemNode::Ideal_DU_postCCP( PhaseCCP *ccp ) { |
689 return Ideal_common_DU_postCCP(ccp, this, in(MemNode::Address)); | |
690 } | |
0 | 691 |
692 // I tried to leave the CastPP's in. This makes the graph more accurate in | |
693 // some sense; we get to keep around the knowledge that an oop is not-null | |
694 // after some test. Alas, the CastPP's interfere with GVN (some values are | |
695 // the regular oop, some are the CastPP of the oop, all merge at Phi's which | |
696 // cannot collapse, etc). This cost us 10% on SpecJVM, even when I removed | |
697 // some of the more trivial cases in the optimizer. Removing more useless | |
698 // Phi's started allowing Loads to illegally float above null checks. I gave | |
699 // up on this approach. CNC 10/20/2000 | |
163 | 700 // This static method may be called not from MemNode (EncodePNode calls it). |
701 // Only the control edge of the node 'n' might be updated. | |
702 Node *MemNode::Ideal_common_DU_postCCP( PhaseCCP *ccp, Node* n, Node* adr ) { | |
0 | 703 Node *skipped_cast = NULL; |
704 // Need a null check? Regular static accesses do not because they are | |
705 // from constant addresses. Array ops are gated by the range check (which | |
706 // always includes a NULL check). Just check field ops. | |
163 | 707 if( n->in(MemNode::Control) == NULL ) { |
0 | 708 // Scan upwards for the highest location we can place this memory op. |
709 while( true ) { | |
710 switch( adr->Opcode() ) { | |
711 | |
712 case Op_AddP: // No change to NULL-ness, so peek thru AddP's | |
713 adr = adr->in(AddPNode::Base); | |
714 continue; | |
715 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
716 case Op_DecodeN: // No change to NULL-ness, so peek thru |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
717 adr = adr->in(1); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
718 continue; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
719 |
0 | 720 case Op_CastPP: |
721 // If the CastPP is useless, just peek on through it. | |
722 if( ccp->type(adr) == ccp->type(adr->in(1)) ) { | |
723 // Remember the cast that we've peeked though. If we peek | |
724 // through more than one, then we end up remembering the highest | |
725 // one, that is, if in a loop, the one closest to the top. | |
726 skipped_cast = adr; | |
727 adr = adr->in(1); | |
728 continue; | |
729 } | |
730 // CastPP is going away in this pass! We need this memory op to be | |
731 // control-dependent on the test that is guarding the CastPP. | |
163 | 732 ccp->hash_delete(n); |
733 n->set_req(MemNode::Control, adr->in(0)); | |
734 ccp->hash_insert(n); | |
735 return n; | |
0 | 736 |
737 case Op_Phi: | |
738 // Attempt to float above a Phi to some dominating point. | |
739 if (adr->in(0) != NULL && adr->in(0)->is_CountedLoop()) { | |
740 // If we've already peeked through a Cast (which could have set the | |
741 // control), we can't float above a Phi, because the skipped Cast | |
742 // may not be loop invariant. | |
743 if (adr_phi_is_loop_invariant(adr, skipped_cast)) { | |
744 adr = adr->in(1); | |
745 continue; | |
746 } | |
747 } | |
748 | |
749 // Intentional fallthrough! | |
750 | |
751 // No obvious dominating point. The mem op is pinned below the Phi | |
752 // by the Phi itself. If the Phi goes away (no true value is merged) | |
753 // then the mem op can float, but not indefinitely. It must be pinned | |
754 // behind the controls leading to the Phi. | |
755 case Op_CheckCastPP: | |
756 // These usually stick around to change address type, however a | |
757 // useless one can be elided and we still need to pick up a control edge | |
758 if (adr->in(0) == NULL) { | |
759 // This CheckCastPP node has NO control and is likely useless. But we | |
760 // need check further up the ancestor chain for a control input to keep | |
761 // the node in place. 4959717. | |
762 skipped_cast = adr; | |
763 adr = adr->in(1); | |
764 continue; | |
765 } | |
163 | 766 ccp->hash_delete(n); |
767 n->set_req(MemNode::Control, adr->in(0)); | |
768 ccp->hash_insert(n); | |
769 return n; | |
0 | 770 |
771 // List of "safe" opcodes; those that implicitly block the memory | |
772 // op below any null check. | |
773 case Op_CastX2P: // no null checks on native pointers | |
774 case Op_Parm: // 'this' pointer is not null | |
775 case Op_LoadP: // Loading from within a klass | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
776 case Op_LoadN: // Loading from within a klass |
0 | 777 case Op_LoadKlass: // Loading from within a klass |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
778 case Op_LoadNKlass: // Loading from within a klass |
0 | 779 case Op_ConP: // Loading from a klass |
163 | 780 case Op_ConN: // Loading from a klass |
0 | 781 case Op_CreateEx: // Sucking up the guts of an exception oop |
782 case Op_Con: // Reading from TLS | |
783 case Op_CMoveP: // CMoveP is pinned | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
784 case Op_CMoveN: // CMoveN is pinned |
0 | 785 break; // No progress |
786 | |
787 case Op_Proj: // Direct call to an allocation routine | |
788 case Op_SCMemProj: // Memory state from store conditional ops | |
789 #ifdef ASSERT | |
790 { | |
791 assert(adr->as_Proj()->_con == TypeFunc::Parms, "must be return value"); | |
792 const Node* call = adr->in(0); | |
163 | 793 if (call->is_CallJava()) { |
794 const CallJavaNode* call_java = call->as_CallJava(); | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
795 const TypeTuple *r = call_java->tf()->range(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
796 assert(r->cnt() > TypeFunc::Parms, "must return value"); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
797 const Type* ret_type = r->field_at(TypeFunc::Parms); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
798 assert(ret_type && ret_type->isa_ptr(), "must return pointer"); |
0 | 799 // We further presume that this is one of |
800 // new_instance_Java, new_array_Java, or | |
801 // the like, but do not assert for this. | |
802 } else if (call->is_Allocate()) { | |
803 // similar case to new_instance_Java, etc. | |
804 } else if (!call->is_CallLeaf()) { | |
805 // Projections from fetch_oop (OSR) are allowed as well. | |
806 ShouldNotReachHere(); | |
807 } | |
808 } | |
809 #endif | |
810 break; | |
811 default: | |
812 ShouldNotReachHere(); | |
813 } | |
814 break; | |
815 } | |
816 } | |
817 | |
818 return NULL; // No progress | |
819 } | |
820 | |
821 | |
822 //============================================================================= | |
823 uint LoadNode::size_of() const { return sizeof(*this); } | |
824 uint LoadNode::cmp( const Node &n ) const | |
825 { return !Type::cmp( _type, ((LoadNode&)n)._type ); } | |
826 const Type *LoadNode::bottom_type() const { return _type; } | |
827 uint LoadNode::ideal_reg() const { | |
828 return Matcher::base2reg[_type->base()]; | |
829 } | |
830 | |
831 #ifndef PRODUCT | |
832 void LoadNode::dump_spec(outputStream *st) const { | |
833 MemNode::dump_spec(st); | |
834 if( !Verbose && !WizardMode ) { | |
835 // standard dump does this in Verbose and WizardMode | |
836 st->print(" #"); _type->dump_on(st); | |
837 } | |
838 } | |
839 #endif | |
840 | |
1609 | 841 #ifdef ASSERT |
842 //----------------------------is_immutable_value------------------------------- | |
843 // Helper function to allow a raw load without control edge for some cases | |
844 bool LoadNode::is_immutable_value(Node* adr) { | |
845 return (adr->is_AddP() && adr->in(AddPNode::Base)->is_top() && | |
846 adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal && | |
847 (adr->in(AddPNode::Offset)->find_intptr_t_con(-1) == | |
848 in_bytes(JavaThread::osthread_offset()))); | |
849 } | |
850 #endif | |
0 | 851 |
852 //----------------------------LoadNode::make----------------------------------- | |
853 // Polymorphic factory method: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
854 Node *LoadNode::make( PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const TypePtr* adr_type, const Type *rt, BasicType bt ) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
855 Compile* C = gvn.C; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
856 |
0 | 857 // sanity check the alias category against the created node type |
858 assert(!(adr_type->isa_oopptr() && | |
859 adr_type->offset() == oopDesc::klass_offset_in_bytes()), | |
860 "use LoadKlassNode instead"); | |
861 assert(!(adr_type->isa_aryptr() && | |
862 adr_type->offset() == arrayOopDesc::length_offset_in_bytes()), | |
863 "use LoadRangeNode instead"); | |
1609 | 864 // Check control edge of raw loads |
865 assert( ctl != NULL || C->get_alias_index(adr_type) != Compile::AliasIdxRaw || | |
866 // oop will be recorded in oop map if load crosses safepoint | |
867 rt->isa_oopptr() || is_immutable_value(adr), | |
868 "raw memory operations should have control edge"); | |
0 | 869 switch (bt) { |
624 | 870 case T_BOOLEAN: return new (C, 3) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int() ); |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
871 case T_BYTE: return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
872 case T_INT: return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int() ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
873 case T_CHAR: return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int() ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
874 case T_SHORT: return new (C, 3) LoadSNode (ctl, mem, adr, adr_type, rt->is_int() ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
875 case T_LONG: return new (C, 3) LoadLNode (ctl, mem, adr, adr_type, rt->is_long() ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
876 case T_FLOAT: return new (C, 3) LoadFNode (ctl, mem, adr, adr_type, rt ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
877 case T_DOUBLE: return new (C, 3) LoadDNode (ctl, mem, adr, adr_type, rt ); |
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
878 case T_ADDRESS: return new (C, 3) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr() ); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
879 case T_OBJECT: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
880 #ifdef _LP64 |
163 | 881 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
882 Node* load = gvn.transform(new (C, 3) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop())); |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
883 return new (C, 2) DecodeNNode(load, load->bottom_type()->make_ptr()); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
884 } else |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
885 #endif |
163 | 886 { |
887 assert(!adr->bottom_type()->is_ptr_to_narrowoop(), "should have got back a narrow oop"); | |
888 return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr()); | |
889 } | |
0 | 890 } |
891 ShouldNotReachHere(); | |
892 return (LoadNode*)NULL; | |
893 } | |
894 | |
895 LoadLNode* LoadLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt) { | |
896 bool require_atomic = true; | |
897 return new (C, 3) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), require_atomic); | |
898 } | |
899 | |
900 | |
901 | |
902 | |
903 //------------------------------hash------------------------------------------- | |
904 uint LoadNode::hash() const { | |
905 // unroll addition of interesting fields | |
906 return (uintptr_t)in(Control) + (uintptr_t)in(Memory) + (uintptr_t)in(Address); | |
907 } | |
908 | |
909 //---------------------------can_see_stored_value------------------------------ | |
910 // This routine exists to make sure this set of tests is done the same | |
911 // everywhere. We need to make a coordinated change: first LoadNode::Ideal | |
912 // will change the graph shape in a way which makes memory alive twice at the | |
913 // same time (uses the Oracle model of aliasing), then some | |
914 // LoadXNode::Identity will fold things back to the equivalence-class model | |
915 // of aliasing. | |
916 Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const { | |
917 Node* ld_adr = in(MemNode::Address); | |
918 | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
919 const TypeInstPtr* tp = phase->type(ld_adr)->isa_instptr(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
920 Compile::AliasType* atp = tp != NULL ? phase->C->alias_type(tp) : NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
921 if (EliminateAutoBox && atp != NULL && atp->index() >= Compile::AliasIdxRaw && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
922 atp->field() != NULL && !atp->field()->is_volatile()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
923 uint alias_idx = atp->index(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
924 bool final = atp->field()->is_final(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
925 Node* result = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
926 Node* current = st; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
927 // Skip through chains of MemBarNodes checking the MergeMems for |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
928 // new states for the slice of this load. Stop once any other |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
929 // kind of node is encountered. Loads from final memory can skip |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
930 // through any kind of MemBar but normal loads shouldn't skip |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
931 // through MemBarAcquire since the could allow them to move out of |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
932 // a synchronized region. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
933 while (current->is_Proj()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
934 int opc = current->in(0)->Opcode(); |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3284
diff
changeset
|
935 if ((final && (opc == Op_MemBarAcquire || opc == Op_MemBarAcquireLock)) || |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3284
diff
changeset
|
936 opc == Op_MemBarRelease || opc == Op_MemBarCPUOrder || |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3284
diff
changeset
|
937 opc == Op_MemBarReleaseLock) { |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
938 Node* mem = current->in(0)->in(TypeFunc::Memory); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
939 if (mem->is_MergeMem()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
940 MergeMemNode* merge = mem->as_MergeMem(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
941 Node* new_st = merge->memory_at(alias_idx); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
942 if (new_st == merge->base_memory()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
943 // Keep searching |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
944 current = merge->base_memory(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
945 continue; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
946 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
947 // Save the new memory state for the slice and fall through |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
948 // to exit. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
949 result = new_st; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
950 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
951 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
952 break; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
953 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
954 if (result != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
955 st = result; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
956 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
957 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
958 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
959 |
0 | 960 // Loop around twice in the case Load -> Initialize -> Store. |
961 // (See PhaseIterGVN::add_users_to_worklist, which knows about this case.) | |
962 for (int trip = 0; trip <= 1; trip++) { | |
963 | |
964 if (st->is_Store()) { | |
965 Node* st_adr = st->in(MemNode::Address); | |
966 if (!phase->eqv(st_adr, ld_adr)) { | |
967 // Try harder before giving up... Match raw and non-raw pointers. | |
968 intptr_t st_off = 0; | |
969 AllocateNode* alloc = AllocateNode::Ideal_allocation(st_adr, phase, st_off); | |
970 if (alloc == NULL) return NULL; | |
971 intptr_t ld_off = 0; | |
972 AllocateNode* allo2 = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off); | |
973 if (alloc != allo2) return NULL; | |
974 if (ld_off != st_off) return NULL; | |
975 // At this point we have proven something like this setup: | |
976 // A = Allocate(...) | |
977 // L = LoadQ(, AddP(CastPP(, A.Parm),, #Off)) | |
978 // S = StoreQ(, AddP(, A.Parm , #Off), V) | |
979 // (Actually, we haven't yet proven the Q's are the same.) | |
980 // In other words, we are loading from a casted version of | |
981 // the same pointer-and-offset that we stored to. | |
982 // Thus, we are able to replace L by V. | |
983 } | |
984 // Now prove that we have a LoadQ matched to a StoreQ, for some Q. | |
985 if (store_Opcode() != st->Opcode()) | |
986 return NULL; | |
987 return st->in(MemNode::ValueIn); | |
988 } | |
989 | |
990 intptr_t offset = 0; // scratch | |
991 | |
992 // A load from a freshly-created object always returns zero. | |
993 // (This can happen after LoadNode::Ideal resets the load's memory input | |
994 // to find_captured_store, which returned InitializeNode::zero_memory.) | |
995 if (st->is_Proj() && st->in(0)->is_Allocate() && | |
996 st->in(0) == AllocateNode::Ideal_allocation(ld_adr, phase, offset) && | |
997 offset >= st->in(0)->as_Allocate()->minimum_header_size()) { | |
998 // return a zero value for the load's basic type | |
999 // (This is one of the few places where a generic PhaseTransform | |
1000 // can create new nodes. Think of it as lazily manifesting | |
1001 // virtually pre-existing constants.) | |
1002 return phase->zerocon(memory_type()); | |
1003 } | |
1004 | |
1005 // A load from an initialization barrier can match a captured store. | |
1006 if (st->is_Proj() && st->in(0)->is_Initialize()) { | |
1007 InitializeNode* init = st->in(0)->as_Initialize(); | |
1008 AllocateNode* alloc = init->allocation(); | |
1009 if (alloc != NULL && | |
1010 alloc == AllocateNode::Ideal_allocation(ld_adr, phase, offset)) { | |
1011 // examine a captured store value | |
1012 st = init->find_captured_store(offset, memory_size(), phase); | |
1013 if (st != NULL) | |
1014 continue; // take one more trip around | |
1015 } | |
1016 } | |
1017 | |
1018 break; | |
1019 } | |
1020 | |
1021 return NULL; | |
1022 } | |
1023 | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1024 //----------------------is_instance_field_load_with_local_phi------------------ |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1025 bool LoadNode::is_instance_field_load_with_local_phi(Node* ctrl) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1026 if( in(MemNode::Memory)->is_Phi() && in(MemNode::Memory)->in(0) == ctrl && |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1027 in(MemNode::Address)->is_AddP() ) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1028 const TypeOopPtr* t_oop = in(MemNode::Address)->bottom_type()->isa_oopptr(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1029 // Only instances. |
223 | 1030 if( t_oop != NULL && t_oop->is_known_instance_field() && |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1031 t_oop->offset() != Type::OffsetBot && |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1032 t_oop->offset() != Type::OffsetTop) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1033 return true; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1034 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1035 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1036 return false; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1037 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1038 |
0 | 1039 //------------------------------Identity--------------------------------------- |
1040 // Loads are identity if previous store is to same address | |
1041 Node *LoadNode::Identity( PhaseTransform *phase ) { | |
1042 // If the previous store-maker is the right kind of Store, and the store is | |
1043 // to the same address, then we are equal to the value stored. | |
1044 Node* mem = in(MemNode::Memory); | |
1045 Node* value = can_see_stored_value(mem, phase); | |
1046 if( value ) { | |
1047 // byte, short & char stores truncate naturally. | |
1048 // A load has to load the truncated value which requires | |
1049 // some sort of masking operation and that requires an | |
1050 // Ideal call instead of an Identity call. | |
1051 if (memory_size() < BytesPerInt) { | |
1052 // If the input to the store does not fit with the load's result type, | |
1053 // it must be truncated via an Ideal call. | |
1054 if (!phase->type(value)->higher_equal(phase->type(this))) | |
1055 return this; | |
1056 } | |
1057 // (This works even when value is a Con, but LoadNode::Value | |
1058 // usually runs first, producing the singleton type of the Con.) | |
1059 return value; | |
1060 } | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1061 |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1062 // Search for an existing data phi which was generated before for the same |
605 | 1063 // instance's field to avoid infinite generation of phis in a loop. |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1064 Node *region = mem->in(0); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1065 if (is_instance_field_load_with_local_phi(region)) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1066 const TypePtr *addr_t = in(MemNode::Address)->bottom_type()->isa_ptr(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1067 int this_index = phase->C->get_alias_index(addr_t); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1068 int this_offset = addr_t->offset(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1069 int this_id = addr_t->is_oopptr()->instance_id(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1070 const Type* this_type = bottom_type(); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1071 for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1072 Node* phi = region->fast_out(i); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1073 if (phi->is_Phi() && phi != mem && |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1074 phi->as_Phi()->is_same_inst_field(this_type, this_id, this_index, this_offset)) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1075 return phi; |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1076 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1077 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1078 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1079 |
0 | 1080 return this; |
1081 } | |
1082 | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1083 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1084 // Returns true if the AliasType refers to the field that holds the |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1085 // cached box array. Currently only handles the IntegerCache case. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1086 static bool is_autobox_cache(Compile::AliasType* atp) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1087 if (atp != NULL && atp->field() != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1088 ciField* field = atp->field(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1089 ciSymbol* klass = field->holder()->name(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1090 if (field->name() == ciSymbol::cache_field_name() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1091 field->holder()->uses_default_loader() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1092 klass == ciSymbol::java_lang_Integer_IntegerCache()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1093 return true; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1094 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1095 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1096 return false; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1097 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1098 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1099 // Fetch the base value in the autobox array |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1100 static bool fetch_autobox_base(Compile::AliasType* atp, int& cache_offset) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1101 if (atp != NULL && atp->field() != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1102 ciField* field = atp->field(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1103 ciSymbol* klass = field->holder()->name(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1104 if (field->name() == ciSymbol::cache_field_name() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1105 field->holder()->uses_default_loader() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1106 klass == ciSymbol::java_lang_Integer_IntegerCache()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1107 assert(field->is_constant(), "what?"); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1108 ciObjArray* array = field->constant_value().as_object()->as_obj_array(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1109 // Fetch the box object at the base of the array and get its value |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1110 ciInstance* box = array->obj_at(0)->as_instance(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1111 ciInstanceKlass* ik = box->klass()->as_instance_klass(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1112 if (ik->nof_nonstatic_fields() == 1) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1113 // This should be true nonstatic_field_at requires calling |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1114 // nof_nonstatic_fields so check it anyway |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1115 ciConstant c = box->field_value(ik->nonstatic_field_at(0)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1116 cache_offset = c.as_int(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1117 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1118 return true; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1119 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1120 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1121 return false; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1122 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1123 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1124 // Returns true if the AliasType refers to the value field of an |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1125 // autobox object. Currently only handles Integer. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1126 static bool is_autobox_object(Compile::AliasType* atp) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1127 if (atp != NULL && atp->field() != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1128 ciField* field = atp->field(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1129 ciSymbol* klass = field->holder()->name(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1130 if (field->name() == ciSymbol::value_name() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1131 field->holder()->uses_default_loader() && |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1132 klass == ciSymbol::java_lang_Integer()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1133 return true; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1134 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1135 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1136 return false; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1137 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1138 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1139 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1140 // We're loading from an object which has autobox behaviour. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1141 // If this object is result of a valueOf call we'll have a phi |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1142 // merging a newly allocated object and a load from the cache. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1143 // We want to replace this load with the original incoming |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1144 // argument to the valueOf call. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1145 Node* LoadNode::eliminate_autobox(PhaseGVN* phase) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1146 Node* base = in(Address)->in(AddPNode::Base); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1147 if (base->is_Phi() && base->req() == 3) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1148 AllocateNode* allocation = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1149 int allocation_index = -1; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1150 int load_index = -1; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1151 for (uint i = 1; i < base->req(); i++) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1152 allocation = AllocateNode::Ideal_allocation(base->in(i), phase); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1153 if (allocation != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1154 allocation_index = i; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1155 load_index = 3 - allocation_index; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1156 break; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1157 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1158 } |
583
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1159 bool has_load = ( allocation != NULL && |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1160 (base->in(load_index)->is_Load() || |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1161 base->in(load_index)->is_DecodeN() && |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1162 base->in(load_index)->in(1)->is_Load()) ); |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1163 if (has_load && in(Memory)->is_Phi() && in(Memory)->in(0) == base->in(0)) { |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1164 // Push the loads from the phi that comes from valueOf up |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1165 // through it to allow elimination of the loads and the recovery |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1166 // of the original value. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1167 Node* mem_phi = in(Memory); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1168 Node* offset = in(Address)->in(AddPNode::Offset); |
553 | 1169 Node* region = base->in(0); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1170 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1171 Node* in1 = clone(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1172 Node* in1_addr = in1->in(Address)->clone(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1173 in1_addr->set_req(AddPNode::Base, base->in(allocation_index)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1174 in1_addr->set_req(AddPNode::Address, base->in(allocation_index)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1175 in1_addr->set_req(AddPNode::Offset, offset); |
553 | 1176 in1->set_req(0, region->in(allocation_index)); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1177 in1->set_req(Address, in1_addr); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1178 in1->set_req(Memory, mem_phi->in(allocation_index)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1179 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1180 Node* in2 = clone(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1181 Node* in2_addr = in2->in(Address)->clone(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1182 in2_addr->set_req(AddPNode::Base, base->in(load_index)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1183 in2_addr->set_req(AddPNode::Address, base->in(load_index)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1184 in2_addr->set_req(AddPNode::Offset, offset); |
553 | 1185 in2->set_req(0, region->in(load_index)); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1186 in2->set_req(Address, in2_addr); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1187 in2->set_req(Memory, mem_phi->in(load_index)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1188 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1189 in1_addr = phase->transform(in1_addr); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1190 in1 = phase->transform(in1); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1191 in2_addr = phase->transform(in2_addr); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1192 in2 = phase->transform(in2); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1193 |
553 | 1194 PhiNode* result = PhiNode::make_blank(region, this); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1195 result->set_req(allocation_index, in1); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1196 result->set_req(load_index, in2); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1197 return result; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1198 } |
583
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1199 } else if (base->is_Load() || |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1200 base->is_DecodeN() && base->in(1)->is_Load()) { |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1201 if (base->is_DecodeN()) { |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1202 // Get LoadN node which loads cached Integer object |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1203 base = base->in(1); |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1204 } |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1205 // Eliminate the load of Integer.value for integers from the cache |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1206 // array by deriving the value from the index into the array. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1207 // Capture the offset of the load and then reverse the computation. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1208 Node* load_base = base->in(Address)->in(AddPNode::Base); |
583
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1209 if (load_base->is_DecodeN()) { |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1210 // Get LoadN node which loads IntegerCache.cache field |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1211 load_base = load_base->in(1); |
5d75ab5f6698
6807084: AutoBox elimination is broken with compressed oops
kvn
parents:
570
diff
changeset
|
1212 } |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1213 if (load_base != NULL) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1214 Compile::AliasType* atp = phase->C->alias_type(load_base->adr_type()); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1215 intptr_t cache_offset; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1216 int shift = -1; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1217 Node* cache = NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1218 if (is_autobox_cache(atp)) { |
29
d5fc211aea19
6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
kvn
parents:
17
diff
changeset
|
1219 shift = exact_log2(type2aelembytes(T_OBJECT)); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1220 cache = AddPNode::Ideal_base_and_offset(load_base->in(Address), phase, cache_offset); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1221 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1222 if (cache != NULL && base->in(Address)->is_AddP()) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1223 Node* elements[4]; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1224 int count = base->in(Address)->as_AddP()->unpack_offsets(elements, ARRAY_SIZE(elements)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1225 int cache_low; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1226 if (count > 0 && fetch_autobox_base(atp, cache_low)) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1227 int offset = arrayOopDesc::base_offset_in_bytes(memory_type()) - (cache_low << shift); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1228 // Add up all the offsets making of the address of the load |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1229 Node* result = elements[0]; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1230 for (int i = 1; i < count; i++) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1231 result = phase->transform(new (phase->C, 3) AddXNode(result, elements[i])); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1232 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1233 // Remove the constant offset from the address and then |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1234 // remove the scaling of the offset to recover the original index. |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1235 result = phase->transform(new (phase->C, 3) AddXNode(result, phase->MakeConX(-offset))); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1236 if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1237 // Peel the shift off directly but wrap it in a dummy node |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1238 // since Ideal can't return existing nodes |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1239 result = new (phase->C, 3) RShiftXNode(result->in(1), phase->intcon(0)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1240 } else { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1241 result = new (phase->C, 3) RShiftXNode(result, phase->intcon(shift)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1242 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1243 #ifdef _LP64 |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1244 result = new (phase->C, 2) ConvL2INode(phase->transform(result)); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1245 #endif |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1246 return result; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1247 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1248 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1249 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1250 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1251 return NULL; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1252 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1253 |
163 | 1254 //------------------------------split_through_phi------------------------------ |
1255 // Split instance field load through Phi. | |
1256 Node *LoadNode::split_through_phi(PhaseGVN *phase) { | |
1257 Node* mem = in(MemNode::Memory); | |
1258 Node* address = in(MemNode::Address); | |
1259 const TypePtr *addr_t = phase->type(address)->isa_ptr(); | |
1260 const TypeOopPtr *t_oop = addr_t->isa_oopptr(); | |
1261 | |
1262 assert(mem->is_Phi() && (t_oop != NULL) && | |
223 | 1263 t_oop->is_known_instance_field(), "invalide conditions"); |
163 | 1264 |
1265 Node *region = mem->in(0); | |
1266 if (region == NULL) { | |
1267 return NULL; // Wait stable graph | |
1268 } | |
1269 uint cnt = mem->req(); | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1270 for (uint i = 1; i < cnt; i++) { |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1271 Node* rc = region->in(i); |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1272 if (rc == NULL || phase->type(rc) == Type::TOP) |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1273 return NULL; // Wait stable graph |
163 | 1274 Node *in = mem->in(i); |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1275 if (in == NULL) { |
163 | 1276 return NULL; // Wait stable graph |
1277 } | |
1278 } | |
1279 // Check for loop invariant. | |
1280 if (cnt == 3) { | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1281 for (uint i = 1; i < cnt; i++) { |
163 | 1282 Node *in = mem->in(i); |
1283 Node* m = MemNode::optimize_memory_chain(in, addr_t, phase); | |
1284 if (m == mem) { | |
1285 set_req(MemNode::Memory, mem->in(cnt - i)); // Skip this phi. | |
1286 return this; | |
1287 } | |
1288 } | |
1289 } | |
1290 // Split through Phi (see original code in loopopts.cpp). | |
1291 assert(phase->C->have_alias_type(addr_t), "instance should have alias type"); | |
1292 | |
1293 // Do nothing here if Identity will find a value | |
1294 // (to avoid infinite chain of value phis generation). | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1295 if (!phase->eqv(this, this->Identity(phase))) |
163 | 1296 return NULL; |
1297 | |
1298 // Skip the split if the region dominates some control edge of the address. | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1299 if (!MemNode::all_controls_dominate(address, region)) |
163 | 1300 return NULL; |
1301 | |
1302 const Type* this_type = this->bottom_type(); | |
1303 int this_index = phase->C->get_alias_index(addr_t); | |
1304 int this_offset = addr_t->offset(); | |
1305 int this_iid = addr_t->is_oopptr()->instance_id(); | |
1306 PhaseIterGVN *igvn = phase->is_IterGVN(); | |
1307 Node *phi = new (igvn->C, region->req()) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset); | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1308 for (uint i = 1; i < region->req(); i++) { |
163 | 1309 Node *x; |
1310 Node* the_clone = NULL; | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1311 if (region->in(i) == phase->C->top()) { |
163 | 1312 x = phase->C->top(); // Dead path? Use a dead data op |
1313 } else { | |
1314 x = this->clone(); // Else clone up the data op | |
1315 the_clone = x; // Remember for possible deletion. | |
1316 // Alter data node to use pre-phi inputs | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1317 if (this->in(0) == region) { |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1318 x->set_req(0, region->in(i)); |
163 | 1319 } else { |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1320 x->set_req(0, NULL); |
163 | 1321 } |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1322 for (uint j = 1; j < this->req(); j++) { |
163 | 1323 Node *in = this->in(j); |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1324 if (in->is_Phi() && in->in(0) == region) |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1325 x->set_req(j, in->in(i)); // Use pre-Phi input for the clone |
163 | 1326 } |
1327 } | |
1328 // Check for a 'win' on some paths | |
1329 const Type *t = x->Value(igvn); | |
1330 | |
1331 bool singleton = t->singleton(); | |
1332 | |
1333 // See comments in PhaseIdealLoop::split_thru_phi(). | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1334 if (singleton && t == Type::TOP) { |
163 | 1335 singleton &= region->is_Loop() && (i != LoopNode::EntryControl); |
1336 } | |
1337 | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1338 if (singleton) { |
163 | 1339 x = igvn->makecon(t); |
1340 } else { | |
1341 // We now call Identity to try to simplify the cloned node. | |
1342 // Note that some Identity methods call phase->type(this). | |
1343 // Make sure that the type array is big enough for | |
1344 // our new node, even though we may throw the node away. | |
1345 // (This tweaking with igvn only works because x is a new node.) | |
1346 igvn->set_type(x, t); | |
293
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
253
diff
changeset
|
1347 // If x is a TypeNode, capture any more-precise type permanently into Node |
605 | 1348 // otherwise it will be not updated during igvn->transform since |
293
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
253
diff
changeset
|
1349 // igvn->type(x) is set to x->Value() already. |
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
253
diff
changeset
|
1350 x->raise_bottom_type(t); |
163 | 1351 Node *y = x->Identity(igvn); |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1352 if (y != x) { |
163 | 1353 x = y; |
1354 } else { | |
1355 y = igvn->hash_find(x); | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1356 if (y) { |
163 | 1357 x = y; |
1358 } else { | |
1359 // Else x is a new node we are keeping | |
1360 // We do not need register_new_node_with_optimizer | |
1361 // because set_type has already been called. | |
1362 igvn->_worklist.push(x); | |
1363 } | |
1364 } | |
1365 } | |
1366 if (x != the_clone && the_clone != NULL) | |
1367 igvn->remove_dead_node(the_clone); | |
1368 phi->set_req(i, x); | |
1369 } | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1370 // Record Phi |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1371 igvn->register_new_node_with_optimizer(phi); |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1372 return phi; |
163 | 1373 } |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1374 |
0 | 1375 //------------------------------Ideal------------------------------------------ |
1376 // If the load is from Field memory and the pointer is non-null, we can | |
1377 // zero out the control input. | |
1378 // If the offset is constant and the base is an object allocation, | |
1379 // try to hook me up to the exact initializing store. | |
1380 Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1381 Node* p = MemNode::Ideal_common(phase, can_reshape); | |
1382 if (p) return (p == NodeSentinel) ? NULL : p; | |
1383 | |
1384 Node* ctrl = in(MemNode::Control); | |
1385 Node* address = in(MemNode::Address); | |
1386 | |
1387 // Skip up past a SafePoint control. Cannot do this for Stores because | |
1388 // pointer stores & cardmarks must stay on the same side of a SafePoint. | |
1389 if( ctrl != NULL && ctrl->Opcode() == Op_SafePoint && | |
1390 phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw ) { | |
1391 ctrl = ctrl->in(0); | |
1392 set_req(MemNode::Control,ctrl); | |
1393 } | |
1394 | |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1395 intptr_t ignore = 0; |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1396 Node* base = AddPNode::Ideal_base_and_offset(address, phase, ignore); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1397 if (base != NULL |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1398 && phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw) { |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1399 // Check for useless control edge in some common special cases |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1400 if (in(MemNode::Control) != NULL |
0 | 1401 && phase->type(base)->higher_equal(TypePtr::NOTNULL) |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
1402 && all_controls_dominate(base, phase->C->start())) { |
0 | 1403 // A method-invariant, non-null address (constant or 'this' argument). |
1404 set_req(MemNode::Control, NULL); | |
1405 } | |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1406 |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1407 if (EliminateAutoBox && can_reshape) { |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1408 assert(!phase->type(base)->higher_equal(TypePtr::NULL_PTR), "the autobox pointer should be non-null"); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1409 Compile::AliasType* atp = phase->C->alias_type(adr_type()); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1410 if (is_autobox_object(atp)) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1411 Node* result = eliminate_autobox(phase); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1412 if (result != NULL) return result; |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1413 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1414 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1415 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1416 |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1417 Node* mem = in(MemNode::Memory); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1418 const TypePtr *addr_t = phase->type(address)->isa_ptr(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1419 |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1420 if (addr_t != NULL) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1421 // try to optimize our memory input |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1422 Node* opt_mem = MemNode::optimize_memory_chain(mem, addr_t, phase); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1423 if (opt_mem != mem) { |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1424 set_req(MemNode::Memory, opt_mem); |
305 | 1425 if (phase->type( opt_mem ) == Type::TOP) return NULL; |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1426 return this; |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1427 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1428 const TypeOopPtr *t_oop = addr_t->isa_oopptr(); |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1429 if (can_reshape && opt_mem->is_Phi() && |
223 | 1430 (t_oop != NULL) && t_oop->is_known_instance_field()) { |
4064
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3961
diff
changeset
|
1431 PhaseIterGVN *igvn = phase->is_IterGVN(); |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3961
diff
changeset
|
1432 if (igvn != NULL && igvn->_worklist.member(opt_mem)) { |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3961
diff
changeset
|
1433 // Delay this transformation until memory Phi is processed. |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3961
diff
changeset
|
1434 phase->is_IterGVN()->_worklist.push(this); |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3961
diff
changeset
|
1435 return NULL; |
670a74b863fc
7107042: assert(no_dead_loop) failed: dead loop detected
kvn
parents:
3961
diff
changeset
|
1436 } |
163 | 1437 // Split instance field load through Phi. |
1438 Node* result = split_through_phi(phase); | |
1439 if (result != NULL) return result; | |
74
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1440 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1441 } |
2a9af0b9cb1c
6674600: (Escape Analysis) Optimize memory graph for instance's fields
kvn
parents:
68
diff
changeset
|
1442 |
0 | 1443 // Check for prior store with a different base or offset; make Load |
1444 // independent. Skip through any number of them. Bail out if the stores | |
1445 // are in an endless dead cycle and report no progress. This is a key | |
1446 // transform for Reflection. However, if after skipping through the Stores | |
1447 // we can't then fold up against a prior store do NOT do the transform as | |
1448 // this amounts to using the 'Oracle' model of aliasing. It leaves the same | |
1449 // array memory alive twice: once for the hoisted Load and again after the | |
1450 // bypassed Store. This situation only works if EVERYBODY who does | |
1451 // anti-dependence work knows how to bypass. I.e. we need all | |
1452 // anti-dependence checks to ask the same Oracle. Right now, that Oracle is | |
1453 // the alias index stuff. So instead, peek through Stores and IFF we can | |
1454 // fold up, do so. | |
1455 Node* prev_mem = find_previous_store(phase); | |
1456 // Steps (a), (b): Walk past independent stores to find an exact match. | |
1457 if (prev_mem != NULL && prev_mem != in(MemNode::Memory)) { | |
1458 // (c) See if we can fold up on the spot, but don't fold up here. | |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
1459 // Fold-up might require truncation (for LoadB/LoadS/LoadUS) or |
0 | 1460 // just return a prior value, which is done by Identity calls. |
1461 if (can_see_stored_value(prev_mem, phase)) { | |
1462 // Make ready for step (d): | |
1463 set_req(MemNode::Memory, prev_mem); | |
1464 return this; | |
1465 } | |
1466 } | |
1467 | |
1468 return NULL; // No further progress | |
1469 } | |
1470 | |
1471 // Helper to recognize certain Klass fields which are invariant across | |
1472 // some group of array types (e.g., int[] or all T[] where T < Object). | |
1473 const Type* | |
1474 LoadNode::load_array_final_field(const TypeKlassPtr *tkls, | |
1475 ciKlass* klass) const { | |
1476 if (tkls->offset() == Klass::modifier_flags_offset_in_bytes() + (int)sizeof(oopDesc)) { | |
1477 // The field is Klass::_modifier_flags. Return its (constant) value. | |
1478 // (Folds up the 2nd indirection in aClassConstant.getModifiers().) | |
1479 assert(this->Opcode() == Op_LoadI, "must load an int from _modifier_flags"); | |
1480 return TypeInt::make(klass->modifier_flags()); | |
1481 } | |
1482 if (tkls->offset() == Klass::access_flags_offset_in_bytes() + (int)sizeof(oopDesc)) { | |
1483 // The field is Klass::_access_flags. Return its (constant) value. | |
1484 // (Folds up the 2nd indirection in Reflection.getClassAccessFlags(aClassConstant).) | |
1485 assert(this->Opcode() == Op_LoadI, "must load an int from _access_flags"); | |
1486 return TypeInt::make(klass->access_flags()); | |
1487 } | |
1488 if (tkls->offset() == Klass::layout_helper_offset_in_bytes() + (int)sizeof(oopDesc)) { | |
1489 // The field is Klass::_layout_helper. Return its constant value if known. | |
1490 assert(this->Opcode() == Op_LoadI, "must load an int from _layout_helper"); | |
1491 return TypeInt::make(klass->layout_helper()); | |
1492 } | |
1493 | |
1494 // No match. | |
1495 return NULL; | |
1496 } | |
1497 | |
1498 //------------------------------Value----------------------------------------- | |
1499 const Type *LoadNode::Value( PhaseTransform *phase ) const { | |
1500 // Either input is TOP ==> the result is TOP | |
1501 Node* mem = in(MemNode::Memory); | |
1502 const Type *t1 = phase->type(mem); | |
1503 if (t1 == Type::TOP) return Type::TOP; | |
1504 Node* adr = in(MemNode::Address); | |
1505 const TypePtr* tp = phase->type(adr)->isa_ptr(); | |
1506 if (tp == NULL || tp->empty()) return Type::TOP; | |
1507 int off = tp->offset(); | |
1508 assert(off != Type::OffsetTop, "case covered by TypePtr::empty"); | |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1509 Compile* C = phase->C; |
0 | 1510 |
1511 // Try to guess loaded type from pointer type | |
1512 if (tp->base() == Type::AryPtr) { | |
1513 const Type *t = tp->is_aryptr()->elem(); | |
1514 // Don't do this for integer types. There is only potential profit if | |
1515 // the element type t is lower than _type; that is, for int types, if _type is | |
1516 // more restrictive than t. This only happens here if one is short and the other | |
1517 // char (both 16 bits), and in those cases we've made an intentional decision | |
1518 // to use one kind of load over the other. See AndINode::Ideal and 4965907. | |
1519 // Also, do not try to narrow the type for a LoadKlass, regardless of offset. | |
1520 // | |
1521 // Yes, it is possible to encounter an expression like (LoadKlass p1:(AddP x x 8)) | |
1522 // where the _gvn.type of the AddP is wider than 8. This occurs when an earlier | |
1523 // copy p0 of (AddP x x 8) has been proven equal to p1, and the p0 has been | |
1524 // subsumed by p1. If p1 is on the worklist but has not yet been re-transformed, | |
1525 // it is possible that p1 will have a type like Foo*[int+]:NotNull*+any. | |
1526 // In fact, that could have been the original type of p1, and p1 could have | |
1527 // had an original form like p1:(AddP x x (LShiftL quux 3)), where the | |
1528 // expression (LShiftL quux 3) independently optimized to the constant 8. | |
1529 if ((t->isa_int() == NULL) && (t->isa_long() == NULL) | |
293
c3e045194476
6731641: assert(m->adr_type() == mach->adr_type(),"matcher should not change adr type")
kvn
parents:
253
diff
changeset
|
1530 && Opcode() != Op_LoadKlass && Opcode() != Op_LoadNKlass) { |
0 | 1531 // t might actually be lower than _type, if _type is a unique |
1532 // concrete subclass of abstract class t. | |
1533 // Make sure the reference is not into the header, by comparing | |
1534 // the offset against the offset of the start of the array's data. | |
1535 // Different array types begin at slightly different offsets (12 vs. 16). | |
1536 // We choose T_BYTE as an example base type that is least restrictive | |
1537 // as to alignment, which will therefore produce the smallest | |
1538 // possible base offset. | |
1539 const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE); | |
1540 if ((uint)off >= (uint)min_base_off) { // is the offset beyond the header? | |
1541 const Type* jt = t->join(_type); | |
1542 // In any case, do not allow the join, per se, to empty out the type. | |
1543 if (jt->empty() && !t->empty()) { | |
1544 // This can happen if a interface-typed array narrows to a class type. | |
1545 jt = _type; | |
1546 } | |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1547 |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1548 if (EliminateAutoBox && adr->is_AddP()) { |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1549 // The pointers in the autobox arrays are always non-null |
708
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1550 Node* base = adr->in(AddPNode::Base); |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1551 if (base != NULL && |
f2049ae95c3d
6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
kvn
parents:
681
diff
changeset
|
1552 !phase->type(base)->higher_equal(TypePtr::NULL_PTR)) { |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1553 Compile::AliasType* atp = C->alias_type(base->adr_type()); |
17
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1554 if (is_autobox_cache(atp)) { |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1555 return jt->join(TypePtr::NOTNULL)->is_ptr(); |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1556 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1557 } |
ff5961f4c095
6395208: Elide autoboxing for calls to HashMap.get(int) and HashMap.get(long)
never
parents:
0
diff
changeset
|
1558 } |
0 | 1559 return jt; |
1560 } | |
1561 } | |
1562 } else if (tp->base() == Type::InstPtr) { | |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1563 ciEnv* env = C->env(); |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1564 const TypeInstPtr* tinst = tp->is_instptr(); |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1565 ciKlass* klass = tinst->klass(); |
0 | 1566 assert( off != Type::OffsetBot || |
1567 // arrays can be cast to Objects | |
1568 tp->is_oopptr()->klass()->is_java_lang_Object() || | |
1569 // unsafe field access may not have a constant offset | |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1570 C->has_unsafe_access(), |
0 | 1571 "Field accesses must be precise" ); |
1572 // For oop loads, we expect the _type to be precise | |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1573 if (klass == env->String_klass() && |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1574 adr->is_AddP() && off != Type::OffsetBot) { |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1575 // For constant Strings treat the final fields as compile time constants. |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1576 Node* base = adr->in(AddPNode::Base); |
1766
02f0a9b6f654
6969586: OptimizeStringConcat: SIGSEGV in LoadNode::Value()
never
parents:
1609
diff
changeset
|
1577 const TypeOopPtr* t = phase->type(base)->isa_oopptr(); |
02f0a9b6f654
6969586: OptimizeStringConcat: SIGSEGV in LoadNode::Value()
never
parents:
1609
diff
changeset
|
1578 if (t != NULL && t->singleton()) { |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1579 ciField* field = env->String_klass()->get_field_by_offset(off, false); |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1580 if (field != NULL && field->is_final()) { |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1581 ciObject* string = t->const_oop(); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1582 ciConstant constant = string->as_instance()->field_value(field); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1583 if (constant.basic_type() == T_INT) { |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1584 return TypeInt::make(constant.as_int()); |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1585 } else if (constant.basic_type() == T_ARRAY) { |
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1586 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
2379
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2320
diff
changeset
|
1587 return TypeNarrowOop::make_from_constant(constant.as_object(), true); |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1588 } else { |
2379
b099aaf51bf8
6962931: move interned strings out of the perm gen
jcoomes
parents:
2320
diff
changeset
|
1589 return TypeOopPtr::make_from_constant(constant.as_object(), true); |
2320
41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
kvn
parents:
2317
diff
changeset
|
1590 } |
1080
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1591 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1592 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1593 } |
7c57aead6d3e
6892658: C2 should optimize some stringbuilder patterns
never
parents:
1062
diff
changeset
|
1594 } |
3902
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1595 // Optimizations for constant objects |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1596 ciObject* const_oop = tinst->const_oop(); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1597 if (const_oop != NULL) { |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1598 // For constant CallSites treat the target field as a compile time constant. |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1599 if (const_oop->is_call_site()) { |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1600 ciCallSite* call_site = const_oop->as_call_site(); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1601 ciField* field = call_site->klass()->as_instance_klass()->get_field_by_offset(off, /*is_static=*/ false); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1602 if (field != NULL && field->is_call_site_target()) { |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1603 ciMethodHandle* target = call_site->get_target(); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1604 if (target != NULL) { // just in case |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1605 ciConstant constant(T_OBJECT, target); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1606 const Type* t; |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1607 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1608 t = TypeNarrowOop::make_from_constant(constant.as_object(), true); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1609 } else { |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1610 t = TypeOopPtr::make_from_constant(constant.as_object(), true); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1611 } |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1612 // Add a dependence for invalidation of the optimization. |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1613 if (!call_site->is_constant_call_site()) { |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1614 C->dependencies()->assert_call_site_target_value(call_site, target); |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1615 } |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1616 return t; |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1617 } |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1618 } |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1619 } |
11a4af030e4b
7071709: JSR 292: switchpoint invalidation should be pushed not pulled
twisti
parents:
3849
diff
changeset
|
1620 } |
0 | 1621 } else if (tp->base() == Type::KlassPtr) { |
1622 assert( off != Type::OffsetBot || | |
1623 // arrays can be cast to Objects | |
1624 tp->is_klassptr()->klass()->is_java_lang_Object() || | |
1625 // also allow array-loading from the primary supertype | |
1626 // array during subtype checks | |
1627 Opcode() == Op_LoadKlass, | |
1628 "Field accesses must be precise" ); | |
1629 // For klass/static loads, we expect the _type to be precise | |
1630 } | |
1631 | |
1632 const TypeKlassPtr *tkls = tp->isa_klassptr(); | |
1633 if (tkls != NULL && !StressReflectiveCode) { | |
1634 ciKlass* klass = tkls->klass(); | |
1635 if (klass->is_loaded() && tkls->klass_is_exact()) { | |
1636 // We are loading a field from a Klass metaobject whose identity | |
1637 // is known at compile time (the type is "exact" or "precise"). | |
1638 // Check for fields we know are maintained as constants by the VM. | |
1639 if (tkls->offset() == Klass::super_check_offset_offset_in_bytes() + (int)sizeof(oopDesc)) { | |
1640 // The field is Klass::_super_check_offset. Return its (constant) value. | |
1641 // (Folds up type checking code.) | |
1642 assert(Opcode() == Op_LoadI, "must load an int from _super_check_offset"); | |
1643 return TypeInt::make(klass->super_check_offset()); | |
1644 } | |
1645 // Compute index into primary_supers array | |
1646 juint depth = (tkls->offset() - (Klass::primary_supers_offset_in_bytes() + (int)sizeof(oopDesc))) / sizeof(klassOop); | |
1647 // Check for overflowing; use unsigned compare to handle the negative case. | |
1648 if( depth < ciKlass::primary_super_limit() ) { | |
1649 // The field is an element of Klass::_primary_supers. Return its (constant) value. | |
1650 // (Folds up type checking code.) | |
1651 assert(Opcode() == Op_LoadKlass, "must load a klass from _primary_supers"); | |
1652 ciKlass *ss = klass->super_of_depth(depth); | |
1653 return ss ? TypeKlassPtr::make(ss) : TypePtr::NULL_PTR; | |
1654 } | |
1655 const Type* aift = load_array_final_field(tkls, klass); | |
1656 if (aift != NULL) return aift; | |
1657 if (tkls->offset() == in_bytes(arrayKlass::component_mirror_offset()) + (int)sizeof(oopDesc) | |
1658 && klass->is_array_klass()) { | |
1659 // The field is arrayKlass::_component_mirror. Return its (constant) value. | |
1660 // (Folds up aClassConstant.getComponentType, common in Arrays.copyOf.) | |
1661 assert(Opcode() == Op_LoadP, "must load an oop from _component_mirror"); | |
1662 return TypeInstPtr::make(klass->as_array_klass()->component_mirror()); | |
1663 } | |
1664 if (tkls->offset() == Klass::java_mirror_offset_in_bytes() + (int)sizeof(oopDesc)) { | |
1665 // The field is Klass::_java_mirror. Return its (constant) value. | |
1666 // (Folds up the 2nd indirection in anObjConstant.getClass().) | |
1667 assert(Opcode() == Op_LoadP, "must load an oop from _java_mirror"); | |
1668 return TypeInstPtr::make(klass->java_mirror()); | |
1669 } | |
1670 } | |
1671 | |
1672 // We can still check if we are loading from the primary_supers array at a | |
1673 // shallow enough depth. Even though the klass is not exact, entries less | |
1674 // than or equal to its super depth are correct. | |
1675 if (klass->is_loaded() ) { | |
1676 ciType *inner = klass->klass(); | |
1677 while( inner->is_obj_array_klass() ) | |
1678 inner = inner->as_obj_array_klass()->base_element_type(); | |
1679 if( inner->is_instance_klass() && | |
1680 !inner->as_instance_klass()->flags().is_interface() ) { | |
1681 // Compute index into primary_supers array | |
1682 juint depth = (tkls->offset() - (Klass::primary_supers_offset_in_bytes() + (int)sizeof(oopDesc))) / sizeof(klassOop); | |
1683 // Check for overflowing; use unsigned compare to handle the negative case. | |
1684 if( depth < ciKlass::primary_super_limit() && | |
1685 depth <= klass->super_depth() ) { // allow self-depth checks to handle self-check case | |
1686 // The field is an element of Klass::_primary_supers. Return its (constant) value. | |
1687 // (Folds up type checking code.) | |
1688 assert(Opcode() == Op_LoadKlass, "must load a klass from _primary_supers"); | |
1689 ciKlass *ss = klass->super_of_depth(depth); | |
1690 return ss ? TypeKlassPtr::make(ss) : TypePtr::NULL_PTR; | |
1691 } | |
1692 } | |
1693 } | |
1694 | |
1695 // If the type is enough to determine that the thing is not an array, | |
1696 // we can give the layout_helper a positive interval type. | |
1697 // This will help short-circuit some reflective code. | |
1698 if (tkls->offset() == Klass::layout_helper_offset_in_bytes() + (int)sizeof(oopDesc) | |
1699 && !klass->is_array_klass() // not directly typed as an array | |
1700 && !klass->is_interface() // specifically not Serializable & Cloneable | |
1701 && !klass->is_java_lang_Object() // not the supertype of all T[] | |
1702 ) { | |
1703 // Note: When interfaces are reliable, we can narrow the interface | |
1704 // test to (klass != Serializable && klass != Cloneable). | |
1705 assert(Opcode() == Op_LoadI, "must load an int from _layout_helper"); | |
1706 jint min_size = Klass::instance_layout_helper(oopDesc::header_size(), false); | |
1707 // The key property of this type is that it folds up tests | |
1708 // for array-ness, since it proves that the layout_helper is positive. | |
1709 // Thus, a generic value like the basic object layout helper works fine. | |
1710 return TypeInt::make(min_size, max_jint, Type::WidenMin); | |
1711 } | |
1712 } | |
1713 | |
1714 // If we are loading from a freshly-allocated object, produce a zero, | |
1715 // if the load is provably beyond the header of the object. | |
1716 // (Also allow a variable load from a fresh array to produce zero.) | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1717 const TypeOopPtr *tinst = tp->isa_oopptr(); |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1718 bool is_instance = (tinst != NULL) && tinst->is_known_instance_field(); |
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1719 if (ReduceFieldZeroing || is_instance) { |
0 | 1720 Node* value = can_see_stored_value(mem,phase); |
1721 if (value != NULL && value->is_Con()) | |
1722 return value->bottom_type(); | |
1723 } | |
1724 | |
3278
66b0e2371912
7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post
kvn
parents:
2417
diff
changeset
|
1725 if (is_instance) { |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1726 // If we have an instance type and our memory input is the |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1727 // programs's initial memory state, there is no matching store, |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1728 // so just return a zero of the appropriate type |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1729 Node *mem = in(MemNode::Memory); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1730 if (mem->is_Parm() && mem->in(0)->is_Start()) { |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1731 assert(mem->as_Parm()->_con == TypeFunc::Memory, "must be memory Parm"); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1732 return Type::get_zero_type(_type->basic_type()); |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1733 } |
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
1734 } |
0 | 1735 return _type; |
1736 } | |
1737 | |
1738 //------------------------------match_edge------------------------------------- | |
1739 // Do we Match on this edge index or not? Match only the address. | |
1740 uint LoadNode::match_edge(uint idx) const { | |
1741 return idx == MemNode::Address; | |
1742 } | |
1743 | |
1744 //--------------------------LoadBNode::Ideal-------------------------------------- | |
1745 // | |
1746 // If the previous store is to the same address as this load, | |
1747 // and the value stored was larger than a byte, replace this load | |
1748 // with the value stored truncated to a byte. If no truncation is | |
1749 // needed, the replacement is done in LoadNode::Identity(). | |
1750 // | |
1751 Node *LoadBNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1752 Node* mem = in(MemNode::Memory); | |
1753 Node* value = can_see_stored_value(mem,phase); | |
1754 if( value && !phase->type(value)->higher_equal( _type ) ) { | |
1755 Node *result = phase->transform( new (phase->C, 3) LShiftINode(value, phase->intcon(24)) ); | |
1756 return new (phase->C, 3) RShiftINode(result, phase->intcon(24)); | |
1757 } | |
1758 // Identity call will handle the case where truncation is not needed. | |
1759 return LoadNode::Ideal(phase, can_reshape); | |
1760 } | |
1761 | |
624 | 1762 //--------------------------LoadUBNode::Ideal------------------------------------- |
1763 // | |
1764 // If the previous store is to the same address as this load, | |
1765 // and the value stored was larger than a byte, replace this load | |
1766 // with the value stored truncated to a byte. If no truncation is | |
1767 // needed, the replacement is done in LoadNode::Identity(). | |
1768 // | |
1769 Node* LoadUBNode::Ideal(PhaseGVN* phase, bool can_reshape) { | |
1770 Node* mem = in(MemNode::Memory); | |
1771 Node* value = can_see_stored_value(mem, phase); | |
1772 if (value && !phase->type(value)->higher_equal(_type)) | |
1773 return new (phase->C, 3) AndINode(value, phase->intcon(0xFF)); | |
1774 // Identity call will handle the case where truncation is not needed. | |
1775 return LoadNode::Ideal(phase, can_reshape); | |
1776 } | |
1777 | |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
1778 //--------------------------LoadUSNode::Ideal------------------------------------- |
0 | 1779 // |
1780 // If the previous store is to the same address as this load, | |
1781 // and the value stored was larger than a char, replace this load | |
1782 // with the value stored truncated to a char. If no truncation is | |
1783 // needed, the replacement is done in LoadNode::Identity(). | |
1784 // | |
558
3b5ac9e7e6ea
6796746: rename LoadC (char) opcode class to LoadUS (unsigned short)
twisti
parents:
553
diff
changeset
|
1785 Node *LoadUSNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
0 | 1786 Node* mem = in(MemNode::Memory); |
1787 Node* value = can_see_stored_value(mem,phase); | |
1788 if( value && !phase->type(value)->higher_equal( _type ) ) | |
1789 return new (phase->C, 3) AndINode(value,phase->intcon(0xFFFF)); | |
1790 // Identity call will handle the case where truncation is not needed. | |
1791 return LoadNode::Ideal(phase, can_reshape); | |
1792 } | |
1793 | |
1794 //--------------------------LoadSNode::Ideal-------------------------------------- | |
1795 // | |
1796 // If the previous store is to the same address as this load, | |
1797 // and the value stored was larger than a short, replace this load | |
1798 // with the value stored truncated to a short. If no truncation is | |
1799 // needed, the replacement is done in LoadNode::Identity(). | |
1800 // | |
1801 Node *LoadSNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1802 Node* mem = in(MemNode::Memory); | |
1803 Node* value = can_see_stored_value(mem,phase); | |
1804 if( value && !phase->type(value)->higher_equal( _type ) ) { | |
1805 Node *result = phase->transform( new (phase->C, 3) LShiftINode(value, phase->intcon(16)) ); | |
1806 return new (phase->C, 3) RShiftINode(result, phase->intcon(16)); | |
1807 } | |
1808 // Identity call will handle the case where truncation is not needed. | |
1809 return LoadNode::Ideal(phase, can_reshape); | |
1810 } | |
1811 | |
1812 //============================================================================= | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1813 //----------------------------LoadKlassNode::make------------------------------ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1814 // Polymorphic factory method: |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1815 Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk ) { |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1816 Compile* C = gvn.C; |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1817 Node *ctl = NULL; |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1818 // sanity check the alias category against the created node type |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1819 const TypeOopPtr *adr_type = adr->bottom_type()->isa_oopptr(); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1820 assert(adr_type != NULL, "expecting TypeOopPtr"); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1821 #ifdef _LP64 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1822 if (adr_type->is_ptr_to_narrowoop()) { |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
1823 Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowoop())); |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
1824 return new (C, 2) DecodeNNode(load_klass, load_klass->bottom_type()->make_ptr()); |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
1825 } |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1826 #endif |
168
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
1827 assert(!adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop"); |
7793bd37a336
6705887: Compressed Oops: generate x64 addressing and implicit null checks with narrow oops
kvn
parents:
164
diff
changeset
|
1828 return new (C, 3) LoadKlassNode(ctl, mem, adr, at, tk); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1829 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1830 |
0 | 1831 //------------------------------Value------------------------------------------ |
1832 const Type *LoadKlassNode::Value( PhaseTransform *phase ) const { | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1833 return klass_value_common(phase); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1834 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1835 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1836 const Type *LoadNode::klass_value_common( PhaseTransform *phase ) const { |
0 | 1837 // Either input is TOP ==> the result is TOP |
1838 const Type *t1 = phase->type( in(MemNode::Memory) ); | |
1839 if (t1 == Type::TOP) return Type::TOP; | |
1840 Node *adr = in(MemNode::Address); | |
1841 const Type *t2 = phase->type( adr ); | |
1842 if (t2 == Type::TOP) return Type::TOP; | |
1843 const TypePtr *tp = t2->is_ptr(); | |
1844 if (TypePtr::above_centerline(tp->ptr()) || | |
1845 tp->ptr() == TypePtr::Null) return Type::TOP; | |
1846 | |
1847 // Return a more precise klass, if possible | |
1848 const TypeInstPtr *tinst = tp->isa_instptr(); | |
1849 if (tinst != NULL) { | |
1850 ciInstanceKlass* ik = tinst->klass()->as_instance_klass(); | |
1851 int offset = tinst->offset(); | |
1852 if (ik == phase->C->env()->Class_klass() | |
1853 && (offset == java_lang_Class::klass_offset_in_bytes() || | |
1854 offset == java_lang_Class::array_klass_offset_in_bytes())) { | |
1855 // We are loading a special hidden field from a Class mirror object, | |
1856 // the field which points to the VM's Klass metaobject. | |
1857 ciType* t = tinst->java_mirror_type(); | |
1858 // java_mirror_type returns non-null for compile-time Class constants. | |
1859 if (t != NULL) { | |
1860 // constant oop => constant klass | |
1861 if (offset == java_lang_Class::array_klass_offset_in_bytes()) { | |
1862 return TypeKlassPtr::make(ciArrayKlass::make(t)); | |
1863 } | |
1864 if (!t->is_klass()) { | |
1865 // a primitive Class (e.g., int.class) has NULL for a klass field | |
1866 return TypePtr::NULL_PTR; | |
1867 } | |
1868 // (Folds up the 1st indirection in aClassConstant.getModifiers().) | |
1869 return TypeKlassPtr::make(t->as_klass()); | |
1870 } | |
1871 // non-constant mirror, so we can't tell what's going on | |
1872 } | |
1873 if( !ik->is_loaded() ) | |
1874 return _type; // Bail out if not loaded | |
1875 if (offset == oopDesc::klass_offset_in_bytes()) { | |
1876 if (tinst->klass_is_exact()) { | |
1877 return TypeKlassPtr::make(ik); | |
1878 } | |
1879 // See if we can become precise: no subklasses and no interface | |
1880 // (Note: We need to support verified interfaces.) | |
1881 if (!ik->is_interface() && !ik->has_subklass()) { | |
1882 //assert(!UseExactTypes, "this code should be useless with exact types"); | |
1883 // Add a dependence; if any subclass added we need to recompile | |
1884 if (!ik->is_final()) { | |
1885 // %%% should use stronger assert_unique_concrete_subtype instead | |
1886 phase->C->dependencies()->assert_leaf_type(ik); | |
1887 } | |
1888 // Return precise klass | |
1889 return TypeKlassPtr::make(ik); | |
1890 } | |
1891 | |
1892 // Return root of possible klass | |
1893 return TypeKlassPtr::make(TypePtr::NotNull, ik, 0/*offset*/); | |
1894 } | |
1895 } | |
1896 | |
1897 // Check for loading klass from an array | |
1898 const TypeAryPtr *tary = tp->isa_aryptr(); | |
1899 if( tary != NULL ) { | |
1900 ciKlass *tary_klass = tary->klass(); | |
1901 if (tary_klass != NULL // can be NULL when at BOTTOM or TOP | |
1902 && tary->offset() == oopDesc::klass_offset_in_bytes()) { | |
1903 if (tary->klass_is_exact()) { | |
1904 return TypeKlassPtr::make(tary_klass); | |
1905 } | |
1906 ciArrayKlass *ak = tary->klass()->as_array_klass(); | |
1907 // If the klass is an object array, we defer the question to the | |
1908 // array component klass. | |
1909 if( ak->is_obj_array_klass() ) { | |
1910 assert( ak->is_loaded(), "" ); | |
1911 ciKlass *base_k = ak->as_obj_array_klass()->base_element_klass(); | |
1912 if( base_k->is_loaded() && base_k->is_instance_klass() ) { | |
1913 ciInstanceKlass* ik = base_k->as_instance_klass(); | |
1914 // See if we can become precise: no subklasses and no interface | |
1915 if (!ik->is_interface() && !ik->has_subklass()) { | |
1916 //assert(!UseExactTypes, "this code should be useless with exact types"); | |
1917 // Add a dependence; if any subclass added we need to recompile | |
1918 if (!ik->is_final()) { | |
1919 phase->C->dependencies()->assert_leaf_type(ik); | |
1920 } | |
1921 // Return precise array klass | |
1922 return TypeKlassPtr::make(ak); | |
1923 } | |
1924 } | |
1925 return TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/); | |
1926 } else { // Found a type-array? | |
1927 //assert(!UseExactTypes, "this code should be useless with exact types"); | |
1928 assert( ak->is_type_array_klass(), "" ); | |
1929 return TypeKlassPtr::make(ak); // These are always precise | |
1930 } | |
1931 } | |
1932 } | |
1933 | |
1934 // Check for loading klass from an array klass | |
1935 const TypeKlassPtr *tkls = tp->isa_klassptr(); | |
1936 if (tkls != NULL && !StressReflectiveCode) { | |
1937 ciKlass* klass = tkls->klass(); | |
1938 if( !klass->is_loaded() ) | |
1939 return _type; // Bail out if not loaded | |
1940 if( klass->is_obj_array_klass() && | |
1941 (uint)tkls->offset() == objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)) { | |
1942 ciKlass* elem = klass->as_obj_array_klass()->element_klass(); | |
1943 // // Always returning precise element type is incorrect, | |
1944 // // e.g., element type could be object and array may contain strings | |
1945 // return TypeKlassPtr::make(TypePtr::Constant, elem, 0); | |
1946 | |
1947 // The array's TypeKlassPtr was declared 'precise' or 'not precise' | |
1948 // according to the element type's subclassing. | |
1949 return TypeKlassPtr::make(tkls->ptr(), elem, 0/*offset*/); | |
1950 } | |
1951 if( klass->is_instance_klass() && tkls->klass_is_exact() && | |
1952 (uint)tkls->offset() == Klass::super_offset_in_bytes() + sizeof(oopDesc)) { | |
1953 ciKlass* sup = klass->as_instance_klass()->super(); | |
1954 // The field is Klass::_super. Return its (constant) value. | |
1955 // (Folds up the 2nd indirection in aClassConstant.getSuperClass().) | |
1956 return sup ? TypeKlassPtr::make(sup) : TypePtr::NULL_PTR; | |
1957 } | |
1958 } | |
1959 | |
1960 // Bailout case | |
1961 return LoadNode::Value(phase); | |
1962 } | |
1963 | |
1964 //------------------------------Identity--------------------------------------- | |
1965 // To clean up reflective code, simplify k.java_mirror.as_klass to plain k. | |
1966 // Also feed through the klass in Allocate(...klass...)._klass. | |
1967 Node* LoadKlassNode::Identity( PhaseTransform *phase ) { | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1968 return klass_identity_common(phase); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1969 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1970 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
1971 Node* LoadNode::klass_identity_common(PhaseTransform *phase ) { |
0 | 1972 Node* x = LoadNode::Identity(phase); |
1973 if (x != this) return x; | |
1974 | |
1975 // Take apart the address into an oop and and offset. | |
1976 // Return 'this' if we cannot. | |
1977 Node* adr = in(MemNode::Address); | |
1978 intptr_t offset = 0; | |
1979 Node* base = AddPNode::Ideal_base_and_offset(adr, phase, offset); | |
1980 if (base == NULL) return this; | |
1981 const TypeOopPtr* toop = phase->type(adr)->isa_oopptr(); | |
1982 if (toop == NULL) return this; | |
1983 | |
1984 // We can fetch the klass directly through an AllocateNode. | |
1985 // This works even if the klass is not constant (clone or newArray). | |
1986 if (offset == oopDesc::klass_offset_in_bytes()) { | |
1987 Node* allocated_klass = AllocateNode::Ideal_klass(base, phase); | |
1988 if (allocated_klass != NULL) { | |
1989 return allocated_klass; | |
1990 } | |
1991 } | |
1992 | |
1993 // Simplify k.java_mirror.as_klass to plain k, where k is a klassOop. | |
1994 // Simplify ak.component_mirror.array_klass to plain ak, ak an arrayKlass. | |
1995 // See inline_native_Class_query for occurrences of these patterns. | |
1996 // Java Example: x.getClass().isAssignableFrom(y) | |
1997 // Java Example: Array.newInstance(x.getClass().getComponentType(), n) | |
1998 // | |
1999 // This improves reflective code, often making the Class | |
2000 // mirror go completely dead. (Current exception: Class | |
2001 // mirrors may appear in debug info, but we could clean them out by | |
2002 // introducing a new debug info operator for klassOop.java_mirror). | |
2003 if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass() | |
2004 && (offset == java_lang_Class::klass_offset_in_bytes() || | |
2005 offset == java_lang_Class::array_klass_offset_in_bytes())) { | |
2006 // We are loading a special hidden field from a Class mirror, | |
2007 // the field which points to its Klass or arrayKlass metaobject. | |
2008 if (base->is_Load()) { | |
2009 Node* adr2 = base->in(MemNode::Address); | |
2010 const TypeKlassPtr* tkls = phase->type(adr2)->isa_klassptr(); | |
2011 if (tkls != NULL && !tkls->empty() | |
2012 && (tkls->klass()->is_instance_klass() || | |
2013 tkls->klass()->is_array_klass()) | |
2014 && adr2->is_AddP() | |
2015 ) { | |
2016 int mirror_field = Klass::java_mirror_offset_in_bytes(); | |
2017 if (offset == java_lang_Class::array_klass_offset_in_bytes()) { | |
2018 mirror_field = in_bytes(arrayKlass::component_mirror_offset()); | |
2019 } | |
2020 if (tkls->offset() == mirror_field + (int)sizeof(oopDesc)) { | |
2021 return adr2->in(AddPNode::Base); | |
2022 } | |
2023 } | |
2024 } | |
2025 } | |
2026 | |
2027 return this; | |
2028 } | |
2029 | |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2030 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2031 //------------------------------Value------------------------------------------ |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2032 const Type *LoadNKlassNode::Value( PhaseTransform *phase ) const { |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2033 const Type *t = klass_value_common(phase); |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2034 if (t == Type::TOP) |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2035 return t; |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2036 |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2037 return t->make_narrowoop(); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2038 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2039 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2040 //------------------------------Identity--------------------------------------- |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2041 // To clean up reflective code, simplify k.java_mirror.as_klass to narrow k. |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2042 // Also feed through the klass in Allocate(...klass...)._klass. |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2043 Node* LoadNKlassNode::Identity( PhaseTransform *phase ) { |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2044 Node *x = klass_identity_common(phase); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2045 |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2046 const Type *t = phase->type( x ); |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2047 if( t == Type::TOP ) return x; |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2048 if( t->isa_narrowoop()) return x; |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2049 |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2050 return phase->transform(new (phase->C, 2) EncodePNode(x, t->make_narrowoop())); |
164
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2051 } |
c436414a719e
6703890: Compressed Oops: add LoadNKlass node to generate narrow oops (32-bits) compare instructions
kvn
parents:
163
diff
changeset
|
2052 |
0 | 2053 //------------------------------Value----------------------------------------- |
2054 const Type *LoadRangeNode::Value( PhaseTransform *phase ) const { | |
2055 // Either input is TOP ==> the result is TOP | |
2056 const Type *t1 = phase->type( in(MemNode::Memory) ); | |
2057 if( t1 == Type::TOP ) return Type::TOP; | |
2058 Node *adr = in(MemNode::Address); | |
2059 const Type *t2 = phase->type( adr ); | |
2060 if( t2 == Type::TOP ) return Type::TOP; | |
2061 const TypePtr *tp = t2->is_ptr(); | |
2062 if (TypePtr::above_centerline(tp->ptr())) return Type::TOP; | |
2063 const TypeAryPtr *tap = tp->isa_aryptr(); | |
2064 if( !tap ) return _type; | |
2065 return tap->size(); | |
2066 } | |
2067 | |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2068 //-------------------------------Ideal--------------------------------------- |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2069 // Feed through the length in AllocateArray(...length...)._length. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2070 Node *LoadRangeNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2071 Node* p = MemNode::Ideal_common(phase, can_reshape); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2072 if (p) return (p == NodeSentinel) ? NULL : p; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2073 |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2074 // Take apart the address into an oop and and offset. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2075 // Return 'this' if we cannot. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2076 Node* adr = in(MemNode::Address); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2077 intptr_t offset = 0; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2078 Node* base = AddPNode::Ideal_base_and_offset(adr, phase, offset); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2079 if (base == NULL) return NULL; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2080 const TypeAryPtr* tary = phase->type(adr)->isa_aryptr(); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2081 if (tary == NULL) return NULL; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2082 |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2083 // We can fetch the length directly through an AllocateArrayNode. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2084 // This works even if the length is not constant (clone or newArray). |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2085 if (offset == arrayOopDesc::length_offset_in_bytes()) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2086 AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(base, phase); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2087 if (alloc != NULL) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2088 Node* allocated_length = alloc->Ideal_length(); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2089 Node* len = alloc->make_ideal_length(tary, phase); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2090 if (allocated_length != len) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2091 // New CastII improves on this. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2092 return len; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2093 } |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2094 } |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2095 } |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2096 |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2097 return NULL; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2098 } |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2099 |
0 | 2100 //------------------------------Identity--------------------------------------- |
2101 // Feed through the length in AllocateArray(...length...)._length. | |
2102 Node* LoadRangeNode::Identity( PhaseTransform *phase ) { | |
2103 Node* x = LoadINode::Identity(phase); | |
2104 if (x != this) return x; | |
2105 | |
2106 // Take apart the address into an oop and and offset. | |
2107 // Return 'this' if we cannot. | |
2108 Node* adr = in(MemNode::Address); | |
2109 intptr_t offset = 0; | |
2110 Node* base = AddPNode::Ideal_base_and_offset(adr, phase, offset); | |
2111 if (base == NULL) return this; | |
2112 const TypeAryPtr* tary = phase->type(adr)->isa_aryptr(); | |
2113 if (tary == NULL) return this; | |
2114 | |
2115 // We can fetch the length directly through an AllocateArrayNode. | |
2116 // This works even if the length is not constant (clone or newArray). | |
2117 if (offset == arrayOopDesc::length_offset_in_bytes()) { | |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2118 AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(base, phase); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2119 if (alloc != NULL) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2120 Node* allocated_length = alloc->Ideal_length(); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2121 // Do not allow make_ideal_length to allocate a CastII node. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2122 Node* len = alloc->make_ideal_length(tary, phase, false); |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2123 if (allocated_length == len) { |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2124 // Return allocated_length only if it would not be improved by a CastII. |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2125 return allocated_length; |
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2126 } |
0 | 2127 } |
2128 } | |
2129 | |
2130 return this; | |
2131 | |
2132 } | |
366
8261ee795323
6711100: 64bit fastdebug server vm crashes with assert(_base == Int,"Not an Int")
rasbold
parents:
305
diff
changeset
|
2133 |
0 | 2134 //============================================================================= |
2135 //---------------------------StoreNode::make----------------------------------- | |
2136 // Polymorphic factory method: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2137 StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, BasicType bt ) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2138 Compile* C = gvn.C; |
1609 | 2139 assert( C->get_alias_index(adr_type) != Compile::AliasIdxRaw || |
2140 ctl != NULL, "raw memory operations should have control edge"); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2141 |
0 | 2142 switch (bt) { |
2143 case T_BOOLEAN: | |
2144 case T_BYTE: return new (C, 4) StoreBNode(ctl, mem, adr, adr_type, val); | |
2145 case T_INT: return new (C, 4) StoreINode(ctl, mem, adr, adr_type, val); | |
2146 case T_CHAR: | |
2147 case T_SHORT: return new (C, 4) StoreCNode(ctl, mem, adr, adr_type, val); | |
2148 case T_LONG: return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val); | |
2149 case T_FLOAT: return new (C, 4) StoreFNode(ctl, mem, adr, adr_type, val); | |
2150 case T_DOUBLE: return new (C, 4) StoreDNode(ctl, mem, adr, adr_type, val); | |
2151 case T_ADDRESS: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2152 case T_OBJECT: |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2153 #ifdef _LP64 |
163 | 2154 if (adr->bottom_type()->is_ptr_to_narrowoop() || |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2155 (UseCompressedOops && val->bottom_type()->isa_klassptr() && |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2156 adr->bottom_type()->isa_rawptr())) { |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2157 val = gvn.transform(new (C, 2) EncodePNode(val, val->bottom_type()->make_narrowoop())); |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2158 return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, val); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2159 } else |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2160 #endif |
221
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2161 { |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2162 return new (C, 4) StorePNode(ctl, mem, adr, adr_type, val); |
1e026f8da827
6710487: More than half of JDI Regression tests hang with COOPs in -Xcomp mode
kvn
parents:
193
diff
changeset
|
2163 } |
0 | 2164 } |
2165 ShouldNotReachHere(); | |
2166 return (StoreNode*)NULL; | |
2167 } | |
2168 | |
2169 StoreLNode* StoreLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val) { | |
2170 bool require_atomic = true; | |
2171 return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val, require_atomic); | |
2172 } | |
2173 | |
2174 | |
2175 //--------------------------bottom_type---------------------------------------- | |
2176 const Type *StoreNode::bottom_type() const { | |
2177 return Type::MEMORY; | |
2178 } | |
2179 | |
2180 //------------------------------hash------------------------------------------- | |
2181 uint StoreNode::hash() const { | |
2182 // unroll addition of interesting fields | |
2183 //return (uintptr_t)in(Control) + (uintptr_t)in(Memory) + (uintptr_t)in(Address) + (uintptr_t)in(ValueIn); | |
2184 | |
2185 // Since they are not commoned, do not hash them: | |
2186 return NO_HASH; | |
2187 } | |
2188 | |
2189 //------------------------------Ideal------------------------------------------ | |
2190 // Change back-to-back Store(, p, x) -> Store(m, p, y) to Store(m, p, x). | |
2191 // When a store immediately follows a relevant allocation/initialization, | |
2192 // try to capture it into the initialization, or hoist it above. | |
2193 Node *StoreNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
2194 Node* p = MemNode::Ideal_common(phase, can_reshape); | |
2195 if (p) return (p == NodeSentinel) ? NULL : p; | |
2196 | |
2197 Node* mem = in(MemNode::Memory); | |
2198 Node* address = in(MemNode::Address); | |
2199 | |
3248
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2379
diff
changeset
|
2200 // Back-to-back stores to same address? Fold em up. Generally |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2379
diff
changeset
|
2201 // unsafe if I have intervening uses... Also disallowed for StoreCM |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2379
diff
changeset
|
2202 // since they must follow each StoreP operation. Redundant StoreCMs |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2379
diff
changeset
|
2203 // are eliminated just before matching in final_graph_reshape. |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2379
diff
changeset
|
2204 if (mem->is_Store() && phase->eqv_uncast(mem->in(MemNode::Address), address) && |
e6beb62de02d
7032963: StoreCM shouldn't participate in store elimination
never
parents:
2379
diff
changeset
|
2205 mem->Opcode() != Op_StoreCM) { |
0 | 2206 // Looking at a dead closed cycle of memory? |
2207 assert(mem != mem->in(MemNode::Memory), "dead loop in StoreNode::Ideal"); | |
2208 | |
2209 assert(Opcode() == mem->Opcode() || | |
2210 phase->C->get_alias_index(adr_type()) == Compile::AliasIdxRaw, | |
2211 "no mismatched stores, except on raw memory"); | |
2212 | |
2213 if (mem->outcnt() == 1 && // check for intervening uses | |
2214 mem->as_Store()->memory_size() <= this->memory_size()) { | |
2215 // If anybody other than 'this' uses 'mem', we cannot fold 'mem' away. | |
2216 // For example, 'mem' might be the final state at a conditional return. | |
2217 // Or, 'mem' might be used by some node which is live at the same time | |
2218 // 'this' is live, which might be unschedulable. So, require exactly | |
2219 // ONE user, the 'this' store, until such time as we clone 'mem' for | |
2220 // each of 'mem's uses (thus making the exactly-1-user-rule hold true). | |
2221 if (can_reshape) { // (%%% is this an anachronism?) | |
2222 set_req_X(MemNode::Memory, mem->in(MemNode::Memory), | |
2223 phase->is_IterGVN()); | |
2224 } else { | |
2225 // It's OK to do this in the parser, since DU info is always accurate, | |
2226 // and the parser always refers to nodes via SafePointNode maps. | |
2227 set_req(MemNode::Memory, mem->in(MemNode::Memory)); | |
2228 } | |
2229 return this; | |
2230 } | |
2231 } | |
2232 | |
2233 // Capture an unaliased, unconditional, simple store into an initializer. | |
2234 // Or, if it is independent of the allocation, hoist it above the allocation. | |
2235 if (ReduceFieldZeroing && /*can_reshape &&*/ | |
2236 mem->is_Proj() && mem->in(0)->is_Initialize()) { | |
2237 InitializeNode* init = mem->in(0)->as_Initialize(); | |
2238 intptr_t offset = init->can_capture_store(this, phase); | |
2239 if (offset > 0) { | |
2240 Node* moved = init->capture_store(this, offset, phase); | |
2241 // If the InitializeNode captured me, it made a raw copy of me, | |
2242 // and I need to disappear. | |
2243 if (moved != NULL) { | |
2244 // %%% hack to ensure that Ideal returns a new node: | |
2245 mem = MergeMemNode::make(phase->C, mem); | |
2246 return mem; // fold me away | |
2247 } | |
2248 } | |
2249 } | |
2250 | |
2251 return NULL; // No further progress | |
2252 } | |
2253 | |
2254 //------------------------------Value----------------------------------------- | |
2255 const Type *StoreNode::Value( PhaseTransform *phase ) const { | |
2256 // Either input is TOP ==> the result is TOP | |
2257 const Type *t1 = phase->type( in(MemNode::Memory) ); | |
2258 if( t1 == Type::TOP ) return Type::TOP; | |
2259 const Type *t2 = phase->type( in(MemNode::Address) ); | |
2260 if( t2 == Type::TOP ) return Type::TOP; | |
2261 const Type *t3 = phase->type( in(MemNode::ValueIn) ); | |
2262 if( t3 == Type::TOP ) return Type::TOP; | |
2263 return Type::MEMORY; | |
2264 } | |
2265 | |
2266 //------------------------------Identity--------------------------------------- | |
2267 // Remove redundant stores: | |
2268 // Store(m, p, Load(m, p)) changes to m. | |
2269 // Store(, p, x) -> Store(m, p, x) changes to Store(m, p, x). | |
2270 Node *StoreNode::Identity( PhaseTransform *phase ) { | |
2271 Node* mem = in(MemNode::Memory); | |
2272 Node* adr = in(MemNode::Address); | |
2273 Node* val = in(MemNode::ValueIn); | |
2274 | |
2275 // Load then Store? Then the Store is useless | |
2276 if (val->is_Load() && | |
2277 phase->eqv_uncast( val->in(MemNode::Address), adr ) && | |
2278 phase->eqv_uncast( val->in(MemNode::Memory ), mem ) && | |
2279 val->as_Load()->store_Opcode() == Opcode()) { | |
2280 return mem; | |
2281 } | |
2282 | |
2283 // Two stores in a row of the same value? | |
2284 if (mem->is_Store() && | |
2285 phase->eqv_uncast( mem->in(MemNode::Address), adr ) && | |
2286 phase->eqv_uncast( mem->in(MemNode::ValueIn), val ) && | |
2287 mem->Opcode() == Opcode()) { | |
2288 return mem; | |
2289 } | |
2290 | |
2291 // Store of zero anywhere into a freshly-allocated object? | |
2292 // Then the store is useless. | |
2293 // (It must already have been captured by the InitializeNode.) | |
2294 if (ReduceFieldZeroing && phase->type(val)->is_zero_type()) { | |
2295 // a newly allocated object is already all-zeroes everywhere | |
2296 if (mem->is_Proj() && mem->in(0)->is_Allocate()) { | |
2297 return mem; | |
2298 } | |
2299 | |
2300 // the store may also apply to zero-bits in an earlier object | |
2301 Node* prev_mem = find_previous_store(phase); | |
2302 // Steps (a), (b): Walk past independent stores to find an exact match. | |
2303 if (prev_mem != NULL) { | |
2304 Node* prev_val = can_see_stored_value(prev_mem, phase); | |
2305 if (prev_val != NULL && phase->eqv(prev_val, val)) { | |
2306 // prev_val and val might differ by a cast; it would be good | |
2307 // to keep the more informative of the two. | |
2308 return mem; | |
2309 } | |
2310 } | |
2311 } | |
2312 | |
2313 return this; | |
2314 } | |
2315 | |
2316 //------------------------------match_edge------------------------------------- | |
2317 // Do we Match on this edge index or not? Match only memory & value | |
2318 uint StoreNode::match_edge(uint idx) const { | |
2319 return idx == MemNode::Address || idx == MemNode::ValueIn; | |
2320 } | |
2321 | |
2322 //------------------------------cmp-------------------------------------------- | |
2323 // Do not common stores up together. They generally have to be split | |
2324 // back up anyways, so do not bother. | |
2325 uint StoreNode::cmp( const Node &n ) const { | |
2326 return (&n == this); // Always fail except on self | |
2327 } | |
2328 | |
2329 //------------------------------Ideal_masked_input----------------------------- | |
2330 // Check for a useless mask before a partial-word store | |
2331 // (StoreB ... (AndI valIn conIa) ) | |
2332 // If (conIa & mask == mask) this simplifies to | |
2333 // (StoreB ... (valIn) ) | |
2334 Node *StoreNode::Ideal_masked_input(PhaseGVN *phase, uint mask) { | |
2335 Node *val = in(MemNode::ValueIn); | |
2336 if( val->Opcode() == Op_AndI ) { | |
2337 const TypeInt *t = phase->type( val->in(2) )->isa_int(); | |
2338 if( t && t->is_con() && (t->get_con() & mask) == mask ) { | |
2339 set_req(MemNode::ValueIn, val->in(1)); | |
2340 return this; | |
2341 } | |
2342 } | |
2343 return NULL; | |
2344 } | |
2345 | |
2346 | |
2347 //------------------------------Ideal_sign_extended_input---------------------- | |
2348 // Check for useless sign-extension before a partial-word store | |
2349 // (StoreB ... (RShiftI _ (LShiftI _ valIn conIL ) conIR) ) | |
2350 // If (conIL == conIR && conIR <= num_bits) this simplifies to | |
2351 // (StoreB ... (valIn) ) | |
2352 Node *StoreNode::Ideal_sign_extended_input(PhaseGVN *phase, int num_bits) { | |
2353 Node *val = in(MemNode::ValueIn); | |
2354 if( val->Opcode() == Op_RShiftI ) { | |
2355 const TypeInt *t = phase->type( val->in(2) )->isa_int(); | |
2356 if( t && t->is_con() && (t->get_con() <= num_bits) ) { | |
2357 Node *shl = val->in(1); | |
2358 if( shl->Opcode() == Op_LShiftI ) { | |
2359 const TypeInt *t2 = phase->type( shl->in(2) )->isa_int(); | |
2360 if( t2 && t2->is_con() && (t2->get_con() == t->get_con()) ) { | |
2361 set_req(MemNode::ValueIn, shl->in(1)); | |
2362 return this; | |
2363 } | |
2364 } | |
2365 } | |
2366 } | |
2367 return NULL; | |
2368 } | |
2369 | |
2370 //------------------------------value_never_loaded----------------------------------- | |
2371 // Determine whether there are any possible loads of the value stored. | |
2372 // For simplicity, we actually check if there are any loads from the | |
2373 // address stored to, not just for loads of the value stored by this node. | |
2374 // | |
2375 bool StoreNode::value_never_loaded( PhaseTransform *phase) const { | |
2376 Node *adr = in(Address); | |
2377 const TypeOopPtr *adr_oop = phase->type(adr)->isa_oopptr(); | |
2378 if (adr_oop == NULL) | |
2379 return false; | |
223 | 2380 if (!adr_oop->is_known_instance_field()) |
0 | 2381 return false; // if not a distinct instance, there may be aliases of the address |
2382 for (DUIterator_Fast imax, i = adr->fast_outs(imax); i < imax; i++) { | |
2383 Node *use = adr->fast_out(i); | |
2384 int opc = use->Opcode(); | |
2385 if (use->is_Load() || use->is_LoadStore()) { | |
2386 return false; | |
2387 } | |
2388 } | |
2389 return true; | |
2390 } | |
2391 | |
2392 //============================================================================= | |
2393 //------------------------------Ideal------------------------------------------ | |
2394 // If the store is from an AND mask that leaves the low bits untouched, then | |
2395 // we can skip the AND operation. If the store is from a sign-extension | |
2396 // (a left shift, then right shift) we can skip both. | |
2397 Node *StoreBNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
2398 Node *progress = StoreNode::Ideal_masked_input(phase, 0xFF); | |
2399 if( progress != NULL ) return progress; | |
2400 | |
2401 progress = StoreNode::Ideal_sign_extended_input(phase, 24); | |
2402 if( progress != NULL ) return progress; | |
2403 | |
2404 // Finally check the default case | |
2405 return StoreNode::Ideal(phase, can_reshape); | |
2406 } | |
2407 | |
2408 //============================================================================= | |
2409 //------------------------------Ideal------------------------------------------ | |
2410 // If the store is from an AND mask that leaves the low bits untouched, then | |
2411 // we can skip the AND operation | |
2412 Node *StoreCNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
2413 Node *progress = StoreNode::Ideal_masked_input(phase, 0xFFFF); | |
2414 if( progress != NULL ) return progress; | |
2415 | |
2416 progress = StoreNode::Ideal_sign_extended_input(phase, 16); | |
2417 if( progress != NULL ) return progress; | |
2418 | |
2419 // Finally check the default case | |
2420 return StoreNode::Ideal(phase, can_reshape); | |
2421 } | |
2422 | |
2423 //============================================================================= | |
2424 //------------------------------Identity--------------------------------------- | |
2425 Node *StoreCMNode::Identity( PhaseTransform *phase ) { | |
2426 // No need to card mark when storing a null ptr | |
2427 Node* my_store = in(MemNode::OopStore); | |
2428 if (my_store->is_Store()) { | |
2429 const Type *t1 = phase->type( my_store->in(MemNode::ValueIn) ); | |
2430 if( t1 == TypePtr::NULL_PTR ) { | |
2431 return in(MemNode::Memory); | |
2432 } | |
2433 } | |
2434 return this; | |
2435 } | |
2436 | |
985
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2437 //============================================================================= |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2438 //------------------------------Ideal--------------------------------------- |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2439 Node *StoreCMNode::Ideal(PhaseGVN *phase, bool can_reshape){ |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2440 Node* progress = StoreNode::Ideal(phase, can_reshape); |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2441 if (progress != NULL) return progress; |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2442 |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2443 Node* my_store = in(MemNode::OopStore); |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2444 if (my_store->is_MergeMem()) { |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2445 Node* mem = my_store->as_MergeMem()->memory_at(oop_alias_idx()); |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2446 set_req(MemNode::OopStore, mem); |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2447 return this; |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2448 } |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2449 |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2450 return NULL; |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2451 } |
685e959d09ea
6877254: Server vm crashes with no branches off of store slice" when run with CMS and UseSuperWord(default)
cfang
parents:
708
diff
changeset
|
2452 |
0 | 2453 //------------------------------Value----------------------------------------- |
2454 const Type *StoreCMNode::Value( PhaseTransform *phase ) const { | |
43 | 2455 // Either input is TOP ==> the result is TOP |
2456 const Type *t = phase->type( in(MemNode::Memory) ); | |
2457 if( t == Type::TOP ) return Type::TOP; | |
2458 t = phase->type( in(MemNode::Address) ); | |
2459 if( t == Type::TOP ) return Type::TOP; | |
2460 t = phase->type( in(MemNode::ValueIn) ); | |
2461 if( t == Type::TOP ) return Type::TOP; | |
0 | 2462 // If extra input is TOP ==> the result is TOP |
43 | 2463 t = phase->type( in(MemNode::OopStore) ); |
2464 if( t == Type::TOP ) return Type::TOP; | |
0 | 2465 |
2466 return StoreNode::Value( phase ); | |
2467 } | |
2468 | |
2469 | |
2470 //============================================================================= | |
2471 //----------------------------------SCMemProjNode------------------------------ | |
2472 const Type * SCMemProjNode::Value( PhaseTransform *phase ) const | |
2473 { | |
2474 return bottom_type(); | |
2475 } | |
2476 | |
2477 //============================================================================= | |
2478 LoadStoreNode::LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex ) : Node(5) { | |
2479 init_req(MemNode::Control, c ); | |
2480 init_req(MemNode::Memory , mem); | |
2481 init_req(MemNode::Address, adr); | |
2482 init_req(MemNode::ValueIn, val); | |
2483 init_req( ExpectedIn, ex ); | |
2484 init_class_id(Class_LoadStore); | |
2485 | |
2486 } | |
2487 | |
2488 //============================================================================= | |
2489 //-------------------------------adr_type-------------------------------------- | |
2490 // Do we Match on this edge index or not? Do not match memory | |
2491 const TypePtr* ClearArrayNode::adr_type() const { | |
2492 Node *adr = in(3); | |
2493 return MemNode::calculate_adr_type(adr->bottom_type()); | |
2494 } | |
2495 | |
2496 //------------------------------match_edge------------------------------------- | |
2497 // Do we Match on this edge index or not? Do not match memory | |
2498 uint ClearArrayNode::match_edge(uint idx) const { | |
2499 return idx > 1; | |
2500 } | |
2501 | |
2502 //------------------------------Identity--------------------------------------- | |
2503 // Clearing a zero length array does nothing | |
2504 Node *ClearArrayNode::Identity( PhaseTransform *phase ) { | |
68
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2505 return phase->type(in(2))->higher_equal(TypeX::ZERO) ? in(1) : this; |
0 | 2506 } |
2507 | |
2508 //------------------------------Idealize--------------------------------------- | |
2509 // Clearing a short array is faster with stores | |
2510 Node *ClearArrayNode::Ideal(PhaseGVN *phase, bool can_reshape){ | |
2511 const int unit = BytesPerLong; | |
2512 const TypeX* t = phase->type(in(2))->isa_intptr_t(); | |
2513 if (!t) return NULL; | |
2514 if (!t->is_con()) return NULL; | |
2515 intptr_t raw_count = t->get_con(); | |
2516 intptr_t size = raw_count; | |
2517 if (!Matcher::init_array_count_is_in_bytes) size *= unit; | |
2518 // Clearing nothing uses the Identity call. | |
2519 // Negative clears are possible on dead ClearArrays | |
2520 // (see jck test stmt114.stmt11402.val). | |
2521 if (size <= 0 || size % unit != 0) return NULL; | |
2522 intptr_t count = size / unit; | |
2523 // Length too long; use fast hardware clear | |
2524 if (size > Matcher::init_array_short_size) return NULL; | |
2525 Node *mem = in(1); | |
2526 if( phase->type(mem)==Type::TOP ) return NULL; | |
2527 Node *adr = in(3); | |
2528 const Type* at = phase->type(adr); | |
2529 if( at==Type::TOP ) return NULL; | |
2530 const TypePtr* atp = at->isa_ptr(); | |
2531 // adjust atp to be the correct array element address type | |
2532 if (atp == NULL) atp = TypePtr::BOTTOM; | |
2533 else atp = atp->add_offset(Type::OffsetBot); | |
2534 // Get base for derived pointer purposes | |
2535 if( adr->Opcode() != Op_AddP ) Unimplemented(); | |
2536 Node *base = adr->in(1); | |
2537 | |
2538 Node *zero = phase->makecon(TypeLong::ZERO); | |
2539 Node *off = phase->MakeConX(BytesPerLong); | |
2540 mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero); | |
2541 count--; | |
2542 while( count-- ) { | |
2543 mem = phase->transform(mem); | |
2544 adr = phase->transform(new (phase->C, 4) AddPNode(base,adr,off)); | |
2545 mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero); | |
2546 } | |
2547 return mem; | |
2548 } | |
2549 | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2550 //----------------------------step_through---------------------------------- |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2551 // Return allocation input memory edge if it is different instance |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2552 // or itself if it is the one we are looking for. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2553 bool ClearArrayNode::step_through(Node** np, uint instance_id, PhaseTransform* phase) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2554 Node* n = *np; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2555 assert(n->is_ClearArray(), "sanity"); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2556 intptr_t offset; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2557 AllocateNode* alloc = AllocateNode::Ideal_allocation(n->in(3), phase, offset); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2558 // This method is called only before Allocate nodes are expanded during |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2559 // macro nodes expansion. Before that ClearArray nodes are only generated |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2560 // in LibraryCallKit::generate_arraycopy() which follows allocations. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2561 assert(alloc != NULL, "should have allocation"); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2562 if (alloc->_idx == instance_id) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2563 // Can not bypass initialization of the instance we are looking for. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2564 return false; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2565 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2566 // Otherwise skip it. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2567 InitializeNode* init = alloc->initialization(); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2568 if (init != NULL) |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2569 *np = init->in(TypeFunc::Memory); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2570 else |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2571 *np = alloc->in(TypeFunc::Memory); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2572 return true; |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2573 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2574 |
0 | 2575 //----------------------------clear_memory------------------------------------- |
2576 // Generate code to initialize object storage to zero. | |
2577 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, | |
2578 intptr_t start_offset, | |
2579 Node* end_offset, | |
2580 PhaseGVN* phase) { | |
2581 Compile* C = phase->C; | |
2582 intptr_t offset = start_offset; | |
2583 | |
2584 int unit = BytesPerLong; | |
2585 if ((offset % unit) != 0) { | |
2586 Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(offset)); | |
2587 adr = phase->transform(adr); | |
2588 const TypePtr* atp = TypeRawPtr::BOTTOM; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2589 mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT); |
0 | 2590 mem = phase->transform(mem); |
2591 offset += BytesPerInt; | |
2592 } | |
2593 assert((offset % unit) == 0, ""); | |
2594 | |
2595 // Initialize the remaining stuff, if any, with a ClearArray. | |
2596 return clear_memory(ctl, mem, dest, phase->MakeConX(offset), end_offset, phase); | |
2597 } | |
2598 | |
2599 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, | |
2600 Node* start_offset, | |
2601 Node* end_offset, | |
2602 PhaseGVN* phase) { | |
68
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2603 if (start_offset == end_offset) { |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2604 // nothing to do |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2605 return mem; |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2606 } |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2607 |
0 | 2608 Compile* C = phase->C; |
2609 int unit = BytesPerLong; | |
2610 Node* zbase = start_offset; | |
2611 Node* zend = end_offset; | |
2612 | |
2613 // Scale to the unit required by the CPU: | |
2614 if (!Matcher::init_array_count_is_in_bytes) { | |
2615 Node* shift = phase->intcon(exact_log2(unit)); | |
2616 zbase = phase->transform( new(C,3) URShiftXNode(zbase, shift) ); | |
2617 zend = phase->transform( new(C,3) URShiftXNode(zend, shift) ); | |
2618 } | |
2619 | |
2620 Node* zsize = phase->transform( new(C,3) SubXNode(zend, zbase) ); | |
2621 Node* zinit = phase->zerocon((unit == BytesPerLong) ? T_LONG : T_INT); | |
2622 | |
2623 // Bulk clear double-words | |
2624 Node* adr = phase->transform( new(C,4) AddPNode(dest, dest, start_offset) ); | |
2625 mem = new (C, 4) ClearArrayNode(ctl, mem, zsize, adr); | |
2626 return phase->transform(mem); | |
2627 } | |
2628 | |
2629 Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, | |
2630 intptr_t start_offset, | |
2631 intptr_t end_offset, | |
2632 PhaseGVN* phase) { | |
68
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2633 if (start_offset == end_offset) { |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2634 // nothing to do |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2635 return mem; |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2636 } |
daf38130e60d
6676841: ClearArrayNode::Identity is incorrect for 64-bit
never
parents:
64
diff
changeset
|
2637 |
0 | 2638 Compile* C = phase->C; |
2639 assert((end_offset % BytesPerInt) == 0, "odd end offset"); | |
2640 intptr_t done_offset = end_offset; | |
2641 if ((done_offset % BytesPerLong) != 0) { | |
2642 done_offset -= BytesPerInt; | |
2643 } | |
2644 if (done_offset > start_offset) { | |
2645 mem = clear_memory(ctl, mem, dest, | |
2646 start_offset, phase->MakeConX(done_offset), phase); | |
2647 } | |
2648 if (done_offset < end_offset) { // emit the final 32-bit store | |
2649 Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(done_offset)); | |
2650 adr = phase->transform(adr); | |
2651 const TypePtr* atp = TypeRawPtr::BOTTOM; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
2652 mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT); |
0 | 2653 mem = phase->transform(mem); |
2654 done_offset += BytesPerInt; | |
2655 } | |
2656 assert(done_offset == end_offset, ""); | |
2657 return mem; | |
2658 } | |
2659 | |
2660 //============================================================================= | |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2661 // Do not match memory edge. |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2662 uint StrIntrinsicNode::match_edge(uint idx) const { |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2663 return idx == 2 || idx == 3; |
681 | 2664 } |
2665 | |
2666 //------------------------------Ideal------------------------------------------ | |
2667 // Return a node which is more "ideal" than the current node. Strip out | |
2668 // control copies | |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2669 Node *StrIntrinsicNode::Ideal(PhaseGVN *phase, bool can_reshape) { |
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2670 if (remove_dead_region(phase, can_reshape)) return this; |
4115 | 2671 // Don't bother trying to transform a dead node |
2672 if (in(0) && in(0)->is_top()) return NULL; | |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2673 |
2417 | 2674 if (can_reshape) { |
2675 Node* mem = phase->transform(in(MemNode::Memory)); | |
2676 // If transformed to a MergeMem, get the desired slice | |
2677 uint alias_idx = phase->C->get_alias_index(adr_type()); | |
2678 mem = mem->is_MergeMem() ? mem->as_MergeMem()->memory_at(alias_idx) : mem; | |
2679 if (mem != in(MemNode::Memory)) { | |
2680 set_req(MemNode::Memory, mem); | |
2681 return this; | |
2682 } | |
2683 } | |
2412
f9424955eb18
7029152: Ideal nodes for String intrinsics miss memory edge optimization
kvn
parents:
2379
diff
changeset
|
2684 return NULL; |
169
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
2685 } |
9148c65abefc
6695049: (coll) Create an x86 intrinsic for Arrays.equals
rasbold
parents:
168
diff
changeset
|
2686 |
4115 | 2687 //------------------------------Value------------------------------------------ |
2688 const Type *StrIntrinsicNode::Value( PhaseTransform *phase ) const { | |
2689 if (in(0) && phase->type(in(0)) == Type::TOP) return Type::TOP; | |
2690 return bottom_type(); | |
2691 } | |
2692 | |
0 | 2693 //============================================================================= |
2694 MemBarNode::MemBarNode(Compile* C, int alias_idx, Node* precedent) | |
2695 : MultiNode(TypeFunc::Parms + (precedent == NULL? 0: 1)), | |
2696 _adr_type(C->get_adr_type(alias_idx)) | |
2697 { | |
2698 init_class_id(Class_MemBar); | |
2699 Node* top = C->top(); | |
2700 init_req(TypeFunc::I_O,top); | |
2701 init_req(TypeFunc::FramePtr,top); | |
2702 init_req(TypeFunc::ReturnAdr,top); | |
2703 if (precedent != NULL) | |
2704 init_req(TypeFunc::Parms, precedent); | |
2705 } | |
2706 | |
2707 //------------------------------cmp-------------------------------------------- | |
2708 uint MemBarNode::hash() const { return NO_HASH; } | |
2709 uint MemBarNode::cmp( const Node &n ) const { | |
2710 return (&n == this); // Always fail except on self | |
2711 } | |
2712 | |
2713 //------------------------------make------------------------------------------- | |
2714 MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) { | |
2715 int len = Precedent + (pn == NULL? 0: 1); | |
2716 switch (opcode) { | |
2717 case Op_MemBarAcquire: return new(C, len) MemBarAcquireNode(C, atp, pn); | |
2718 case Op_MemBarRelease: return new(C, len) MemBarReleaseNode(C, atp, pn); | |
3849
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3284
diff
changeset
|
2719 case Op_MemBarAcquireLock: return new(C, len) MemBarAcquireLockNode(C, atp, pn); |
f1c12354c3f7
7074017: Introduce MemBarAcquireLock/MemBarReleaseLock nodes for monitor enter/exit code paths
roland
parents:
3284
diff
changeset
|
2720 case Op_MemBarReleaseLock: return new(C, len) MemBarReleaseLockNode(C, atp, pn); |
0 | 2721 case Op_MemBarVolatile: return new(C, len) MemBarVolatileNode(C, atp, pn); |
2722 case Op_MemBarCPUOrder: return new(C, len) MemBarCPUOrderNode(C, atp, pn); | |
2723 case Op_Initialize: return new(C, len) InitializeNode(C, atp, pn); | |
2724 default: ShouldNotReachHere(); return NULL; | |
2725 } | |
2726 } | |
2727 | |
2728 //------------------------------Ideal------------------------------------------ | |
2729 // Return a node which is more "ideal" than the current node. Strip out | |
2730 // control copies | |
2731 Node *MemBarNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2732 if (remove_dead_region(phase, can_reshape)) return this; |
4115 | 2733 // Don't bother trying to transform a dead node |
2734 if (in(0) && in(0)->is_top()) return NULL; | |
1100
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2735 |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2736 // Eliminate volatile MemBars for scalar replaced objects. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2737 if (can_reshape && req() == (Precedent+1) && |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2738 (Opcode() == Op_MemBarAcquire || Opcode() == Op_MemBarVolatile)) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2739 // Volatile field loads and stores. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2740 Node* my_mem = in(MemBarNode::Precedent); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2741 if (my_mem != NULL && my_mem->is_Mem()) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2742 const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr(); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2743 // Check for scalar replaced object reference. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2744 if( t_oop != NULL && t_oop->is_known_instance_field() && |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2745 t_oop->offset() != Type::OffsetBot && |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2746 t_oop->offset() != Type::OffsetTop) { |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2747 // Replace MemBar projections by its inputs. |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2748 PhaseIterGVN* igvn = phase->is_IterGVN(); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2749 igvn->replace_node(proj_out(TypeFunc::Memory), in(TypeFunc::Memory)); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2750 igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control)); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2751 // Must return either the original node (now dead) or a new node |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2752 // (Do not return a top here, since that would break the uniqueness of top.) |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2753 return new (phase->C, 1) ConINode(TypeInt::ZERO); |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2754 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2755 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2756 } |
f96a1a986f7b
6895383: JCK test throws NPE for method compiled with Escape Analysis
kvn
parents:
1080
diff
changeset
|
2757 return NULL; |
0 | 2758 } |
2759 | |
2760 //------------------------------Value------------------------------------------ | |
2761 const Type *MemBarNode::Value( PhaseTransform *phase ) const { | |
2762 if( !in(0) ) return Type::TOP; | |
2763 if( phase->type(in(0)) == Type::TOP ) | |
2764 return Type::TOP; | |
2765 return TypeTuple::MEMBAR; | |
2766 } | |
2767 | |
2768 //------------------------------match------------------------------------------ | |
2769 // Construct projections for memory. | |
2770 Node *MemBarNode::match( const ProjNode *proj, const Matcher *m ) { | |
2771 switch (proj->_con) { | |
2772 case TypeFunc::Control: | |
2773 case TypeFunc::Memory: | |
2774 return new (m->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj); | |
2775 } | |
2776 ShouldNotReachHere(); | |
2777 return NULL; | |
2778 } | |
2779 | |
2780 //===========================InitializeNode==================================== | |
2781 // SUMMARY: | |
2782 // This node acts as a memory barrier on raw memory, after some raw stores. | |
2783 // The 'cooked' oop value feeds from the Initialize, not the Allocation. | |
2784 // The Initialize can 'capture' suitably constrained stores as raw inits. | |
2785 // It can coalesce related raw stores into larger units (called 'tiles'). | |
2786 // It can avoid zeroing new storage for memory units which have raw inits. | |
2787 // At macro-expansion, it is marked 'complete', and does not optimize further. | |
2788 // | |
2789 // EXAMPLE: | |
2790 // The object 'new short[2]' occupies 16 bytes in a 32-bit machine. | |
2791 // ctl = incoming control; mem* = incoming memory | |
2792 // (Note: A star * on a memory edge denotes I/O and other standard edges.) | |
2793 // First allocate uninitialized memory and fill in the header: | |
2794 // alloc = (Allocate ctl mem* 16 #short[].klass ...) | |
2795 // ctl := alloc.Control; mem* := alloc.Memory* | |
2796 // rawmem = alloc.Memory; rawoop = alloc.RawAddress | |
2797 // Then initialize to zero the non-header parts of the raw memory block: | |
2798 // init = (Initialize alloc.Control alloc.Memory* alloc.RawAddress) | |
2799 // ctl := init.Control; mem.SLICE(#short[*]) := init.Memory | |
2800 // After the initialize node executes, the object is ready for service: | |
2801 // oop := (CheckCastPP init.Control alloc.RawAddress #short[]) | |
2802 // Suppose its body is immediately initialized as {1,2}: | |
2803 // store1 = (StoreC init.Control init.Memory (+ oop 12) 1) | |
2804 // store2 = (StoreC init.Control store1 (+ oop 14) 2) | |
2805 // mem.SLICE(#short[*]) := store2 | |
2806 // | |
2807 // DETAILS: | |
2808 // An InitializeNode collects and isolates object initialization after | |
2809 // an AllocateNode and before the next possible safepoint. As a | |
2810 // memory barrier (MemBarNode), it keeps critical stores from drifting | |
2811 // down past any safepoint or any publication of the allocation. | |
2812 // Before this barrier, a newly-allocated object may have uninitialized bits. | |
2813 // After this barrier, it may be treated as a real oop, and GC is allowed. | |
2814 // | |
2815 // The semantics of the InitializeNode include an implicit zeroing of | |
2816 // the new object from object header to the end of the object. | |
2817 // (The object header and end are determined by the AllocateNode.) | |
2818 // | |
2819 // Certain stores may be added as direct inputs to the InitializeNode. | |
2820 // These stores must update raw memory, and they must be to addresses | |
2821 // derived from the raw address produced by AllocateNode, and with | |
2822 // a constant offset. They must be ordered by increasing offset. | |
2823 // The first one is at in(RawStores), the last at in(req()-1). | |
2824 // Unlike most memory operations, they are not linked in a chain, | |
2825 // but are displayed in parallel as users of the rawmem output of | |
2826 // the allocation. | |
2827 // | |
2828 // (See comments in InitializeNode::capture_store, which continue | |
2829 // the example given above.) | |
2830 // | |
2831 // When the associated Allocate is macro-expanded, the InitializeNode | |
2832 // may be rewritten to optimize collected stores. A ClearArrayNode | |
2833 // may also be created at that point to represent any required zeroing. | |
2834 // The InitializeNode is then marked 'complete', prohibiting further | |
2835 // capturing of nearby memory operations. | |
2836 // | |
2837 // During macro-expansion, all captured initializations which store | |
605 | 2838 // constant values of 32 bits or smaller are coalesced (if advantageous) |
0 | 2839 // into larger 'tiles' 32 or 64 bits. This allows an object to be |
2840 // initialized in fewer memory operations. Memory words which are | |
2841 // covered by neither tiles nor non-constant stores are pre-zeroed | |
2842 // by explicit stores of zero. (The code shape happens to do all | |
2843 // zeroing first, then all other stores, with both sequences occurring | |
2844 // in order of ascending offsets.) | |
2845 // | |
2846 // Alternatively, code may be inserted between an AllocateNode and its | |
2847 // InitializeNode, to perform arbitrary initialization of the new object. | |
2848 // E.g., the object copying intrinsics insert complex data transfers here. | |
2849 // The initialization must then be marked as 'complete' disable the | |
2850 // built-in zeroing semantics and the collection of initializing stores. | |
2851 // | |
2852 // While an InitializeNode is incomplete, reads from the memory state | |
2853 // produced by it are optimizable if they match the control edge and | |
2854 // new oop address associated with the allocation/initialization. | |
2855 // They return a stored value (if the offset matches) or else zero. | |
2856 // A write to the memory state, if it matches control and address, | |
2857 // and if it is to a constant offset, may be 'captured' by the | |
2858 // InitializeNode. It is cloned as a raw memory operation and rewired | |
2859 // inside the initialization, to the raw oop produced by the allocation. | |
2860 // Operations on addresses which are provably distinct (e.g., to | |
2861 // other AllocateNodes) are allowed to bypass the initialization. | |
2862 // | |
2863 // The effect of all this is to consolidate object initialization | |
2864 // (both arrays and non-arrays, both piecewise and bulk) into a | |
2865 // single location, where it can be optimized as a unit. | |
2866 // | |
2867 // Only stores with an offset less than TrackedInitializationLimit words | |
2868 // will be considered for capture by an InitializeNode. This puts a | |
2869 // reasonable limit on the complexity of optimized initializations. | |
2870 | |
2871 //---------------------------InitializeNode------------------------------------ | |
2872 InitializeNode::InitializeNode(Compile* C, int adr_type, Node* rawoop) | |
3961
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3902
diff
changeset
|
2873 : _is_complete(Incomplete), |
0 | 2874 MemBarNode(C, adr_type, rawoop) |
2875 { | |
2876 init_class_id(Class_Initialize); | |
2877 | |
2878 assert(adr_type == Compile::AliasIdxRaw, "only valid atp"); | |
2879 assert(in(RawAddress) == rawoop, "proper init"); | |
2880 // Note: allocation() can be NULL, for secondary initialization barriers | |
2881 } | |
2882 | |
2883 // Since this node is not matched, it will be processed by the | |
2884 // register allocator. Declare that there are no constraints | |
2885 // on the allocation of the RawAddress edge. | |
2886 const RegMask &InitializeNode::in_RegMask(uint idx) const { | |
2887 // This edge should be set to top, by the set_complete. But be conservative. | |
2888 if (idx == InitializeNode::RawAddress) | |
2889 return *(Compile::current()->matcher()->idealreg2spillmask[in(idx)->ideal_reg()]); | |
2890 return RegMask::Empty; | |
2891 } | |
2892 | |
2893 Node* InitializeNode::memory(uint alias_idx) { | |
2894 Node* mem = in(Memory); | |
2895 if (mem->is_MergeMem()) { | |
2896 return mem->as_MergeMem()->memory_at(alias_idx); | |
2897 } else { | |
2898 // incoming raw memory is not split | |
2899 return mem; | |
2900 } | |
2901 } | |
2902 | |
2903 bool InitializeNode::is_non_zero() { | |
2904 if (is_complete()) return false; | |
2905 remove_extra_zeroes(); | |
2906 return (req() > RawStores); | |
2907 } | |
2908 | |
2909 void InitializeNode::set_complete(PhaseGVN* phase) { | |
2910 assert(!is_complete(), "caller responsibility"); | |
3961
a92cdbac8b9e
7081933: Use zeroing elimination optimization for large array
kvn
parents:
3902
diff
changeset
|
2911 _is_complete = Complete; |
0 | 2912 |
2913 // After this node is complete, it contains a bunch of | |
2914 // raw-memory initializations. There is no need for | |
2915 // it to have anything to do with non-raw memory effects. | |
2916 // Therefore, tell all non-raw users to re-optimize themselves, | |
2917 // after skipping the memory effects of this initialization. | |
2918 PhaseIterGVN* igvn = phase->is_IterGVN(); | |
2919 if (igvn) igvn->add_users_to_worklist(this); | |
2920 } | |
2921 | |
2922 // convenience function | |
2923 // return false if the init contains any stores already | |
2924 bool AllocateNode::maybe_set_complete(PhaseGVN* phase) { | |
2925 InitializeNode* init = initialization(); | |
2926 if (init == NULL || init->is_complete()) return false; | |
2927 init->remove_extra_zeroes(); | |
2928 // for now, if this allocation has already collected any inits, bail: | |
2929 if (init->is_non_zero()) return false; | |
2930 init->set_complete(phase); | |
2931 return true; | |
2932 } | |
2933 | |
2934 void InitializeNode::remove_extra_zeroes() { | |
2935 if (req() == RawStores) return; | |
2936 Node* zmem = zero_memory(); | |
2937 uint fill = RawStores; | |
2938 for (uint i = fill; i < req(); i++) { | |
2939 Node* n = in(i); | |
2940 if (n->is_top() || n == zmem) continue; // skip | |
2941 if (fill < i) set_req(fill, n); // compact | |
2942 ++fill; | |
2943 } | |
2944 // delete any empty spaces created: | |
2945 while (fill < req()) { | |
2946 del_req(fill); | |
2947 } | |
2948 } | |
2949 | |
2950 // Helper for remembering which stores go with which offsets. | |
2951 intptr_t InitializeNode::get_store_offset(Node* st, PhaseTransform* phase) { | |
2952 if (!st->is_Store()) return -1; // can happen to dead code via subsume_node | |
2953 intptr_t offset = -1; | |
2954 Node* base = AddPNode::Ideal_base_and_offset(st->in(MemNode::Address), | |
2955 phase, offset); | |
2956 if (base == NULL) return -1; // something is dead, | |
2957 if (offset < 0) return -1; // dead, dead | |
2958 return offset; | |
2959 } | |
2960 | |
2961 // Helper for proving that an initialization expression is | |
2962 // "simple enough" to be folded into an object initialization. | |
2963 // Attempts to prove that a store's initial value 'n' can be captured | |
2964 // within the initialization without creating a vicious cycle, such as: | |
2965 // { Foo p = new Foo(); p.next = p; } | |
2966 // True for constants and parameters and small combinations thereof. | |
2967 bool InitializeNode::detect_init_independence(Node* n, | |
2968 bool st_is_pinned, | |
2969 int& count) { | |
2970 if (n == NULL) return true; // (can this really happen?) | |
2971 if (n->is_Proj()) n = n->in(0); | |
2972 if (n == this) return false; // found a cycle | |
2973 if (n->is_Con()) return true; | |
2974 if (n->is_Start()) return true; // params, etc., are OK | |
2975 if (n->is_Root()) return true; // even better | |
2976 | |
2977 Node* ctl = n->in(0); | |
2978 if (ctl != NULL && !ctl->is_top()) { | |
2979 if (ctl->is_Proj()) ctl = ctl->in(0); | |
2980 if (ctl == this) return false; | |
2981 | |
2982 // If we already know that the enclosing memory op is pinned right after | |
2983 // the init, then any control flow that the store has picked up | |
2984 // must have preceded the init, or else be equal to the init. | |
2985 // Even after loop optimizations (which might change control edges) | |
2986 // a store is never pinned *before* the availability of its inputs. | |
119
d1a5218d7eaf
6686791: Side effect in NumberFormat tests with -server -Xcomp
kvn
parents:
113
diff
changeset
|
2987 if (!MemNode::all_controls_dominate(n, this)) |
0 | 2988 return false; // failed to prove a good control |
2989 | |
2990 } | |
2991 | |
2992 // Check data edges for possible dependencies on 'this'. | |
2993 if ((count += 1) > 20) return false; // complexity limit | |
2994 for (uint i = 1; i < n->req(); i++) { | |
2995 Node* m = n->in(i); | |
2996 if (m == NULL || m == n || m->is_top()) continue; | |
2997 uint first_i = n->find_edge(m); | |
2998 if (i != first_i) continue; // process duplicate edge just once | |
2999 if (!detect_init_independence(m, st_is_pinned, count)) { | |
3000 return false; | |
3001 } | |
3002 } | |
3003 | |
3004 return true; | |
3005 } | |
3006 | |
3007 // Here are all the checks a Store must pass before it can be moved into | |
3008 // an initialization. Returns zero if a check fails. | |
3009 // On success, returns the (constant) offset to which the store applies, | |
3010 // within the initialized memory. | |
3011 intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase) { | |
3012 const int FAIL = 0; | |
3013 if (st->req() != MemNode::ValueIn + 1) | |
3014 return FAIL; // an inscrutable StoreNode (card mark?) | |
3015 Node* ctl = st->in(MemNode::Control); | |
3016 if (!(ctl != NULL && ctl->is_Proj() && ctl->in(0) == this)) | |
3017 return FAIL; // must be unconditional after the initialization | |
3018 Node* mem = st->in(MemNode::Memory); | |
3019 if (!(mem->is_Proj() && mem->in(0) == this)) | |
3020 return FAIL; // must not be preceded by other stores | |
3021 Node* adr = st->in(MemNode::Address); | |
3022 intptr_t offset; | |
3023 AllocateNode* alloc = AllocateNode::Ideal_allocation(adr, phase, offset); | |
3024 if (alloc == NULL) | |
3025 return FAIL; // inscrutable address | |
3026 if (alloc != allocation()) | |
3027 return FAIL; // wrong allocation! (store needs to float up) | |
3028 Node* val = st->in(MemNode::ValueIn); | |
3029 int complexity_count = 0; | |
3030 if (!detect_init_independence(val, true, complexity_count)) | |
3031 return FAIL; // stored value must be 'simple enough' | |
3032 | |
3033 return offset; // success | |
3034 } | |
3035 | |
3036 // Find the captured store in(i) which corresponds to the range | |
3037 // [start..start+size) in the initialized object. | |
3038 // If there is one, return its index i. If there isn't, return the | |
3039 // negative of the index where it should be inserted. | |
3040 // Return 0 if the queried range overlaps an initialization boundary | |
3041 // or if dead code is encountered. | |
3042 // If size_in_bytes is zero, do not bother with overlap checks. | |
3043 int InitializeNode::captured_store_insertion_point(intptr_t start, | |
3044 int size_in_bytes, | |
3045 PhaseTransform* phase) { | |
3046 const int FAIL = 0, MAX_STORE = BytesPerLong; | |
3047 | |
3048 if (is_complete()) | |
3049 return FAIL; // arraycopy got here first; punt | |
3050 | |
3051 assert(allocation() != NULL, "must be present"); | |
3052 | |
3053 // no negatives, no header fields: | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3054 if (start < (intptr_t) allocation()->minimum_header_size()) return FAIL; |
0 | 3055 |
3056 // after a certain size, we bail out on tracking all the stores: | |
3057 intptr_t ti_limit = (TrackedInitializationLimit * HeapWordSize); | |
3058 if (start >= ti_limit) return FAIL; | |
3059 | |
3060 for (uint i = InitializeNode::RawStores, limit = req(); ; ) { | |
3061 if (i >= limit) return -(int)i; // not found; here is where to put it | |
3062 | |
3063 Node* st = in(i); | |
3064 intptr_t st_off = get_store_offset(st, phase); | |
3065 if (st_off < 0) { | |
3066 if (st != zero_memory()) { | |
3067 return FAIL; // bail out if there is dead garbage | |
3068 } | |
3069 } else if (st_off > start) { | |
3070 // ...we are done, since stores are ordered | |
3071 if (st_off < start + size_in_bytes) { | |
3072 return FAIL; // the next store overlaps | |
3073 } | |
3074 return -(int)i; // not found; here is where to put it | |
3075 } else if (st_off < start) { | |
3076 if (size_in_bytes != 0 && | |
3077 start < st_off + MAX_STORE && | |
3078 start < st_off + st->as_Store()->memory_size()) { | |
3079 return FAIL; // the previous store overlaps | |
3080 } | |
3081 } else { | |
3082 if (size_in_bytes != 0 && | |
3083 st->as_Store()->memory_size() != size_in_bytes) { | |
3084 return FAIL; // mismatched store size | |
3085 } | |
3086 return i; | |
3087 } | |
3088 | |
3089 ++i; | |
3090 } | |
3091 } | |
3092 | |
3093 // Look for a captured store which initializes at the offset 'start' | |
3094 // with the given size. If there is no such store, and no other | |
3095 // initialization interferes, then return zero_memory (the memory | |
3096 // projection of the AllocateNode). | |
3097 Node* InitializeNode::find_captured_store(intptr_t start, int size_in_bytes, | |
3098 PhaseTransform* phase) { | |
3099 assert(stores_are_sane(phase), ""); | |
3100 int i = captured_store_insertion_point(start, size_in_bytes, phase); | |
3101 if (i == 0) { | |
3102 return NULL; // something is dead | |
3103 } else if (i < 0) { | |
3104 return zero_memory(); // just primordial zero bits here | |
3105 } else { | |
3106 Node* st = in(i); // here is the store at this position | |
3107 assert(get_store_offset(st->as_Store(), phase) == start, "sanity"); | |
3108 return st; | |
3109 } | |
3110 } | |
3111 | |
3112 // Create, as a raw pointer, an address within my new object at 'offset'. | |
3113 Node* InitializeNode::make_raw_address(intptr_t offset, | |
3114 PhaseTransform* phase) { | |
3115 Node* addr = in(RawAddress); | |
3116 if (offset != 0) { | |
3117 Compile* C = phase->C; | |
3118 addr = phase->transform( new (C, 4) AddPNode(C->top(), addr, | |
3119 phase->MakeConX(offset)) ); | |
3120 } | |
3121 return addr; | |
3122 } | |
3123 | |
3124 // Clone the given store, converting it into a raw store | |
3125 // initializing a field or element of my new object. | |
3126 // Caller is responsible for retiring the original store, | |
3127 // with subsume_node or the like. | |
3128 // | |
3129 // From the example above InitializeNode::InitializeNode, | |
3130 // here are the old stores to be captured: | |
3131 // store1 = (StoreC init.Control init.Memory (+ oop 12) 1) | |
3132 // store2 = (StoreC init.Control store1 (+ oop 14) 2) | |
3133 // | |
3134 // Here is the changed code; note the extra edges on init: | |
3135 // alloc = (Allocate ...) | |
3136 // rawoop = alloc.RawAddress | |
3137 // rawstore1 = (StoreC alloc.Control alloc.Memory (+ rawoop 12) 1) | |
3138 // rawstore2 = (StoreC alloc.Control alloc.Memory (+ rawoop 14) 2) | |
3139 // init = (Initialize alloc.Control alloc.Memory rawoop | |
3140 // rawstore1 rawstore2) | |
3141 // | |
3142 Node* InitializeNode::capture_store(StoreNode* st, intptr_t start, | |
3143 PhaseTransform* phase) { | |
3144 assert(stores_are_sane(phase), ""); | |
3145 | |
3146 if (start < 0) return NULL; | |
3147 assert(can_capture_store(st, phase) == start, "sanity"); | |
3148 | |
3149 Compile* C = phase->C; | |
3150 int size_in_bytes = st->memory_size(); | |
3151 int i = captured_store_insertion_point(start, size_in_bytes, phase); | |
3152 if (i == 0) return NULL; // bail out | |
3153 Node* prev_mem = NULL; // raw memory for the captured store | |
3154 if (i > 0) { | |
3155 prev_mem = in(i); // there is a pre-existing store under this one | |
3156 set_req(i, C->top()); // temporarily disconnect it | |
3157 // See StoreNode::Ideal 'st->outcnt() == 1' for the reason to disconnect. | |
3158 } else { | |
3159 i = -i; // no pre-existing store | |
3160 prev_mem = zero_memory(); // a slice of the newly allocated object | |
3161 if (i > InitializeNode::RawStores && in(i-1) == prev_mem) | |
3162 set_req(--i, C->top()); // reuse this edge; it has been folded away | |
3163 else | |
3164 ins_req(i, C->top()); // build a new edge | |
3165 } | |
3166 Node* new_st = st->clone(); | |
3167 new_st->set_req(MemNode::Control, in(Control)); | |
3168 new_st->set_req(MemNode::Memory, prev_mem); | |
3169 new_st->set_req(MemNode::Address, make_raw_address(start, phase)); | |
3170 new_st = phase->transform(new_st); | |
3171 | |
3172 // At this point, new_st might have swallowed a pre-existing store | |
3173 // at the same offset, or perhaps new_st might have disappeared, | |
3174 // if it redundantly stored the same value (or zero to fresh memory). | |
3175 | |
3176 // In any case, wire it in: | |
3177 set_req(i, new_st); | |
3178 | |
3179 // The caller may now kill the old guy. | |
3180 DEBUG_ONLY(Node* check_st = find_captured_store(start, size_in_bytes, phase)); | |
3181 assert(check_st == new_st || check_st == NULL, "must be findable"); | |
3182 assert(!is_complete(), ""); | |
3183 return new_st; | |
3184 } | |
3185 | |
3186 static bool store_constant(jlong* tiles, int num_tiles, | |
3187 intptr_t st_off, int st_size, | |
3188 jlong con) { | |
3189 if ((st_off & (st_size-1)) != 0) | |
3190 return false; // strange store offset (assume size==2**N) | |
3191 address addr = (address)tiles + st_off; | |
3192 assert(st_off >= 0 && addr+st_size <= (address)&tiles[num_tiles], "oob"); | |
3193 switch (st_size) { | |
3194 case sizeof(jbyte): *(jbyte*) addr = (jbyte) con; break; | |
3195 case sizeof(jchar): *(jchar*) addr = (jchar) con; break; | |
3196 case sizeof(jint): *(jint*) addr = (jint) con; break; | |
3197 case sizeof(jlong): *(jlong*) addr = (jlong) con; break; | |
3198 default: return false; // strange store size (detect size!=2**N here) | |
3199 } | |
3200 return true; // return success to caller | |
3201 } | |
3202 | |
3203 // Coalesce subword constants into int constants and possibly | |
3204 // into long constants. The goal, if the CPU permits, | |
3205 // is to initialize the object with a small number of 64-bit tiles. | |
3206 // Also, convert floating-point constants to bit patterns. | |
3207 // Non-constants are not relevant to this pass. | |
3208 // | |
3209 // In terms of the running example on InitializeNode::InitializeNode | |
3210 // and InitializeNode::capture_store, here is the transformation | |
3211 // of rawstore1 and rawstore2 into rawstore12: | |
3212 // alloc = (Allocate ...) | |
3213 // rawoop = alloc.RawAddress | |
3214 // tile12 = 0x00010002 | |
3215 // rawstore12 = (StoreI alloc.Control alloc.Memory (+ rawoop 12) tile12) | |
3216 // init = (Initialize alloc.Control alloc.Memory rawoop rawstore12) | |
3217 // | |
3218 void | |
3219 InitializeNode::coalesce_subword_stores(intptr_t header_size, | |
3220 Node* size_in_bytes, | |
3221 PhaseGVN* phase) { | |
3222 Compile* C = phase->C; | |
3223 | |
3224 assert(stores_are_sane(phase), ""); | |
3225 // Note: After this pass, they are not completely sane, | |
3226 // since there may be some overlaps. | |
3227 | |
3228 int old_subword = 0, old_long = 0, new_int = 0, new_long = 0; | |
3229 | |
3230 intptr_t ti_limit = (TrackedInitializationLimit * HeapWordSize); | |
3231 intptr_t size_limit = phase->find_intptr_t_con(size_in_bytes, ti_limit); | |
3232 size_limit = MIN2(size_limit, ti_limit); | |
3233 size_limit = align_size_up(size_limit, BytesPerLong); | |
3234 int num_tiles = size_limit / BytesPerLong; | |
3235 | |
3236 // allocate space for the tile map: | |
3237 const int small_len = DEBUG_ONLY(true ? 3 :) 30; // keep stack frames small | |
3238 jlong tiles_buf[small_len]; | |
3239 Node* nodes_buf[small_len]; | |
3240 jlong inits_buf[small_len]; | |
3241 jlong* tiles = ((num_tiles <= small_len) ? &tiles_buf[0] | |
3242 : NEW_RESOURCE_ARRAY(jlong, num_tiles)); | |
3243 Node** nodes = ((num_tiles <= small_len) ? &nodes_buf[0] | |
3244 : NEW_RESOURCE_ARRAY(Node*, num_tiles)); | |
3245 jlong* inits = ((num_tiles <= small_len) ? &inits_buf[0] | |
3246 : NEW_RESOURCE_ARRAY(jlong, num_tiles)); | |
3247 // tiles: exact bitwise model of all primitive constants | |
3248 // nodes: last constant-storing node subsumed into the tiles model | |
3249 // inits: which bytes (in each tile) are touched by any initializations | |
3250 | |
3251 //// Pass A: Fill in the tile model with any relevant stores. | |
3252 | |
3253 Copy::zero_to_bytes(tiles, sizeof(tiles[0]) * num_tiles); | |
3254 Copy::zero_to_bytes(nodes, sizeof(nodes[0]) * num_tiles); | |
3255 Copy::zero_to_bytes(inits, sizeof(inits[0]) * num_tiles); | |
3256 Node* zmem = zero_memory(); // initially zero memory state | |
3257 for (uint i = InitializeNode::RawStores, limit = req(); i < limit; i++) { | |
3258 Node* st = in(i); | |
3259 intptr_t st_off = get_store_offset(st, phase); | |
3260 | |
3261 // Figure out the store's offset and constant value: | |
3262 if (st_off < header_size) continue; //skip (ignore header) | |
3263 if (st->in(MemNode::Memory) != zmem) continue; //skip (odd store chain) | |
3264 int st_size = st->as_Store()->memory_size(); | |
3265 if (st_off + st_size > size_limit) break; | |
3266 | |
3267 // Record which bytes are touched, whether by constant or not. | |
3268 if (!store_constant(inits, num_tiles, st_off, st_size, (jlong) -1)) | |
3269 continue; // skip (strange store size) | |
3270 | |
3271 const Type* val = phase->type(st->in(MemNode::ValueIn)); | |
3272 if (!val->singleton()) continue; //skip (non-con store) | |
3273 BasicType type = val->basic_type(); | |
3274 | |
3275 jlong con = 0; | |
3276 switch (type) { | |
3277 case T_INT: con = val->is_int()->get_con(); break; | |
3278 case T_LONG: con = val->is_long()->get_con(); break; | |
3279 case T_FLOAT: con = jint_cast(val->getf()); break; | |
3280 case T_DOUBLE: con = jlong_cast(val->getd()); break; | |
3281 default: continue; //skip (odd store type) | |
3282 } | |
3283 | |
3284 if (type == T_LONG && Matcher::isSimpleConstant64(con) && | |
3285 st->Opcode() == Op_StoreL) { | |
3286 continue; // This StoreL is already optimal. | |
3287 } | |
3288 | |
3289 // Store down the constant. | |
3290 store_constant(tiles, num_tiles, st_off, st_size, con); | |
3291 | |
3292 intptr_t j = st_off >> LogBytesPerLong; | |
3293 | |
3294 if (type == T_INT && st_size == BytesPerInt | |
3295 && (st_off & BytesPerInt) == BytesPerInt) { | |
3296 jlong lcon = tiles[j]; | |
3297 if (!Matcher::isSimpleConstant64(lcon) && | |
3298 st->Opcode() == Op_StoreI) { | |
3299 // This StoreI is already optimal by itself. | |
3300 jint* intcon = (jint*) &tiles[j]; | |
3301 intcon[1] = 0; // undo the store_constant() | |
3302 | |
3303 // If the previous store is also optimal by itself, back up and | |
3304 // undo the action of the previous loop iteration... if we can. | |
3305 // But if we can't, just let the previous half take care of itself. | |
3306 st = nodes[j]; | |
3307 st_off -= BytesPerInt; | |
3308 con = intcon[0]; | |
3309 if (con != 0 && st != NULL && st->Opcode() == Op_StoreI) { | |
3310 assert(st_off >= header_size, "still ignoring header"); | |
3311 assert(get_store_offset(st, phase) == st_off, "must be"); | |
3312 assert(in(i-1) == zmem, "must be"); | |
3313 DEBUG_ONLY(const Type* tcon = phase->type(st->in(MemNode::ValueIn))); | |
3314 assert(con == tcon->is_int()->get_con(), "must be"); | |
3315 // Undo the effects of the previous loop trip, which swallowed st: | |
3316 intcon[0] = 0; // undo store_constant() | |
3317 set_req(i-1, st); // undo set_req(i, zmem) | |
3318 nodes[j] = NULL; // undo nodes[j] = st | |
3319 --old_subword; // undo ++old_subword | |
3320 } | |
3321 continue; // This StoreI is already optimal. | |
3322 } | |
3323 } | |
3324 | |
3325 // This store is not needed. | |
3326 set_req(i, zmem); | |
3327 nodes[j] = st; // record for the moment | |
3328 if (st_size < BytesPerLong) // something has changed | |
3329 ++old_subword; // includes int/float, but who's counting... | |
3330 else ++old_long; | |
3331 } | |
3332 | |
3333 if ((old_subword + old_long) == 0) | |
3334 return; // nothing more to do | |
3335 | |
3336 //// Pass B: Convert any non-zero tiles into optimal constant stores. | |
3337 // Be sure to insert them before overlapping non-constant stores. | |
3338 // (E.g., byte[] x = { 1,2,y,4 } => x[int 0] = 0x01020004, x[2]=y.) | |
3339 for (int j = 0; j < num_tiles; j++) { | |
3340 jlong con = tiles[j]; | |
3341 jlong init = inits[j]; | |
3342 if (con == 0) continue; | |
3343 jint con0, con1; // split the constant, address-wise | |
3344 jint init0, init1; // split the init map, address-wise | |
3345 { union { jlong con; jint intcon[2]; } u; | |
3346 u.con = con; | |
3347 con0 = u.intcon[0]; | |
3348 con1 = u.intcon[1]; | |
3349 u.con = init; | |
3350 init0 = u.intcon[0]; | |
3351 init1 = u.intcon[1]; | |
3352 } | |
3353 | |
3354 Node* old = nodes[j]; | |
3355 assert(old != NULL, "need the prior store"); | |
3356 intptr_t offset = (j * BytesPerLong); | |
3357 | |
3358 bool split = !Matcher::isSimpleConstant64(con); | |
3359 | |
3360 if (offset < header_size) { | |
3361 assert(offset + BytesPerInt >= header_size, "second int counts"); | |
3362 assert(*(jint*)&tiles[j] == 0, "junk in header"); | |
3363 split = true; // only the second word counts | |
3364 // Example: int a[] = { 42 ... } | |
3365 } else if (con0 == 0 && init0 == -1) { | |
3366 split = true; // first word is covered by full inits | |
3367 // Example: int a[] = { ... foo(), 42 ... } | |
3368 } else if (con1 == 0 && init1 == -1) { | |
3369 split = true; // second word is covered by full inits | |
3370 // Example: int a[] = { ... 42, foo() ... } | |
3371 } | |
3372 | |
3373 // Here's a case where init0 is neither 0 nor -1: | |
3374 // byte a[] = { ... 0,0,foo(),0, 0,0,0,42 ... } | |
3375 // Assuming big-endian memory, init0, init1 are 0x0000FF00, 0x000000FF. | |
3376 // In this case the tile is not split; it is (jlong)42. | |
3377 // The big tile is stored down, and then the foo() value is inserted. | |
3378 // (If there were foo(),foo() instead of foo(),0, init0 would be -1.) | |
3379 | |
3380 Node* ctl = old->in(MemNode::Control); | |
3381 Node* adr = make_raw_address(offset, phase); | |
3382 const TypePtr* atp = TypeRawPtr::BOTTOM; | |
3383 | |
3384 // One or two coalesced stores to plop down. | |
3385 Node* st[2]; | |
3386 intptr_t off[2]; | |
3387 int nst = 0; | |
3388 if (!split) { | |
3389 ++new_long; | |
3390 off[nst] = offset; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3391 st[nst++] = StoreNode::make(*phase, ctl, zmem, adr, atp, |
0 | 3392 phase->longcon(con), T_LONG); |
3393 } else { | |
3394 // Omit either if it is a zero. | |
3395 if (con0 != 0) { | |
3396 ++new_int; | |
3397 off[nst] = offset; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3398 st[nst++] = StoreNode::make(*phase, ctl, zmem, adr, atp, |
0 | 3399 phase->intcon(con0), T_INT); |
3400 } | |
3401 if (con1 != 0) { | |
3402 ++new_int; | |
3403 offset += BytesPerInt; | |
3404 adr = make_raw_address(offset, phase); | |
3405 off[nst] = offset; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3406 st[nst++] = StoreNode::make(*phase, ctl, zmem, adr, atp, |
0 | 3407 phase->intcon(con1), T_INT); |
3408 } | |
3409 } | |
3410 | |
3411 // Insert second store first, then the first before the second. | |
3412 // Insert each one just before any overlapping non-constant stores. | |
3413 while (nst > 0) { | |
3414 Node* st1 = st[--nst]; | |
3415 C->copy_node_notes_to(st1, old); | |
3416 st1 = phase->transform(st1); | |
3417 offset = off[nst]; | |
3418 assert(offset >= header_size, "do not smash header"); | |
3419 int ins_idx = captured_store_insertion_point(offset, /*size:*/0, phase); | |
3420 guarantee(ins_idx != 0, "must re-insert constant store"); | |
3421 if (ins_idx < 0) ins_idx = -ins_idx; // never overlap | |
3422 if (ins_idx > InitializeNode::RawStores && in(ins_idx-1) == zmem) | |
3423 set_req(--ins_idx, st1); | |
3424 else | |
3425 ins_req(ins_idx, st1); | |
3426 } | |
3427 } | |
3428 | |
3429 if (PrintCompilation && WizardMode) | |
3430 tty->print_cr("Changed %d/%d subword/long constants into %d/%d int/long", | |
3431 old_subword, old_long, new_int, new_long); | |
3432 if (C->log() != NULL) | |
3433 C->log()->elem("comment that='%d/%d subword/long to %d/%d int/long'", | |
3434 old_subword, old_long, new_int, new_long); | |
3435 | |
3436 // Clean up any remaining occurrences of zmem: | |
3437 remove_extra_zeroes(); | |
3438 } | |
3439 | |
3440 // Explore forward from in(start) to find the first fully initialized | |
3441 // word, and return its offset. Skip groups of subword stores which | |
3442 // together initialize full words. If in(start) is itself part of a | |
3443 // fully initialized word, return the offset of in(start). If there | |
3444 // are no following full-word stores, or if something is fishy, return | |
3445 // a negative value. | |
3446 intptr_t InitializeNode::find_next_fullword_store(uint start, PhaseGVN* phase) { | |
3447 int int_map = 0; | |
3448 intptr_t int_map_off = 0; | |
3449 const int FULL_MAP = right_n_bits(BytesPerInt); // the int_map we hope for | |
3450 | |
3451 for (uint i = start, limit = req(); i < limit; i++) { | |
3452 Node* st = in(i); | |
3453 | |
3454 intptr_t st_off = get_store_offset(st, phase); | |
3455 if (st_off < 0) break; // return conservative answer | |
3456 | |
3457 int st_size = st->as_Store()->memory_size(); | |
3458 if (st_size >= BytesPerInt && (st_off % BytesPerInt) == 0) { | |
3459 return st_off; // we found a complete word init | |
3460 } | |
3461 | |
3462 // update the map: | |
3463 | |
3464 intptr_t this_int_off = align_size_down(st_off, BytesPerInt); | |
3465 if (this_int_off != int_map_off) { | |
3466 // reset the map: | |
3467 int_map = 0; | |
3468 int_map_off = this_int_off; | |
3469 } | |
3470 | |
3471 int subword_off = st_off - this_int_off; | |
3472 int_map |= right_n_bits(st_size) << subword_off; | |
3473 if ((int_map & FULL_MAP) == FULL_MAP) { | |
3474 return this_int_off; // we found a complete word init | |
3475 } | |
3476 | |
3477 // Did this store hit or cross the word boundary? | |
3478 intptr_t next_int_off = align_size_down(st_off + st_size, BytesPerInt); | |
3479 if (next_int_off == this_int_off + BytesPerInt) { | |
3480 // We passed the current int, without fully initializing it. | |
3481 int_map_off = next_int_off; | |
3482 int_map >>= BytesPerInt; | |
3483 } else if (next_int_off > this_int_off + BytesPerInt) { | |
3484 // We passed the current and next int. | |
3485 return this_int_off + BytesPerInt; | |
3486 } | |
3487 } | |
3488 | |
3489 return -1; | |
3490 } | |
3491 | |
3492 | |
3493 // Called when the associated AllocateNode is expanded into CFG. | |
3494 // At this point, we may perform additional optimizations. | |
3495 // Linearize the stores by ascending offset, to make memory | |
3496 // activity as coherent as possible. | |
3497 Node* InitializeNode::complete_stores(Node* rawctl, Node* rawmem, Node* rawptr, | |
3498 intptr_t header_size, | |
3499 Node* size_in_bytes, | |
3500 PhaseGVN* phase) { | |
3501 assert(!is_complete(), "not already complete"); | |
3502 assert(stores_are_sane(phase), ""); | |
3503 assert(allocation() != NULL, "must be present"); | |
3504 | |
3505 remove_extra_zeroes(); | |
3506 | |
3507 if (ReduceFieldZeroing || ReduceBulkZeroing) | |
3508 // reduce instruction count for common initialization patterns | |
3509 coalesce_subword_stores(header_size, size_in_bytes, phase); | |
3510 | |
3511 Node* zmem = zero_memory(); // initially zero memory state | |
3512 Node* inits = zmem; // accumulating a linearized chain of inits | |
3513 #ifdef ASSERT | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3514 intptr_t first_offset = allocation()->minimum_header_size(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3515 intptr_t last_init_off = first_offset; // previous init offset |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3516 intptr_t last_init_end = first_offset; // previous init offset+size |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3517 intptr_t last_tile_end = first_offset; // previous tile offset+size |
0 | 3518 #endif |
3519 intptr_t zeroes_done = header_size; | |
3520 | |
3521 bool do_zeroing = true; // we might give up if inits are very sparse | |
3522 int big_init_gaps = 0; // how many large gaps have we seen? | |
3523 | |
3524 if (ZeroTLAB) do_zeroing = false; | |
3525 if (!ReduceFieldZeroing && !ReduceBulkZeroing) do_zeroing = false; | |
3526 | |
3527 for (uint i = InitializeNode::RawStores, limit = req(); i < limit; i++) { | |
3528 Node* st = in(i); | |
3529 intptr_t st_off = get_store_offset(st, phase); | |
3530 if (st_off < 0) | |
3531 break; // unknown junk in the inits | |
3532 if (st->in(MemNode::Memory) != zmem) | |
3533 break; // complicated store chains somehow in list | |
3534 | |
3535 int st_size = st->as_Store()->memory_size(); | |
3536 intptr_t next_init_off = st_off + st_size; | |
3537 | |
3538 if (do_zeroing && zeroes_done < next_init_off) { | |
3539 // See if this store needs a zero before it or under it. | |
3540 intptr_t zeroes_needed = st_off; | |
3541 | |
3542 if (st_size < BytesPerInt) { | |
3543 // Look for subword stores which only partially initialize words. | |
3544 // If we find some, we must lay down some word-level zeroes first, | |
3545 // underneath the subword stores. | |
3546 // | |
3547 // Examples: | |
3548 // byte[] a = { p,q,r,s } => a[0]=p,a[1]=q,a[2]=r,a[3]=s | |
3549 // byte[] a = { x,y,0,0 } => a[0..3] = 0, a[0]=x,a[1]=y | |
3550 // byte[] a = { 0,0,z,0 } => a[0..3] = 0, a[2]=z | |
3551 // | |
3552 // Note: coalesce_subword_stores may have already done this, | |
3553 // if it was prompted by constant non-zero subword initializers. | |
3554 // But this case can still arise with non-constant stores. | |
3555 | |
3556 intptr_t next_full_store = find_next_fullword_store(i, phase); | |
3557 | |
3558 // In the examples above: | |
3559 // in(i) p q r s x y z | |
3560 // st_off 12 13 14 15 12 13 14 | |
3561 // st_size 1 1 1 1 1 1 1 | |
3562 // next_full_s. 12 16 16 16 16 16 16 | |
3563 // z's_done 12 16 16 16 12 16 12 | |
3564 // z's_needed 12 16 16 16 16 16 16 | |
3565 // zsize 0 0 0 0 4 0 4 | |
3566 if (next_full_store < 0) { | |
3567 // Conservative tack: Zero to end of current word. | |
3568 zeroes_needed = align_size_up(zeroes_needed, BytesPerInt); | |
3569 } else { | |
3570 // Zero to beginning of next fully initialized word. | |
3571 // Or, don't zero at all, if we are already in that word. | |
3572 assert(next_full_store >= zeroes_needed, "must go forward"); | |
3573 assert((next_full_store & (BytesPerInt-1)) == 0, "even boundary"); | |
3574 zeroes_needed = next_full_store; | |
3575 } | |
3576 } | |
3577 | |
3578 if (zeroes_needed > zeroes_done) { | |
3579 intptr_t zsize = zeroes_needed - zeroes_done; | |
3580 // Do some incremental zeroing on rawmem, in parallel with inits. | |
3581 zeroes_done = align_size_down(zeroes_done, BytesPerInt); | |
3582 rawmem = ClearArrayNode::clear_memory(rawctl, rawmem, rawptr, | |
3583 zeroes_done, zeroes_needed, | |
3584 phase); | |
3585 zeroes_done = zeroes_needed; | |
3586 if (zsize > Matcher::init_array_short_size && ++big_init_gaps > 2) | |
3587 do_zeroing = false; // leave the hole, next time | |
3588 } | |
3589 } | |
3590 | |
3591 // Collect the store and move on: | |
3592 st->set_req(MemNode::Memory, inits); | |
3593 inits = st; // put it on the linearized chain | |
3594 set_req(i, zmem); // unhook from previous position | |
3595 | |
3596 if (zeroes_done == st_off) | |
3597 zeroes_done = next_init_off; | |
3598 | |
3599 assert(!do_zeroing || zeroes_done >= next_init_off, "don't miss any"); | |
3600 | |
3601 #ifdef ASSERT | |
3602 // Various order invariants. Weaker than stores_are_sane because | |
3603 // a large constant tile can be filled in by smaller non-constant stores. | |
3604 assert(st_off >= last_init_off, "inits do not reverse"); | |
3605 last_init_off = st_off; | |
3606 const Type* val = NULL; | |
3607 if (st_size >= BytesPerInt && | |
3608 (val = phase->type(st->in(MemNode::ValueIn)))->singleton() && | |
3609 (int)val->basic_type() < (int)T_OBJECT) { | |
3610 assert(st_off >= last_tile_end, "tiles do not overlap"); | |
3611 assert(st_off >= last_init_end, "tiles do not overwrite inits"); | |
3612 last_tile_end = MAX2(last_tile_end, next_init_off); | |
3613 } else { | |
3614 intptr_t st_tile_end = align_size_up(next_init_off, BytesPerLong); | |
3615 assert(st_tile_end >= last_tile_end, "inits stay with tiles"); | |
3616 assert(st_off >= last_init_end, "inits do not overlap"); | |
3617 last_init_end = next_init_off; // it's a non-tile | |
3618 } | |
3619 #endif //ASSERT | |
3620 } | |
3621 | |
3622 remove_extra_zeroes(); // clear out all the zmems left over | |
3623 add_req(inits); | |
3624 | |
3625 if (!ZeroTLAB) { | |
3626 // If anything remains to be zeroed, zero it all now. | |
3627 zeroes_done = align_size_down(zeroes_done, BytesPerInt); | |
3628 // if it is the last unused 4 bytes of an instance, forget about it | |
3629 intptr_t size_limit = phase->find_intptr_t_con(size_in_bytes, max_jint); | |
3630 if (zeroes_done + BytesPerLong >= size_limit) { | |
3631 assert(allocation() != NULL, ""); | |
2004
4da76e32c0be
7002666: eclipse CDT projects crash with compressed oops
never
parents:
1972
diff
changeset
|
3632 if (allocation()->Opcode() == Op_Allocate) { |
4da76e32c0be
7002666: eclipse CDT projects crash with compressed oops
never
parents:
1972
diff
changeset
|
3633 Node* klass_node = allocation()->in(AllocateNode::KlassNode); |
4da76e32c0be
7002666: eclipse CDT projects crash with compressed oops
never
parents:
1972
diff
changeset
|
3634 ciKlass* k = phase->type(klass_node)->is_klassptr()->klass(); |
4da76e32c0be
7002666: eclipse CDT projects crash with compressed oops
never
parents:
1972
diff
changeset
|
3635 if (zeroes_done == k->layout_helper()) |
4da76e32c0be
7002666: eclipse CDT projects crash with compressed oops
never
parents:
1972
diff
changeset
|
3636 zeroes_done = size_limit; |
4da76e32c0be
7002666: eclipse CDT projects crash with compressed oops
never
parents:
1972
diff
changeset
|
3637 } |
0 | 3638 } |
3639 if (zeroes_done < size_limit) { | |
3640 rawmem = ClearArrayNode::clear_memory(rawctl, rawmem, rawptr, | |
3641 zeroes_done, size_in_bytes, phase); | |
3642 } | |
3643 } | |
3644 | |
3645 set_complete(phase); | |
3646 return rawmem; | |
3647 } | |
3648 | |
3649 | |
3650 #ifdef ASSERT | |
3651 bool InitializeNode::stores_are_sane(PhaseTransform* phase) { | |
3652 if (is_complete()) | |
3653 return true; // stores could be anything at this point | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3654 assert(allocation() != NULL, "must be present"); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
82
diff
changeset
|
3655 intptr_t last_off = allocation()->minimum_header_size(); |
0 | 3656 for (uint i = InitializeNode::RawStores; i < req(); i++) { |
3657 Node* st = in(i); | |
3658 intptr_t st_off = get_store_offset(st, phase); | |
3659 if (st_off < 0) continue; // ignore dead garbage | |
3660 if (last_off > st_off) { | |
3661 tty->print_cr("*** bad store offset at %d: %d > %d", i, last_off, st_off); | |
3662 this->dump(2); | |
3663 assert(false, "ascending store offsets"); | |
3664 return false; | |
3665 } | |
3666 last_off = st_off + st->as_Store()->memory_size(); | |
3667 } | |
3668 return true; | |
3669 } | |
3670 #endif //ASSERT | |
3671 | |
3672 | |
3673 | |
3674 | |
3675 //============================MergeMemNode===================================== | |
3676 // | |
3677 // SEMANTICS OF MEMORY MERGES: A MergeMem is a memory state assembled from several | |
3678 // contributing store or call operations. Each contributor provides the memory | |
3679 // state for a particular "alias type" (see Compile::alias_type). For example, | |
3680 // if a MergeMem has an input X for alias category #6, then any memory reference | |
3681 // to alias category #6 may use X as its memory state input, as an exact equivalent | |
3682 // to using the MergeMem as a whole. | |
3683 // Load<6>( MergeMem(<6>: X, ...), p ) <==> Load<6>(X,p) | |
3684 // | |
3685 // (Here, the <N> notation gives the index of the relevant adr_type.) | |
3686 // | |
3687 // In one special case (and more cases in the future), alias categories overlap. | |
3688 // The special alias category "Bot" (Compile::AliasIdxBot) includes all memory | |
3689 // states. Therefore, if a MergeMem has only one contributing input W for Bot, | |
3690 // it is exactly equivalent to that state W: | |
3691 // MergeMem(<Bot>: W) <==> W | |
3692 // | |
3693 // Usually, the merge has more than one input. In that case, where inputs | |
3694 // overlap (i.e., one is Bot), the narrower alias type determines the memory | |
3695 // state for that type, and the wider alias type (Bot) fills in everywhere else: | |
3696 // Load<5>( MergeMem(<Bot>: W, <6>: X), p ) <==> Load<5>(W,p) | |
3697 // Load<6>( MergeMem(<Bot>: W, <6>: X), p ) <==> Load<6>(X,p) | |
3698 // | |
3699 // A merge can take a "wide" memory state as one of its narrow inputs. | |
3700 // This simply means that the merge observes out only the relevant parts of | |
3701 // the wide input. That is, wide memory states arriving at narrow merge inputs | |
3702 // are implicitly "filtered" or "sliced" as necessary. (This is rare.) | |
3703 // | |
3704 // These rules imply that MergeMem nodes may cascade (via their <Bot> links), | |
3705 // and that memory slices "leak through": | |
3706 // MergeMem(<Bot>: MergeMem(<Bot>: W, <7>: Y)) <==> MergeMem(<Bot>: W, <7>: Y) | |
3707 // | |
3708 // But, in such a cascade, repeated memory slices can "block the leak": | |
3709 // MergeMem(<Bot>: MergeMem(<Bot>: W, <7>: Y), <7>: Y') <==> MergeMem(<Bot>: W, <7>: Y') | |
3710 // | |
3711 // In the last example, Y is not part of the combined memory state of the | |
3712 // outermost MergeMem. The system must, of course, prevent unschedulable | |
3713 // memory states from arising, so you can be sure that the state Y is somehow | |
3714 // a precursor to state Y'. | |
3715 // | |
3716 // | |
3717 // REPRESENTATION OF MEMORY MERGES: The indexes used to address the Node::in array | |
3718 // of each MergeMemNode array are exactly the numerical alias indexes, including | |
3719 // but not limited to AliasIdxTop, AliasIdxBot, and AliasIdxRaw. The functions | |
3720 // Compile::alias_type (and kin) produce and manage these indexes. | |
3721 // | |
3722 // By convention, the value of in(AliasIdxTop) (i.e., in(1)) is always the top node. | |
3723 // (Note that this provides quick access to the top node inside MergeMem methods, | |
3724 // without the need to reach out via TLS to Compile::current.) | |
3725 // | |
3726 // As a consequence of what was just described, a MergeMem that represents a full | |
3727 // memory state has an edge in(AliasIdxBot) which is a "wide" memory state, | |
3728 // containing all alias categories. | |
3729 // | |
3730 // MergeMem nodes never (?) have control inputs, so in(0) is NULL. | |
3731 // | |
3732 // All other edges in(N) (including in(AliasIdxRaw), which is in(3)) are either | |
3733 // a memory state for the alias type <N>, or else the top node, meaning that | |
3734 // there is no particular input for that alias type. Note that the length of | |
3735 // a MergeMem is variable, and may be extended at any time to accommodate new | |
3736 // memory states at larger alias indexes. When merges grow, they are of course | |
3737 // filled with "top" in the unused in() positions. | |
3738 // | |
3739 // This use of top is named "empty_memory()", or "empty_mem" (no-memory) as a variable. | |
3740 // (Top was chosen because it works smoothly with passes like GCM.) | |
3741 // | |
3742 // For convenience, we hardwire the alias index for TypeRawPtr::BOTTOM. (It is | |
3743 // the type of random VM bits like TLS references.) Since it is always the | |
3744 // first non-Bot memory slice, some low-level loops use it to initialize an | |
3745 // index variable: for (i = AliasIdxRaw; i < req(); i++). | |
3746 // | |
3747 // | |
3748 // ACCESSORS: There is a special accessor MergeMemNode::base_memory which returns | |
3749 // the distinguished "wide" state. The accessor MergeMemNode::memory_at(N) returns | |
3750 // the memory state for alias type <N>, or (if there is no particular slice at <N>, | |
3751 // it returns the base memory. To prevent bugs, memory_at does not accept <Top> | |
3752 // or <Bot> indexes. The iterator MergeMemStream provides robust iteration over | |
3753 // MergeMem nodes or pairs of such nodes, ensuring that the non-top edges are visited. | |
3754 // | |
3755 // %%%% We may get rid of base_memory as a separate accessor at some point; it isn't | |
3756 // really that different from the other memory inputs. An abbreviation called | |
3757 // "bot_memory()" for "memory_at(AliasIdxBot)" would keep code tidy. | |
3758 // | |
3759 // | |
3760 // PARTIAL MEMORY STATES: During optimization, MergeMem nodes may arise that represent | |
3761 // partial memory states. When a Phi splits through a MergeMem, the copy of the Phi | |
3762 // that "emerges though" the base memory will be marked as excluding the alias types | |
3763 // of the other (narrow-memory) copies which "emerged through" the narrow edges: | |
3764 // | |
3765 // Phi<Bot>(U, MergeMem(<Bot>: W, <8>: Y)) | |
3766 // ==Ideal=> MergeMem(<Bot>: Phi<Bot-8>(U, W), Phi<8>(U, Y)) | |
3767 // | |
3768 // This strange "subtraction" effect is necessary to ensure IGVN convergence. | |
3769 // (It is currently unimplemented.) As you can see, the resulting merge is | |
3770 // actually a disjoint union of memory states, rather than an overlay. | |
3771 // | |
3772 | |
3773 //------------------------------MergeMemNode----------------------------------- | |
3774 Node* MergeMemNode::make_empty_memory() { | |
3775 Node* empty_memory = (Node*) Compile::current()->top(); | |
3776 assert(empty_memory->is_top(), "correct sentinel identity"); | |
3777 return empty_memory; | |
3778 } | |
3779 | |
3780 MergeMemNode::MergeMemNode(Node *new_base) : Node(1+Compile::AliasIdxRaw) { | |
3781 init_class_id(Class_MergeMem); | |
3782 // all inputs are nullified in Node::Node(int) | |
3783 // set_input(0, NULL); // no control input | |
3784 | |
3785 // Initialize the edges uniformly to top, for starters. | |
3786 Node* empty_mem = make_empty_memory(); | |
3787 for (uint i = Compile::AliasIdxTop; i < req(); i++) { | |
3788 init_req(i,empty_mem); | |
3789 } | |
3790 assert(empty_memory() == empty_mem, ""); | |
3791 | |
3792 if( new_base != NULL && new_base->is_MergeMem() ) { | |
3793 MergeMemNode* mdef = new_base->as_MergeMem(); | |
3794 assert(mdef->empty_memory() == empty_mem, "consistent sentinels"); | |
3795 for (MergeMemStream mms(this, mdef); mms.next_non_empty2(); ) { | |
3796 mms.set_memory(mms.memory2()); | |
3797 } | |
3798 assert(base_memory() == mdef->base_memory(), ""); | |
3799 } else { | |
3800 set_base_memory(new_base); | |
3801 } | |
3802 } | |
3803 | |
3804 // Make a new, untransformed MergeMem with the same base as 'mem'. | |
3805 // If mem is itself a MergeMem, populate the result with the same edges. | |
3806 MergeMemNode* MergeMemNode::make(Compile* C, Node* mem) { | |
3807 return new(C, 1+Compile::AliasIdxRaw) MergeMemNode(mem); | |
3808 } | |
3809 | |
3810 //------------------------------cmp-------------------------------------------- | |
3811 uint MergeMemNode::hash() const { return NO_HASH; } | |
3812 uint MergeMemNode::cmp( const Node &n ) const { | |
3813 return (&n == this); // Always fail except on self | |
3814 } | |
3815 | |
3816 //------------------------------Identity--------------------------------------- | |
3817 Node* MergeMemNode::Identity(PhaseTransform *phase) { | |
3818 // Identity if this merge point does not record any interesting memory | |
3819 // disambiguations. | |
3820 Node* base_mem = base_memory(); | |
3821 Node* empty_mem = empty_memory(); | |
3822 if (base_mem != empty_mem) { // Memory path is not dead? | |
3823 for (uint i = Compile::AliasIdxRaw; i < req(); i++) { | |
3824 Node* mem = in(i); | |
3825 if (mem != empty_mem && mem != base_mem) { | |
3826 return this; // Many memory splits; no change | |
3827 } | |
3828 } | |
3829 } | |
3830 return base_mem; // No memory splits; ID on the one true input | |
3831 } | |
3832 | |
3833 //------------------------------Ideal------------------------------------------ | |
3834 // This method is invoked recursively on chains of MergeMem nodes | |
3835 Node *MergeMemNode::Ideal(PhaseGVN *phase, bool can_reshape) { | |
3836 // Remove chain'd MergeMems | |
3837 // | |
3838 // This is delicate, because the each "in(i)" (i >= Raw) is interpreted | |
3839 // relative to the "in(Bot)". Since we are patching both at the same time, | |
3840 // we have to be careful to read each "in(i)" relative to the old "in(Bot)", | |
3841 // but rewrite each "in(i)" relative to the new "in(Bot)". | |
3842 Node *progress = NULL; | |
3843 | |
3844 | |
3845 Node* old_base = base_memory(); | |
3846 Node* empty_mem = empty_memory(); | |
3847 if (old_base == empty_mem) | |
3848 return NULL; // Dead memory path. | |
3849 | |
3850 MergeMemNode* old_mbase; | |
3851 if (old_base != NULL && old_base->is_MergeMem()) | |
3852 old_mbase = old_base->as_MergeMem(); | |
3853 else | |
3854 old_mbase = NULL; | |
3855 Node* new_base = old_base; | |
3856 | |
3857 // simplify stacked MergeMems in base memory | |
3858 if (old_mbase) new_base = old_mbase->base_memory(); | |
3859 | |
3860 // the base memory might contribute new slices beyond my req() | |
3861 if (old_mbase) grow_to_match(old_mbase); | |
3862 | |
3863 // Look carefully at the base node if it is a phi. | |
3864 PhiNode* phi_base; | |
3865 if (new_base != NULL && new_base->is_Phi()) | |
3866 phi_base = new_base->as_Phi(); | |
3867 else | |
3868 phi_base = NULL; | |
3869 | |
3870 Node* phi_reg = NULL; | |
3871 uint phi_len = (uint)-1; | |
3872 if (phi_base != NULL && !phi_base->is_copy()) { | |
3873 // do not examine phi if degraded to a copy | |
3874 phi_reg = phi_base->region(); | |
3875 phi_len = phi_base->req(); | |
3876 // see if the phi is unfinished | |
3877 for (uint i = 1; i < phi_len; i++) { | |
3878 if (phi_base->in(i) == NULL) { | |
3879 // incomplete phi; do not look at it yet! | |
3880 phi_reg = NULL; | |
3881 phi_len = (uint)-1; | |
3882 break; | |
3883 } | |
3884 } | |
3885 } | |
3886 | |
3887 // Note: We do not call verify_sparse on entry, because inputs | |
3888 // can normalize to the base_memory via subsume_node or similar | |
3889 // mechanisms. This method repairs that damage. | |
3890 | |
3891 assert(!old_mbase || old_mbase->is_empty_memory(empty_mem), "consistent sentinels"); | |
3892 | |
3893 // Look at each slice. | |
3894 for (uint i = Compile::AliasIdxRaw; i < req(); i++) { | |
3895 Node* old_in = in(i); | |
3896 // calculate the old memory value | |
3897 Node* old_mem = old_in; | |
3898 if (old_mem == empty_mem) old_mem = old_base; | |
3899 assert(old_mem == memory_at(i), ""); | |
3900 | |
3901 // maybe update (reslice) the old memory value | |
3902 | |
3903 // simplify stacked MergeMems | |
3904 Node* new_mem = old_mem; | |
3905 MergeMemNode* old_mmem; | |
3906 if (old_mem != NULL && old_mem->is_MergeMem()) | |
3907 old_mmem = old_mem->as_MergeMem(); | |
3908 else | |
3909 old_mmem = NULL; | |
3910 if (old_mmem == this) { | |
3911 // This can happen if loops break up and safepoints disappear. | |
3912 // A merge of BotPtr (default) with a RawPtr memory derived from a | |
3913 // safepoint can be rewritten to a merge of the same BotPtr with | |
3914 // the BotPtr phi coming into the loop. If that phi disappears | |
3915 // also, we can end up with a self-loop of the mergemem. | |
3916 // In general, if loops degenerate and memory effects disappear, | |
3917 // a mergemem can be left looking at itself. This simply means | |
3918 // that the mergemem's default should be used, since there is | |
3919 // no longer any apparent effect on this slice. | |
3920 // Note: If a memory slice is a MergeMem cycle, it is unreachable | |
3921 // from start. Update the input to TOP. | |
3922 new_mem = (new_base == this || new_base == empty_mem)? empty_mem : new_base; | |
3923 } | |
3924 else if (old_mmem != NULL) { | |
3925 new_mem = old_mmem->memory_at(i); | |
3926 } | |
605 | 3927 // else preceding memory was not a MergeMem |
0 | 3928 |
3929 // replace equivalent phis (unfortunately, they do not GVN together) | |
3930 if (new_mem != NULL && new_mem != new_base && | |
3931 new_mem->req() == phi_len && new_mem->in(0) == phi_reg) { | |
3932 if (new_mem->is_Phi()) { | |
3933 PhiNode* phi_mem = new_mem->as_Phi(); | |
3934 for (uint i = 1; i < phi_len; i++) { | |
3935 if (phi_base->in(i) != phi_mem->in(i)) { | |
3936 phi_mem = NULL; | |
3937 break; | |
3938 } | |
3939 } | |
3940 if (phi_mem != NULL) { | |
3941 // equivalent phi nodes; revert to the def | |
3942 new_mem = new_base; | |
3943 } | |
3944 } | |
3945 } | |
3946 | |
3947 // maybe store down a new value | |
3948 Node* new_in = new_mem; | |
3949 if (new_in == new_base) new_in = empty_mem; | |
3950 | |
3951 if (new_in != old_in) { | |
3952 // Warning: Do not combine this "if" with the previous "if" | |
3953 // A memory slice might have be be rewritten even if it is semantically | |
3954 // unchanged, if the base_memory value has changed. | |
3955 set_req(i, new_in); | |
3956 progress = this; // Report progress | |
3957 } | |
3958 } | |
3959 | |
3960 if (new_base != old_base) { | |
3961 set_req(Compile::AliasIdxBot, new_base); | |
3962 // Don't use set_base_memory(new_base), because we need to update du. | |
3963 assert(base_memory() == new_base, ""); | |
3964 progress = this; | |
3965 } | |
3966 | |
3967 if( base_memory() == this ) { | |
3968 // a self cycle indicates this memory path is dead | |
3969 set_req(Compile::AliasIdxBot, empty_mem); | |
3970 } | |
3971 | |
3972 // Resolve external cycles by calling Ideal on a MergeMem base_memory | |
3973 // Recursion must occur after the self cycle check above | |
3974 if( base_memory()->is_MergeMem() ) { | |
3975 MergeMemNode *new_mbase = base_memory()->as_MergeMem(); | |
3976 Node *m = phase->transform(new_mbase); // Rollup any cycles | |
3977 if( m != NULL && (m->is_top() || | |
3978 m->is_MergeMem() && m->as_MergeMem()->base_memory() == empty_mem) ) { | |
3979 // propagate rollup of dead cycle to self | |
3980 set_req(Compile::AliasIdxBot, empty_mem); | |
3981 } | |
3982 } | |
3983 | |
3984 if( base_memory() == empty_mem ) { | |
3985 progress = this; | |
3986 // Cut inputs during Parse phase only. | |
3987 // During Optimize phase a dead MergeMem node will be subsumed by Top. | |
3988 if( !can_reshape ) { | |
3989 for (uint i = Compile::AliasIdxRaw; i < req(); i++) { | |
3990 if( in(i) != empty_mem ) { set_req(i, empty_mem); } | |
3991 } | |
3992 } | |
3993 } | |
3994 | |
3995 if( !progress && base_memory()->is_Phi() && can_reshape ) { | |
3996 // Check if PhiNode::Ideal's "Split phis through memory merges" | |
3997 // transform should be attempted. Look for this->phi->this cycle. | |
3998 uint merge_width = req(); | |
3999 if (merge_width > Compile::AliasIdxRaw) { | |
4000 PhiNode* phi = base_memory()->as_Phi(); | |
4001 for( uint i = 1; i < phi->req(); ++i ) {// For all paths in | |
4002 if (phi->in(i) == this) { | |
4003 phase->is_IterGVN()->_worklist.push(phi); | |
4004 break; | |
4005 } | |
4006 } | |
4007 } | |
4008 } | |
4009 | |
64
b8f5ba577b02
6673473: (Escape Analysis) Add the instance's field information to PhiNode
kvn
parents:
43
diff
changeset
|
4010 assert(progress || verify_sparse(), "please, no dups of base"); |
0 | 4011 return progress; |
4012 } | |
4013 | |
4014 //-------------------------set_base_memory------------------------------------- | |
4015 void MergeMemNode::set_base_memory(Node *new_base) { | |
4016 Node* empty_mem = empty_memory(); | |
4017 set_req(Compile::AliasIdxBot, new_base); | |
4018 assert(memory_at(req()) == new_base, "must set default memory"); | |
4019 // Clear out other occurrences of new_base: | |
4020 if (new_base != empty_mem) { | |
4021 for (uint i = Compile::AliasIdxRaw; i < req(); i++) { | |
4022 if (in(i) == new_base) set_req(i, empty_mem); | |
4023 } | |
4024 } | |
4025 } | |
4026 | |
4027 //------------------------------out_RegMask------------------------------------ | |
4028 const RegMask &MergeMemNode::out_RegMask() const { | |
4029 return RegMask::Empty; | |
4030 } | |
4031 | |
4032 //------------------------------dump_spec-------------------------------------- | |
4033 #ifndef PRODUCT | |
4034 void MergeMemNode::dump_spec(outputStream *st) const { | |
4035 st->print(" {"); | |
4036 Node* base_mem = base_memory(); | |
4037 for( uint i = Compile::AliasIdxRaw; i < req(); i++ ) { | |
4038 Node* mem = memory_at(i); | |
4039 if (mem == base_mem) { st->print(" -"); continue; } | |
4040 st->print( " N%d:", mem->_idx ); | |
4041 Compile::current()->get_adr_type(i)->dump_on(st); | |
4042 } | |
4043 st->print(" }"); | |
4044 } | |
4045 #endif // !PRODUCT | |
4046 | |
4047 | |
4048 #ifdef ASSERT | |
4049 static bool might_be_same(Node* a, Node* b) { | |
4050 if (a == b) return true; | |
4051 if (!(a->is_Phi() || b->is_Phi())) return false; | |
4052 // phis shift around during optimization | |
4053 return true; // pretty stupid... | |
4054 } | |
4055 | |
4056 // verify a narrow slice (either incoming or outgoing) | |
4057 static void verify_memory_slice(const MergeMemNode* m, int alias_idx, Node* n) { | |
4058 if (!VerifyAliases) return; // don't bother to verify unless requested | |
4059 if (is_error_reported()) return; // muzzle asserts when debugging an error | |
4060 if (Node::in_dump()) return; // muzzle asserts when printing | |
4061 assert(alias_idx >= Compile::AliasIdxRaw, "must not disturb base_memory or sentinel"); | |
4062 assert(n != NULL, ""); | |
4063 // Elide intervening MergeMem's | |
4064 while (n->is_MergeMem()) { | |
4065 n = n->as_MergeMem()->memory_at(alias_idx); | |
4066 } | |
4067 Compile* C = Compile::current(); | |
4068 const TypePtr* n_adr_type = n->adr_type(); | |
4069 if (n == m->empty_memory()) { | |
4070 // Implicit copy of base_memory() | |
4071 } else if (n_adr_type != TypePtr::BOTTOM) { | |
4072 assert(n_adr_type != NULL, "new memory must have a well-defined adr_type"); | |
4073 assert(C->must_alias(n_adr_type, alias_idx), "new memory must match selected slice"); | |
4074 } else { | |
4075 // A few places like make_runtime_call "know" that VM calls are narrow, | |
4076 // and can be used to update only the VM bits stored as TypeRawPtr::BOTTOM. | |
4077 bool expected_wide_mem = false; | |
4078 if (n == m->base_memory()) { | |
4079 expected_wide_mem = true; | |
4080 } else if (alias_idx == Compile::AliasIdxRaw || | |
4081 n == m->memory_at(Compile::AliasIdxRaw)) { | |
4082 expected_wide_mem = true; | |
4083 } else if (!C->alias_type(alias_idx)->is_rewritable()) { | |
4084 // memory can "leak through" calls on channels that | |
4085 // are write-once. Allow this also. | |
4086 expected_wide_mem = true; | |
4087 } | |
4088 assert(expected_wide_mem, "expected narrow slice replacement"); | |
4089 } | |
4090 } | |
4091 #else // !ASSERT | |
4092 #define verify_memory_slice(m,i,n) (0) // PRODUCT version is no-op | |
4093 #endif | |
4094 | |
4095 | |
4096 //-----------------------------memory_at--------------------------------------- | |
4097 Node* MergeMemNode::memory_at(uint alias_idx) const { | |
4098 assert(alias_idx >= Compile::AliasIdxRaw || | |
4099 alias_idx == Compile::AliasIdxBot && Compile::current()->AliasLevel() == 0, | |
4100 "must avoid base_memory and AliasIdxTop"); | |
4101 | |
4102 // Otherwise, it is a narrow slice. | |
4103 Node* n = alias_idx < req() ? in(alias_idx) : empty_memory(); | |
4104 Compile *C = Compile::current(); | |
4105 if (is_empty_memory(n)) { | |
4106 // the array is sparse; empty slots are the "top" node | |
4107 n = base_memory(); | |
4108 assert(Node::in_dump() | |
4109 || n == NULL || n->bottom_type() == Type::TOP | |
2317
5a41a201d08c
6812217: Base memory of MergeMem node violates assert during killing expanded AllocateArray node
kvn
parents:
2004
diff
changeset
|
4110 || n->adr_type() == NULL // address is TOP |
0 | 4111 || n->adr_type() == TypePtr::BOTTOM |
4112 || n->adr_type() == TypeRawPtr::BOTTOM | |
4113 || Compile::current()->AliasLevel() == 0, | |
4114 "must be a wide memory"); | |
4115 // AliasLevel == 0 if we are organizing the memory states manually. | |
4116 // See verify_memory_slice for comments on TypeRawPtr::BOTTOM. | |
4117 } else { | |
4118 // make sure the stored slice is sane | |
4119 #ifdef ASSERT | |
4120 if (is_error_reported() || Node::in_dump()) { | |
4121 } else if (might_be_same(n, base_memory())) { | |
4122 // Give it a pass: It is a mostly harmless repetition of the base. | |
4123 // This can arise normally from node subsumption during optimization. | |
4124 } else { | |
4125 verify_memory_slice(this, alias_idx, n); | |
4126 } | |
4127 #endif | |
4128 } | |
4129 return n; | |
4130 } | |
4131 | |
4132 //---------------------------set_memory_at------------------------------------- | |
4133 void MergeMemNode::set_memory_at(uint alias_idx, Node *n) { | |
4134 verify_memory_slice(this, alias_idx, n); | |
4135 Node* empty_mem = empty_memory(); | |
4136 if (n == base_memory()) n = empty_mem; // collapse default | |
4137 uint need_req = alias_idx+1; | |
4138 if (req() < need_req) { | |
4139 if (n == empty_mem) return; // already the default, so do not grow me | |
4140 // grow the sparse array | |
4141 do { | |
4142 add_req(empty_mem); | |
4143 } while (req() < need_req); | |
4144 } | |
4145 set_req( alias_idx, n ); | |
4146 } | |
4147 | |
4148 | |
4149 | |
4150 //--------------------------iteration_setup------------------------------------ | |
4151 void MergeMemNode::iteration_setup(const MergeMemNode* other) { | |
4152 if (other != NULL) { | |
4153 grow_to_match(other); | |
4154 // invariant: the finite support of mm2 is within mm->req() | |
4155 #ifdef ASSERT | |
4156 for (uint i = req(); i < other->req(); i++) { | |
4157 assert(other->is_empty_memory(other->in(i)), "slice left uncovered"); | |
4158 } | |
4159 #endif | |
4160 } | |
4161 // Replace spurious copies of base_memory by top. | |
4162 Node* base_mem = base_memory(); | |
4163 if (base_mem != NULL && !base_mem->is_top()) { | |
4164 for (uint i = Compile::AliasIdxBot+1, imax = req(); i < imax; i++) { | |
4165 if (in(i) == base_mem) | |
4166 set_req(i, empty_memory()); | |
4167 } | |
4168 } | |
4169 } | |
4170 | |
4171 //---------------------------grow_to_match------------------------------------- | |
4172 void MergeMemNode::grow_to_match(const MergeMemNode* other) { | |
4173 Node* empty_mem = empty_memory(); | |
4174 assert(other->is_empty_memory(empty_mem), "consistent sentinels"); | |
4175 // look for the finite support of the other memory | |
4176 for (uint i = other->req(); --i >= req(); ) { | |
4177 if (other->in(i) != empty_mem) { | |
4178 uint new_len = i+1; | |
4179 while (req() < new_len) add_req(empty_mem); | |
4180 break; | |
4181 } | |
4182 } | |
4183 } | |
4184 | |
4185 //---------------------------verify_sparse------------------------------------- | |
4186 #ifndef PRODUCT | |
4187 bool MergeMemNode::verify_sparse() const { | |
4188 assert(is_empty_memory(make_empty_memory()), "sane sentinel"); | |
4189 Node* base_mem = base_memory(); | |
4190 // The following can happen in degenerate cases, since empty==top. | |
4191 if (is_empty_memory(base_mem)) return true; | |
4192 for (uint i = Compile::AliasIdxRaw; i < req(); i++) { | |
4193 assert(in(i) != NULL, "sane slice"); | |
4194 if (in(i) == base_mem) return false; // should have been the sentinel value! | |
4195 } | |
4196 return true; | |
4197 } | |
4198 | |
4199 bool MergeMemStream::match_memory(Node* mem, const MergeMemNode* mm, int idx) { | |
4200 Node* n; | |
4201 n = mm->in(idx); | |
4202 if (mem == n) return true; // might be empty_memory() | |
4203 n = (idx == Compile::AliasIdxBot)? mm->base_memory(): mm->memory_at(idx); | |
4204 if (mem == n) return true; | |
4205 while (n->is_Phi() && (n = n->as_Phi()->is_copy()) != NULL) { | |
4206 if (mem == n) return true; | |
4207 if (n == NULL) break; | |
4208 } | |
4209 return false; | |
4210 } | |
4211 #endif // !PRODUCT |