Mercurial > hg > truffle
comparison src/share/vm/opto/matcher.cpp @ 235:9c2ecc2ffb12 jdk7-b31
Merge
author | trims |
---|---|
date | Fri, 11 Jul 2008 01:14:44 -0700 |
parents | d1605aabd0a1 2a1a77d3458f |
children | eaf496ad4a14 |
comparison
equal
deleted
inserted
replaced
197:de141433919f | 235:9c2ecc2ffb12 |
---|---|
49 //---------------------------Matcher------------------------------------------- | 49 //---------------------------Matcher------------------------------------------- |
50 Matcher::Matcher( Node_List &proj_list ) : | 50 Matcher::Matcher( Node_List &proj_list ) : |
51 PhaseTransform( Phase::Ins_Select ), | 51 PhaseTransform( Phase::Ins_Select ), |
52 #ifdef ASSERT | 52 #ifdef ASSERT |
53 _old2new_map(C->comp_arena()), | 53 _old2new_map(C->comp_arena()), |
54 _new2old_map(C->comp_arena()), | |
54 #endif | 55 #endif |
55 _shared_nodes(C->comp_arena()), | 56 _shared_nodes(C->comp_arena()), |
56 _reduceOp(reduceOp), _leftOp(leftOp), _rightOp(rightOp), | 57 _reduceOp(reduceOp), _leftOp(leftOp), _rightOp(rightOp), |
57 _swallowed(swallowed), | 58 _swallowed(swallowed), |
58 _begin_inst_chain_rule(_BEGIN_INST_CHAIN_RULE), | 59 _begin_inst_chain_rule(_BEGIN_INST_CHAIN_RULE), |
80 idealreg2debugmask[Op_RegN] = NULL; | 81 idealreg2debugmask[Op_RegN] = NULL; |
81 idealreg2debugmask[Op_RegL] = NULL; | 82 idealreg2debugmask[Op_RegL] = NULL; |
82 idealreg2debugmask[Op_RegF] = NULL; | 83 idealreg2debugmask[Op_RegF] = NULL; |
83 idealreg2debugmask[Op_RegD] = NULL; | 84 idealreg2debugmask[Op_RegD] = NULL; |
84 idealreg2debugmask[Op_RegP] = NULL; | 85 idealreg2debugmask[Op_RegP] = NULL; |
86 debug_only(_mem_node = NULL;) // Ideal memory node consumed by mach node | |
85 } | 87 } |
86 | 88 |
87 //------------------------------warp_incoming_stk_arg------------------------ | 89 //------------------------------warp_incoming_stk_arg------------------------ |
88 // This warps a VMReg into an OptoReg::Name | 90 // This warps a VMReg into an OptoReg::Name |
89 OptoReg::Name Matcher::warp_incoming_stk_arg( VMReg reg ) { | 91 OptoReg::Name Matcher::warp_incoming_stk_arg( VMReg reg ) { |
832 if (m == NULL) { Matcher::soft_match_failure(); return NULL; } | 834 if (m == NULL) { Matcher::soft_match_failure(); return NULL; } |
833 } else { // Nothing the matcher cares about | 835 } else { // Nothing the matcher cares about |
834 if( n->is_Proj() && n->in(0)->is_Multi()) { // Projections? | 836 if( n->is_Proj() && n->in(0)->is_Multi()) { // Projections? |
835 // Convert to machine-dependent projection | 837 // Convert to machine-dependent projection |
836 m = n->in(0)->as_Multi()->match( n->as_Proj(), this ); | 838 m = n->in(0)->as_Multi()->match( n->as_Proj(), this ); |
839 #ifdef ASSERT | |
840 _new2old_map.map(m->_idx, n); | |
841 #endif | |
837 if (m->in(0) != NULL) // m might be top | 842 if (m->in(0) != NULL) // m might be top |
838 collect_null_checks(m); | 843 collect_null_checks(m); |
839 } else { // Else just a regular 'ol guy | 844 } else { // Else just a regular 'ol guy |
840 m = n->clone(); // So just clone into new-space | 845 m = n->clone(); // So just clone into new-space |
846 #ifdef ASSERT | |
847 _new2old_map.map(m->_idx, n); | |
848 #endif | |
841 // Def-Use edges will be added incrementally as Uses | 849 // Def-Use edges will be added incrementally as Uses |
842 // of this node are matched. | 850 // of this node are matched. |
843 assert(m->outcnt() == 0, "no Uses of this clone yet"); | 851 assert(m->outcnt() == 0, "no Uses of this clone yet"); |
844 } | 852 } |
845 } | 853 } |
884 if( op == Op_ConI || op == Op_ConP || op == Op_ConN || | 892 if( op == Op_ConI || op == Op_ConP || op == Op_ConN || |
885 op == Op_ConF || op == Op_ConD || op == Op_ConL | 893 op == Op_ConF || op == Op_ConD || op == Op_ConL |
886 // || op == Op_BoxLock // %%%% enable this and remove (+++) in chaitin.cpp | 894 // || op == Op_BoxLock // %%%% enable this and remove (+++) in chaitin.cpp |
887 ) { | 895 ) { |
888 m = m->clone(); | 896 m = m->clone(); |
897 #ifdef ASSERT | |
898 _new2old_map.map(m->_idx, n); | |
899 #endif | |
889 mstack.push(m, Post_Visit, n, i); // Don't neet to visit | 900 mstack.push(m, Post_Visit, n, i); // Don't neet to visit |
890 mstack.push(m->in(0), Visit, m, 0); | 901 mstack.push(m->in(0), Visit, m, 0); |
891 } else { | 902 } else { |
892 mstack.push(m, Visit, n, i); | 903 mstack.push(m, Visit, n, i); |
893 } | 904 } |
1151 | 1162 |
1152 LabelRootDepth = 0; | 1163 LabelRootDepth = 0; |
1153 | 1164 |
1154 // StoreNodes require their Memory input to match any LoadNodes | 1165 // StoreNodes require their Memory input to match any LoadNodes |
1155 Node *mem = n->is_Store() ? n->in(MemNode::Memory) : (Node*)1 ; | 1166 Node *mem = n->is_Store() ? n->in(MemNode::Memory) : (Node*)1 ; |
1156 | 1167 #ifdef ASSERT |
1168 Node* save_mem_node = _mem_node; | |
1169 _mem_node = n->is_Store() ? (Node*)n : NULL; | |
1170 #endif | |
1157 // State object for root node of match tree | 1171 // State object for root node of match tree |
1158 // Allocate it on _states_arena - stack allocation can cause stack overflow. | 1172 // Allocate it on _states_arena - stack allocation can cause stack overflow. |
1159 State *s = new (&_states_arena) State; | 1173 State *s = new (&_states_arena) State; |
1160 s->_kids[0] = NULL; | 1174 s->_kids[0] = NULL; |
1161 s->_kids[1] = NULL; | 1175 s->_kids[1] = NULL; |
1184 } | 1198 } |
1185 // Reduce input tree based upon the state labels to machine Nodes | 1199 // Reduce input tree based upon the state labels to machine Nodes |
1186 MachNode *m = ReduceInst( s, s->_rule[mincost], mem ); | 1200 MachNode *m = ReduceInst( s, s->_rule[mincost], mem ); |
1187 #ifdef ASSERT | 1201 #ifdef ASSERT |
1188 _old2new_map.map(n->_idx, m); | 1202 _old2new_map.map(n->_idx, m); |
1203 _new2old_map.map(m->_idx, (Node*)n); | |
1189 #endif | 1204 #endif |
1190 | 1205 |
1191 // Add any Matcher-ignored edges | 1206 // Add any Matcher-ignored edges |
1192 uint cnt = n->req(); | 1207 uint cnt = n->req(); |
1193 uint start = 1; | 1208 uint start = 1; |
1203 else | 1218 else |
1204 m->add_req( n->in(i) ); | 1219 m->add_req( n->in(i) ); |
1205 } | 1220 } |
1206 } | 1221 } |
1207 | 1222 |
1223 debug_only( _mem_node = save_mem_node; ) | |
1208 return m; | 1224 return m; |
1209 } | 1225 } |
1210 | 1226 |
1211 | 1227 |
1212 //------------------------------match_into_reg--------------------------------- | 1228 //------------------------------match_into_reg--------------------------------- |
1443 mach->add_req(0); // Set initial control to none | 1459 mach->add_req(0); // Set initial control to none |
1444 ReduceInst_Chain_Rule( s, rule, mem, mach ); | 1460 ReduceInst_Chain_Rule( s, rule, mem, mach ); |
1445 } | 1461 } |
1446 | 1462 |
1447 // If a Memory was used, insert a Memory edge | 1463 // If a Memory was used, insert a Memory edge |
1448 if( mem != (Node*)1 ) | 1464 if( mem != (Node*)1 ) { |
1449 mach->ins_req(MemNode::Memory,mem); | 1465 mach->ins_req(MemNode::Memory,mem); |
1466 #ifdef ASSERT | |
1467 // Verify adr type after matching memory operation | |
1468 const MachOper* oper = mach->memory_operand(); | |
1469 if (oper != NULL && oper != (MachOper*)-1 && | |
1470 mach->adr_type() != TypeRawPtr::BOTTOM) { // non-direct addressing mode | |
1471 // It has a unique memory operand. Find corresponding ideal mem node. | |
1472 Node* m = NULL; | |
1473 if (leaf->is_Mem()) { | |
1474 m = leaf; | |
1475 } else { | |
1476 m = _mem_node; | |
1477 assert(m != NULL && m->is_Mem(), "expecting memory node"); | |
1478 } | |
1479 if (m->adr_type() != mach->adr_type()) { | |
1480 m->dump(); | |
1481 tty->print_cr("mach:"); | |
1482 mach->dump(1); | |
1483 } | |
1484 assert(m->adr_type() == mach->adr_type(), "matcher should not change adr type"); | |
1485 } | |
1486 #endif | |
1487 } | |
1450 | 1488 |
1451 // If the _leaf is an AddP, insert the base edge | 1489 // If the _leaf is an AddP, insert the base edge |
1452 if( leaf->is_AddP() ) | 1490 if( leaf->is_AddP() ) |
1453 mach->ins_req(AddPNode::Base,leaf->in(AddPNode::Base)); | 1491 mach->ins_req(AddPNode::Base,leaf->in(AddPNode::Base)); |
1454 | 1492 |
1462 ex->in(1)->set_req(0, C->root()); | 1500 ex->in(1)->set_req(0, C->root()); |
1463 // Remove old node from the graph | 1501 // Remove old node from the graph |
1464 for( uint i=0; i<mach->req(); i++ ) { | 1502 for( uint i=0; i<mach->req(); i++ ) { |
1465 mach->set_req(i,NULL); | 1503 mach->set_req(i,NULL); |
1466 } | 1504 } |
1505 #ifdef ASSERT | |
1506 _new2old_map.map(ex->_idx, s->_leaf); | |
1507 #endif | |
1467 } | 1508 } |
1468 | 1509 |
1469 // PhaseChaitin::fixup_spills will sometimes generate spill code | 1510 // PhaseChaitin::fixup_spills will sometimes generate spill code |
1470 // via the matcher. By the time, nodes have been wired into the CFG, | 1511 // via the matcher. By the time, nodes have been wired into the CFG, |
1471 // and any further nodes generated by expand rules will be left hanging | 1512 // and any further nodes generated by expand rules will be left hanging |
1508 } else { | 1549 } else { |
1509 // Chain from the result of an instruction | 1550 // Chain from the result of an instruction |
1510 assert( newrule >= _LAST_MACH_OPER, "Do NOT chain from internal operand"); | 1551 assert( newrule >= _LAST_MACH_OPER, "Do NOT chain from internal operand"); |
1511 mach->_opnds[1] = s->MachOperGenerator( _reduceOp[catch_op], C ); | 1552 mach->_opnds[1] = s->MachOperGenerator( _reduceOp[catch_op], C ); |
1512 Node *mem1 = (Node*)1; | 1553 Node *mem1 = (Node*)1; |
1554 debug_only(Node *save_mem_node = _mem_node;) | |
1513 mach->add_req( ReduceInst(s, newrule, mem1) ); | 1555 mach->add_req( ReduceInst(s, newrule, mem1) ); |
1556 debug_only(_mem_node = save_mem_node;) | |
1514 } | 1557 } |
1515 return; | 1558 return; |
1516 } | 1559 } |
1517 | 1560 |
1518 | 1561 |
1519 uint Matcher::ReduceInst_Interior( State *s, int rule, Node *&mem, MachNode *mach, uint num_opnds ) { | 1562 uint Matcher::ReduceInst_Interior( State *s, int rule, Node *&mem, MachNode *mach, uint num_opnds ) { |
1520 if( s->_leaf->is_Load() ) { | 1563 if( s->_leaf->is_Load() ) { |
1521 Node *mem2 = s->_leaf->in(MemNode::Memory); | 1564 Node *mem2 = s->_leaf->in(MemNode::Memory); |
1522 assert( mem == (Node*)1 || mem == mem2, "multiple Memories being matched at once?" ); | 1565 assert( mem == (Node*)1 || mem == mem2, "multiple Memories being matched at once?" ); |
1566 debug_only( if( mem == (Node*)1 ) _mem_node = s->_leaf;) | |
1523 mem = mem2; | 1567 mem = mem2; |
1524 } | 1568 } |
1525 if( s->_leaf->in(0) != NULL && s->_leaf->req() > 1) { | 1569 if( s->_leaf->in(0) != NULL && s->_leaf->req() > 1) { |
1526 if( mach->in(0) == NULL ) | 1570 if( mach->in(0) == NULL ) |
1527 mach->set_req(0, s->_leaf->in(0)); | 1571 mach->set_req(0, s->_leaf->in(0)); |
1561 } else { | 1605 } else { |
1562 // instruction --> call build operand( ) to catch result | 1606 // instruction --> call build operand( ) to catch result |
1563 // --> ReduceInst( newrule ) | 1607 // --> ReduceInst( newrule ) |
1564 mach->_opnds[num_opnds++] = s->MachOperGenerator( _reduceOp[catch_op], C ); | 1608 mach->_opnds[num_opnds++] = s->MachOperGenerator( _reduceOp[catch_op], C ); |
1565 Node *mem1 = (Node*)1; | 1609 Node *mem1 = (Node*)1; |
1610 debug_only(Node *save_mem_node = _mem_node;) | |
1566 mach->add_req( ReduceInst( newstate, newrule, mem1 ) ); | 1611 mach->add_req( ReduceInst( newstate, newrule, mem1 ) ); |
1612 debug_only(_mem_node = save_mem_node;) | |
1567 } | 1613 } |
1568 } | 1614 } |
1569 assert( mach->_opnds[num_opnds-1], "" ); | 1615 assert( mach->_opnds[num_opnds-1], "" ); |
1570 } | 1616 } |
1571 return num_opnds; | 1617 return num_opnds; |
1592 } | 1638 } |
1593 | 1639 |
1594 if( s->_leaf->is_Load() ) { | 1640 if( s->_leaf->is_Load() ) { |
1595 assert( mem == (Node*)1, "multiple Memories being matched at once?" ); | 1641 assert( mem == (Node*)1, "multiple Memories being matched at once?" ); |
1596 mem = s->_leaf->in(MemNode::Memory); | 1642 mem = s->_leaf->in(MemNode::Memory); |
1643 debug_only(_mem_node = s->_leaf;) | |
1597 } | 1644 } |
1598 if( s->_leaf->in(0) && s->_leaf->req() > 1) { | 1645 if( s->_leaf->in(0) && s->_leaf->req() > 1) { |
1599 if( !mach->in(0) ) | 1646 if( !mach->in(0) ) |
1600 mach->set_req(0,s->_leaf->in(0)); | 1647 mach->set_req(0,s->_leaf->in(0)); |
1601 else { | 1648 else { |
1616 | 1663 |
1617 } else { // Child is a new instruction | 1664 } else { // Child is a new instruction |
1618 // Reduce the instruction, and add a direct pointer from this | 1665 // Reduce the instruction, and add a direct pointer from this |
1619 // machine instruction to the newly reduced one. | 1666 // machine instruction to the newly reduced one. |
1620 Node *mem1 = (Node*)1; | 1667 Node *mem1 = (Node*)1; |
1668 debug_only(Node *save_mem_node = _mem_node;) | |
1621 mach->add_req( ReduceInst( kid, newrule, mem1 ) ); | 1669 mach->add_req( ReduceInst( kid, newrule, mem1 ) ); |
1670 debug_only(_mem_node = save_mem_node;) | |
1622 } | 1671 } |
1623 } | 1672 } |
1624 } | 1673 } |
1625 | 1674 |
1626 | 1675 |
1729 } | 1778 } |
1730 break; | 1779 break; |
1731 } | 1780 } |
1732 case Op_ConN: { // Convert narrow pointers above the centerline to NUL | 1781 case Op_ConN: { // Convert narrow pointers above the centerline to NUL |
1733 TypeNode *tn = n->as_Type(); // Constants derive from type nodes | 1782 TypeNode *tn = n->as_Type(); // Constants derive from type nodes |
1734 const TypePtr* tp = tn->type()->is_narrowoop()->make_oopptr(); | 1783 const TypePtr* tp = tn->type()->make_ptr(); |
1735 if (tp->_ptr == TypePtr::AnyNull) { | 1784 if (tp && tp->_ptr == TypePtr::AnyNull) { |
1736 tn->set_type(TypeNarrowOop::NULL_PTR); | 1785 tn->set_type(TypeNarrowOop::NULL_PTR); |
1737 } | 1786 } |
1738 break; | 1787 break; |
1739 } | 1788 } |
1740 case Op_Binary: // These are introduced in the Post_Visit state. | 1789 case Op_Binary: // These are introduced in the Post_Visit state. |