110 // Phis. Skip over a CatchNode and projs, inserting in the fall-through block |
110 // Phis. Skip over a CatchNode and projs, inserting in the fall-through block |
111 // instead. Update high-pressure indices. Create a new live range. |
111 // instead. Update high-pressure indices. Create a new live range. |
112 void PhaseChaitin::insert_proj( Block *b, uint i, Node *spill, uint maxlrg ) { |
112 void PhaseChaitin::insert_proj( Block *b, uint i, Node *spill, uint maxlrg ) { |
113 // Skip intervening ProjNodes. Do not insert between a ProjNode and |
113 // Skip intervening ProjNodes. Do not insert between a ProjNode and |
114 // its definer. |
114 // its definer. |
115 while( i < b->_nodes.size() && |
115 while( i < b->number_of_nodes() && |
116 (b->_nodes[i]->is_Proj() || |
116 (b->get_node(i)->is_Proj() || |
117 b->_nodes[i]->is_Phi() ) ) |
117 b->get_node(i)->is_Phi() ) ) |
118 i++; |
118 i++; |
119 |
119 |
120 // Do not insert between a call and his Catch |
120 // Do not insert between a call and his Catch |
121 if( b->_nodes[i]->is_Catch() ) { |
121 if( b->get_node(i)->is_Catch() ) { |
122 // Put the instruction at the top of the fall-thru block. |
122 // Put the instruction at the top of the fall-thru block. |
123 // Find the fall-thru projection |
123 // Find the fall-thru projection |
124 while( 1 ) { |
124 while( 1 ) { |
125 const CatchProjNode *cp = b->_nodes[++i]->as_CatchProj(); |
125 const CatchProjNode *cp = b->get_node(++i)->as_CatchProj(); |
126 if( cp->_con == CatchProjNode::fall_through_index ) |
126 if( cp->_con == CatchProjNode::fall_through_index ) |
127 break; |
127 break; |
128 } |
128 } |
129 int sidx = i - b->end_idx()-1; |
129 int sidx = i - b->end_idx()-1; |
130 b = b->_succs[sidx]; // Switch to successor block |
130 b = b->_succs[sidx]; // Switch to successor block |
131 i = 1; // Right at start of block |
131 i = 1; // Right at start of block |
132 } |
132 } |
133 |
133 |
134 b->_nodes.insert(i,spill); // Insert node in block |
134 b->insert_node(spill, i); // Insert node in block |
135 _cfg.map_node_to_block(spill, b); // Update node->block mapping to reflect |
135 _cfg.map_node_to_block(spill, b); // Update node->block mapping to reflect |
136 // Adjust the point where we go hi-pressure |
136 // Adjust the point where we go hi-pressure |
137 if( i <= b->_ihrp_index ) b->_ihrp_index++; |
137 if( i <= b->_ihrp_index ) b->_ihrp_index++; |
138 if( i <= b->_fhrp_index ) b->_fhrp_index++; |
138 if( i <= b->_fhrp_index ) b->_fhrp_index++; |
139 |
139 |
158 // null check location (ie - null check is in HRP block) we need to do |
158 // null check location (ie - null check is in HRP block) we need to do |
159 // the null-check first, then spill-down in the following block. |
159 // the null-check first, then spill-down in the following block. |
160 // (The implicit_null_check function ensures the use is also dominated |
160 // (The implicit_null_check function ensures the use is also dominated |
161 // by the branch-not-taken block.) |
161 // by the branch-not-taken block.) |
162 Node *be = b->end(); |
162 Node *be = b->end(); |
163 if( be->is_MachNullCheck() && be->in(1) == def && def == b->_nodes[loc] ) { |
163 if( be->is_MachNullCheck() && be->in(1) == def && def == b->get_node(loc)) { |
164 // Spill goes in the branch-not-taken block |
164 // Spill goes in the branch-not-taken block |
165 b = b->_succs[b->_nodes[b->end_idx()+1]->Opcode() == Op_IfTrue]; |
165 b = b->_succs[b->get_node(b->end_idx()+1)->Opcode() == Op_IfTrue]; |
166 loc = 0; // Just past the Region |
166 loc = 0; // Just past the Region |
167 } |
167 } |
168 assert( loc >= 0, "must insert past block head" ); |
168 assert( loc >= 0, "must insert past block head" ); |
169 |
169 |
170 // Get a def-side SpillCopy |
170 // Get a def-side SpillCopy |
448 return false; |
448 return false; |
449 } |
449 } |
450 |
450 |
451 // Scan block for 1st use. |
451 // Scan block for 1st use. |
452 for( uint i = 1; i <= b->end_idx(); i++ ) { |
452 for( uint i = 1; i <= b->end_idx(); i++ ) { |
453 Node *n = b->_nodes[i]; |
453 Node *n = b->get_node(i); |
454 // Ignore PHI use, these can be up or down |
454 // Ignore PHI use, these can be up or down |
455 if (n->is_Phi()) { |
455 if (n->is_Phi()) { |
456 continue; |
456 continue; |
457 } |
457 } |
458 for (uint j = 1; j < n->req(); j++) { |
458 for (uint j = 1; j < n->req(); j++) { |
645 } |
645 } |
646 } // End for all potential Phi inputs |
646 } // End for all potential Phi inputs |
647 |
647 |
648 // check block for appropriate phinode & update edges |
648 // check block for appropriate phinode & update edges |
649 for( insidx = 1; insidx <= b->end_idx(); insidx++ ) { |
649 for( insidx = 1; insidx <= b->end_idx(); insidx++ ) { |
650 n1 = b->_nodes[insidx]; |
650 n1 = b->get_node(insidx); |
651 // bail if this is not a phi |
651 // bail if this is not a phi |
652 phi = n1->is_Phi() ? n1->as_Phi() : NULL; |
652 phi = n1->is_Phi() ? n1->as_Phi() : NULL; |
653 if( phi == NULL ) { |
653 if( phi == NULL ) { |
654 // Keep track of index of first non-PhiNode instruction in block |
654 // Keep track of index of first non-PhiNode instruction in block |
655 non_phi = insidx; |
655 non_phi = insidx; |
745 } |
745 } |
746 |
746 |
747 //----------Walk Instructions in the Block and Split---------- |
747 //----------Walk Instructions in the Block and Split---------- |
748 // For all non-phi instructions in the block |
748 // For all non-phi instructions in the block |
749 for( insidx = 1; insidx <= b->end_idx(); insidx++ ) { |
749 for( insidx = 1; insidx <= b->end_idx(); insidx++ ) { |
750 Node *n = b->_nodes[insidx]; |
750 Node *n = b->get_node(insidx); |
751 // Find the defining Node's live range index |
751 // Find the defining Node's live range index |
752 uint defidx = _lrg_map.find_id(n); |
752 uint defidx = _lrg_map.find_id(n); |
753 uint cnt = n->req(); |
753 uint cnt = n->req(); |
754 |
754 |
755 if (n->is_Phi()) { |
755 if (n->is_Phi()) { |
774 assert( u, "at least 1 valid input expected" ); |
774 assert( u, "at least 1 valid input expected" ); |
775 if (i >= cnt) { // Found one unique input |
775 if (i >= cnt) { // Found one unique input |
776 assert(_lrg_map.find_id(n) == _lrg_map.find_id(u), "should be the same lrg"); |
776 assert(_lrg_map.find_id(n) == _lrg_map.find_id(u), "should be the same lrg"); |
777 n->replace_by(u); // Then replace with unique input |
777 n->replace_by(u); // Then replace with unique input |
778 n->disconnect_inputs(NULL, C); |
778 n->disconnect_inputs(NULL, C); |
779 b->_nodes.remove(insidx); |
779 b->remove_node(insidx); |
780 insidx--; |
780 insidx--; |
781 b->_ihrp_index--; |
781 b->_ihrp_index--; |
782 b->_fhrp_index--; |
782 b->_fhrp_index--; |
783 } |
783 } |
784 } |
784 } |
787 } |
787 } |
788 assert( insidx > b->_ihrp_index || |
788 assert( insidx > b->_ihrp_index || |
789 (b->_reg_pressure < (uint)INTPRESSURE) || |
789 (b->_reg_pressure < (uint)INTPRESSURE) || |
790 b->_ihrp_index > 4000000 || |
790 b->_ihrp_index > 4000000 || |
791 b->_ihrp_index >= b->end_idx() || |
791 b->_ihrp_index >= b->end_idx() || |
792 !b->_nodes[b->_ihrp_index]->is_Proj(), "" ); |
792 !b->get_node(b->_ihrp_index)->is_Proj(), "" ); |
793 assert( insidx > b->_fhrp_index || |
793 assert( insidx > b->_fhrp_index || |
794 (b->_freg_pressure < (uint)FLOATPRESSURE) || |
794 (b->_freg_pressure < (uint)FLOATPRESSURE) || |
795 b->_fhrp_index > 4000000 || |
795 b->_fhrp_index > 4000000 || |
796 b->_fhrp_index >= b->end_idx() || |
796 b->_fhrp_index >= b->end_idx() || |
797 !b->_nodes[b->_fhrp_index]->is_Proj(), "" ); |
797 !b->get_node(b->_fhrp_index)->is_Proj(), "" ); |
798 |
798 |
799 // ********** Handle Crossing HRP Boundry ********** |
799 // ********** Handle Crossing HRP Boundry ********** |
800 if( (insidx == b->_ihrp_index) || (insidx == b->_fhrp_index) ) { |
800 if( (insidx == b->_ihrp_index) || (insidx == b->_fhrp_index) ) { |
801 for( slidx = 0; slidx < spill_cnt; slidx++ ) { |
801 for( slidx = 0; slidx < spill_cnt; slidx++ ) { |
802 // Check for need to split at HRP boundary - split if UP |
802 // Check for need to split at HRP boundary - split if UP |
817 } |
817 } |
818 else { |
818 else { |
819 // Insert point is just past last use or def in the block |
819 // Insert point is just past last use or def in the block |
820 int insert_point = insidx-1; |
820 int insert_point = insidx-1; |
821 while( insert_point > 0 ) { |
821 while( insert_point > 0 ) { |
822 Node *n = b->_nodes[insert_point]; |
822 Node *n = b->get_node(insert_point); |
823 // Hit top of block? Quit going backwards |
823 // Hit top of block? Quit going backwards |
824 if (n->is_Phi()) { |
824 if (n->is_Phi()) { |
825 break; |
825 break; |
826 } |
826 } |
827 // Found a def? Better split after it. |
827 // Found a def? Better split after it. |
863 } |
863 } |
864 #endif |
864 #endif |
865 } |
865 } |
866 } // end if LRG is UP |
866 } // end if LRG is UP |
867 } // end for all spilling live ranges |
867 } // end for all spilling live ranges |
868 assert( b->_nodes[insidx] == n, "got insidx set incorrectly" ); |
868 assert( b->get_node(insidx) == n, "got insidx set incorrectly" ); |
869 } // end if crossing HRP Boundry |
869 } // end if crossing HRP Boundry |
870 |
870 |
871 // If the LRG index is oob, then this is a new spillcopy, skip it. |
871 // If the LRG index is oob, then this is a new spillcopy, skip it. |
872 if (defidx >= _lrg_map.max_lrg_id()) { |
872 if (defidx >= _lrg_map.max_lrg_id()) { |
873 continue; |
873 continue; |
876 uint copyidx = n->is_Copy(); |
876 uint copyidx = n->is_Copy(); |
877 // Remove coalesced copy from CFG |
877 // Remove coalesced copy from CFG |
878 if (copyidx && defidx == _lrg_map.live_range_id(n->in(copyidx))) { |
878 if (copyidx && defidx == _lrg_map.live_range_id(n->in(copyidx))) { |
879 n->replace_by( n->in(copyidx) ); |
879 n->replace_by( n->in(copyidx) ); |
880 n->set_req( copyidx, NULL ); |
880 n->set_req( copyidx, NULL ); |
881 b->_nodes.remove(insidx--); |
881 b->remove_node(insidx--); |
882 b->_ihrp_index--; // Adjust the point where we go hi-pressure |
882 b->_ihrp_index--; // Adjust the point where we go hi-pressure |
883 b->_fhrp_index--; |
883 b->_fhrp_index--; |
884 continue; |
884 continue; |
885 } |
885 } |
886 |
886 |
930 } |
930 } |
931 |
931 |
932 // Rematerializable? Then clone def at use site instead |
932 // Rematerializable? Then clone def at use site instead |
933 // of store/load |
933 // of store/load |
934 if( def->rematerialize() ) { |
934 if( def->rematerialize() ) { |
935 int old_size = b->_nodes.size(); |
935 int old_size = b->number_of_nodes(); |
936 def = split_Rematerialize( def, b, insidx, maxlrg, splits, slidx, lrg2reach, Reachblock, true ); |
936 def = split_Rematerialize( def, b, insidx, maxlrg, splits, slidx, lrg2reach, Reachblock, true ); |
937 if( !def ) return 0; // Bail out |
937 if( !def ) return 0; // Bail out |
938 insidx += b->_nodes.size()-old_size; |
938 insidx += b->number_of_nodes()-old_size; |
939 } |
939 } |
940 |
940 |
941 MachNode *mach = n->is_Mach() ? n->as_Mach() : NULL; |
941 MachNode *mach = n->is_Mach() ? n->as_Mach() : NULL; |
942 // Base pointers and oopmap references do not care where they live. |
942 // Base pointers and oopmap references do not care where they live. |
943 if ((inpidx >= oopoff) || |
943 if ((inpidx >= oopoff) || |
1330 // Place the rematerialized node above any MSCs created during |
1330 // Place the rematerialized node above any MSCs created during |
1331 // phi node splitting. end_idx points at the insertion point |
1331 // phi node splitting. end_idx points at the insertion point |
1332 // so look at the node before it. |
1332 // so look at the node before it. |
1333 int insert = pred->end_idx(); |
1333 int insert = pred->end_idx(); |
1334 while (insert >= 1 && |
1334 while (insert >= 1 && |
1335 pred->_nodes[insert - 1]->is_SpillCopy() && |
1335 pred->get_node(insert - 1)->is_SpillCopy() && |
1336 _lrg_map.find(pred->_nodes[insert - 1]) >= lrgs_before_phi_split) { |
1336 _lrg_map.find(pred->get_node(insert - 1)) >= lrgs_before_phi_split) { |
1337 insert--; |
1337 insert--; |
1338 } |
1338 } |
1339 def = split_Rematerialize(def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false); |
1339 def = split_Rematerialize(def, pred, insert, maxlrg, splits, slidx, lrg2reach, Reachblock, false); |
1340 if (!def) { |
1340 if (!def) { |
1341 return 0; // Bail out |
1341 return 0; // Bail out |
1400 #ifdef ASSERT |
1400 #ifdef ASSERT |
1401 // Validate all live range index assignments |
1401 // Validate all live range index assignments |
1402 for (bidx = 0; bidx < _cfg.number_of_blocks(); bidx++) { |
1402 for (bidx = 0; bidx < _cfg.number_of_blocks(); bidx++) { |
1403 b = _cfg.get_block(bidx); |
1403 b = _cfg.get_block(bidx); |
1404 for (insidx = 0; insidx <= b->end_idx(); insidx++) { |
1404 for (insidx = 0; insidx <= b->end_idx(); insidx++) { |
1405 Node *n = b->_nodes[insidx]; |
1405 Node *n = b->get_node(insidx); |
1406 uint defidx = _lrg_map.find(n); |
1406 uint defidx = _lrg_map.find(n); |
1407 assert(defidx < _lrg_map.max_lrg_id(), "Bad live range index in Split"); |
1407 assert(defidx < _lrg_map.max_lrg_id(), "Bad live range index in Split"); |
1408 assert(defidx < maxlrg,"Bad live range index in Split"); |
1408 assert(defidx < maxlrg,"Bad live range index in Split"); |
1409 } |
1409 } |
1410 } |
1410 } |