comparison src/share/vm/c1/c1_ValueMap.cpp @ 9081:84ab5667f290

8011706: specjvm2008 test xml.transform gets array bound exception with c1 Summary: loop invariant code motion may move load before store to the same field Reviewed-by: kvn
author roland
date Wed, 10 Apr 2013 09:52:49 +0200
parents 46f6f063b272
children de6a9e811145
comparison
equal deleted inserted replaced
9080:b84fd7d73702 9081:84ab5667f290
314 private: 314 private:
315 GlobalValueNumbering* _gvn; 315 GlobalValueNumbering* _gvn;
316 ShortLoopOptimizer* _short_loop_optimizer; 316 ShortLoopOptimizer* _short_loop_optimizer;
317 Instruction* _insertion_point; 317 Instruction* _insertion_point;
318 ValueStack * _state; 318 ValueStack * _state;
319 bool _insert_is_pred;
319 320
320 void set_invariant(Value v) const { _gvn->set_processed(v); } 321 void set_invariant(Value v) const { _gvn->set_processed(v); }
321 bool is_invariant(Value v) const { return _gvn->is_processed(v); } 322 bool is_invariant(Value v) const { return _gvn->is_processed(v); }
322 323
323 void process_block(BlockBegin* block); 324 void process_block(BlockBegin* block);
337 return; // only the entry block does not have a predecessor 338 return; // only the entry block does not have a predecessor
338 } 339 }
339 340
340 assert(insertion_block->end()->as_Base() == NULL, "cannot insert into entry block"); 341 assert(insertion_block->end()->as_Base() == NULL, "cannot insert into entry block");
341 _insertion_point = insertion_block->end()->prev(); 342 _insertion_point = insertion_block->end()->prev();
343 _insert_is_pred = loop_header->is_predecessor(insertion_block);
342 344
343 BlockEnd *block_end = insertion_block->end(); 345 BlockEnd *block_end = insertion_block->end();
344 _state = block_end->state_before(); 346 _state = block_end->state_before();
345 347
346 if (!_state) { 348 if (!_state) {
377 Op2* op2 = (Op2*)cur; 379 Op2* op2 = (Op2*)cur;
378 cur_invariant = !op2->can_trap() && is_invariant(op2->x()) && is_invariant(op2->y()); 380 cur_invariant = !op2->can_trap() && is_invariant(op2->x()) && is_invariant(op2->y());
379 } else if (cur->as_LoadField() != NULL) { 381 } else if (cur->as_LoadField() != NULL) {
380 LoadField* lf = (LoadField*)cur; 382 LoadField* lf = (LoadField*)cur;
381 // deoptimizes on NullPointerException 383 // deoptimizes on NullPointerException
382 cur_invariant = !lf->needs_patching() && !lf->field()->is_volatile() && !_short_loop_optimizer->has_field_store(lf->field()->type()->basic_type()) && is_invariant(lf->obj()); 384 cur_invariant = !lf->needs_patching() && !lf->field()->is_volatile() && !_short_loop_optimizer->has_field_store(lf->field()->type()->basic_type()) && is_invariant(lf->obj()) && _insert_is_pred;
383 } else if (cur->as_ArrayLength() != NULL) { 385 } else if (cur->as_ArrayLength() != NULL) {
384 ArrayLength *length = cur->as_ArrayLength(); 386 ArrayLength *length = cur->as_ArrayLength();
385 cur_invariant = is_invariant(length->array()); 387 cur_invariant = is_invariant(length->array());
386 } else if (cur->as_LoadIndexed() != NULL) { 388 } else if (cur->as_LoadIndexed() != NULL) {
387 LoadIndexed *li = (LoadIndexed *)cur->as_LoadIndexed(); 389 LoadIndexed *li = (LoadIndexed *)cur->as_LoadIndexed();
388 cur_invariant = !_short_loop_optimizer->has_indexed_store(as_BasicType(cur->type())) && is_invariant(li->array()) && is_invariant(li->index()); 390 cur_invariant = !_short_loop_optimizer->has_indexed_store(as_BasicType(cur->type())) && is_invariant(li->array()) && is_invariant(li->index()) && _insert_is_pred;
389 } 391 }
390 392
391 if (cur_invariant) { 393 if (cur_invariant) {
392 // perform value numbering and mark instruction as loop-invariant 394 // perform value numbering and mark instruction as loop-invariant
393 _gvn->substitute(cur); 395 _gvn->substitute(cur);