1.1 --- a/src/share/vm/opto/lcm.cpp Mon Nov 21 00:57:43 2011 -0800 1.2 +++ b/src/share/vm/opto/lcm.cpp Wed Sep 14 09:22:51 2011 +0200 1.3 @@ -548,6 +548,22 @@ 1.4 set_next_call(call, next_call, bbs); 1.5 } 1.6 1.7 +//------------------------------add_call_kills------------------------------------- 1.8 +void Block::add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe) { 1.9 + // Fill in the kill mask for the call 1.10 + for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) { 1.11 + if( !regs.Member(r) ) { // Not already defined by the call 1.12 + // Save-on-call register? 1.13 + if ((save_policy[r] == 'C') || 1.14 + (save_policy[r] == 'A') || 1.15 + ((save_policy[r] == 'E') && exclude_soe)) { 1.16 + proj->_rout.Insert(r); 1.17 + } 1.18 + } 1.19 + } 1.20 +} 1.21 + 1.22 + 1.23 //------------------------------sched_call------------------------------------- 1.24 uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, int *ready_cnt, MachCallNode *mcall, VectorSet &next_call ) { 1.25 RegMask regs; 1.26 @@ -631,17 +647,7 @@ 1.27 proj->_rout.OR(Matcher::method_handle_invoke_SP_save_mask()); 1.28 } 1.29 1.30 - // Fill in the kill mask for the call 1.31 - for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) { 1.32 - if( !regs.Member(r) ) { // Not already defined by the call 1.33 - // Save-on-call register? 1.34 - if ((save_policy[r] == 'C') || 1.35 - (save_policy[r] == 'A') || 1.36 - ((save_policy[r] == 'E') && exclude_soe)) { 1.37 - proj->_rout.Insert(r); 1.38 - } 1.39 - } 1.40 - } 1.41 + add_call_kills(proj, regs, save_policy, exclude_soe); 1.42 1.43 return node_cnt; 1.44 } 1.45 @@ -776,6 +782,7 @@ 1.46 } 1.47 #endif 1.48 1.49 + uint max_idx = matcher.C->unique(); 1.50 // Pull from worklist and schedule 1.51 while( worklist.size() ) { // Worklist is not ready 1.52 1.53 @@ -815,11 +822,28 @@ 1.54 phi_cnt = sched_call(matcher, cfg->_bbs, phi_cnt, worklist, ready_cnt, mcall, next_call); 1.55 continue; 1.56 } 1.57 + 1.58 + if (n->is_Mach() && n->as_Mach()->has_call()) { 1.59 + RegMask regs; 1.60 + regs.Insert(matcher.c_frame_pointer()); 1.61 + regs.OR(n->out_RegMask()); 1.62 + 1.63 + MachProjNode *proj = new (matcher.C, 1) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj ); 1.64 + cfg->_bbs.map(proj->_idx,this); 1.65 + _nodes.insert(phi_cnt++, proj); 1.66 + 1.67 + add_call_kills(proj, regs, matcher._c_reg_save_policy, false); 1.68 + } 1.69 + 1.70 // Children are now all ready 1.71 for (DUIterator_Fast i5max, i5 = n->fast_outs(i5max); i5 < i5max; i5++) { 1.72 Node* m = n->fast_out(i5); // Get user 1.73 if( cfg->_bbs[m->_idx] != this ) continue; 1.74 if( m->is_Phi() ) continue; 1.75 + if (m->_idx > max_idx) { // new node, skip it 1.76 + assert(m->is_MachProj() && n->is_Mach() && n->as_Mach()->has_call(), "unexpected node types"); 1.77 + continue; 1.78 + } 1.79 if( !--ready_cnt[m->_idx] ) 1.80 worklist.push(m); 1.81 }