Mercurial > hg > graal-compiler
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; } |