comparison src/share/vm/opto/lcm.cpp @ 4120:f03a3c8bd5e5

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: twisti, never
author roland
date Wed, 14 Sep 2011 09:22:51 +0200
parents c7b60b601eb4
children cf407b7d3d78
comparison
equal deleted inserted replaced
4119:7793051af7d6 4120:f03a3c8bd5e5
546 if (call == NULL) return; // No next call (e.g., block end is near) 546 if (call == NULL) return; // No next call (e.g., block end is near)
547 // Set next-call for all inputs to this call 547 // Set next-call for all inputs to this call
548 set_next_call(call, next_call, bbs); 548 set_next_call(call, next_call, bbs);
549 } 549 }
550 550
551 //------------------------------add_call_kills-------------------------------------
552 void Block::add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe) {
553 // Fill in the kill mask for the call
554 for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) {
555 if( !regs.Member(r) ) { // Not already defined by the call
556 // Save-on-call register?
557 if ((save_policy[r] == 'C') ||
558 (save_policy[r] == 'A') ||
559 ((save_policy[r] == 'E') && exclude_soe)) {
560 proj->_rout.Insert(r);
561 }
562 }
563 }
564 }
565
566
551 //------------------------------sched_call------------------------------------- 567 //------------------------------sched_call-------------------------------------
552 uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, int *ready_cnt, MachCallNode *mcall, VectorSet &next_call ) { 568 uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, int *ready_cnt, MachCallNode *mcall, VectorSet &next_call ) {
553 RegMask regs; 569 RegMask regs;
554 570
555 // Schedule all the users of the call right now. All the users are 571 // Schedule all the users of the call right now. All the users are
629 MachCallStaticJavaNode* mcallstaticjava = (MachCallStaticJavaNode*) mcall; 645 MachCallStaticJavaNode* mcallstaticjava = (MachCallStaticJavaNode*) mcall;
630 if (mcallstaticjava->_method_handle_invoke) 646 if (mcallstaticjava->_method_handle_invoke)
631 proj->_rout.OR(Matcher::method_handle_invoke_SP_save_mask()); 647 proj->_rout.OR(Matcher::method_handle_invoke_SP_save_mask());
632 } 648 }
633 649
634 // Fill in the kill mask for the call 650 add_call_kills(proj, regs, save_policy, exclude_soe);
635 for( OptoReg::Name r = OptoReg::Name(0); r < _last_Mach_Reg; r=OptoReg::add(r,1) ) {
636 if( !regs.Member(r) ) { // Not already defined by the call
637 // Save-on-call register?
638 if ((save_policy[r] == 'C') ||
639 (save_policy[r] == 'A') ||
640 ((save_policy[r] == 'E') && exclude_soe)) {
641 proj->_rout.Insert(r);
642 }
643 }
644 }
645 651
646 return node_cnt; 652 return node_cnt;
647 } 653 }
648 654
649 655
774 tty->print("%4d: %s\n", idx, n->Name()); 780 tty->print("%4d: %s\n", idx, n->Name());
775 } 781 }
776 } 782 }
777 #endif 783 #endif
778 784
785 uint max_idx = matcher.C->unique();
779 // Pull from worklist and schedule 786 // Pull from worklist and schedule
780 while( worklist.size() ) { // Worklist is not ready 787 while( worklist.size() ) { // Worklist is not ready
781 788
782 #ifndef PRODUCT 789 #ifndef PRODUCT
783 if (cfg->trace_opto_pipelining()) { 790 if (cfg->trace_opto_pipelining()) {
813 if( n->is_MachCall() ) { 820 if( n->is_MachCall() ) {
814 MachCallNode *mcall = n->as_MachCall(); 821 MachCallNode *mcall = n->as_MachCall();
815 phi_cnt = sched_call(matcher, cfg->_bbs, phi_cnt, worklist, ready_cnt, mcall, next_call); 822 phi_cnt = sched_call(matcher, cfg->_bbs, phi_cnt, worklist, ready_cnt, mcall, next_call);
816 continue; 823 continue;
817 } 824 }
825
826 if (n->is_Mach() && n->as_Mach()->has_call()) {
827 RegMask regs;
828 regs.Insert(matcher.c_frame_pointer());
829 regs.OR(n->out_RegMask());
830
831 MachProjNode *proj = new (matcher.C, 1) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj );
832 cfg->_bbs.map(proj->_idx,this);
833 _nodes.insert(phi_cnt++, proj);
834
835 add_call_kills(proj, regs, matcher._c_reg_save_policy, false);
836 }
837
818 // Children are now all ready 838 // Children are now all ready
819 for (DUIterator_Fast i5max, i5 = n->fast_outs(i5max); i5 < i5max; i5++) { 839 for (DUIterator_Fast i5max, i5 = n->fast_outs(i5max); i5 < i5max; i5++) {
820 Node* m = n->fast_out(i5); // Get user 840 Node* m = n->fast_out(i5); // Get user
821 if( cfg->_bbs[m->_idx] != this ) continue; 841 if( cfg->_bbs[m->_idx] != this ) continue;
822 if( m->is_Phi() ) continue; 842 if( m->is_Phi() ) continue;
843 if (m->_idx > max_idx) { // new node, skip it
844 assert(m->is_MachProj() && n->is_Mach() && n->as_Mach()->has_call(), "unexpected node types");
845 continue;
846 }
823 if( !--ready_cnt[m->_idx] ) 847 if( !--ready_cnt[m->_idx] )
824 worklist.push(m); 848 worklist.push(m);
825 } 849 }
826 } 850 }
827 851