comparison src/share/vm/opto/parse2.cpp @ 248:18aab3cdd513

6726504: handle do_ifxxx calls in parser more uniformly Summary: make do_ifnull() handling similar to do_if() Reviewed-by: jrose, kvn
author rasbold
date Mon, 21 Jul 2008 13:37:05 -0700
parents 9b66e6287f4a
children 3e333d6f35dd
comparison
equal deleted inserted replaced
247:02a35ad4adf8 248:18aab3cdd513
892 assert(bc_depth == 1 || argument(1) != NULL, "two must exist"); 892 assert(bc_depth == 1 || argument(1) != NULL, "two must exist");
893 _sp += bc_depth; 893 _sp += bc_depth;
894 } 894 }
895 895
896 //----------------------------------do_ifnull---------------------------------- 896 //----------------------------------do_ifnull----------------------------------
897 void Parse::do_ifnull(BoolTest::mask btest) { 897 void Parse::do_ifnull(BoolTest::mask btest, Node *c) {
898 int target_bci = iter().get_dest(); 898 int target_bci = iter().get_dest();
899 899
900 Block* branch_block = successor_for_bci(target_bci); 900 Block* branch_block = successor_for_bci(target_bci);
901 Block* next_block = successor_for_bci(iter().next_bci()); 901 Block* next_block = successor_for_bci(iter().next_bci());
902 902
904 float prob = branch_prediction(cnt, btest, target_bci); 904 float prob = branch_prediction(cnt, btest, target_bci);
905 if (prob == PROB_UNKNOWN) { 905 if (prob == PROB_UNKNOWN) {
906 // (An earlier version of do_ifnull omitted this trap for OSR methods.) 906 // (An earlier version of do_ifnull omitted this trap for OSR methods.)
907 #ifndef PRODUCT 907 #ifndef PRODUCT
908 if (PrintOpto && Verbose) 908 if (PrintOpto && Verbose)
909 tty->print_cr("Never-taken backedge stops compilation at bci %d",bci()); 909 tty->print_cr("Never-taken edge stops compilation at bci %d",bci());
910 #endif
911 // We need to mark this branch as taken so that if we recompile we will
912 // see that it is possible. In the tiered system the interpreter doesn't
913 // do profiling and by the time we get to the lower tier from the interpreter
914 // the path may be cold again. Make sure it doesn't look untaken
915 profile_taken_branch(target_bci, !ProfileInterpreter);
916 uncommon_trap(Deoptimization::Reason_unreached,
917 Deoptimization::Action_reinterpret,
918 NULL, "cold");
919 if (EliminateAutoBox) {
920 // Mark the successor blocks as parsed
921 branch_block->next_path_num();
922 next_block->next_path_num();
923 }
924 return;
925 }
926
927 // If this is a backwards branch in the bytecodes, add Safepoint
928 maybe_add_safepoint(target_bci);
929
930 explicit_null_checks_inserted++;
931 Node* a = null();
932 Node* b = pop();
933 Node* c = _gvn.transform( new (C, 3) CmpPNode(b, a) );
934
935 // Make a cast-away-nullness that is control dependent on the test
936 const Type *t = _gvn.type(b);
937 const Type *t_not_null = t->join(TypePtr::NOTNULL);
938 Node *cast = new (C, 2) CastPPNode(b,t_not_null);
939
940 // Generate real control flow
941 Node *tst = _gvn.transform( new (C, 2) BoolNode( c, btest ) );
942
943 // Sanity check the probability value
944 assert(prob > 0.0f,"Bad probability in Parser");
945 // Need xform to put node in hash table
946 IfNode *iff = create_and_xform_if( control(), tst, prob, cnt );
947 assert(iff->_prob > 0.0f,"Optimizer made bad probability in parser");
948 // True branch
949 { PreserveJVMState pjvms(this);
950 Node* iftrue = _gvn.transform( new (C, 1) IfTrueNode (iff) );
951 set_control(iftrue);
952
953 if (stopped()) { // Path is dead?
954 explicit_null_checks_elided++;
955 if (EliminateAutoBox) {
956 // Mark the successor block as parsed
957 branch_block->next_path_num();
958 }
959 } else { // Path is live.
960 // Update method data
961 profile_taken_branch(target_bci);
962 adjust_map_after_if(btest, c, prob, branch_block, next_block);
963 if (!stopped())
964 merge(target_bci);
965 }
966 }
967
968 // False branch
969 Node* iffalse = _gvn.transform( new (C, 1) IfFalseNode(iff) );
970 set_control(iffalse);
971
972 if (stopped()) { // Path is dead?
973 explicit_null_checks_elided++;
974 if (EliminateAutoBox) {
975 // Mark the successor block as parsed
976 next_block->next_path_num();
977 }
978 } else { // Path is live.
979 // Update method data
980 profile_not_taken_branch();
981 adjust_map_after_if(BoolTest(btest).negate(), c, 1.0-prob,
982 next_block, branch_block);
983 }
984 }
985
986 //------------------------------------do_if------------------------------------
987 void Parse::do_if(BoolTest::mask btest, Node* c) {
988 int target_bci = iter().get_dest();
989
990 Block* branch_block = successor_for_bci(target_bci);
991 Block* next_block = successor_for_bci(iter().next_bci());
992
993 float cnt;
994 float prob = branch_prediction(cnt, btest, target_bci);
995 float untaken_prob = 1.0 - prob;
996
997 if (prob == PROB_UNKNOWN) {
998 #ifndef PRODUCT
999 if (PrintOpto && Verbose)
1000 tty->print_cr("Never-taken backedge stops compilation at bci %d",bci());
1001 #endif 910 #endif
1002 repush_if_args(); // to gather stats on loop 911 repush_if_args(); // to gather stats on loop
1003 // We need to mark this branch as taken so that if we recompile we will 912 // We need to mark this branch as taken so that if we recompile we will
1004 // see that it is possible. In the tiered system the interpreter doesn't 913 // see that it is possible. In the tiered system the interpreter doesn't
1005 // do profiling and by the time we get to the lower tier from the interpreter 914 // do profiling and by the time we get to the lower tier from the interpreter
1013 branch_block->next_path_num(); 922 branch_block->next_path_num();
1014 next_block->next_path_num(); 923 next_block->next_path_num();
1015 } 924 }
1016 return; 925 return;
1017 } 926 }
927
928 // If this is a backwards branch in the bytecodes, add Safepoint
929 maybe_add_safepoint(target_bci);
930
931 explicit_null_checks_inserted++;
932
933 // Generate real control flow
934 Node *tst = _gvn.transform( new (C, 2) BoolNode( c, btest ) );
935
936 // Sanity check the probability value
937 assert(prob > 0.0f,"Bad probability in Parser");
938 // Need xform to put node in hash table
939 IfNode *iff = create_and_xform_if( control(), tst, prob, cnt );
940 assert(iff->_prob > 0.0f,"Optimizer made bad probability in parser");
941 // True branch
942 { PreserveJVMState pjvms(this);
943 Node* iftrue = _gvn.transform( new (C, 1) IfTrueNode (iff) );
944 set_control(iftrue);
945
946 if (stopped()) { // Path is dead?
947 explicit_null_checks_elided++;
948 if (EliminateAutoBox) {
949 // Mark the successor block as parsed
950 branch_block->next_path_num();
951 }
952 } else { // Path is live.
953 // Update method data
954 profile_taken_branch(target_bci);
955 adjust_map_after_if(btest, c, prob, branch_block, next_block);
956 if (!stopped())
957 merge(target_bci);
958 }
959 }
960
961 // False branch
962 Node* iffalse = _gvn.transform( new (C, 1) IfFalseNode(iff) );
963 set_control(iffalse);
964
965 if (stopped()) { // Path is dead?
966 explicit_null_checks_elided++;
967 if (EliminateAutoBox) {
968 // Mark the successor block as parsed
969 next_block->next_path_num();
970 }
971 } else { // Path is live.
972 // Update method data
973 profile_not_taken_branch();
974 adjust_map_after_if(BoolTest(btest).negate(), c, 1.0-prob,
975 next_block, branch_block);
976 }
977 }
978
979 //------------------------------------do_if------------------------------------
980 void Parse::do_if(BoolTest::mask btest, Node* c) {
981 int target_bci = iter().get_dest();
982
983 Block* branch_block = successor_for_bci(target_bci);
984 Block* next_block = successor_for_bci(iter().next_bci());
985
986 float cnt;
987 float prob = branch_prediction(cnt, btest, target_bci);
988 float untaken_prob = 1.0 - prob;
989
990 if (prob == PROB_UNKNOWN) {
991 #ifndef PRODUCT
992 if (PrintOpto && Verbose)
993 tty->print_cr("Never-taken edge stops compilation at bci %d",bci());
994 #endif
995 repush_if_args(); // to gather stats on loop
996 // We need to mark this branch as taken so that if we recompile we will
997 // see that it is possible. In the tiered system the interpreter doesn't
998 // do profiling and by the time we get to the lower tier from the interpreter
999 // the path may be cold again. Make sure it doesn't look untaken
1000 profile_taken_branch(target_bci, !ProfileInterpreter);
1001 uncommon_trap(Deoptimization::Reason_unreached,
1002 Deoptimization::Action_reinterpret,
1003 NULL, "cold");
1004 if (EliminateAutoBox) {
1005 // Mark the successor blocks as parsed
1006 branch_block->next_path_num();
1007 next_block->next_path_num();
1008 }
1009 return;
1010 }
1011
1012 // If this is a backwards branch in the bytecodes, add Safepoint
1013 maybe_add_safepoint(target_bci);
1018 1014
1019 // Sanity check the probability value 1015 // Sanity check the probability value
1020 assert(0.0f < prob && prob < 1.0f,"Bad probability in Parser"); 1016 assert(0.0f < prob && prob < 1.0f,"Bad probability in Parser");
1021 1017
1022 bool taken_if_true = true; 1018 bool taken_if_true = true;
2099 taken = method()->scale_count(taken); 2095 taken = method()->scale_count(taken);
2100 target_block->set_count(taken); 2096 target_block->set_count(taken);
2101 break; 2097 break;
2102 } 2098 }
2103 2099
2104 case Bytecodes::_ifnull: 2100 case Bytecodes::_ifnull: btest = BoolTest::eq; goto handle_if_null;
2105 do_ifnull(BoolTest::eq); 2101 case Bytecodes::_ifnonnull: btest = BoolTest::ne; goto handle_if_null;
2106 break; 2102 handle_if_null:
2107 case Bytecodes::_ifnonnull: 2103 a = null();
2108 do_ifnull(BoolTest::ne); 2104 b = pop();
2105 c = _gvn.transform( new (C, 3) CmpPNode(b, a) );
2106 do_ifnull(btest, c);
2109 break; 2107 break;
2110 2108
2111 case Bytecodes::_if_acmpeq: btest = BoolTest::eq; goto handle_if_acmp; 2109 case Bytecodes::_if_acmpeq: btest = BoolTest::eq; goto handle_if_acmp;
2112 case Bytecodes::_if_acmpne: btest = BoolTest::ne; goto handle_if_acmp; 2110 case Bytecodes::_if_acmpne: btest = BoolTest::ne; goto handle_if_acmp;
2113 handle_if_acmp: 2111 handle_if_acmp:
2114 // If this is a backwards branch in the bytecodes, add Safepoint
2115 maybe_add_safepoint(iter().get_dest());
2116 a = pop(); 2112 a = pop();
2117 b = pop(); 2113 b = pop();
2118 c = _gvn.transform( new (C, 3) CmpPNode(b, a) ); 2114 c = _gvn.transform( new (C, 3) CmpPNode(b, a) );
2119 do_if(btest, c); 2115 do_if(btest, c);
2120 break; 2116 break;
2124 case Bytecodes::_iflt: btest = BoolTest::lt; goto handle_ifxx; 2120 case Bytecodes::_iflt: btest = BoolTest::lt; goto handle_ifxx;
2125 case Bytecodes::_ifle: btest = BoolTest::le; goto handle_ifxx; 2121 case Bytecodes::_ifle: btest = BoolTest::le; goto handle_ifxx;
2126 case Bytecodes::_ifgt: btest = BoolTest::gt; goto handle_ifxx; 2122 case Bytecodes::_ifgt: btest = BoolTest::gt; goto handle_ifxx;
2127 case Bytecodes::_ifge: btest = BoolTest::ge; goto handle_ifxx; 2123 case Bytecodes::_ifge: btest = BoolTest::ge; goto handle_ifxx;
2128 handle_ifxx: 2124 handle_ifxx:
2129 // If this is a backwards branch in the bytecodes, add Safepoint
2130 maybe_add_safepoint(iter().get_dest());
2131 a = _gvn.intcon(0); 2125 a = _gvn.intcon(0);
2132 b = pop(); 2126 b = pop();
2133 c = _gvn.transform( new (C, 3) CmpINode(b, a) ); 2127 c = _gvn.transform( new (C, 3) CmpINode(b, a) );
2134 do_if(btest, c); 2128 do_if(btest, c);
2135 break; 2129 break;
2139 case Bytecodes::_if_icmplt: btest = BoolTest::lt; goto handle_if_icmp; 2133 case Bytecodes::_if_icmplt: btest = BoolTest::lt; goto handle_if_icmp;
2140 case Bytecodes::_if_icmple: btest = BoolTest::le; goto handle_if_icmp; 2134 case Bytecodes::_if_icmple: btest = BoolTest::le; goto handle_if_icmp;
2141 case Bytecodes::_if_icmpgt: btest = BoolTest::gt; goto handle_if_icmp; 2135 case Bytecodes::_if_icmpgt: btest = BoolTest::gt; goto handle_if_icmp;
2142 case Bytecodes::_if_icmpge: btest = BoolTest::ge; goto handle_if_icmp; 2136 case Bytecodes::_if_icmpge: btest = BoolTest::ge; goto handle_if_icmp;
2143 handle_if_icmp: 2137 handle_if_icmp:
2144 // If this is a backwards branch in the bytecodes, add Safepoint
2145 maybe_add_safepoint(iter().get_dest());
2146 a = pop(); 2138 a = pop();
2147 b = pop(); 2139 b = pop();
2148 c = _gvn.transform( new (C, 3) CmpINode( b, a ) ); 2140 c = _gvn.transform( new (C, 3) CmpINode( b, a ) );
2149 do_if(btest, c); 2141 do_if(btest, c);
2150 break; 2142 break;