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

src/share/vm/opto/matcher.cpp

Print this page




1317     // Slot 0 of constants is not really a Control.
1318     if( control && m->in(0) && control != m->in(0) ) {
1319 
1320       // Actually, we can live with the most conservative control we
1321       // find, if it post-dominates the others.  This allows us to
1322       // pick up load/op/store trees where the load can float a little
1323       // above the store.
1324       Node *x = control;
1325       const uint max_scan = 6;   // Arbitrary scan cutoff
1326       uint j;
1327       for( j=0; j<max_scan; j++ ) {
1328         if( x->is_Region() )    // Bail out at merge points
1329           return true;
1330         x = x->in(0);
1331         if( x == m->in(0) )     // Does 'control' post-dominate
1332           break;                // m->in(0)?  If so, we can use it
1333       }
1334       if( j == max_scan )       // No post-domination before scan end?
1335         return true;            // Then break the match tree up
1336     }
1337     if (m->is_DecodeN() && Matcher::clone_shift_expressions) {
1338       // These are commonly used in address expressions and can
1339       // efficiently fold into them on X64 in some cases.
1340       return false;
1341     }
1342   }
1343 
1344   // Not forceable cloning.  If shared, put it into a register.
1345   return shared;
1346 }
1347 
1348 
1349 //------------------------------Instruction Selection--------------------------
1350 // Label method walks a "tree" of nodes, using the ADLC generated DFA to match
1351 // ideal nodes to machine instructions.  Trees are delimited by shared Nodes,
1352 // things the Matcher does not match (e.g., Memory), and things with different
1353 // Controls (hence forced into different blocks).  We pass in the Control
1354 // selected for this entire State tree.
1355 
1356 // The Matcher works on Trees, but an Intel add-to-memory requires a DAG: the
1357 // Store and the Load must have identical Memories (as well as identical


2093     if (ct == TypePtr::NULL_PTR ||
2094         (opc == Op_CmpN && ct == TypeNarrowOop::NULL_PTR)) {
2095 
2096       bool push_it = false;
2097       if( proj->Opcode() == Op_IfTrue ) {
2098         extern int all_null_checks_found;
2099         all_null_checks_found++;
2100         if( b->_test._test == BoolTest::ne ) {
2101           push_it = true;
2102         }
2103       } else {
2104         assert( proj->Opcode() == Op_IfFalse, "" );
2105         if( b->_test._test == BoolTest::eq ) {
2106           push_it = true;
2107         }
2108       }
2109       if( push_it ) {
2110         _null_check_tests.push(proj);
2111         Node* val = cmp->in(1);
2112 #ifdef _LP64
2113         if (UseCompressedOops && !Matcher::clone_shift_expressions &&
2114             val->bottom_type()->isa_narrowoop()) {
2115           //
2116           // Look for DecodeN node which should be pinned to orig_proj.
2117           // On platforms (Sparc) which can not handle 2 adds
2118           // in addressing mode we have to keep a DecodeN node and
2119           // use it to do implicit NULL check in address.
2120           //
2121           // DecodeN node was pinned to non-null path (orig_proj) during
2122           // CastPP transformation in final_graph_reshaping_impl().
2123           //
2124           uint cnt = orig_proj->outcnt();
2125           for (uint i = 0; i < orig_proj->outcnt(); i++) {
2126             Node* d = orig_proj->raw_out(i);
2127             if (d->is_DecodeN() && d->in(1) == val) {
2128               val = d;
2129               val->set_req(0, NULL); // Unpin now.
2130               break;
2131             }
2132           }
2133         }
2134 #endif




1317     // Slot 0 of constants is not really a Control.
1318     if( control && m->in(0) && control != m->in(0) ) {
1319 
1320       // Actually, we can live with the most conservative control we
1321       // find, if it post-dominates the others.  This allows us to
1322       // pick up load/op/store trees where the load can float a little
1323       // above the store.
1324       Node *x = control;
1325       const uint max_scan = 6;   // Arbitrary scan cutoff
1326       uint j;
1327       for( j=0; j<max_scan; j++ ) {
1328         if( x->is_Region() )    // Bail out at merge points
1329           return true;
1330         x = x->in(0);
1331         if( x == m->in(0) )     // Does 'control' post-dominate
1332           break;                // m->in(0)?  If so, we can use it
1333       }
1334       if( j == max_scan )       // No post-domination before scan end?
1335         return true;            // Then break the match tree up
1336     }
1337     if (m->is_DecodeN() && Matcher::narrow_oop_use_complex_address()) {
1338       // These are commonly used in address expressions and can
1339       // efficiently fold into them on X64 in some cases.
1340       return false;
1341     }
1342   }
1343 
1344   // Not forceable cloning.  If shared, put it into a register.
1345   return shared;
1346 }
1347 
1348 
1349 //------------------------------Instruction Selection--------------------------
1350 // Label method walks a "tree" of nodes, using the ADLC generated DFA to match
1351 // ideal nodes to machine instructions.  Trees are delimited by shared Nodes,
1352 // things the Matcher does not match (e.g., Memory), and things with different
1353 // Controls (hence forced into different blocks).  We pass in the Control
1354 // selected for this entire State tree.
1355 
1356 // The Matcher works on Trees, but an Intel add-to-memory requires a DAG: the
1357 // Store and the Load must have identical Memories (as well as identical


2093     if (ct == TypePtr::NULL_PTR ||
2094         (opc == Op_CmpN && ct == TypeNarrowOop::NULL_PTR)) {
2095 
2096       bool push_it = false;
2097       if( proj->Opcode() == Op_IfTrue ) {
2098         extern int all_null_checks_found;
2099         all_null_checks_found++;
2100         if( b->_test._test == BoolTest::ne ) {
2101           push_it = true;
2102         }
2103       } else {
2104         assert( proj->Opcode() == Op_IfFalse, "" );
2105         if( b->_test._test == BoolTest::eq ) {
2106           push_it = true;
2107         }
2108       }
2109       if( push_it ) {
2110         _null_check_tests.push(proj);
2111         Node* val = cmp->in(1);
2112 #ifdef _LP64
2113         if (val->bottom_type()->isa_narrowoop() &&
2114             !Matcher::narrow_oop_use_complex_address()) {
2115           //
2116           // Look for DecodeN node which should be pinned to orig_proj.
2117           // On platforms (Sparc) which can not handle 2 adds
2118           // in addressing mode we have to keep a DecodeN node and
2119           // use it to do implicit NULL check in address.
2120           //
2121           // DecodeN node was pinned to non-null path (orig_proj) during
2122           // CastPP transformation in final_graph_reshaping_impl().
2123           //
2124           uint cnt = orig_proj->outcnt();
2125           for (uint i = 0; i < orig_proj->outcnt(); i++) {
2126             Node* d = orig_proj->raw_out(i);
2127             if (d->is_DecodeN() && d->in(1) == val) {
2128               val = d;
2129               val->set_req(0, NULL); // Unpin now.
2130               break;
2131             }
2132           }
2133         }
2134 #endif


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