src/share/vm/opto/lcm.cpp

Print this page
rev 2647 : 7077312: Provide a CALL effect for instruct declaration in the ad file
Summary: abstracted way to declare that the MachNode has the effect of a call (kills caller save registers, preserves callee save registers)
Reviewed-by:

*** 546,555 **** --- 546,571 ---- if (call == NULL) return; // No next call (e.g., block end is near) // Set next-call for all inputs to this call set_next_call(call, next_call, bbs); } + //------------------------------add_call_kills------------------------------------- + void Block::add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe) { + // Fill in the kill mask for the call + for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) { + if( !regs.Member(r) ) { // Not already defined by the call + // Save-on-call register? + if ((save_policy[r] == 'C') || + (save_policy[r] == 'A') || + ((save_policy[r] == 'E') && exclude_soe)) { + proj->_rout.Insert(r); + } + } + } + } + + //------------------------------sched_call------------------------------------- uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, int *ready_cnt, MachCallNode *mcall, VectorSet &next_call ) { RegMask regs; // Schedule all the users of the call right now. All the users are
*** 629,649 **** MachCallStaticJavaNode* mcallstaticjava = (MachCallStaticJavaNode*) mcall; if (mcallstaticjava->_method_handle_invoke) proj->_rout.OR(Matcher::method_handle_invoke_SP_save_mask()); } ! // Fill in the kill mask for the call ! for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) { ! if( !regs.Member(r) ) { // Not already defined by the call ! // Save-on-call register? ! if ((save_policy[r] == 'C') || ! (save_policy[r] == 'A') || ! ((save_policy[r] == 'E') && exclude_soe)) { ! proj->_rout.Insert(r); ! } ! } ! } return node_cnt; } --- 645,655 ---- MachCallStaticJavaNode* mcallstaticjava = (MachCallStaticJavaNode*) mcall; if (mcallstaticjava->_method_handle_invoke) proj->_rout.OR(Matcher::method_handle_invoke_SP_save_mask()); } ! add_call_kills(proj, regs, save_policy, exclude_soe); return node_cnt; }
*** 774,783 **** --- 780,790 ---- tty->print("%4d: %s\n", idx, n->Name()); } } #endif + uint max_idx = matcher.C->unique(); // Pull from worklist and schedule while( worklist.size() ) { // Worklist is not ready #ifndef PRODUCT if (cfg->trace_opto_pipelining()) {
*** 813,827 **** --- 820,851 ---- if( n->is_MachCall() ) { MachCallNode *mcall = n->as_MachCall(); phi_cnt = sched_call(matcher, cfg->_bbs, phi_cnt, worklist, ready_cnt, mcall, next_call); continue; } + + if (n->is_Mach() && n->as_Mach()->has_call()) { + RegMask regs; + regs.Insert(matcher.c_frame_pointer()); + regs.OR(n->out_RegMask()); + + MachProjNode *proj = new (matcher.C, 1) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj ); + cfg->_bbs.map(proj->_idx,this); + _nodes.insert(phi_cnt++, proj); + + add_call_kills(proj, regs, matcher._c_reg_save_policy, false); + } + // Children are now all ready for (DUIterator_Fast i5max, i5 = n->fast_outs(i5max); i5 < i5max; i5++) { Node* m = n->fast_out(i5); // Get user if( cfg->_bbs[m->_idx] != this ) continue; if( m->is_Phi() ) continue; + if (m->_idx > max_idx) { // new node, skip it + assert(m->is_MachProj() && n->is_Mach() && n->as_Mach()->has_call(), "unexpected node types"); + continue; + } if( !--ready_cnt[m->_idx] ) worklist.push(m); } }