Mercurial > hg > truffle
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 |