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 }
|