src/share/vm/opto/compile.hpp
Print this page
rev 3904 : 8005071: Incremental inlining for JSR 292
Summary: post parse inlining driven by number of live nodes.
Reviewed-by:
*** 278,287 ****
--- 278,289 ----
// For deopt
int _orig_pc_slot;
int _orig_pc_slot_offset_in_bytes;
int _major_progress; // Count of something big happening
+ bool _inlining_progress; // progress doing incremental inlining?
+ bool _inlining_incrementally;// Are we doing incremental inlining (post parse)
bool _has_loops; // True if the method _may_ have some loops
bool _has_split_ifs; // True if the method _may_ have some split-if
bool _has_unsafe_access; // True if the method _may_ produce faults in unsafe loads or stores.
bool _has_stringbuilder; // True StringBuffers or StringBuilders are allocated
int _max_vector_size; // Maximum size of generated vectors
*** 367,376 ****
--- 369,383 ----
Unique_Node_List* _for_igvn; // Initial work-list for next round of Iterative GVN
WarmCallInfo* _warm_calls; // Sorted work-list for heat-based inlining.
GrowableArray<CallGenerator*> _late_inlines; // List of CallGenerators to be revisited after
// main parsing has finished.
+ GrowableArray<CallGenerator*> _string_late_inlines; // same but for string operations
+
+ int _late_inlines_pos; // Where in the queue should the next late inlining candidate go (emulate depth first inlining)
+ uint _number_of_mh_late_inlines; // number of method handle late inlining still pending
+
// Inlining may not happen in parse order which would make
// PrintInlining output confusing. Keep track of PrintInlining
// pieces in order.
class PrintInliningBuffer : public ResourceObj {
*** 489,498 ****
--- 496,511 ----
// Control of this compilation.
int fixed_slots() const { assert(_fixed_slots >= 0, ""); return _fixed_slots; }
void set_fixed_slots(int n) { _fixed_slots = n; }
int major_progress() const { return _major_progress; }
+ void set_inlining_progress() { _inlining_progress = true; }
+ void clear_inlining_progress() { _inlining_progress = false; }
+ int inlining_progress() const { return _inlining_progress; }
+ int inlining_incrementally() const { return _inlining_incrementally; }
+ void set_inlining_incrementally() { _inlining_incrementally = true; }
+ void clear_inlining_incrementally() { _inlining_incrementally = false; }
void set_major_progress() { _major_progress++; }
void clear_major_progress() { _major_progress = 0; }
int num_loop_opts() const { return _num_loop_opts; }
void set_num_loop_opts(int n) { _num_loop_opts = n; }
int max_inline_size() const { return _max_inline_size; }
*** 727,737 ****
void return_values(JVMState* jvms);
JVMState* build_start_state(StartNode* start, const TypeFunc* tf);
// Decide how to build a call.
// The profile factor is a discount to apply to this site's interp. profile.
! CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true);
bool should_delay_inlining(ciMethod* call_method, JVMState* jvms);
// Report if there were too many traps at a current method and bci.
// Report if a trap was recorded, and/or PerMethodTrapLimit was exceeded.
// If there is no MDO at all, report no trap unless told to assume it.
--- 740,750 ----
void return_values(JVMState* jvms);
JVMState* build_start_state(StartNode* start, const TypeFunc* tf);
// Decide how to build a call.
// The profile factor is a discount to apply to this site's interp. profile.
! CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true, bool delayed_forbidden = false);
bool should_delay_inlining(ciMethod* call_method, JVMState* jvms);
// Report if there were too many traps at a current method and bci.
// Report if a trap was recorded, and/or PerMethodTrapLimit was exceeded.
// If there is no MDO at all, report no trap unless told to assume it.
*** 763,776 ****
WarmCallInfo* warm_calls() const { return _warm_calls; }
void set_warm_calls(WarmCallInfo* l) { _warm_calls = l; }
WarmCallInfo* pop_warm_call();
// Record this CallGenerator for inlining at the end of parsing.
! void add_late_inline(CallGenerator* cg) { _late_inlines.push(cg); }
void dump_inlining();
// Matching, CFG layout, allocation, code generation
PhaseCFG* cfg() { return _cfg; }
bool select_24_bit_instr() const { return _select_24_bit_instr; }
bool in_24_bit_fp_mode() const { return _in_24_bit_fp_mode; }
bool has_java_calls() const { return _java_calls > 0; }
--- 776,818 ----
WarmCallInfo* warm_calls() const { return _warm_calls; }
void set_warm_calls(WarmCallInfo* l) { _warm_calls = l; }
WarmCallInfo* pop_warm_call();
// Record this CallGenerator for inlining at the end of parsing.
! void add_late_inline(CallGenerator* cg) {
! _late_inlines.insert_before(_late_inlines_pos, cg);
! _late_inlines_pos++;
! }
!
! void prepend_late_inline(CallGenerator* cg) {
! _late_inlines.insert_before(0, cg);
! }
!
! void add_string_late_inline(CallGenerator* cg) {
! _string_late_inlines.push(cg);
! }
!
! void remove_useless_late_inlines(Unique_Node_List &useful, bool string);
void dump_inlining();
+ bool over_inlining_cutoff() const {
+ if (!inlining_incrementally()) {
+ return unique() > (uint)NodeCountInliningCutoff;
+ } else {
+ return live_nodes() > (uint)LiveNodeCountInliningCutoff;
+ }
+ }
+
+ void inc_number_of_mh_late_inlines() { _number_of_mh_late_inlines++; }
+ void dec_number_of_mh_late_inlines() { assert(_number_of_mh_late_inlines > 0, "_number_of_mh_late_inlines < 0 !"); _number_of_mh_late_inlines--; }
+ bool has_mh_late_inlines() const { return _number_of_mh_late_inlines > 0; }
+
+ void incremental_inline_one(PhaseIterGVN& igvn);
+ void incremental_inline(PhaseIterGVN& igvn);
+ void string_inline(bool parse_time);
+
// Matching, CFG layout, allocation, code generation
PhaseCFG* cfg() { return _cfg; }
bool select_24_bit_instr() const { return _select_24_bit_instr; }
bool in_24_bit_fp_mode() const { return _in_24_bit_fp_mode; }
bool has_java_calls() const { return _java_calls > 0; }