comparison src/share/vm/c1/c1_GraphBuilder.cpp @ 1783:d5d065957597

6953144: Tiered compilation Summary: Infrastructure for tiered compilation support (interpreter + c1 + c2) for 32 and 64 bit. Simple tiered policy implementation. Reviewed-by: kvn, never, phh, twisti
author iveresov
date Fri, 03 Sep 2010 17:51:07 -0700
parents 136b78722a08
children 3a294e483abc
comparison
equal deleted inserted replaced
1782:f353275af40e 1783:d5d065957597
1142 store_local(intType, index); 1142 store_local(intType, index);
1143 } 1143 }
1144 1144
1145 1145
1146 void GraphBuilder::_goto(int from_bci, int to_bci) { 1146 void GraphBuilder::_goto(int from_bci, int to_bci) {
1147 profile_bci(from_bci); 1147 Goto *x = new Goto(block_at(to_bci), to_bci <= from_bci);
1148 append(new Goto(block_at(to_bci), to_bci <= from_bci)); 1148 if (is_profiling()) {
1149 compilation()->set_would_profile(true);
1150 }
1151 if (profile_branches()) {
1152 x->set_profiled_method(method());
1153 x->set_profiled_bci(bci());
1154 x->set_should_profile(true);
1155 }
1156 append(x);
1149 } 1157 }
1150 1158
1151 1159
1152 void GraphBuilder::if_node(Value x, If::Condition cond, Value y, ValueStack* state_before) { 1160 void GraphBuilder::if_node(Value x, If::Condition cond, Value y, ValueStack* state_before) {
1153 BlockBegin* tsux = block_at(stream()->get_dest()); 1161 BlockBegin* tsux = block_at(stream()->get_dest());
1154 BlockBegin* fsux = block_at(stream()->next_bci()); 1162 BlockBegin* fsux = block_at(stream()->next_bci());
1155 bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci(); 1163 bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci();
1156 If* if_node = append(new If(x, cond, false, y, tsux, fsux, is_bb ? state_before : NULL, is_bb))->as_If(); 1164 Instruction *i = append(new If(x, cond, false, y, tsux, fsux, is_bb ? state_before : NULL, is_bb));
1157 if (profile_branches() && (if_node != NULL)) { 1165
1158 if_node->set_profiled_method(method()); 1166 if (is_profiling()) {
1159 if_node->set_profiled_bci(bci()); 1167 If* if_node = i->as_If();
1160 if_node->set_should_profile(true); 1168 if (if_node != NULL) {
1169 // Note that we'd collect profile data in this method if we wanted it.
1170 compilation()->set_would_profile(true);
1171 // At level 2 we need the proper bci to count backedges
1172 if_node->set_profiled_bci(bci());
1173 if (profile_branches()) {
1174 // Successors can be rotated by the canonicalizer, check for this case.
1175 if_node->set_profiled_method(method());
1176 if_node->set_should_profile(true);
1177 if (if_node->tsux() == fsux) {
1178 if_node->set_swapped(true);
1179 }
1180 }
1181 return;
1182 }
1183
1184 // Check if this If was reduced to Goto.
1185 Goto *goto_node = i->as_Goto();
1186 if (goto_node != NULL) {
1187 compilation()->set_would_profile(true);
1188 if (profile_branches()) {
1189 goto_node->set_profiled_method(method());
1190 goto_node->set_profiled_bci(bci());
1191 goto_node->set_should_profile(true);
1192 // Find out which successor is used.
1193 if (goto_node->default_sux() == tsux) {
1194 goto_node->set_direction(Goto::taken);
1195 } else if (goto_node->default_sux() == fsux) {
1196 goto_node->set_direction(Goto::not_taken);
1197 } else {
1198 ShouldNotReachHere();
1199 }
1200 }
1201 return;
1202 }
1161 } 1203 }
1162 } 1204 }
1163 1205
1164 1206
1165 void GraphBuilder::if_zero(ValueType* type, If::Condition cond) { 1207 void GraphBuilder::if_zero(ValueType* type, If::Condition cond) {
1696 } 1738 }
1697 #endif 1739 #endif
1698 1740
1699 if (recv != NULL && 1741 if (recv != NULL &&
1700 (code == Bytecodes::_invokespecial || 1742 (code == Bytecodes::_invokespecial ||
1701 !is_loaded || target->is_final() || 1743 !is_loaded || target->is_final())) {
1702 profile_calls())) {
1703 // invokespecial always needs a NULL check. invokevirtual where 1744 // invokespecial always needs a NULL check. invokevirtual where
1704 // the target is final or where it's not known that whether the 1745 // the target is final or where it's not known that whether the
1705 // target is final requires a NULL check. Otherwise normal 1746 // target is final requires a NULL check. Otherwise normal
1706 // invokevirtual will perform the null check during the lookup 1747 // invokevirtual will perform the null check during the lookup
1707 // logic or the unverified entry point. Profiling of calls 1748 // logic or the unverified entry point. Profiling of calls
1708 // requires that the null check is performed in all cases. 1749 // requires that the null check is performed in all cases.
1709 null_check(recv); 1750 null_check(recv);
1710 } 1751 }
1711 1752
1712 if (profile_calls()) { 1753 if (is_profiling()) {
1713 assert(cha_monomorphic_target == NULL || exact_target == NULL, "both can not be set"); 1754 if (recv != NULL && profile_calls()) {
1714 ciKlass* target_klass = NULL; 1755 null_check(recv);
1715 if (cha_monomorphic_target != NULL) { 1756 }
1716 target_klass = cha_monomorphic_target->holder(); 1757 // Note that we'd collect profile data in this method if we wanted it.
1717 } else if (exact_target != NULL) { 1758 compilation()->set_would_profile(true);
1718 target_klass = exact_target->holder(); 1759
1719 } 1760 if (profile_calls()) {
1720 profile_call(recv, target_klass); 1761 assert(cha_monomorphic_target == NULL || exact_target == NULL, "both can not be set");
1762 ciKlass* target_klass = NULL;
1763 if (cha_monomorphic_target != NULL) {
1764 target_klass = cha_monomorphic_target->holder();
1765 } else if (exact_target != NULL) {
1766 target_klass = exact_target->holder();
1767 }
1768 profile_call(recv, target_klass);
1769 }
1721 } 1770 }
1722 1771
1723 Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before); 1772 Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before);
1724 // push result 1773 // push result
1725 append_split(result); 1774 append_split(result);
1780 ciKlass* klass = stream()->get_klass(will_link); 1829 ciKlass* klass = stream()->get_klass(will_link);
1781 ValueStack* state_before = !klass->is_loaded() || PatchALot ? state()->copy() : NULL; 1830 ValueStack* state_before = !klass->is_loaded() || PatchALot ? state()->copy() : NULL;
1782 CheckCast* c = new CheckCast(klass, apop(), state_before); 1831 CheckCast* c = new CheckCast(klass, apop(), state_before);
1783 apush(append_split(c)); 1832 apush(append_split(c));
1784 c->set_direct_compare(direct_compare(klass)); 1833 c->set_direct_compare(direct_compare(klass));
1785 if (profile_checkcasts()) { 1834
1786 c->set_profiled_method(method()); 1835 if (is_profiling()) {
1787 c->set_profiled_bci(bci()); 1836 // Note that we'd collect profile data in this method if we wanted it.
1788 c->set_should_profile(true); 1837 compilation()->set_would_profile(true);
1838
1839 if (profile_checkcasts()) {
1840 c->set_profiled_method(method());
1841 c->set_profiled_bci(bci());
1842 c->set_should_profile(true);
1843 }
1789 } 1844 }
1790 } 1845 }
1791 1846
1792 1847
1793 void GraphBuilder::instance_of(int klass_index) { 1848 void GraphBuilder::instance_of(int klass_index) {
1866 return fp_value; 1921 return fp_value;
1867 } 1922 }
1868 1923
1869 1924
1870 Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) { 1925 Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) {
1871 Canonicalizer canon(instr, bci); 1926 Canonicalizer canon(compilation(), instr, bci);
1872 Instruction* i1 = canon.canonical(); 1927 Instruction* i1 = canon.canonical();
1873 if (i1->bci() != -99) { 1928 if (i1->bci() != -99) {
1874 // Canonicalizer returned an instruction which was already 1929 // Canonicalizer returned an instruction which was already
1875 // appended so simply return it. 1930 // appended so simply return it.
1876 return i1; 1931 return i1;
2649 // create header block 2704 // create header block
2650 BlockBegin* h = new BlockBegin(entry->bci()); 2705 BlockBegin* h = new BlockBegin(entry->bci());
2651 h->set_depth_first_number(0); 2706 h->set_depth_first_number(0);
2652 2707
2653 Value l = h; 2708 Value l = h;
2654 if (profile_branches()) {
2655 // Increment the invocation count on entry to the method. We
2656 // can't use profile_invocation here because append isn't setup to
2657 // work properly at this point. The instruction have to be
2658 // appended to the instruction stream by hand.
2659 Value m = new Constant(new ObjectConstant(compilation()->method()));
2660 h->set_next(m, 0);
2661 Value p = new ProfileCounter(m, methodOopDesc::interpreter_invocation_counter_offset_in_bytes(), 1);
2662 m->set_next(p, 0);
2663 l = p;
2664 }
2665
2666 BlockEnd* g = new Goto(entry, false); 2709 BlockEnd* g = new Goto(entry, false);
2667 l->set_next(g, entry->bci()); 2710 l->set_next(g, entry->bci());
2668 h->set_end(g); 2711 h->set_end(g);
2669 h->set(f); 2712 h->set(f);
2670 // setup header block end state 2713 // setup header block end state
2686 // necesary if std_entry is also a backward branch target because 2729 // necesary if std_entry is also a backward branch target because
2687 // then phi functions may be necessary in the header block. It's 2730 // then phi functions may be necessary in the header block. It's
2688 // also necessary when profiling so that there's a single block that 2731 // also necessary when profiling so that there's a single block that
2689 // can increment the interpreter_invocation_count. 2732 // can increment the interpreter_invocation_count.
2690 BlockBegin* new_header_block; 2733 BlockBegin* new_header_block;
2691 if (std_entry->number_of_preds() == 0 && !profile_branches()) { 2734 if (std_entry->number_of_preds() > 0 || count_invocations() || count_backedges()) {
2735 new_header_block = header_block(std_entry, BlockBegin::std_entry_flag, state);
2736 } else {
2692 new_header_block = std_entry; 2737 new_header_block = std_entry;
2693 } else {
2694 new_header_block = header_block(std_entry, BlockBegin::std_entry_flag, state);
2695 } 2738 }
2696 2739
2697 // setup start block (root for the IR graph) 2740 // setup start block (root for the IR graph)
2698 Base* base = 2741 Base* base =
2699 new Base( 2742 new Base(
3113 const bool has_receiver = !callee->is_static(); 3156 const bool has_receiver = !callee->is_static();
3114 ValueType* result_type = as_ValueType(callee->return_type()); 3157 ValueType* result_type = as_ValueType(callee->return_type());
3115 3158
3116 Values* args = state()->pop_arguments(callee->arg_size()); 3159 Values* args = state()->pop_arguments(callee->arg_size());
3117 ValueStack* locks = lock_stack(); 3160 ValueStack* locks = lock_stack();
3118 if (profile_calls()) { 3161
3162 if (is_profiling()) {
3119 // Don't profile in the special case where the root method 3163 // Don't profile in the special case where the root method
3120 // is the intrinsic 3164 // is the intrinsic
3121 if (callee != method()) { 3165 if (callee != method()) {
3122 Value recv = NULL; 3166 // Note that we'd collect profile data in this method if we wanted it.
3123 if (has_receiver) { 3167 compilation()->set_would_profile(true);
3124 recv = args->at(0); 3168 if (profile_calls()) {
3125 null_check(recv); 3169 Value recv = NULL;
3126 } 3170 if (has_receiver) {
3127 profile_call(recv, NULL); 3171 recv = args->at(0);
3172 null_check(recv);
3173 }
3174 profile_call(recv, NULL);
3175 }
3128 } 3176 }
3129 } 3177 }
3130 3178
3131 Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, lock_stack(), 3179 Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, lock_stack(),
3132 preserves_state, cantrap); 3180 preserves_state, cantrap);
3294 } 3342 }
3295 3343
3296 3344
3297 bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) { 3345 bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) {
3298 assert(!callee->is_native(), "callee must not be native"); 3346 assert(!callee->is_native(), "callee must not be native");
3299 3347 if (count_backedges() && callee->has_loops()) {
3348 INLINE_BAILOUT("too complex for tiered");
3349 }
3300 // first perform tests of things it's not possible to inline 3350 // first perform tests of things it's not possible to inline
3301 if (callee->has_exception_handlers() && 3351 if (callee->has_exception_handlers() &&
3302 !InlineMethodsWithExceptionHandlers) INLINE_BAILOUT("callee has exception handlers"); 3352 !InlineMethodsWithExceptionHandlers) INLINE_BAILOUT("callee has exception handlers");
3303 if (callee->is_synchronized() && 3353 if (callee->is_synchronized() &&
3304 !InlineSynchronizedMethods ) INLINE_BAILOUT("callee is synchronized"); 3354 !InlineSynchronizedMethods ) INLINE_BAILOUT("callee is synchronized");
3363 assert(callee->arg_size() > 0, "must have at least a receiver"); 3413 assert(callee->arg_size() > 0, "must have at least a receiver");
3364 recv = state()->stack_at(args_base); 3414 recv = state()->stack_at(args_base);
3365 null_check(recv); 3415 null_check(recv);
3366 } 3416 }
3367 3417
3368 if (profile_inlined_calls()) { 3418 if (is_profiling()) {
3369 profile_call(recv, holder_known ? callee->holder() : NULL); 3419 // Note that we'd collect profile data in this method if we wanted it.
3370 } 3420 // this may be redundant here...
3371 3421 compilation()->set_would_profile(true);
3372 profile_invocation(callee); 3422
3423 if (profile_calls()) {
3424 profile_call(recv, holder_known ? callee->holder() : NULL);
3425 }
3426 if (profile_inlined_calls()) {
3427 profile_invocation(callee, state(), 0);
3428 }
3429 }
3373 3430
3374 // Introduce a new callee continuation point - if the callee has 3431 // Introduce a new callee continuation point - if the callee has
3375 // more than one return instruction or the return does not allow 3432 // more than one return instruction or the return does not allow
3376 // fall-through of control flow, all return instructions of the 3433 // fall-through of control flow, all return instructions of the
3377 // callee will need to be replaced by Goto's pointing to this 3434 // callee will need to be replaced by Goto's pointing to this
3753 void GraphBuilder::print_stats() { 3810 void GraphBuilder::print_stats() {
3754 vmap()->print(); 3811 vmap()->print();
3755 } 3812 }
3756 #endif // PRODUCT 3813 #endif // PRODUCT
3757 3814
3758
3759 void GraphBuilder::profile_call(Value recv, ciKlass* known_holder) { 3815 void GraphBuilder::profile_call(Value recv, ciKlass* known_holder) {
3760 append(new ProfileCall(method(), bci(), recv, known_holder)); 3816 append(new ProfileCall(method(), bci(), recv, known_holder));
3761 } 3817 }
3762 3818
3763 3819 void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state, int bci) {
3764 void GraphBuilder::profile_invocation(ciMethod* callee) { 3820 append(new ProfileInvoke(callee, state, bci));
3765 if (profile_calls()) { 3821 }
3766 // increment the interpreter_invocation_count for the inlinee
3767 Value m = append(new Constant(new ObjectConstant(callee)));
3768 append(new ProfileCounter(m, methodOopDesc::interpreter_invocation_counter_offset_in_bytes(), 1));
3769 }
3770 }
3771
3772
3773 void GraphBuilder::profile_bci(int bci) {
3774 if (profile_branches()) {
3775 ciMethodData* md = method()->method_data();
3776 if (md == NULL) {
3777 BAILOUT("out of memory building methodDataOop");
3778 }
3779 ciProfileData* data = md->bci_to_data(bci);
3780 assert(data != NULL && data->is_JumpData(), "need JumpData for goto");
3781 Value mdo = append(new Constant(new ObjectConstant(md)));
3782 append(new ProfileCounter(mdo, md->byte_offset_of_slot(data, JumpData::taken_offset()), 1));
3783 }
3784 }