Mercurial > hg > truffle
comparison src/share/vm/c1/c1_Instruction.hpp @ 8860:46f6f063b272
7153771: array bound check elimination for c1
Summary: when possible optimize out array bound checks, inserting predicates when needed.
Reviewed-by: never, kvn, twisti
Contributed-by: thomaswue <thomas.wuerthinger@oracle.com>
author | roland |
---|---|
date | Thu, 21 Mar 2013 09:27:54 +0100 |
parents | 7eca5de9e0b6 |
children | acadb114c818 |
comparison
equal
deleted
inserted
replaced
8780:98f3af397705 | 8860:46f6f063b272 |
---|---|
108 class UnsafePrefetchWrite; | 108 class UnsafePrefetchWrite; |
109 class ProfileCall; | 109 class ProfileCall; |
110 class ProfileInvoke; | 110 class ProfileInvoke; |
111 class RuntimeCall; | 111 class RuntimeCall; |
112 class MemBar; | 112 class MemBar; |
113 class RangeCheckPredicate; | |
114 class Assert; | |
113 | 115 |
114 // A Value is a reference to the instruction creating the value | 116 // A Value is a reference to the instruction creating the value |
115 typedef Instruction* Value; | 117 typedef Instruction* Value; |
116 define_array(ValueArray, Value) | 118 define_array(ValueArray, Value) |
117 define_stack(Values, ValueArray) | 119 define_stack(Values, ValueArray) |
208 virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0; | 210 virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0; |
209 virtual void do_ProfileCall (ProfileCall* x) = 0; | 211 virtual void do_ProfileCall (ProfileCall* x) = 0; |
210 virtual void do_ProfileInvoke (ProfileInvoke* x) = 0; | 212 virtual void do_ProfileInvoke (ProfileInvoke* x) = 0; |
211 virtual void do_RuntimeCall (RuntimeCall* x) = 0; | 213 virtual void do_RuntimeCall (RuntimeCall* x) = 0; |
212 virtual void do_MemBar (MemBar* x) = 0; | 214 virtual void do_MemBar (MemBar* x) = 0; |
215 virtual void do_RangeCheckPredicate(RangeCheckPredicate* x) = 0; | |
216 #ifdef ASSERT | |
217 virtual void do_Assert (Assert* x) = 0; | |
218 #endif | |
213 }; | 219 }; |
214 | 220 |
215 | 221 |
216 // Hashing support | 222 // Hashing support |
217 // | 223 // |
304 friend class UseCountComputer; | 310 friend class UseCountComputer; |
305 friend class BlockBegin; | 311 friend class BlockBegin; |
306 | 312 |
307 void update_exception_state(ValueStack* state); | 313 void update_exception_state(ValueStack* state); |
308 | 314 |
309 //protected: | 315 protected: |
310 public: | 316 BlockBegin* _block; // Block that contains this instruction |
317 | |
311 void set_type(ValueType* type) { | 318 void set_type(ValueType* type) { |
312 assert(type != NULL, "type must exist"); | 319 assert(type != NULL, "type must exist"); |
313 _type = type; | 320 _type = type; |
314 } | 321 } |
315 | 322 |
340 UnorderedIsTrueFlag, | 347 UnorderedIsTrueFlag, |
341 NeedsPatchingFlag, | 348 NeedsPatchingFlag, |
342 ThrowIncompatibleClassChangeErrorFlag, | 349 ThrowIncompatibleClassChangeErrorFlag, |
343 ProfileMDOFlag, | 350 ProfileMDOFlag, |
344 IsLinkedInBlockFlag, | 351 IsLinkedInBlockFlag, |
352 NeedsRangeCheckFlag, | |
353 InWorkListFlag, | |
354 DeoptimizeOnException, | |
345 InstructionLastFlag | 355 InstructionLastFlag |
346 }; | 356 }; |
347 | 357 |
348 public: | 358 public: |
349 bool check_flag(InstructionFlag id) const { return (_flags & (1 << id)) != 0; } | 359 bool check_flag(InstructionFlag id) const { return (_flags & (1 << id)) != 0; } |
350 void set_flag(InstructionFlag id, bool f) { _flags = f ? (_flags | (1 << id)) : (_flags & ~(1 << id)); }; | 360 void set_flag(InstructionFlag id, bool f) { _flags = f ? (_flags | (1 << id)) : (_flags & ~(1 << id)); }; |
351 | 361 |
352 // 'globally' used condition values | 362 // 'globally' used condition values |
353 enum Condition { | 363 enum Condition { |
354 eql, neq, lss, leq, gtr, geq | 364 eql, neq, lss, leq, gtr, geq, aeq, beq |
355 }; | 365 }; |
356 | 366 |
357 // Instructions may be pinned for many reasons and under certain conditions | 367 // Instructions may be pinned for many reasons and under certain conditions |
358 // with enough knowledge it's possible to safely unpin them. | 368 // with enough knowledge it's possible to safely unpin them. |
359 enum PinReason { | 369 enum PinReason { |
379 , _printable_bci(-99) | 389 , _printable_bci(-99) |
380 #endif | 390 #endif |
381 , _pin_state(0) | 391 , _pin_state(0) |
382 , _type(type) | 392 , _type(type) |
383 , _next(NULL) | 393 , _next(NULL) |
394 , _block(NULL) | |
384 , _subst(NULL) | 395 , _subst(NULL) |
385 , _flags(0) | 396 , _flags(0) |
386 , _operand(LIR_OprFact::illegalOpr) | 397 , _operand(LIR_OprFact::illegalOpr) |
387 , _state_before(state_before) | 398 , _state_before(state_before) |
388 , _exception_handlers(NULL) | 399 , _exception_handlers(NULL) |
397 #ifndef PRODUCT | 408 #ifndef PRODUCT |
398 bool has_printable_bci() const { return _printable_bci != -99; } | 409 bool has_printable_bci() const { return _printable_bci != -99; } |
399 int printable_bci() const { assert(has_printable_bci(), "_printable_bci should have been set"); return _printable_bci; } | 410 int printable_bci() const { assert(has_printable_bci(), "_printable_bci should have been set"); return _printable_bci; } |
400 void set_printable_bci(int bci) { _printable_bci = bci; } | 411 void set_printable_bci(int bci) { _printable_bci = bci; } |
401 #endif | 412 #endif |
413 int dominator_depth(); | |
402 int use_count() const { return _use_count; } | 414 int use_count() const { return _use_count; } |
403 int pin_state() const { return _pin_state; } | 415 int pin_state() const { return _pin_state; } |
404 bool is_pinned() const { return _pin_state != 0 || PinAllInstructions; } | 416 bool is_pinned() const { return _pin_state != 0 || PinAllInstructions; } |
405 ValueType* type() const { return _type; } | 417 ValueType* type() const { return _type; } |
406 Instruction* prev(BlockBegin* block); // use carefully, expensive operation | 418 BlockBegin *block() const { return _block; } |
419 Instruction* prev(); // use carefully, expensive operation | |
407 Instruction* next() const { return _next; } | 420 Instruction* next() const { return _next; } |
408 bool has_subst() const { return _subst != NULL; } | 421 bool has_subst() const { return _subst != NULL; } |
409 Instruction* subst() { return _subst == NULL ? this : _subst->subst(); } | 422 Instruction* subst() { return _subst == NULL ? this : _subst->subst(); } |
410 LIR_Opr operand() const { return _operand; } | 423 LIR_Opr operand() const { return _operand; } |
411 | 424 |
430 assert(next->has_printable_bci(), "_printable_bci should have been set"); | 443 assert(next->has_printable_bci(), "_printable_bci should have been set"); |
431 assert(next != NULL, "must not be NULL"); | 444 assert(next != NULL, "must not be NULL"); |
432 assert(as_BlockEnd() == NULL, "BlockEnd instructions must have no next"); | 445 assert(as_BlockEnd() == NULL, "BlockEnd instructions must have no next"); |
433 assert(next->can_be_linked(), "shouldn't link these instructions into list"); | 446 assert(next->can_be_linked(), "shouldn't link these instructions into list"); |
434 | 447 |
448 BlockBegin *block = this->block(); | |
449 next->_block = block; | |
450 | |
435 next->set_flag(Instruction::IsLinkedInBlockFlag, true); | 451 next->set_flag(Instruction::IsLinkedInBlockFlag, true); |
436 _next = next; | 452 _next = next; |
437 return next; | 453 return next; |
438 } | 454 } |
439 | 455 |
442 next->set_printable_bci(bci); | 458 next->set_printable_bci(bci); |
443 #endif | 459 #endif |
444 return set_next(next); | 460 return set_next(next); |
445 } | 461 } |
446 | 462 |
463 // when blocks are merged | |
464 void fixup_block_pointers() { | |
465 Instruction *cur = next()->next(); // next()'s block is set in set_next | |
466 while (cur && cur->_block != block()) { | |
467 cur->_block = block(); | |
468 cur = cur->next(); | |
469 } | |
470 } | |
471 | |
472 Instruction *insert_after(Instruction *i) { | |
473 Instruction* n = _next; | |
474 set_next(i); | |
475 i->set_next(n); | |
476 return _next; | |
477 } | |
478 | |
479 Instruction *insert_after_same_bci(Instruction *i) { | |
480 #ifndef PRODUCT | |
481 i->set_printable_bci(printable_bci()); | |
482 #endif | |
483 return insert_after(i); | |
484 } | |
485 | |
447 void set_subst(Instruction* subst) { | 486 void set_subst(Instruction* subst) { |
448 assert(subst == NULL || | 487 assert(subst == NULL || |
449 type()->base() == subst->type()->base() || | 488 type()->base() == subst->type()->base() || |
450 subst->type()->base() == illegalType, "type can't change"); | 489 subst->type()->base() == illegalType, "type can't change"); |
451 _subst = subst; | 490 _subst = subst; |
452 } | 491 } |
453 void set_exception_handlers(XHandlers *xhandlers) { _exception_handlers = xhandlers; } | 492 void set_exception_handlers(XHandlers *xhandlers) { _exception_handlers = xhandlers; } |
454 void set_exception_state(ValueStack* s) { check_state(s); _exception_state = s; } | 493 void set_exception_state(ValueStack* s) { check_state(s); _exception_state = s; } |
494 void set_state_before(ValueStack* s) { check_state(s); _state_before = s; } | |
455 | 495 |
456 // machine-specifics | 496 // machine-specifics |
457 void set_operand(LIR_Opr operand) { assert(operand != LIR_OprFact::illegalOpr, "operand must exist"); _operand = operand; } | 497 void set_operand(LIR_Opr operand) { assert(operand != LIR_OprFact::illegalOpr, "operand must exist"); _operand = operand; } |
458 void clear_operand() { _operand = LIR_OprFact::illegalOpr; } | 498 void clear_operand() { _operand = LIR_OprFact::illegalOpr; } |
459 | 499 |
507 virtual Base* as_Base() { return NULL; } | 547 virtual Base* as_Base() { return NULL; } |
508 virtual RoundFP* as_RoundFP() { return NULL; } | 548 virtual RoundFP* as_RoundFP() { return NULL; } |
509 virtual ExceptionObject* as_ExceptionObject() { return NULL; } | 549 virtual ExceptionObject* as_ExceptionObject() { return NULL; } |
510 virtual UnsafeOp* as_UnsafeOp() { return NULL; } | 550 virtual UnsafeOp* as_UnsafeOp() { return NULL; } |
511 virtual ProfileInvoke* as_ProfileInvoke() { return NULL; } | 551 virtual ProfileInvoke* as_ProfileInvoke() { return NULL; } |
552 virtual RangeCheckPredicate* as_RangeCheckPredicate() { return NULL; } | |
553 | |
554 #ifdef ASSERT | |
555 virtual Assert* as_Assert() { return NULL; } | |
556 #endif | |
512 | 557 |
513 virtual void visit(InstructionVisitor* v) = 0; | 558 virtual void visit(InstructionVisitor* v) = 0; |
514 | 559 |
515 virtual bool can_trap() const { return false; } | 560 virtual bool can_trap() const { return false; } |
516 | 561 |
568 // the value of a local variable at the beginning of a join block. | 613 // the value of a local variable at the beginning of a join block. |
569 // A Phi consists of n operands, one for every incoming branch. | 614 // A Phi consists of n operands, one for every incoming branch. |
570 | 615 |
571 LEAF(Phi, Instruction) | 616 LEAF(Phi, Instruction) |
572 private: | 617 private: |
573 BlockBegin* _block; // the block to which the phi function belongs | |
574 int _pf_flags; // the flags of the phi function | 618 int _pf_flags; // the flags of the phi function |
575 int _index; // to value on operand stack (index < 0) or to local | 619 int _index; // to value on operand stack (index < 0) or to local |
576 public: | 620 public: |
577 // creation | 621 // creation |
578 Phi(ValueType* type, BlockBegin* b, int index) | 622 Phi(ValueType* type, BlockBegin* b, int index) |
579 : Instruction(type->base()) | 623 : Instruction(type->base()) |
580 , _pf_flags(0) | 624 , _pf_flags(0) |
581 , _block(b) | |
582 , _index(index) | 625 , _index(index) |
583 { | 626 { |
627 _block = b; | |
584 NOT_PRODUCT(set_printable_bci(Value(b)->printable_bci())); | 628 NOT_PRODUCT(set_printable_bci(Value(b)->printable_bci())); |
585 if (type->is_illegal()) { | 629 if (type->is_illegal()) { |
586 make_illegal(); | 630 make_illegal(); |
587 } | 631 } |
588 } | 632 } |
601 int stack_index() const { assert(is_on_stack(), ""); return -(_index+1); } | 645 int stack_index() const { assert(is_on_stack(), ""); return -(_index+1); } |
602 | 646 |
603 Value operand_at(int i) const; | 647 Value operand_at(int i) const; |
604 int operand_count() const; | 648 int operand_count() const; |
605 | 649 |
606 BlockBegin* block() const { return _block; } | |
607 | |
608 void set(Flag f) { _pf_flags |= f; } | 650 void set(Flag f) { _pf_flags |= f; } |
609 void clear(Flag f) { _pf_flags &= ~f; } | 651 void clear(Flag f) { _pf_flags &= ~f; } |
610 bool is_set(Flag f) const { return (_pf_flags & f) != 0; } | 652 bool is_set(Flag f) const { return (_pf_flags & f) != 0; } |
611 | 653 |
612 // Invalidates phis corresponding to merges of locals of two different types | 654 // Invalidates phis corresponding to merges of locals of two different types |
668 assert(type->is_constant(), "must be a constant"); | 710 assert(type->is_constant(), "must be a constant"); |
669 // since it's patching it needs to be pinned | 711 // since it's patching it needs to be pinned |
670 pin(); | 712 pin(); |
671 } | 713 } |
672 | 714 |
715 // generic | |
673 virtual bool can_trap() const { return state_before() != NULL; } | 716 virtual bool can_trap() const { return state_before() != NULL; } |
674 virtual void input_values_do(ValueVisitor* f) { /* no values */ } | 717 virtual void input_values_do(ValueVisitor* f) { /* no values */ } |
675 | 718 |
676 virtual intx hash() const; | 719 virtual intx hash() const; |
677 virtual bool is_equal(Value v) const; | 720 virtual bool is_equal(Value v) const; |
850 : AccessArray(as_ValueType(elt_type), array, state_before) | 893 : AccessArray(as_ValueType(elt_type), array, state_before) |
851 , _index(index) | 894 , _index(index) |
852 , _length(length) | 895 , _length(length) |
853 , _elt_type(elt_type) | 896 , _elt_type(elt_type) |
854 { | 897 { |
898 set_flag(Instruction::NeedsRangeCheckFlag, true); | |
855 ASSERT_VALUES | 899 ASSERT_VALUES |
856 } | 900 } |
857 | 901 |
858 // accessors | 902 // accessors |
859 Value index() const { return _index; } | 903 Value index() const { return _index; } |
860 Value length() const { return _length; } | 904 Value length() const { return _length; } |
861 BasicType elt_type() const { return _elt_type; } | 905 BasicType elt_type() const { return _elt_type; } |
862 | 906 |
907 void clear_length() { _length = NULL; } | |
863 // perform elimination of range checks involving constants | 908 // perform elimination of range checks involving constants |
864 bool compute_needs_range_check(); | 909 bool compute_needs_range_check(); |
865 | 910 |
866 // generic | 911 // generic |
867 virtual void input_values_do(ValueVisitor* f) { AccessArray::input_values_do(f); f->visit(&_index); if (_length != NULL) f->visit(&_length); } | 912 virtual void input_values_do(ValueVisitor* f) { AccessArray::input_values_do(f); f->visit(&_index); if (_length != NULL) f->visit(&_length); } |
1522 private: | 1567 private: |
1523 int _block_id; // the unique block id | 1568 int _block_id; // the unique block id |
1524 int _bci; // start-bci of block | 1569 int _bci; // start-bci of block |
1525 int _depth_first_number; // number of this block in a depth-first ordering | 1570 int _depth_first_number; // number of this block in a depth-first ordering |
1526 int _linear_scan_number; // number of this block in linear-scan ordering | 1571 int _linear_scan_number; // number of this block in linear-scan ordering |
1572 int _dominator_depth; | |
1527 int _loop_depth; // the loop nesting level of this block | 1573 int _loop_depth; // the loop nesting level of this block |
1528 int _loop_index; // number of the innermost loop of this block | 1574 int _loop_index; // number of the innermost loop of this block |
1529 int _flags; // the flags associated with this block | 1575 int _flags; // the flags associated with this block |
1530 | 1576 |
1531 // fields used by BlockListBuilder | 1577 // fields used by BlockListBuilder |
1533 BitMap _stores_to_locals; // bit is set when a local variable is stored in the block | 1579 BitMap _stores_to_locals; // bit is set when a local variable is stored in the block |
1534 | 1580 |
1535 // SSA specific fields: (factor out later) | 1581 // SSA specific fields: (factor out later) |
1536 BlockList _successors; // the successors of this block | 1582 BlockList _successors; // the successors of this block |
1537 BlockList _predecessors; // the predecessors of this block | 1583 BlockList _predecessors; // the predecessors of this block |
1584 BlockList _dominates; // list of blocks that are dominated by this block | |
1538 BlockBegin* _dominator; // the dominator of this block | 1585 BlockBegin* _dominator; // the dominator of this block |
1539 // SSA specific ends | 1586 // SSA specific ends |
1540 BlockEnd* _end; // the last instruction of this block | 1587 BlockEnd* _end; // the last instruction of this block |
1541 BlockList _exception_handlers; // the exception handlers potentially invoked by this block | 1588 BlockList _exception_handlers; // the exception handlers potentially invoked by this block |
1542 ValueStackStack* _exception_states; // only for xhandler entries: states of all instructions that have an edge to this xhandler | 1589 ValueStackStack* _exception_states; // only for xhandler entries: states of all instructions that have an edge to this xhandler |
1581 , _bci(bci) | 1628 , _bci(bci) |
1582 , _depth_first_number(-1) | 1629 , _depth_first_number(-1) |
1583 , _linear_scan_number(-1) | 1630 , _linear_scan_number(-1) |
1584 , _loop_depth(0) | 1631 , _loop_depth(0) |
1585 , _flags(0) | 1632 , _flags(0) |
1633 , _dominator_depth(-1) | |
1586 , _dominator(NULL) | 1634 , _dominator(NULL) |
1587 , _end(NULL) | 1635 , _end(NULL) |
1588 , _predecessors(2) | 1636 , _predecessors(2) |
1589 , _successors(2) | 1637 , _successors(2) |
1638 , _dominates(2) | |
1590 , _exception_handlers(1) | 1639 , _exception_handlers(1) |
1591 , _exception_states(NULL) | 1640 , _exception_states(NULL) |
1592 , _exception_handler_pco(-1) | 1641 , _exception_handler_pco(-1) |
1593 , _lir(NULL) | 1642 , _lir(NULL) |
1594 , _loop_index(-1) | 1643 , _loop_index(-1) |
1601 , _first_lir_instruction_id(-1) | 1650 , _first_lir_instruction_id(-1) |
1602 , _last_lir_instruction_id(-1) | 1651 , _last_lir_instruction_id(-1) |
1603 , _total_preds(0) | 1652 , _total_preds(0) |
1604 , _stores_to_locals() | 1653 , _stores_to_locals() |
1605 { | 1654 { |
1655 _block = this; | |
1606 #ifndef PRODUCT | 1656 #ifndef PRODUCT |
1607 set_printable_bci(bci); | 1657 set_printable_bci(bci); |
1608 #endif | 1658 #endif |
1609 } | 1659 } |
1610 | 1660 |
1611 // accessors | 1661 // accessors |
1612 int block_id() const { return _block_id; } | 1662 int block_id() const { return _block_id; } |
1613 int bci() const { return _bci; } | 1663 int bci() const { return _bci; } |
1614 BlockList* successors() { return &_successors; } | 1664 BlockList* successors() { return &_successors; } |
1665 BlockList* dominates() { return &_dominates; } | |
1615 BlockBegin* dominator() const { return _dominator; } | 1666 BlockBegin* dominator() const { return _dominator; } |
1616 int loop_depth() const { return _loop_depth; } | 1667 int loop_depth() const { return _loop_depth; } |
1668 int dominator_depth() const { return _dominator_depth; } | |
1617 int depth_first_number() const { return _depth_first_number; } | 1669 int depth_first_number() const { return _depth_first_number; } |
1618 int linear_scan_number() const { return _linear_scan_number; } | 1670 int linear_scan_number() const { return _linear_scan_number; } |
1619 BlockEnd* end() const { return _end; } | 1671 BlockEnd* end() const { return _end; } |
1620 Label* label() { return &_label; } | 1672 Label* label() { return &_label; } |
1621 LIR_List* lir() const { return _lir; } | 1673 LIR_List* lir() const { return _lir; } |
1632 BitMap& stores_to_locals() { return _stores_to_locals; } | 1684 BitMap& stores_to_locals() { return _stores_to_locals; } |
1633 | 1685 |
1634 // manipulation | 1686 // manipulation |
1635 void set_dominator(BlockBegin* dom) { _dominator = dom; } | 1687 void set_dominator(BlockBegin* dom) { _dominator = dom; } |
1636 void set_loop_depth(int d) { _loop_depth = d; } | 1688 void set_loop_depth(int d) { _loop_depth = d; } |
1689 void set_dominator_depth(int d) { _dominator_depth = d; } | |
1637 void set_depth_first_number(int dfn) { _depth_first_number = dfn; } | 1690 void set_depth_first_number(int dfn) { _depth_first_number = dfn; } |
1638 void set_linear_scan_number(int lsn) { _linear_scan_number = lsn; } | 1691 void set_linear_scan_number(int lsn) { _linear_scan_number = lsn; } |
1639 void set_end(BlockEnd* end); | 1692 void set_end(BlockEnd* end); |
1640 void clear_end(); | 1693 void clear_end(); |
1641 void disconnect_from_graph(); | 1694 void disconnect_from_graph(); |
1693 is_on_work_list_flag = 1 << 5, | 1746 is_on_work_list_flag = 1 << 5, |
1694 was_visited_flag = 1 << 6, | 1747 was_visited_flag = 1 << 6, |
1695 parser_loop_header_flag = 1 << 7, // set by parser to identify blocks where phi functions can not be created on demand | 1748 parser_loop_header_flag = 1 << 7, // set by parser to identify blocks where phi functions can not be created on demand |
1696 critical_edge_split_flag = 1 << 8, // set for all blocks that are introduced when critical edges are split | 1749 critical_edge_split_flag = 1 << 8, // set for all blocks that are introduced when critical edges are split |
1697 linear_scan_loop_header_flag = 1 << 9, // set during loop-detection for LinearScan | 1750 linear_scan_loop_header_flag = 1 << 9, // set during loop-detection for LinearScan |
1698 linear_scan_loop_end_flag = 1 << 10 // set during loop-detection for LinearScan | 1751 linear_scan_loop_end_flag = 1 << 10, // set during loop-detection for LinearScan |
1752 donot_eliminate_range_checks = 1 << 11 // Should be try to eliminate range checks in this block | |
1699 }; | 1753 }; |
1700 | 1754 |
1701 void set(Flag f) { _flags |= f; } | 1755 void set(Flag f) { _flags |= f; } |
1702 void clear(Flag f) { _flags &= ~f; } | 1756 void clear(Flag f) { _flags &= ~f; } |
1703 bool is_set(Flag f) const { return (_flags & f) != 0; } | 1757 bool is_set(Flag f) const { return (_flags & f) != 0; } |
1726 }; | 1780 }; |
1727 | 1781 |
1728 | 1782 |
1729 BASE(BlockEnd, StateSplit) | 1783 BASE(BlockEnd, StateSplit) |
1730 private: | 1784 private: |
1731 BlockBegin* _begin; | |
1732 BlockList* _sux; | 1785 BlockList* _sux; |
1733 | 1786 |
1734 protected: | 1787 protected: |
1735 BlockList* sux() const { return _sux; } | 1788 BlockList* sux() const { return _sux; } |
1736 | 1789 |
1744 | 1797 |
1745 public: | 1798 public: |
1746 // creation | 1799 // creation |
1747 BlockEnd(ValueType* type, ValueStack* state_before, bool is_safepoint) | 1800 BlockEnd(ValueType* type, ValueStack* state_before, bool is_safepoint) |
1748 : StateSplit(type, state_before) | 1801 : StateSplit(type, state_before) |
1749 , _begin(NULL) | |
1750 , _sux(NULL) | 1802 , _sux(NULL) |
1751 { | 1803 { |
1752 set_flag(IsSafepointFlag, is_safepoint); | 1804 set_flag(IsSafepointFlag, is_safepoint); |
1753 } | 1805 } |
1754 | 1806 |
1755 // accessors | 1807 // accessors |
1756 bool is_safepoint() const { return check_flag(IsSafepointFlag); } | 1808 bool is_safepoint() const { return check_flag(IsSafepointFlag); } |
1757 BlockBegin* begin() const { return _begin; } | 1809 // For compatibility with old code, for new code use block() |
1810 BlockBegin* begin() const { return _block; } | |
1758 | 1811 |
1759 // manipulation | 1812 // manipulation |
1760 void set_begin(BlockBegin* begin); | 1813 void set_begin(BlockBegin* begin); |
1761 | 1814 |
1762 // successors | 1815 // successors |
1809 void set_profiled_method(ciMethod* method) { _profiled_method = method; } | 1862 void set_profiled_method(ciMethod* method) { _profiled_method = method; } |
1810 void set_profiled_bci(int bci) { _profiled_bci = bci; } | 1863 void set_profiled_bci(int bci) { _profiled_bci = bci; } |
1811 void set_direction(Direction d) { _direction = d; } | 1864 void set_direction(Direction d) { _direction = d; } |
1812 }; | 1865 }; |
1813 | 1866 |
1867 #ifdef ASSERT | |
1868 LEAF(Assert, Instruction) | |
1869 private: | |
1870 Value _x; | |
1871 Condition _cond; | |
1872 Value _y; | |
1873 char *_message; | |
1874 | |
1875 public: | |
1876 // creation | |
1877 // unordered_is_true is valid for float/double compares only | |
1878 Assert(Value x, Condition cond, bool unordered_is_true, Value y); | |
1879 | |
1880 // accessors | |
1881 Value x() const { return _x; } | |
1882 Condition cond() const { return _cond; } | |
1883 bool unordered_is_true() const { return check_flag(UnorderedIsTrueFlag); } | |
1884 Value y() const { return _y; } | |
1885 const char *message() const { return _message; } | |
1886 | |
1887 // generic | |
1888 virtual void input_values_do(ValueVisitor* f) { f->visit(&_x); f->visit(&_y); } | |
1889 }; | |
1890 #endif | |
1891 | |
1892 LEAF(RangeCheckPredicate, StateSplit) | |
1893 private: | |
1894 Value _x; | |
1895 Condition _cond; | |
1896 Value _y; | |
1897 | |
1898 void check_state(); | |
1899 | |
1900 public: | |
1901 // creation | |
1902 // unordered_is_true is valid for float/double compares only | |
1903 RangeCheckPredicate(Value x, Condition cond, bool unordered_is_true, Value y, ValueStack* state) : StateSplit(illegalType) | |
1904 , _x(x) | |
1905 , _cond(cond) | |
1906 , _y(y) | |
1907 { | |
1908 ASSERT_VALUES | |
1909 set_flag(UnorderedIsTrueFlag, unordered_is_true); | |
1910 assert(x->type()->tag() == y->type()->tag(), "types must match"); | |
1911 this->set_state(state); | |
1912 check_state(); | |
1913 } | |
1914 | |
1915 // Always deoptimize | |
1916 RangeCheckPredicate(ValueStack* state) : StateSplit(illegalType) | |
1917 { | |
1918 this->set_state(state); | |
1919 _x = _y = NULL; | |
1920 check_state(); | |
1921 } | |
1922 | |
1923 // accessors | |
1924 Value x() const { return _x; } | |
1925 Condition cond() const { return _cond; } | |
1926 bool unordered_is_true() const { return check_flag(UnorderedIsTrueFlag); } | |
1927 Value y() const { return _y; } | |
1928 | |
1929 void always_fail() { _x = _y = NULL; } | |
1930 | |
1931 // generic | |
1932 virtual void input_values_do(ValueVisitor* f) { StateSplit::input_values_do(f); f->visit(&_x); f->visit(&_y); } | |
1933 HASHING3(RangeCheckPredicate, true, x()->subst(), y()->subst(), cond()) | |
1934 }; | |
1814 | 1935 |
1815 LEAF(If, BlockEnd) | 1936 LEAF(If, BlockEnd) |
1816 private: | 1937 private: |
1817 Value _x; | 1938 Value _x; |
1818 Condition _cond; | 1939 Condition _cond; |