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

src/share/vm/opto/lcm.cpp

Print this page




 989     assert( clone->Opcode() == use->Opcode(), "" );
 990 
 991     // Make use-clone reference the def-clone
 992     catch_cleanup_fix_all_inputs(clone, def, sb->_nodes[n_clone_idx]);
 993   }
 994 }
 995 
 996 //------------------------------catch_cleanup_inter_block---------------------
 997 // Fix all input edges in use that reference "def".  The use is in a different
 998 // block than the def.
 999 static void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, Block_Array &bbs, int n_clone_idx) {
1000   if( !use_blk ) return;        // Can happen if the use is a precedence edge
1001 
1002   Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, bbs, n_clone_idx);
1003   catch_cleanup_fix_all_inputs(use, def, new_def);
1004 }
1005 
1006 //------------------------------call_catch_cleanup-----------------------------
1007 // If we inserted any instructions between a Call and his CatchNode,
1008 // clone the instructions on all paths below the Catch.
1009 void Block::call_catch_cleanup(Block_Array &bbs) {
1010 
1011   // End of region to clone
1012   uint end = end_idx();
1013   if( !_nodes[end]->is_Catch() ) return;
1014   // Start of region to clone
1015   uint beg = end;
1016   while(!_nodes[beg-1]->is_MachProj() ||
1017         !_nodes[beg-1]->in(0)->is_MachCall() ) {
1018     beg--;
1019     assert(beg > 0,"Catch cleanup walking beyond block boundary");
1020   }
1021   // Range of inserted instructions is [beg, end)
1022   if( beg == end ) return;
1023 
1024   // Clone along all Catch output paths.  Clone area between the 'beg' and
1025   // 'end' indices.
1026   for( uint i = 0; i < _num_succs; i++ ) {
1027     Block *sb = _succs[i];
1028     // Clone the entire area; ignoring the edge fixup for now.
1029     for( uint j = end; j > beg; j-- ) {


1051       Block *buse = bbs[use->_idx];
1052       if( use->is_Phi() ) {
1053         for( uint k = 1; k < use->req(); k++ )
1054           if( use->in(k) == n ) {
1055             Node *fixup = catch_cleanup_find_cloned_def(bbs[buse->pred(k)->_idx], n, this, bbs, n_clone_idx);
1056             use->set_req(k, fixup);
1057           }
1058       } else {
1059         if (this == buse) {
1060           catch_cleanup_intra_block(use, n, this, beg, n_clone_idx);
1061         } else {
1062           catch_cleanup_inter_block(use, buse, n, this, bbs, n_clone_idx);
1063         }
1064       }
1065     } // End for all users
1066 
1067   } // End of for all Nodes in cloned area
1068 
1069   // Remove the now-dead cloned ops
1070   for(uint i3 = beg; i3 < end; i3++ ) {
1071     _nodes[beg]->disconnect_inputs(NULL);
1072     _nodes.remove(beg);
1073   }
1074 
1075   // If the successor blocks have a CreateEx node, move it back to the top
1076   for(uint i4 = 0; i4 < _num_succs; i4++ ) {
1077     Block *sb = _succs[i4];
1078     uint new_cnt = end - beg;
1079     // Remove any newly created, but dead, nodes.
1080     for( uint j = new_cnt; j > 0; j-- ) {
1081       Node *n = sb->_nodes[j];
1082       if (n->outcnt() == 0 &&
1083           (!n->is_Proj() || n->as_Proj()->in(0)->outcnt() == 1) ){
1084         n->disconnect_inputs(NULL);
1085         sb->_nodes.remove(j);
1086         new_cnt--;
1087       }
1088     }
1089     // If any newly created nodes remain, move the CreateEx node to the top
1090     if (new_cnt > 0) {
1091       Node *cex = sb->_nodes[1+new_cnt];
1092       if( cex->is_Mach() && cex->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
1093         sb->_nodes.remove(1+new_cnt);
1094         sb->_nodes.insert(1,cex);
1095       }
1096     }
1097   }
1098 }


 989     assert( clone->Opcode() == use->Opcode(), "" );
 990 
 991     // Make use-clone reference the def-clone
 992     catch_cleanup_fix_all_inputs(clone, def, sb->_nodes[n_clone_idx]);
 993   }
 994 }
 995 
 996 //------------------------------catch_cleanup_inter_block---------------------
 997 // Fix all input edges in use that reference "def".  The use is in a different
 998 // block than the def.
 999 static void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, Block_Array &bbs, int n_clone_idx) {
1000   if( !use_blk ) return;        // Can happen if the use is a precedence edge
1001 
1002   Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, bbs, n_clone_idx);
1003   catch_cleanup_fix_all_inputs(use, def, new_def);
1004 }
1005 
1006 //------------------------------call_catch_cleanup-----------------------------
1007 // If we inserted any instructions between a Call and his CatchNode,
1008 // clone the instructions on all paths below the Catch.
1009 void Block::call_catch_cleanup(Block_Array &bbs, Compile* C) {
1010 
1011   // End of region to clone
1012   uint end = end_idx();
1013   if( !_nodes[end]->is_Catch() ) return;
1014   // Start of region to clone
1015   uint beg = end;
1016   while(!_nodes[beg-1]->is_MachProj() ||
1017         !_nodes[beg-1]->in(0)->is_MachCall() ) {
1018     beg--;
1019     assert(beg > 0,"Catch cleanup walking beyond block boundary");
1020   }
1021   // Range of inserted instructions is [beg, end)
1022   if( beg == end ) return;
1023 
1024   // Clone along all Catch output paths.  Clone area between the 'beg' and
1025   // 'end' indices.
1026   for( uint i = 0; i < _num_succs; i++ ) {
1027     Block *sb = _succs[i];
1028     // Clone the entire area; ignoring the edge fixup for now.
1029     for( uint j = end; j > beg; j-- ) {


1051       Block *buse = bbs[use->_idx];
1052       if( use->is_Phi() ) {
1053         for( uint k = 1; k < use->req(); k++ )
1054           if( use->in(k) == n ) {
1055             Node *fixup = catch_cleanup_find_cloned_def(bbs[buse->pred(k)->_idx], n, this, bbs, n_clone_idx);
1056             use->set_req(k, fixup);
1057           }
1058       } else {
1059         if (this == buse) {
1060           catch_cleanup_intra_block(use, n, this, beg, n_clone_idx);
1061         } else {
1062           catch_cleanup_inter_block(use, buse, n, this, bbs, n_clone_idx);
1063         }
1064       }
1065     } // End for all users
1066 
1067   } // End of for all Nodes in cloned area
1068 
1069   // Remove the now-dead cloned ops
1070   for(uint i3 = beg; i3 < end; i3++ ) {
1071     _nodes[beg]->disconnect_inputs(NULL, C);
1072     _nodes.remove(beg);
1073   }
1074 
1075   // If the successor blocks have a CreateEx node, move it back to the top
1076   for(uint i4 = 0; i4 < _num_succs; i4++ ) {
1077     Block *sb = _succs[i4];
1078     uint new_cnt = end - beg;
1079     // Remove any newly created, but dead, nodes.
1080     for( uint j = new_cnt; j > 0; j-- ) {
1081       Node *n = sb->_nodes[j];
1082       if (n->outcnt() == 0 &&
1083           (!n->is_Proj() || n->as_Proj()->in(0)->outcnt() == 1) ){
1084         n->disconnect_inputs(NULL, C);
1085         sb->_nodes.remove(j);
1086         new_cnt--;
1087       }
1088     }
1089     // If any newly created nodes remain, move the CreateEx node to the top
1090     if (new_cnt > 0) {
1091       Node *cex = sb->_nodes[1+new_cnt];
1092       if( cex->is_Mach() && cex->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
1093         sb->_nodes.remove(1+new_cnt);
1094         sb->_nodes.insert(1,cex);
1095       }
1096     }
1097   }
1098 }
src/share/vm/opto/lcm.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File