src/share/vm/opto/memnode.cpp

changeset 4657
6931f425c517
parent 4479
b30b3c2a0cf2
child 4695
ff55877839bc
equal deleted inserted replaced
4636:be1fbee20765 4657:6931f425c517
318 mem = step_through_mergemem(phase, mmem, tp, adr_type(), tty); 318 mem = step_through_mergemem(phase, mmem, tp, adr_type(), tty);
319 } 319 }
320 320
321 if (mem != old_mem) { 321 if (mem != old_mem) {
322 set_req(MemNode::Memory, mem); 322 set_req(MemNode::Memory, mem);
323 if (can_reshape && old_mem->outcnt() == 0) {
324 igvn->_worklist.push(old_mem);
325 }
323 if (phase->type( mem ) == Type::TOP) return NodeSentinel; 326 if (phase->type( mem ) == Type::TOP) return NodeSentinel;
324 return this; 327 return this;
325 } 328 }
326 329
327 // let the subclass continue analyzing... 330 // let the subclass continue analyzing...
2317 // Capture an unaliased, unconditional, simple store into an initializer. 2320 // Capture an unaliased, unconditional, simple store into an initializer.
2318 // Or, if it is independent of the allocation, hoist it above the allocation. 2321 // Or, if it is independent of the allocation, hoist it above the allocation.
2319 if (ReduceFieldZeroing && /*can_reshape &&*/ 2322 if (ReduceFieldZeroing && /*can_reshape &&*/
2320 mem->is_Proj() && mem->in(0)->is_Initialize()) { 2323 mem->is_Proj() && mem->in(0)->is_Initialize()) {
2321 InitializeNode* init = mem->in(0)->as_Initialize(); 2324 InitializeNode* init = mem->in(0)->as_Initialize();
2322 intptr_t offset = init->can_capture_store(this, phase); 2325 intptr_t offset = init->can_capture_store(this, phase, can_reshape);
2323 if (offset > 0) { 2326 if (offset > 0) {
2324 Node* moved = init->capture_store(this, offset, phase); 2327 Node* moved = init->capture_store(this, offset, phase, can_reshape);
2325 // If the InitializeNode captured me, it made a raw copy of me, 2328 // If the InitializeNode captured me, it made a raw copy of me,
2326 // and I need to disappear. 2329 // and I need to disappear.
2327 if (moved != NULL) { 2330 if (moved != NULL) {
2328 // %%% hack to ensure that Ideal returns a new node: 2331 // %%% hack to ensure that Ideal returns a new node:
2329 mem = MergeMemNode::make(phase->C, mem); 2332 mem = MergeMemNode::make(phase->C, mem);
3132 3135
3133 // Here are all the checks a Store must pass before it can be moved into 3136 // Here are all the checks a Store must pass before it can be moved into
3134 // an initialization. Returns zero if a check fails. 3137 // an initialization. Returns zero if a check fails.
3135 // On success, returns the (constant) offset to which the store applies, 3138 // On success, returns the (constant) offset to which the store applies,
3136 // within the initialized memory. 3139 // within the initialized memory.
3137 intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase) { 3140 intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase, bool can_reshape) {
3138 const int FAIL = 0; 3141 const int FAIL = 0;
3139 if (st->req() != MemNode::ValueIn + 1) 3142 if (st->req() != MemNode::ValueIn + 1)
3140 return FAIL; // an inscrutable StoreNode (card mark?) 3143 return FAIL; // an inscrutable StoreNode (card mark?)
3141 Node* ctl = st->in(MemNode::Control); 3144 Node* ctl = st->in(MemNode::Control);
3142 if (!(ctl != NULL && ctl->is_Proj() && ctl->in(0) == this)) 3145 if (!(ctl != NULL && ctl->is_Proj() && ctl->in(0) == this))
3154 Node* val = st->in(MemNode::ValueIn); 3157 Node* val = st->in(MemNode::ValueIn);
3155 int complexity_count = 0; 3158 int complexity_count = 0;
3156 if (!detect_init_independence(val, true, complexity_count)) 3159 if (!detect_init_independence(val, true, complexity_count))
3157 return FAIL; // stored value must be 'simple enough' 3160 return FAIL; // stored value must be 'simple enough'
3158 3161
3162 // The Store can be captured only if nothing after the allocation
3163 // and before the Store is using the memory location that the store
3164 // overwrites.
3165 bool failed = false;
3166 // If is_complete_with_arraycopy() is true the shape of the graph is
3167 // well defined and is safe so no need for extra checks.
3168 if (!is_complete_with_arraycopy()) {
3169 // We are going to look at each use of the memory state following
3170 // the allocation to make sure nothing reads the memory that the
3171 // Store writes.
3172 const TypePtr* t_adr = phase->type(adr)->isa_ptr();
3173 int alias_idx = phase->C->get_alias_index(t_adr);
3174 ResourceMark rm;
3175 Unique_Node_List mems;
3176 mems.push(mem);
3177 Node* unique_merge = NULL;
3178 for (uint next = 0; next < mems.size(); ++next) {
3179 Node *m = mems.at(next);
3180 for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax; j++) {
3181 Node *n = m->fast_out(j);
3182 if (n->outcnt() == 0) {
3183 continue;
3184 }
3185 if (n == st) {
3186 continue;
3187 } else if (n->in(0) != NULL && n->in(0) != ctl) {
3188 // If the control of this use is different from the control
3189 // of the Store which is right after the InitializeNode then
3190 // this node cannot be between the InitializeNode and the
3191 // Store.
3192 continue;
3193 } else if (n->is_MergeMem()) {
3194 if (n->as_MergeMem()->memory_at(alias_idx) == m) {
3195 // We can hit a MergeMemNode (that will likely go away
3196 // later) that is a direct use of the memory state
3197 // following the InitializeNode on the same slice as the
3198 // store node that we'd like to capture. We need to check
3199 // the uses of the MergeMemNode.
3200 mems.push(n);
3201 }
3202 } else if (n->is_Mem()) {
3203 Node* other_adr = n->in(MemNode::Address);
3204 if (other_adr == adr) {
3205 failed = true;
3206 break;
3207 } else {
3208 const TypePtr* other_t_adr = phase->type(other_adr)->isa_ptr();
3209 if (other_t_adr != NULL) {
3210 int other_alias_idx = phase->C->get_alias_index(other_t_adr);
3211 if (other_alias_idx == alias_idx) {
3212 // A load from the same memory slice as the store right
3213 // after the InitializeNode. We check the control of the
3214 // object/array that is loaded from. If it's the same as
3215 // the store control then we cannot capture the store.
3216 assert(!n->is_Store(), "2 stores to same slice on same control?");
3217 Node* base = other_adr;
3218 assert(base->is_AddP(), err_msg_res("should be addp but is %s", base->Name()));
3219 base = base->in(AddPNode::Base);
3220 if (base != NULL) {
3221 base = base->uncast();
3222 if (base->is_Proj() && base->in(0) == alloc) {
3223 failed = true;
3224 break;
3225 }
3226 }
3227 }
3228 }
3229 }
3230 } else {
3231 failed = true;
3232 break;
3233 }
3234 }
3235 }
3236 }
3237 if (failed) {
3238 if (!can_reshape) {
3239 // We decided we couldn't capture the store during parsing. We
3240 // should try again during the next IGVN once the graph is
3241 // cleaner.
3242 phase->C->record_for_igvn(st);
3243 }
3244 return FAIL;
3245 }
3246
3159 return offset; // success 3247 return offset; // success
3160 } 3248 }
3161 3249
3162 // Find the captured store in(i) which corresponds to the range 3250 // Find the captured store in(i) which corresponds to the range
3163 // [start..start+size) in the initialized object. 3251 // [start..start+size) in the initialized object.
3264 // rawstore2 = (StoreC alloc.Control alloc.Memory (+ rawoop 14) 2) 3352 // rawstore2 = (StoreC alloc.Control alloc.Memory (+ rawoop 14) 2)
3265 // init = (Initialize alloc.Control alloc.Memory rawoop 3353 // init = (Initialize alloc.Control alloc.Memory rawoop
3266 // rawstore1 rawstore2) 3354 // rawstore1 rawstore2)
3267 // 3355 //
3268 Node* InitializeNode::capture_store(StoreNode* st, intptr_t start, 3356 Node* InitializeNode::capture_store(StoreNode* st, intptr_t start,
3269 PhaseTransform* phase) { 3357 PhaseTransform* phase, bool can_reshape) {
3270 assert(stores_are_sane(phase), ""); 3358 assert(stores_are_sane(phase), "");
3271 3359
3272 if (start < 0) return NULL; 3360 if (start < 0) return NULL;
3273 assert(can_capture_store(st, phase) == start, "sanity"); 3361 assert(can_capture_store(st, phase, can_reshape) == start, "sanity");
3274 3362
3275 Compile* C = phase->C; 3363 Compile* C = phase->C;
3276 int size_in_bytes = st->memory_size(); 3364 int size_in_bytes = st->memory_size();
3277 int i = captured_store_insertion_point(start, size_in_bytes, phase); 3365 int i = captured_store_insertion_point(start, size_in_bytes, phase);
3278 if (i == 0) return NULL; // bail out 3366 if (i == 0) return NULL; // bail out

mercurial