comparison src/share/vm/opto/compile.hpp @ 7482:989155e2d07a

Merge with hs25-b15.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Wed, 16 Jan 2013 01:34:24 +0100
parents 5698813d45eb
children 8b3da8d14c93
comparison
equal deleted inserted replaced
7381:6761a8f854a4 7482:989155e2d07a
28 #include "asm/codeBuffer.hpp" 28 #include "asm/codeBuffer.hpp"
29 #include "ci/compilerInterface.hpp" 29 #include "ci/compilerInterface.hpp"
30 #include "code/debugInfoRec.hpp" 30 #include "code/debugInfoRec.hpp"
31 #include "code/exceptionHandlerTable.hpp" 31 #include "code/exceptionHandlerTable.hpp"
32 #include "compiler/compilerOracle.hpp" 32 #include "compiler/compilerOracle.hpp"
33 #include "compiler/compileBroker.hpp"
33 #include "libadt/dict.hpp" 34 #include "libadt/dict.hpp"
34 #include "libadt/port.hpp" 35 #include "libadt/port.hpp"
35 #include "libadt/vectset.hpp" 36 #include "libadt/vectset.hpp"
36 #include "memory/resourceArea.hpp" 37 #include "memory/resourceArea.hpp"
37 #include "opto/idealGraphPrinter.hpp" 38 #include "opto/idealGraphPrinter.hpp"
69 class StartNode; 70 class StartNode;
70 class SafePointNode; 71 class SafePointNode;
71 class JVMState; 72 class JVMState;
72 class TypeData; 73 class TypeData;
73 class TypePtr; 74 class TypePtr;
75 class TypeOopPtr;
74 class TypeFunc; 76 class TypeFunc;
75 class Unique_Node_List; 77 class Unique_Node_List;
76 class nmethod; 78 class nmethod;
77 class WarmCallInfo; 79 class WarmCallInfo;
78 class Node_Stack; 80 class Node_Stack;
277 // For deopt 279 // For deopt
278 int _orig_pc_slot; 280 int _orig_pc_slot;
279 int _orig_pc_slot_offset_in_bytes; 281 int _orig_pc_slot_offset_in_bytes;
280 282
281 int _major_progress; // Count of something big happening 283 int _major_progress; // Count of something big happening
284 bool _inlining_progress; // progress doing incremental inlining?
285 bool _inlining_incrementally;// Are we doing incremental inlining (post parse)
282 bool _has_loops; // True if the method _may_ have some loops 286 bool _has_loops; // True if the method _may_ have some loops
283 bool _has_split_ifs; // True if the method _may_ have some split-if 287 bool _has_split_ifs; // True if the method _may_ have some split-if
284 bool _has_unsafe_access; // True if the method _may_ produce faults in unsafe loads or stores. 288 bool _has_unsafe_access; // True if the method _may_ produce faults in unsafe loads or stores.
285 bool _has_stringbuilder; // True StringBuffers or StringBuilders are allocated 289 bool _has_stringbuilder; // True StringBuffers or StringBuilders are allocated
286 int _max_vector_size; // Maximum size of generated vectors 290 int _max_vector_size; // Maximum size of generated vectors
364 // Parsing, optimization 368 // Parsing, optimization
365 PhaseGVN* _initial_gvn; // Results of parse-time PhaseGVN 369 PhaseGVN* _initial_gvn; // Results of parse-time PhaseGVN
366 Unique_Node_List* _for_igvn; // Initial work-list for next round of Iterative GVN 370 Unique_Node_List* _for_igvn; // Initial work-list for next round of Iterative GVN
367 WarmCallInfo* _warm_calls; // Sorted work-list for heat-based inlining. 371 WarmCallInfo* _warm_calls; // Sorted work-list for heat-based inlining.
368 372
369 GrowableArray<CallGenerator*> _late_inlines; // List of CallGenerators to be revisited after 373 GrowableArray<CallGenerator*> _late_inlines; // List of CallGenerators to be revisited after
370 // main parsing has finished. 374 // main parsing has finished.
371 375 GrowableArray<CallGenerator*> _string_late_inlines; // same but for string operations
376
377 int _late_inlines_pos; // Where in the queue should the next late inlining candidate go (emulate depth first inlining)
378 uint _number_of_mh_late_inlines; // number of method handle late inlining still pending
379
380
381 // Inlining may not happen in parse order which would make
382 // PrintInlining output confusing. Keep track of PrintInlining
383 // pieces in order.
384 class PrintInliningBuffer : public ResourceObj {
385 private:
386 CallGenerator* _cg;
387 stringStream* _ss;
388
389 public:
390 PrintInliningBuffer()
391 : _cg(NULL) { _ss = new stringStream(); }
392
393 stringStream* ss() const { return _ss; }
394 CallGenerator* cg() const { return _cg; }
395 void set_cg(CallGenerator* cg) { _cg = cg; }
396 };
397
398 GrowableArray<PrintInliningBuffer>* _print_inlining_list;
399 int _print_inlining;
400
401 public:
402
403 outputStream* print_inlining_stream() const {
404 return _print_inlining_list->at(_print_inlining).ss();
405 }
406
407 void print_inlining_skip(CallGenerator* cg) {
408 if (PrintInlining) {
409 _print_inlining_list->at(_print_inlining).set_cg(cg);
410 _print_inlining++;
411 _print_inlining_list->insert_before(_print_inlining, PrintInliningBuffer());
412 }
413 }
414
415 void print_inlining_insert(CallGenerator* cg) {
416 if (PrintInlining) {
417 for (int i = 0; i < _print_inlining_list->length(); i++) {
418 if (_print_inlining_list->at(i).cg() == cg) {
419 _print_inlining_list->insert_before(i+1, PrintInliningBuffer());
420 _print_inlining = i+1;
421 _print_inlining_list->at(i).set_cg(NULL);
422 return;
423 }
424 }
425 ShouldNotReachHere();
426 }
427 }
428
429 void print_inlining(ciMethod* method, int inline_level, int bci, const char* msg = NULL) {
430 stringStream ss;
431 CompileTask::print_inlining(&ss, method, inline_level, bci, msg);
432 print_inlining_stream()->print(ss.as_string());
433 }
434
435 private:
372 // Matching, CFG layout, allocation, code generation 436 // Matching, CFG layout, allocation, code generation
373 PhaseCFG* _cfg; // Results of CFG finding 437 PhaseCFG* _cfg; // Results of CFG finding
374 bool _select_24_bit_instr; // We selected an instruction with a 24-bit result 438 bool _select_24_bit_instr; // We selected an instruction with a 24-bit result
375 bool _in_24_bit_fp_mode; // We are emitting instructions with 24-bit results 439 bool _in_24_bit_fp_mode; // We are emitting instructions with 24-bit results
376 int _java_calls; // Number of java calls in the method 440 int _java_calls; // Number of java calls in the method
433 497
434 // Control of this compilation. 498 // Control of this compilation.
435 int fixed_slots() const { assert(_fixed_slots >= 0, ""); return _fixed_slots; } 499 int fixed_slots() const { assert(_fixed_slots >= 0, ""); return _fixed_slots; }
436 void set_fixed_slots(int n) { _fixed_slots = n; } 500 void set_fixed_slots(int n) { _fixed_slots = n; }
437 int major_progress() const { return _major_progress; } 501 int major_progress() const { return _major_progress; }
502 void set_inlining_progress(bool z) { _inlining_progress = z; }
503 int inlining_progress() const { return _inlining_progress; }
504 void set_inlining_incrementally(bool z) { _inlining_incrementally = z; }
505 int inlining_incrementally() const { return _inlining_incrementally; }
438 void set_major_progress() { _major_progress++; } 506 void set_major_progress() { _major_progress++; }
439 void clear_major_progress() { _major_progress = 0; } 507 void clear_major_progress() { _major_progress = 0; }
440 int num_loop_opts() const { return _num_loop_opts; } 508 int num_loop_opts() const { return _num_loop_opts; }
441 void set_num_loop_opts(int n) { _num_loop_opts = n; } 509 void set_num_loop_opts(int n) { _num_loop_opts = n; }
442 int max_inline_size() const { return _max_inline_size; } 510 int max_inline_size() const { return _max_inline_size; }
589 } 657 }
590 uint dead_node_count() { return _dead_node_count; } 658 uint dead_node_count() { return _dead_node_count; }
591 void reset_dead_node_list() { _dead_node_list.Reset(); 659 void reset_dead_node_list() { _dead_node_list.Reset();
592 _dead_node_count = 0; 660 _dead_node_count = 0;
593 } 661 }
594 uint live_nodes() { 662 uint live_nodes() const {
595 int val = _unique - _dead_node_count; 663 int val = _unique - _dead_node_count;
596 assert (val >= 0, err_msg_res("number of tracked dead nodes %d more than created nodes %d", _unique, _dead_node_count)); 664 assert (val >= 0, err_msg_res("number of tracked dead nodes %d more than created nodes %d", _unique, _dead_node_count));
597 return (uint) val; 665 return (uint) val;
598 } 666 }
599 #ifdef ASSERT 667 #ifdef ASSERT
671 void return_values(JVMState* jvms); 739 void return_values(JVMState* jvms);
672 JVMState* build_start_state(StartNode* start, const TypeFunc* tf); 740 JVMState* build_start_state(StartNode* start, const TypeFunc* tf);
673 741
674 // Decide how to build a call. 742 // Decide how to build a call.
675 // The profile factor is a discount to apply to this site's interp. profile. 743 // The profile factor is a discount to apply to this site's interp. profile.
676 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); 744 CallGenerator* call_generator(ciMethod* call_method, int vtable_index, bool call_does_dispatch, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true, bool delayed_forbidden = false);
677 bool should_delay_inlining(ciMethod* call_method, JVMState* jvms); 745 bool should_delay_inlining(ciMethod* call_method, JVMState* jvms);
746
747 // Helper functions to identify inlining potential at call-site
748 ciMethod* optimize_virtual_call(ciMethod* caller, int bci, ciInstanceKlass* klass,
749 ciMethod* callee, const TypeOopPtr* receiver_type,
750 bool is_virtual,
751 bool &call_does_dispatch, int &vtable_index);
752 ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass,
753 ciMethod* callee, const TypeOopPtr* receiver_type);
678 754
679 // Report if there were too many traps at a current method and bci. 755 // Report if there were too many traps at a current method and bci.
680 // Report if a trap was recorded, and/or PerMethodTrapLimit was exceeded. 756 // Report if a trap was recorded, and/or PerMethodTrapLimit was exceeded.
681 // If there is no MDO at all, report no trap unless told to assume it. 757 // If there is no MDO at all, report no trap unless told to assume it.
682 bool too_many_traps(ciMethod* method, int bci, Deoptimization::DeoptReason reason); 758 bool too_many_traps(ciMethod* method, int bci, Deoptimization::DeoptReason reason);
700 void gvn_replace_by(Node* n, Node* nn); 776 void gvn_replace_by(Node* n, Node* nn);
701 777
702 778
703 void identify_useful_nodes(Unique_Node_List &useful); 779 void identify_useful_nodes(Unique_Node_List &useful);
704 void update_dead_node_list(Unique_Node_List &useful); 780 void update_dead_node_list(Unique_Node_List &useful);
705 void remove_useless_nodes (Unique_Node_List &useful); 781 void remove_useless_nodes (Unique_Node_List &useful);
706 782
707 WarmCallInfo* warm_calls() const { return _warm_calls; } 783 WarmCallInfo* warm_calls() const { return _warm_calls; }
708 void set_warm_calls(WarmCallInfo* l) { _warm_calls = l; } 784 void set_warm_calls(WarmCallInfo* l) { _warm_calls = l; }
709 WarmCallInfo* pop_warm_call(); 785 WarmCallInfo* pop_warm_call();
710 786
711 // Record this CallGenerator for inlining at the end of parsing. 787 // Record this CallGenerator for inlining at the end of parsing.
712 void add_late_inline(CallGenerator* cg) { _late_inlines.push(cg); } 788 void add_late_inline(CallGenerator* cg) {
789 _late_inlines.insert_before(_late_inlines_pos, cg);
790 _late_inlines_pos++;
791 }
792
793 void prepend_late_inline(CallGenerator* cg) {
794 _late_inlines.insert_before(0, cg);
795 }
796
797 void add_string_late_inline(CallGenerator* cg) {
798 _string_late_inlines.push(cg);
799 }
800
801 void remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines, Unique_Node_List &useful);
802
803 void dump_inlining();
804
805 bool over_inlining_cutoff() const {
806 if (!inlining_incrementally()) {
807 return unique() > (uint)NodeCountInliningCutoff;
808 } else {
809 return live_nodes() > (uint)LiveNodeCountInliningCutoff;
810 }
811 }
812
813 void inc_number_of_mh_late_inlines() { _number_of_mh_late_inlines++; }
814 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--; }
815 bool has_mh_late_inlines() const { return _number_of_mh_late_inlines > 0; }
816
817 void inline_incrementally_one(PhaseIterGVN& igvn);
818 void inline_incrementally(PhaseIterGVN& igvn);
819 void inline_string_calls(bool parse_time);
713 820
714 // Matching, CFG layout, allocation, code generation 821 // Matching, CFG layout, allocation, code generation
715 PhaseCFG* cfg() { return _cfg; } 822 PhaseCFG* cfg() { return _cfg; }
716 bool select_24_bit_instr() const { return _select_24_bit_instr; } 823 bool select_24_bit_instr() const { return _select_24_bit_instr; }
717 bool in_24_bit_fp_mode() const { return _in_24_bit_fp_mode; } 824 bool in_24_bit_fp_mode() const { return _in_24_bit_fp_mode; }