src/share/vm/opto/matcher.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/matcher.cpp

Print this page
rev 8016 : 8069191: moving predicate out of loops may cause array accesses to bypass null check
Summary: Remove CastPP nodes only during final graph reshape
Reviewed-by:


1032             C->set_node_notes_at(m->_idx, nn);
1033           }
1034           debug_only(match_alias_type(C, n, m));
1035         }
1036         n = m;    // n is now a new-space node
1037         mstack.set_node(n);
1038       }
1039 
1040       // New space!
1041       if (_visited.test_set(n->_idx)) continue; // while(mstack.is_nonempty())
1042 
1043       int i;
1044       // Put precedence edges on stack first (match them last).
1045       for (i = oldn->req(); (uint)i < oldn->len(); i++) {
1046         Node *m = oldn->in(i);
1047         if (m == NULL) break;
1048         // set -1 to call add_prec() instead of set_req() during Step1
1049         mstack.push(m, Visit, n, -1);
1050       }
1051 









1052       // For constant debug info, I'd rather have unmatched constants.
1053       int cnt = n->req();
1054       JVMState* jvms = n->jvms();
1055       int debug_cnt = jvms ? jvms->debug_start() : cnt;
1056 
1057       // Now do only debug info.  Clone constants rather than matching.
1058       // Constants are represented directly in the debug info without
1059       // the need for executable machine instructions.
1060       // Monitor boxes are also represented directly.
1061       for (i = cnt - 1; i >= debug_cnt; --i) { // For all debug inputs do
1062         Node *m = n->in(i);          // Get input
1063         int op = m->Opcode();
1064         assert((op == Op_BoxLock) == jvms->is_monitor_use(i), "boxes only at monitor sites");
1065         if( op == Op_ConI || op == Op_ConP || op == Op_ConN || op == Op_ConNKlass ||
1066             op == Op_ConF || op == Op_ConD || op == Op_ConL
1067             // || op == Op_BoxLock  // %%%% enable this and remove (+++) in chaitin.cpp
1068             ) {
1069           m = m->clone();
1070 #ifdef ASSERT
1071           _new2old_map.map(m->_idx, n);


1721 
1722   // PhaseChaitin::fixup_spills will sometimes generate spill code
1723   // via the matcher.  By the time, nodes have been wired into the CFG,
1724   // and any further nodes generated by expand rules will be left hanging
1725   // in space, and will not get emitted as output code.  Catch this.
1726   // Also, catch any new register allocation constraints ("projections")
1727   // generated belatedly during spill code generation.
1728   if (_allocation_started) {
1729     guarantee(ex == mach, "no expand rules during spill generation");
1730     guarantee(number_of_projections_prior == number_of_projections(), "no allocation during spill generation");
1731   }
1732 
1733   if (leaf->is_Con() || leaf->is_DecodeNarrowPtr()) {
1734     // Record the con for sharing
1735     _shared_nodes.map(leaf->_idx, ex);
1736   }
1737 
1738   return ex;
1739 }
1740 








1741 void Matcher::ReduceInst_Chain_Rule( State *s, int rule, Node *&mem, MachNode *mach ) {
1742   // 'op' is what I am expecting to receive
1743   int op = _leftOp[rule];
1744   // Operand type to catch childs result
1745   // This is what my child will give me.
1746   int opnd_class_instance = s->_rule[op];
1747   // Choose between operand class or not.
1748   // This is what I will receive.
1749   int catch_op = (FIRST_OPERAND_CLASS <= op && op < NUM_OPERANDS) ? opnd_class_instance : op;
1750   // New rule for child.  Chase operand classes to get the actual rule.
1751   int newrule = s->_rule[catch_op];
1752 
1753   if( newrule < NUM_OPERANDS ) {
1754     // Chain from operand or operand class, may be output of shared node
1755     assert( 0 <= opnd_class_instance && opnd_class_instance < NUM_OPERANDS,
1756             "Bad AD file: Instruction chain rule must chain from operand");
1757     // Insert operand into array of operands for this instruction
1758     mach->_opnds[1] = s->MachOperGenerator(opnd_class_instance);
1759 
1760     ReduceOper( s, newrule, mem, mach );
1761   } else {
1762     // Chain from the result of an instruction
1763     assert( newrule >= _LAST_MACH_OPER, "Do NOT chain from internal operand");
1764     mach->_opnds[1] = s->MachOperGenerator(_reduceOp[catch_op]);
1765     Node *mem1 = (Node*)1;
1766     debug_only(Node *save_mem_node = _mem_node;)
1767     mach->add_req( ReduceInst(s, newrule, mem1) );
1768     debug_only(_mem_node = save_mem_node;)
1769   }
1770   return;
1771 }
1772 
1773 
1774 uint Matcher::ReduceInst_Interior( State *s, int rule, Node *&mem, MachNode *mach, uint num_opnds ) {


1775   if( s->_leaf->is_Load() ) {
1776     Node *mem2 = s->_leaf->in(MemNode::Memory);
1777     assert( mem == (Node*)1 || mem == mem2, "multiple Memories being matched at once?" );
1778     debug_only( if( mem == (Node*)1 ) _mem_node = s->_leaf;)
1779     mem = mem2;
1780   }
1781   if( s->_leaf->in(0) != NULL && s->_leaf->req() > 1) {
1782     if( mach->in(0) == NULL )
1783       mach->set_req(0, s->_leaf->in(0));
1784   }
1785 
1786   // Now recursively walk the state tree & add operand list.
1787   for( uint i=0; i<2; i++ ) {   // binary tree
1788     State *newstate = s->_kids[i];
1789     if( newstate == NULL ) break;      // Might only have 1 child
1790     // 'op' is what I am expecting to receive
1791     int op;
1792     if( i == 0 ) {
1793       op = _leftOp[rule];
1794     } else {


1837 //     Skip over it ( do nothing )
1838 // (3) Child is an instruction -
1839 //     Call ReduceInst recursively and
1840 //     and instruction as an input to the MachNode
1841 void Matcher::ReduceOper( State *s, int rule, Node *&mem, MachNode *mach ) {
1842   assert( rule < _LAST_MACH_OPER, "called with operand rule" );
1843   State *kid = s->_kids[0];
1844   assert( kid == NULL || s->_leaf->in(0) == NULL, "internal operands have no control" );
1845 
1846   // Leaf?  And not subsumed?
1847   if( kid == NULL && !_swallowed[rule] ) {
1848     mach->add_req( s->_leaf );  // Add leaf pointer
1849     return;                     // Bail out
1850   }
1851 
1852   if( s->_leaf->is_Load() ) {
1853     assert( mem == (Node*)1, "multiple Memories being matched at once?" );
1854     mem = s->_leaf->in(MemNode::Memory);
1855     debug_only(_mem_node = s->_leaf;)
1856   }



1857   if( s->_leaf->in(0) && s->_leaf->req() > 1) {
1858     if( !mach->in(0) )
1859       mach->set_req(0,s->_leaf->in(0));
1860     else {
1861       assert( s->_leaf->in(0) == mach->in(0), "same instruction, differing controls?" );
1862     }
1863   }
1864 
1865   for( uint i=0; kid != NULL && i<2; kid = s->_kids[1], i++ ) {   // binary tree
1866     int newrule;
1867     if( i == 0)
1868       newrule = kid->_rule[_leftOp[rule]];
1869     else
1870       newrule = kid->_rule[_rightOp[rule]];
1871 
1872     if( newrule < _LAST_MACH_OPER ) { // Operand or instruction?
1873       // Internal operand; recurse but do nothing else
1874       ReduceOper( kid, newrule, mem, mach );
1875 
1876     } else {                    // Child is a new instruction




1032             C->set_node_notes_at(m->_idx, nn);
1033           }
1034           debug_only(match_alias_type(C, n, m));
1035         }
1036         n = m;    // n is now a new-space node
1037         mstack.set_node(n);
1038       }
1039 
1040       // New space!
1041       if (_visited.test_set(n->_idx)) continue; // while(mstack.is_nonempty())
1042 
1043       int i;
1044       // Put precedence edges on stack first (match them last).
1045       for (i = oldn->req(); (uint)i < oldn->len(); i++) {
1046         Node *m = oldn->in(i);
1047         if (m == NULL) break;
1048         // set -1 to call add_prec() instead of set_req() during Step1
1049         mstack.push(m, Visit, n, -1);
1050       }
1051 
1052       // Handle precedence edges for interior nodes
1053       for (i = n->len()-1; (uint)i >= n->req(); i--) {
1054         Node *m = n->in(i);
1055         if (m == NULL || C->node_arena()->contains(m)) continue;
1056         n->rm_prec(i);
1057         // set -1 to call add_prec() instead of set_req() during Step1
1058         mstack.push(m, Visit, n, -1);
1059       }
1060 
1061       // For constant debug info, I'd rather have unmatched constants.
1062       int cnt = n->req();
1063       JVMState* jvms = n->jvms();
1064       int debug_cnt = jvms ? jvms->debug_start() : cnt;
1065 
1066       // Now do only debug info.  Clone constants rather than matching.
1067       // Constants are represented directly in the debug info without
1068       // the need for executable machine instructions.
1069       // Monitor boxes are also represented directly.
1070       for (i = cnt - 1; i >= debug_cnt; --i) { // For all debug inputs do
1071         Node *m = n->in(i);          // Get input
1072         int op = m->Opcode();
1073         assert((op == Op_BoxLock) == jvms->is_monitor_use(i), "boxes only at monitor sites");
1074         if( op == Op_ConI || op == Op_ConP || op == Op_ConN || op == Op_ConNKlass ||
1075             op == Op_ConF || op == Op_ConD || op == Op_ConL
1076             // || op == Op_BoxLock  // %%%% enable this and remove (+++) in chaitin.cpp
1077             ) {
1078           m = m->clone();
1079 #ifdef ASSERT
1080           _new2old_map.map(m->_idx, n);


1730 
1731   // PhaseChaitin::fixup_spills will sometimes generate spill code
1732   // via the matcher.  By the time, nodes have been wired into the CFG,
1733   // and any further nodes generated by expand rules will be left hanging
1734   // in space, and will not get emitted as output code.  Catch this.
1735   // Also, catch any new register allocation constraints ("projections")
1736   // generated belatedly during spill code generation.
1737   if (_allocation_started) {
1738     guarantee(ex == mach, "no expand rules during spill generation");
1739     guarantee(number_of_projections_prior == number_of_projections(), "no allocation during spill generation");
1740   }
1741 
1742   if (leaf->is_Con() || leaf->is_DecodeNarrowPtr()) {
1743     // Record the con for sharing
1744     _shared_nodes.map(leaf->_idx, ex);
1745   }
1746 
1747   return ex;
1748 }
1749 
1750 void Matcher::handle_precedence_edges(Node* n, MachNode *mach) {
1751   for (uint i = n->req(); i < n->len(); i++) {
1752     if (n->in(i) != NULL) {
1753       mach->add_prec(n->in(i));
1754     }
1755   }
1756 }
1757 
1758 void Matcher::ReduceInst_Chain_Rule( State *s, int rule, Node *&mem, MachNode *mach ) {
1759   // 'op' is what I am expecting to receive
1760   int op = _leftOp[rule];
1761   // Operand type to catch childs result
1762   // This is what my child will give me.
1763   int opnd_class_instance = s->_rule[op];
1764   // Choose between operand class or not.
1765   // This is what I will receive.
1766   int catch_op = (FIRST_OPERAND_CLASS <= op && op < NUM_OPERANDS) ? opnd_class_instance : op;
1767   // New rule for child.  Chase operand classes to get the actual rule.
1768   int newrule = s->_rule[catch_op];
1769 
1770   if( newrule < NUM_OPERANDS ) {
1771     // Chain from operand or operand class, may be output of shared node
1772     assert( 0 <= opnd_class_instance && opnd_class_instance < NUM_OPERANDS,
1773             "Bad AD file: Instruction chain rule must chain from operand");
1774     // Insert operand into array of operands for this instruction
1775     mach->_opnds[1] = s->MachOperGenerator(opnd_class_instance);
1776 
1777     ReduceOper( s, newrule, mem, mach );
1778   } else {
1779     // Chain from the result of an instruction
1780     assert( newrule >= _LAST_MACH_OPER, "Do NOT chain from internal operand");
1781     mach->_opnds[1] = s->MachOperGenerator(_reduceOp[catch_op]);
1782     Node *mem1 = (Node*)1;
1783     debug_only(Node *save_mem_node = _mem_node;)
1784     mach->add_req( ReduceInst(s, newrule, mem1) );
1785     debug_only(_mem_node = save_mem_node;)
1786   }
1787   return;
1788 }
1789 
1790 
1791 uint Matcher::ReduceInst_Interior( State *s, int rule, Node *&mem, MachNode *mach, uint num_opnds ) {
1792   handle_precedence_edges(s->_leaf, mach);
1793 
1794   if( s->_leaf->is_Load() ) {
1795     Node *mem2 = s->_leaf->in(MemNode::Memory);
1796     assert( mem == (Node*)1 || mem == mem2, "multiple Memories being matched at once?" );
1797     debug_only( if( mem == (Node*)1 ) _mem_node = s->_leaf;)
1798     mem = mem2;
1799   }
1800   if( s->_leaf->in(0) != NULL && s->_leaf->req() > 1) {
1801     if( mach->in(0) == NULL )
1802       mach->set_req(0, s->_leaf->in(0));
1803   }
1804 
1805   // Now recursively walk the state tree & add operand list.
1806   for( uint i=0; i<2; i++ ) {   // binary tree
1807     State *newstate = s->_kids[i];
1808     if( newstate == NULL ) break;      // Might only have 1 child
1809     // 'op' is what I am expecting to receive
1810     int op;
1811     if( i == 0 ) {
1812       op = _leftOp[rule];
1813     } else {


1856 //     Skip over it ( do nothing )
1857 // (3) Child is an instruction -
1858 //     Call ReduceInst recursively and
1859 //     and instruction as an input to the MachNode
1860 void Matcher::ReduceOper( State *s, int rule, Node *&mem, MachNode *mach ) {
1861   assert( rule < _LAST_MACH_OPER, "called with operand rule" );
1862   State *kid = s->_kids[0];
1863   assert( kid == NULL || s->_leaf->in(0) == NULL, "internal operands have no control" );
1864 
1865   // Leaf?  And not subsumed?
1866   if( kid == NULL && !_swallowed[rule] ) {
1867     mach->add_req( s->_leaf );  // Add leaf pointer
1868     return;                     // Bail out
1869   }
1870 
1871   if( s->_leaf->is_Load() ) {
1872     assert( mem == (Node*)1, "multiple Memories being matched at once?" );
1873     mem = s->_leaf->in(MemNode::Memory);
1874     debug_only(_mem_node = s->_leaf;)
1875   }
1876 
1877   handle_precedence_edges(s->_leaf, mach);
1878 
1879   if( s->_leaf->in(0) && s->_leaf->req() > 1) {
1880     if( !mach->in(0) )
1881       mach->set_req(0,s->_leaf->in(0));
1882     else {
1883       assert( s->_leaf->in(0) == mach->in(0), "same instruction, differing controls?" );
1884     }
1885   }
1886 
1887   for( uint i=0; kid != NULL && i<2; kid = s->_kids[1], i++ ) {   // binary tree
1888     int newrule;
1889     if( i == 0)
1890       newrule = kid->_rule[_leftOp[rule]];
1891     else
1892       newrule = kid->_rule[_rightOp[rule]];
1893 
1894     if( newrule < _LAST_MACH_OPER ) { // Operand or instruction?
1895       // Internal operand; recurse but do nothing else
1896       ReduceOper( kid, newrule, mem, mach );
1897 
1898     } else {                    // Child is a new instruction


src/share/vm/opto/matcher.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File