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