comparison src/share/vm/opto/lcm.cpp @ 12167:650868c062a9

8023691: Create interface for nodes in class Block Summary: Create public methods for accessing the nodes in a block Reviewed-by: kvn, roland
author adlertz
date Mon, 26 Aug 2013 12:50:23 +0200
parents adb9a7d94cb5
children 4b078f877b56
comparison
equal deleted inserted replaced
12161:e1fbb86b47e4 12167:650868c062a9
73 bool was_store; // Memory op is a store op 73 bool was_store; // Memory op is a store op
74 74
75 // Get the successor block for if the test ptr is non-null 75 // Get the successor block for if the test ptr is non-null
76 Block* not_null_block; // this one goes with the proj 76 Block* not_null_block; // this one goes with the proj
77 Block* null_block; 77 Block* null_block;
78 if (_nodes[_nodes.size()-1] == proj) { 78 if (get_node(number_of_nodes()-1) == proj) {
79 null_block = _succs[0]; 79 null_block = _succs[0];
80 not_null_block = _succs[1]; 80 not_null_block = _succs[1];
81 } else { 81 } else {
82 assert(_nodes[_nodes.size()-2] == proj, "proj is one or the other"); 82 assert(get_node(number_of_nodes()-2) == proj, "proj is one or the other");
83 not_null_block = _succs[0]; 83 not_null_block = _succs[0];
84 null_block = _succs[1]; 84 null_block = _succs[1];
85 } 85 }
86 while (null_block->is_Empty() == Block::empty_with_goto) { 86 while (null_block->is_Empty() == Block::empty_with_goto) {
87 null_block = null_block->_succs[0]; 87 null_block = null_block->_succs[0];
92 // we need an uncommon trap. Briefly, we need a way to 92 // we need an uncommon trap. Briefly, we need a way to
93 // detect failure of this optimization, as in 6366351.) 93 // detect failure of this optimization, as in 6366351.)
94 { 94 {
95 bool found_trap = false; 95 bool found_trap = false;
96 for (uint i1 = 0; i1 < null_block->_nodes.size(); i1++) { 96 for (uint i1 = 0; i1 < null_block->_nodes.size(); i1++) {
97 Node* nn = null_block->_nodes[i1]; 97 Node* nn = null_block->get_node(i1);
98 if (nn->is_MachCall() && 98 if (nn->is_MachCall() &&
99 nn->as_MachCall()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point()) { 99 nn->as_MachCall()->entry_point() == SharedRuntime::uncommon_trap_blob()->entry_point()) {
100 const Type* trtype = nn->in(TypeFunc::Parms)->bottom_type(); 100 const Type* trtype = nn->in(TypeFunc::Parms)->bottom_type();
101 if (trtype->isa_int() && trtype->is_int()->is_con()) { 101 if (trtype->isa_int() && trtype->is_int()->is_con()) {
102 jint tr_con = trtype->is_int()->get_con(); 102 jint tr_con = trtype->is_int()->get_con();
280 // mach use (faulting) trying to hoist 280 // mach use (faulting) trying to hoist
281 // n might be blocker to hoisting 281 // n might be blocker to hoisting
282 while( b != this ) { 282 while( b != this ) {
283 uint k; 283 uint k;
284 for( k = 1; k < b->_nodes.size(); k++ ) { 284 for( k = 1; k < b->_nodes.size(); k++ ) {
285 Node *n = b->_nodes[k]; 285 Node *n = b->get_node(k);
286 if( n->needs_anti_dependence_check() && 286 if( n->needs_anti_dependence_check() &&
287 n->in(LoadNode::Memory) == mach->in(StoreNode::Memory) ) 287 n->in(LoadNode::Memory) == mach->in(StoreNode::Memory) )
288 break; // Found anti-dependent load 288 break; // Found anti-dependent load
289 } 289 }
290 if( k < b->_nodes.size() ) 290 if( k < b->_nodes.size() )
342 old_block->find_remove(best); 342 old_block->find_remove(best);
343 add_inst(best); 343 add_inst(best);
344 cfg->map_node_to_block(best, this); 344 cfg->map_node_to_block(best, this);
345 345
346 // Move the control dependence 346 // Move the control dependence
347 if (best->in(0) && best->in(0) == old_block->_nodes[0]) 347 if (best->in(0) && best->in(0) == old_block->head())
348 best->set_req(0, _nodes[0]); 348 best->set_req(0, head());
349 349
350 // Check for flag-killing projections that also need to be hoisted 350 // Check for flag-killing projections that also need to be hoisted
351 // Should be DU safe because no edge updates. 351 // Should be DU safe because no edge updates.
352 for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) { 352 for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) {
353 Node* n = best->fast_out(j); 353 Node* n = best->fast_out(j);
366 // NULL checks are always branch-if-eq. If we see a IfTrue projection 366 // NULL checks are always branch-if-eq. If we see a IfTrue projection
367 // then we are replacing a 'ne' test with a 'eq' NULL check test. 367 // then we are replacing a 'ne' test with a 'eq' NULL check test.
368 // We need to flip the projections to keep the same semantics. 368 // We need to flip the projections to keep the same semantics.
369 if( proj->Opcode() == Op_IfTrue ) { 369 if( proj->Opcode() == Op_IfTrue ) {
370 // Swap order of projections in basic block to swap branch targets 370 // Swap order of projections in basic block to swap branch targets
371 Node *tmp1 = _nodes[end_idx()+1]; 371 Node *tmp1 = get_node(end_idx()+1);
372 Node *tmp2 = _nodes[end_idx()+2]; 372 Node *tmp2 = get_node(end_idx()+2);
373 _nodes.map(end_idx()+1, tmp2); 373 _nodes.map(end_idx()+1, tmp2);
374 _nodes.map(end_idx()+2, tmp1); 374 _nodes.map(end_idx()+2, tmp1);
375 Node *tmp = new (C) Node(C->top()); // Use not NULL input 375 Node *tmp = new (C) Node(C->top()); // Use not NULL input
376 tmp1->replace_by(tmp); 376 tmp1->replace_by(tmp);
377 tmp2->replace_by(tmp1); 377 tmp2->replace_by(tmp1);
622 // Set all registers killed and not already defined by the call. 622 // Set all registers killed and not already defined by the call.
623 uint r_cnt = mcall->tf()->range()->cnt(); 623 uint r_cnt = mcall->tf()->range()->cnt();
624 int op = mcall->ideal_Opcode(); 624 int op = mcall->ideal_Opcode();
625 MachProjNode *proj = new (matcher.C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj ); 625 MachProjNode *proj = new (matcher.C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj );
626 cfg->map_node_to_block(proj, this); 626 cfg->map_node_to_block(proj, this);
627 _nodes.insert(node_cnt++, proj); 627 insert_node(proj, node_cnt++);
628 628
629 // Select the right register save policy. 629 // Select the right register save policy.
630 const char * save_policy; 630 const char * save_policy;
631 switch (op) { 631 switch (op) {
632 case Op_CallRuntime: 632 case Op_CallRuntime:
683 #ifndef PRODUCT 683 #ifndef PRODUCT
684 if (cfg->trace_opto_pipelining()) { 684 if (cfg->trace_opto_pipelining()) {
685 tty->print_cr("# --- schedule_local B%d, before: ---", _pre_order); 685 tty->print_cr("# --- schedule_local B%d, before: ---", _pre_order);
686 for (uint i = 0;i < _nodes.size();i++) { 686 for (uint i = 0;i < _nodes.size();i++) {
687 tty->print("# "); 687 tty->print("# ");
688 _nodes[i]->fast_dump(); 688 get_node(i)->fast_dump();
689 } 689 }
690 tty->print_cr("#"); 690 tty->print_cr("#");
691 } 691 }
692 #endif 692 #endif
693 693
697 // Move PhiNodes and ParmNodes from 1 to cnt up to the start 697 // Move PhiNodes and ParmNodes from 1 to cnt up to the start
698 uint node_cnt = end_idx(); 698 uint node_cnt = end_idx();
699 uint phi_cnt = 1; 699 uint phi_cnt = 1;
700 uint i; 700 uint i;
701 for( i = 1; i<node_cnt; i++ ) { // Scan for Phi 701 for( i = 1; i<node_cnt; i++ ) { // Scan for Phi
702 Node *n = _nodes[i]; 702 Node *n = get_node(i);
703 if( n->is_Phi() || // Found a PhiNode or ParmNode 703 if( n->is_Phi() || // Found a PhiNode or ParmNode
704 (n->is_Proj() && n->in(0) == head()) ) { 704 (n->is_Proj() && n->in(0) == head()) ) {
705 // Move guy at 'phi_cnt' to the end; makes a hole at phi_cnt 705 // Move guy at 'phi_cnt' to the end; makes a hole at phi_cnt
706 _nodes.map(i,_nodes[phi_cnt]); 706 _nodes.map(i,get_node(phi_cnt));
707 _nodes.map(phi_cnt++,n); // swap Phi/Parm up front 707 _nodes.map(phi_cnt++,n); // swap Phi/Parm up front
708 } else { // All others 708 } else { // All others
709 // Count block-local inputs to 'n' 709 // Count block-local inputs to 'n'
710 uint cnt = n->len(); // Input count 710 uint cnt = n->len(); // Input count
711 uint local = 0; 711 uint local = 0;
746 n->add_prec(x); 746 n->add_prec(x);
747 } 747 }
748 } 748 }
749 } 749 }
750 for(uint i2=i; i2<_nodes.size(); i2++ ) // Trailing guys get zapped count 750 for(uint i2=i; i2<_nodes.size(); i2++ ) // Trailing guys get zapped count
751 ready_cnt.at_put(_nodes[i2]->_idx, 0); 751 ready_cnt.at_put(get_node(i2)->_idx, 0);
752 752
753 // All the prescheduled guys do not hold back internal nodes 753 // All the prescheduled guys do not hold back internal nodes
754 uint i3; 754 uint i3;
755 for(i3 = 0; i3<phi_cnt; i3++ ) { // For all pre-scheduled 755 for(i3 = 0; i3<phi_cnt; i3++ ) { // For all pre-scheduled
756 Node *n = _nodes[i3]; // Get pre-scheduled 756 Node *n = get_node(i3); // Get pre-scheduled
757 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { 757 for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
758 Node* m = n->fast_out(j); 758 Node* m = n->fast_out(j);
759 if (cfg->get_block_for_node(m) == this) { // Local-block user 759 if (cfg->get_block_for_node(m) == this) { // Local-block user
760 int m_cnt = ready_cnt.at(m->_idx)-1; 760 int m_cnt = ready_cnt.at(m->_idx)-1;
761 ready_cnt.at_put(m->_idx, m_cnt); // Fix ready count 761 ready_cnt.at_put(m->_idx, m_cnt); // Fix ready count
765 765
766 Node_List delay; 766 Node_List delay;
767 // Make a worklist 767 // Make a worklist
768 Node_List worklist; 768 Node_List worklist;
769 for(uint i4=i3; i4<node_cnt; i4++ ) { // Put ready guys on worklist 769 for(uint i4=i3; i4<node_cnt; i4++ ) { // Put ready guys on worklist
770 Node *m = _nodes[i4]; 770 Node *m = get_node(i4);
771 if( !ready_cnt.at(m->_idx) ) { // Zero ready count? 771 if( !ready_cnt.at(m->_idx) ) { // Zero ready count?
772 if (m->is_iteratively_computed()) { 772 if (m->is_iteratively_computed()) {
773 // Push induction variable increments last to allow other uses 773 // Push induction variable increments last to allow other uses
774 // of the phi to be scheduled first. The select() method breaks 774 // of the phi to be scheduled first. The select() method breaks
775 // ties in scheduling by worklist order. 775 // ties in scheduling by worklist order.
787 Node* d = delay.pop(); 787 Node* d = delay.pop();
788 worklist.push(d); 788 worklist.push(d);
789 } 789 }
790 790
791 // Warm up the 'next_call' heuristic bits 791 // Warm up the 'next_call' heuristic bits
792 needed_for_next_call(_nodes[0], next_call, cfg); 792 needed_for_next_call(head(), next_call, cfg);
793 793
794 #ifndef PRODUCT 794 #ifndef PRODUCT
795 if (cfg->trace_opto_pipelining()) { 795 if (cfg->trace_opto_pipelining()) {
796 for (uint j=0; j<_nodes.size(); j++) { 796 for (uint j=0; j<_nodes.size(); j++) {
797 Node *n = _nodes[j]; 797 Node *n = get_node(j);
798 int idx = n->_idx; 798 int idx = n->_idx;
799 tty->print("# ready cnt:%3d ", ready_cnt.at(idx)); 799 tty->print("# ready cnt:%3d ", ready_cnt.at(idx));
800 tty->print("latency:%3d ", cfg->get_latency_for_node(n)); 800 tty->print("latency:%3d ", cfg->get_latency_for_node(n));
801 tty->print("%4d: %s\n", idx, n->Name()); 801 tty->print("%4d: %s\n", idx, n->Name());
802 } 802 }
849 regs.Insert(matcher.c_frame_pointer()); 849 regs.Insert(matcher.c_frame_pointer());
850 regs.OR(n->out_RegMask()); 850 regs.OR(n->out_RegMask());
851 851
852 MachProjNode *proj = new (matcher.C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj ); 852 MachProjNode *proj = new (matcher.C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj );
853 cfg->map_node_to_block(proj, this); 853 cfg->map_node_to_block(proj, this);
854 _nodes.insert(phi_cnt++, proj); 854 insert_node(proj, phi_cnt++);
855 855
856 add_call_kills(proj, regs, matcher._c_reg_save_policy, false); 856 add_call_kills(proj, regs, matcher._c_reg_save_policy, false);
857 } 857 }
858 858
859 // Children are now all ready 859 // Children are now all ready
891 if (cfg->trace_opto_pipelining()) { 891 if (cfg->trace_opto_pipelining()) {
892 tty->print_cr("#"); 892 tty->print_cr("#");
893 tty->print_cr("# after schedule_local"); 893 tty->print_cr("# after schedule_local");
894 for (uint i = 0;i < _nodes.size();i++) { 894 for (uint i = 0;i < _nodes.size();i++) {
895 tty->print("# "); 895 tty->print("# ");
896 _nodes[i]->fast_dump(); 896 get_node(i)->fast_dump();
897 } 897 }
898 tty->cr(); 898 tty->cr();
899 } 899 }
900 #endif 900 #endif
901 901
950 } 950 }
951 951
952 // Check to see if the use_blk already has an identical phi inserted. 952 // Check to see if the use_blk already has an identical phi inserted.
953 // If it exists, it will be at the first position since all uses of a 953 // If it exists, it will be at the first position since all uses of a
954 // def are processed together. 954 // def are processed together.
955 Node *phi = use_blk->_nodes[1]; 955 Node *phi = use_blk->get_node(1);
956 if( phi->is_Phi() ) { 956 if( phi->is_Phi() ) {
957 fixup = phi; 957 fixup = phi;
958 for (uint k = 1; k < use_blk->num_preds(); k++) { 958 for (uint k = 1; k < use_blk->num_preds(); k++) {
959 if (phi->in(k) != inputs[k]) { 959 if (phi->in(k) != inputs[k]) {
960 // Not a match 960 // Not a match
965 } 965 }
966 966
967 // If an existing PhiNode was not found, make a new one. 967 // If an existing PhiNode was not found, make a new one.
968 if (fixup == NULL) { 968 if (fixup == NULL) {
969 Node *new_phi = PhiNode::make(use_blk->head(), def); 969 Node *new_phi = PhiNode::make(use_blk->head(), def);
970 use_blk->_nodes.insert(1, new_phi); 970 use_blk->insert_node(new_phi, 1);
971 cfg->map_node_to_block(new_phi, use_blk); 971 cfg->map_node_to_block(new_phi, use_blk);
972 for (uint k = 1; k < use_blk->num_preds(); k++) { 972 for (uint k = 1; k < use_blk->num_preds(); k++) {
973 new_phi->set_req(k, inputs[k]); 973 new_phi->set_req(k, inputs[k]);
974 } 974 }
975 fixup = new_phi; 975 fixup = new_phi;
976 } 976 }
977 977
978 } else { 978 } else {
979 // Found the use just below the Catch. Make it use the clone. 979 // Found the use just below the Catch. Make it use the clone.
980 fixup = use_blk->_nodes[n_clone_idx]; 980 fixup = use_blk->get_node(n_clone_idx);
981 } 981 }
982 982
983 return fixup; 983 return fixup;
984 } 984 }
985 985
995 uint use_idx = blk->find_node(use); 995 uint use_idx = blk->find_node(use);
996 uint offset_idx = use_idx - beg; 996 uint offset_idx = use_idx - beg;
997 for( uint k = 0; k < blk->_num_succs; k++ ) { 997 for( uint k = 0; k < blk->_num_succs; k++ ) {
998 // Get clone in each successor block 998 // Get clone in each successor block
999 Block *sb = blk->_succs[k]; 999 Block *sb = blk->_succs[k];
1000 Node *clone = sb->_nodes[offset_idx+1]; 1000 Node *clone = sb->get_node(offset_idx+1);
1001 assert( clone->Opcode() == use->Opcode(), "" ); 1001 assert( clone->Opcode() == use->Opcode(), "" );
1002 1002
1003 // Make use-clone reference the def-clone 1003 // Make use-clone reference the def-clone
1004 catch_cleanup_fix_all_inputs(clone, def, sb->_nodes[n_clone_idx]); 1004 catch_cleanup_fix_all_inputs(clone, def, sb->get_node(n_clone_idx));
1005 } 1005 }
1006 } 1006 }
1007 1007
1008 //------------------------------catch_cleanup_inter_block--------------------- 1008 //------------------------------catch_cleanup_inter_block---------------------
1009 // Fix all input edges in use that reference "def". The use is in a different 1009 // Fix all input edges in use that reference "def". The use is in a different
1020 // clone the instructions on all paths below the Catch. 1020 // clone the instructions on all paths below the Catch.
1021 void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) { 1021 void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) {
1022 1022
1023 // End of region to clone 1023 // End of region to clone
1024 uint end = end_idx(); 1024 uint end = end_idx();
1025 if( !_nodes[end]->is_Catch() ) return; 1025 if( !get_node(end)->is_Catch() ) return;
1026 // Start of region to clone 1026 // Start of region to clone
1027 uint beg = end; 1027 uint beg = end;
1028 while(!_nodes[beg-1]->is_MachProj() || 1028 while(!get_node(beg-1)->is_MachProj() ||
1029 !_nodes[beg-1]->in(0)->is_MachCall() ) { 1029 !get_node(beg-1)->in(0)->is_MachCall() ) {
1030 beg--; 1030 beg--;
1031 assert(beg > 0,"Catch cleanup walking beyond block boundary"); 1031 assert(beg > 0,"Catch cleanup walking beyond block boundary");
1032 } 1032 }
1033 // Range of inserted instructions is [beg, end) 1033 // Range of inserted instructions is [beg, end)
1034 if( beg == end ) return; 1034 if( beg == end ) return;
1039 Block *sb = _succs[i]; 1039 Block *sb = _succs[i];
1040 // Clone the entire area; ignoring the edge fixup for now. 1040 // Clone the entire area; ignoring the edge fixup for now.
1041 for( uint j = end; j > beg; j-- ) { 1041 for( uint j = end; j > beg; j-- ) {
1042 // It is safe here to clone a node with anti_dependence 1042 // It is safe here to clone a node with anti_dependence
1043 // since clones dominate on each path. 1043 // since clones dominate on each path.
1044 Node *clone = _nodes[j-1]->clone(); 1044 Node *clone = get_node(j-1)->clone();
1045 sb->_nodes.insert( 1, clone ); 1045 sb->insert_node(clone, 1);
1046 cfg->map_node_to_block(clone, sb); 1046 cfg->map_node_to_block(clone, sb);
1047 } 1047 }
1048 } 1048 }
1049 1049
1050 1050
1051 // Fixup edges. Check the def-use info per cloned Node 1051 // Fixup edges. Check the def-use info per cloned Node
1052 for(uint i2 = beg; i2 < end; i2++ ) { 1052 for(uint i2 = beg; i2 < end; i2++ ) {
1053 uint n_clone_idx = i2-beg+1; // Index of clone of n in each successor block 1053 uint n_clone_idx = i2-beg+1; // Index of clone of n in each successor block
1054 Node *n = _nodes[i2]; // Node that got cloned 1054 Node *n = get_node(i2); // Node that got cloned
1055 // Need DU safe iterator because of edge manipulation in calls. 1055 // Need DU safe iterator because of edge manipulation in calls.
1056 Unique_Node_List *out = new Unique_Node_List(Thread::current()->resource_area()); 1056 Unique_Node_List *out = new Unique_Node_List(Thread::current()->resource_area());
1057 for (DUIterator_Fast j1max, j1 = n->fast_outs(j1max); j1 < j1max; j1++) { 1057 for (DUIterator_Fast j1max, j1 = n->fast_outs(j1max); j1 < j1max; j1++) {
1058 out->push(n->fast_out(j1)); 1058 out->push(n->fast_out(j1));
1059 } 1059 }
1079 1079
1080 } // End of for all Nodes in cloned area 1080 } // End of for all Nodes in cloned area
1081 1081
1082 // Remove the now-dead cloned ops 1082 // Remove the now-dead cloned ops
1083 for(uint i3 = beg; i3 < end; i3++ ) { 1083 for(uint i3 = beg; i3 < end; i3++ ) {
1084 _nodes[beg]->disconnect_inputs(NULL, C); 1084 get_node(beg)->disconnect_inputs(NULL, C);
1085 _nodes.remove(beg); 1085 remove_node(beg);
1086 } 1086 }
1087 1087
1088 // If the successor blocks have a CreateEx node, move it back to the top 1088 // If the successor blocks have a CreateEx node, move it back to the top
1089 for(uint i4 = 0; i4 < _num_succs; i4++ ) { 1089 for(uint i4 = 0; i4 < _num_succs; i4++ ) {
1090 Block *sb = _succs[i4]; 1090 Block *sb = _succs[i4];
1091 uint new_cnt = end - beg; 1091 uint new_cnt = end - beg;
1092 // Remove any newly created, but dead, nodes. 1092 // Remove any newly created, but dead, nodes.
1093 for( uint j = new_cnt; j > 0; j-- ) { 1093 for( uint j = new_cnt; j > 0; j-- ) {
1094 Node *n = sb->_nodes[j]; 1094 Node *n = sb->get_node(j);
1095 if (n->outcnt() == 0 && 1095 if (n->outcnt() == 0 &&
1096 (!n->is_Proj() || n->as_Proj()->in(0)->outcnt() == 1) ){ 1096 (!n->is_Proj() || n->as_Proj()->in(0)->outcnt() == 1) ){
1097 n->disconnect_inputs(NULL, C); 1097 n->disconnect_inputs(NULL, C);
1098 sb->_nodes.remove(j); 1098 sb->remove_node(j);
1099 new_cnt--; 1099 new_cnt--;
1100 } 1100 }
1101 } 1101 }
1102 // If any newly created nodes remain, move the CreateEx node to the top 1102 // If any newly created nodes remain, move the CreateEx node to the top
1103 if (new_cnt > 0) { 1103 if (new_cnt > 0) {
1104 Node *cex = sb->_nodes[1+new_cnt]; 1104 Node *cex = sb->get_node(1+new_cnt);
1105 if( cex->is_Mach() && cex->as_Mach()->ideal_Opcode() == Op_CreateEx ) { 1105 if( cex->is_Mach() && cex->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
1106 sb->_nodes.remove(1+new_cnt); 1106 sb->remove_node(1+new_cnt);
1107 sb->_nodes.insert(1,cex); 1107 sb->insert_node(cex, 1);
1108 } 1108 }
1109 } 1109 }
1110 } 1110 }
1111 } 1111 }