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