Mercurial > hg > truffle
comparison src/share/vm/opto/chaitin.hpp @ 14909:4ca6dc0799b6
Backout jdk9 merge
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Tue, 01 Apr 2014 13:57:07 +0200 |
parents | 04e7587c97dc |
children | 89152779163c |
comparison
equal
deleted
inserted
replaced
14908:8db6e76cb658 | 14909:4ca6dc0799b6 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
32 #include "opto/live.hpp" | 32 #include "opto/live.hpp" |
33 #include "opto/matcher.hpp" | 33 #include "opto/matcher.hpp" |
34 #include "opto/phase.hpp" | 34 #include "opto/phase.hpp" |
35 #include "opto/regalloc.hpp" | 35 #include "opto/regalloc.hpp" |
36 #include "opto/regmask.hpp" | 36 #include "opto/regmask.hpp" |
37 #include "opto/machnode.hpp" | |
38 | 37 |
39 class LoopTree; | 38 class LoopTree; |
39 class MachCallNode; | |
40 class MachSafePointNode; | |
40 class Matcher; | 41 class Matcher; |
41 class PhaseCFG; | 42 class PhaseCFG; |
42 class PhaseLive; | 43 class PhaseLive; |
43 class PhaseRegAlloc; | 44 class PhaseRegAlloc; |
44 class PhaseChaitin; | 45 class PhaseChaitin; |
95 _eff_degree += mod; | 96 _eff_degree += mod; |
96 assert(!_mask.is_AllStack() || (_mask.is_AllStack() && lo_degree()), "_eff_degree can't be bigger than AllStack_size - _num_regs if the mask supports stack registers"); | 97 assert(!_mask.is_AllStack() || (_mask.is_AllStack() && lo_degree()), "_eff_degree can't be bigger than AllStack_size - _num_regs if the mask supports stack registers"); |
97 } | 98 } |
98 // Compute the degree between 2 live ranges | 99 // Compute the degree between 2 live ranges |
99 int compute_degree( LRG &l ) const; | 100 int compute_degree( LRG &l ) const; |
100 bool mask_is_nonempty_and_up() const { | |
101 return mask().is_UP() && mask_size(); | |
102 } | |
103 bool is_float_or_vector() const { | |
104 return _is_float || _is_vector; | |
105 } | |
106 | 101 |
107 private: | 102 private: |
108 RegMask _mask; // Allowed registers for this LRG | 103 RegMask _mask; // Allowed registers for this LRG |
109 uint _mask_size; // cache of _mask.Size(); | 104 uint _mask_size; // cache of _mask.Size(); |
110 public: | 105 public: |
132 void set_mask( const RegMask &rm ) { _mask = rm; debug_only(_msize_valid=0;)} | 127 void set_mask( const RegMask &rm ) { _mask = rm; debug_only(_msize_valid=0;)} |
133 void AND( const RegMask &rm ) { _mask.AND(rm); debug_only(_msize_valid=0;)} | 128 void AND( const RegMask &rm ) { _mask.AND(rm); debug_only(_msize_valid=0;)} |
134 void SUBTRACT( const RegMask &rm ) { _mask.SUBTRACT(rm); debug_only(_msize_valid=0;)} | 129 void SUBTRACT( const RegMask &rm ) { _mask.SUBTRACT(rm); debug_only(_msize_valid=0;)} |
135 void Clear() { _mask.Clear() ; debug_only(_msize_valid=1); _mask_size = 0; } | 130 void Clear() { _mask.Clear() ; debug_only(_msize_valid=1); _mask_size = 0; } |
136 void Set_All() { _mask.Set_All(); debug_only(_msize_valid=1); _mask_size = RegMask::CHUNK_SIZE; } | 131 void Set_All() { _mask.Set_All(); debug_only(_msize_valid=1); _mask_size = RegMask::CHUNK_SIZE; } |
137 | |
138 void Insert( OptoReg::Name reg ) { _mask.Insert(reg); debug_only(_msize_valid=0;) } | 132 void Insert( OptoReg::Name reg ) { _mask.Insert(reg); debug_only(_msize_valid=0;) } |
139 void Remove( OptoReg::Name reg ) { _mask.Remove(reg); debug_only(_msize_valid=0;) } | 133 void Remove( OptoReg::Name reg ) { _mask.Remove(reg); debug_only(_msize_valid=0;) } |
140 void clear_to_pairs() { _mask.clear_to_pairs(); debug_only(_msize_valid=0;) } | 134 void clear_to_pairs() { _mask.clear_to_pairs(); debug_only(_msize_valid=0;) } |
141 void clear_to_sets() { _mask.clear_to_sets(_num_regs); debug_only(_msize_valid=0;) } | 135 void clear_to_sets() { _mask.clear_to_sets(_num_regs); debug_only(_msize_valid=0;) } |
142 | 136 |
421 uint _lo_stk_degree; // Head of lo-stk-degree LRGs list | 415 uint _lo_stk_degree; // Head of lo-stk-degree LRGs list |
422 uint _hi_degree; // Head of hi-degree LRGs list | 416 uint _hi_degree; // Head of hi-degree LRGs list |
423 uint _simplified; // Linked list head of simplified LRGs | 417 uint _simplified; // Linked list head of simplified LRGs |
424 | 418 |
425 // Helper functions for Split() | 419 // Helper functions for Split() |
426 uint split_DEF(Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray<uint> splits, int slidx ); | 420 uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray<uint> splits, int slidx ); |
427 uint split_USE(MachSpillCopyNode::SpillType spill_type, Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx ); | 421 uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx ); |
428 | 422 |
429 //------------------------------clone_projs------------------------------------ | 423 //------------------------------clone_projs------------------------------------ |
430 // After cloning some rematerialized instruction, clone any MachProj's that | 424 // After cloning some rematerialized instruction, clone any MachProj's that |
431 // follow it. Example: Intel zero is XOR, kills flags. Sparc FP constants | 425 // follow it. Example: Intel zero is XOR, kills flags. Sparc FP constants |
432 // use G3 as an address temp. | 426 // use G3 as an address temp. |
444 | 438 |
445 Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits, | 439 Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits, |
446 int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru); | 440 int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru); |
447 // True if lidx is used before any real register is def'd in the block | 441 // True if lidx is used before any real register is def'd in the block |
448 bool prompt_use( Block *b, uint lidx ); | 442 bool prompt_use( Block *b, uint lidx ); |
449 Node *get_spillcopy_wide(MachSpillCopyNode::SpillType spill_type, Node *def, Node *use, uint uidx ); | 443 Node *get_spillcopy_wide( Node *def, Node *use, uint uidx ); |
450 // Insert the spill at chosen location. Skip over any intervening Proj's or | 444 // Insert the spill at chosen location. Skip over any intervening Proj's or |
451 // Phis. Skip over a CatchNode and projs, inserting in the fall-through block | 445 // Phis. Skip over a CatchNode and projs, inserting in the fall-through block |
452 // instead. Update high-pressure indices. Create a new live range. | 446 // instead. Update high-pressure indices. Create a new live range. |
453 void insert_proj( Block *b, uint i, Node *spill, uint maxlrg ); | 447 void insert_proj( Block *b, uint i, Node *spill, uint maxlrg ); |
454 | 448 |
487 | 481 |
488 // Add edge between reg and everything in the vector. | 482 // Add edge between reg and everything in the vector. |
489 // Same as _ifg->add_vector(reg,live) EXCEPT use the RegMask | 483 // Same as _ifg->add_vector(reg,live) EXCEPT use the RegMask |
490 // information to trim the set of interferences. Return the | 484 // information to trim the set of interferences. Return the |
491 // count of edges added. | 485 // count of edges added. |
492 void interfere_with_live(uint lid, IndexSet* liveout); | 486 void interfere_with_live( uint reg, IndexSet *live ); |
493 #ifdef ASSERT | |
494 // Count register pressure for asserts | 487 // Count register pressure for asserts |
495 uint count_int_pressure(IndexSet* liveout); | 488 uint count_int_pressure( IndexSet *liveout ); |
496 uint count_float_pressure(IndexSet* liveout); | 489 uint count_float_pressure( IndexSet *liveout ); |
497 #endif | |
498 | 490 |
499 // Build the interference graph using virtual registers only. | 491 // Build the interference graph using virtual registers only. |
500 // Used for aggressive coalescing. | 492 // Used for aggressive coalescing. |
501 void build_ifg_virtual( ); | 493 void build_ifg_virtual( ); |
502 | |
503 // used when computing the register pressure for each block in the CFG. This | |
504 // is done during IFG creation. | |
505 class Pressure { | |
506 // keeps track of the register pressure at the current | |
507 // instruction (used when stepping backwards in the block) | |
508 uint _current_pressure; | |
509 | |
510 // keeps track of the instruction index of the first low to high register pressure | |
511 // transition (starting from the top) in the block | |
512 // if high_pressure_index == 0 then the whole block is high pressure | |
513 // if high_pressure_index = b.end_idx() + 1 then the whole block is low pressure | |
514 uint _high_pressure_index; | |
515 | |
516 // stores the highest pressure we find | |
517 uint _final_pressure; | |
518 | |
519 // number of live ranges that constitute high register pressure | |
520 const uint _high_pressure_limit; | |
521 public: | |
522 | |
523 // lower the register pressure and look for a low to high pressure | |
524 // transition | |
525 void lower(LRG& lrg, uint& location) { | |
526 _current_pressure -= lrg.reg_pressure(); | |
527 if (_current_pressure == _high_pressure_limit) { | |
528 _high_pressure_index = location; | |
529 } | |
530 } | |
531 | |
532 // raise the pressure and store the pressure if it's the biggest | |
533 // pressure so far | |
534 void raise(LRG &lrg) { | |
535 _current_pressure += lrg.reg_pressure(); | |
536 if (_current_pressure > _final_pressure) { | |
537 _final_pressure = _current_pressure; | |
538 } | |
539 } | |
540 | |
541 uint high_pressure_index() const { | |
542 return _high_pressure_index; | |
543 } | |
544 | |
545 uint final_pressure() const { | |
546 return _final_pressure; | |
547 } | |
548 | |
549 uint current_pressure() const { | |
550 return _current_pressure; | |
551 } | |
552 | |
553 uint high_pressure_limit() const { | |
554 return _high_pressure_limit; | |
555 } | |
556 | |
557 void lower_high_pressure_index() { | |
558 _high_pressure_index--; | |
559 } | |
560 | |
561 void set_high_pressure_index_to_block_start() { | |
562 _high_pressure_index = 0; | |
563 } | |
564 | |
565 void check_pressure_at_fatproj(uint fatproj_location, RegMask& fatproj_mask) { | |
566 // this pressure is only valid at this instruction, i.e. we don't need to lower | |
567 // the register pressure since the fat proj was never live before (going backwards) | |
568 uint new_pressure = current_pressure() + fatproj_mask.Size(); | |
569 if (new_pressure > final_pressure()) { | |
570 _final_pressure = new_pressure; | |
571 } | |
572 | |
573 // if we were at a low pressure and now and the fat proj is at high pressure, record the fat proj location | |
574 // as coming from a low to high (to low again) | |
575 if (current_pressure() <= high_pressure_limit() && new_pressure > high_pressure_limit()) { | |
576 _high_pressure_index = fatproj_location; | |
577 } | |
578 } | |
579 | |
580 Pressure(uint high_pressure_index, uint high_pressure_limit) | |
581 : _current_pressure(0) | |
582 , _high_pressure_index(high_pressure_index) | |
583 , _high_pressure_limit(high_pressure_limit) | |
584 , _final_pressure(0) {} | |
585 }; | |
586 | |
587 void lower_pressure(Block* b, uint location, LRG& lrg, IndexSet* liveout, Pressure& int_pressure, Pressure& float_pressure); | |
588 void raise_pressure(Block* b, LRG& lrg, Pressure& int_pressure, Pressure& float_pressure); | |
589 void check_for_high_pressure_transition_at_fatproj(uint& block_reg_pressure, uint location, LRG& lrg, Pressure& pressure, const int op_regtype); | |
590 void add_input_to_liveout(Block* b, Node* n, IndexSet* liveout, double cost, Pressure& int_pressure, Pressure& float_pressure); | |
591 void compute_initial_block_pressure(Block* b, IndexSet* liveout, Pressure& int_pressure, Pressure& float_pressure, double cost); | |
592 bool remove_node_if_not_used(Block* b, uint location, Node* n, uint lid, IndexSet* liveout); | |
593 void assign_high_score_to_immediate_copies(Block* b, Node* n, LRG& lrg, uint next_inst, uint last_inst); | |
594 void remove_interference_from_copy(Block* b, uint location, uint lid_copy, IndexSet* liveout, double cost, Pressure& int_pressure, Pressure& float_pressure); | |
595 void remove_bound_register_from_interfering_live_ranges(LRG& lrg, IndexSet* liveout, uint& must_spill); | |
596 void check_for_high_pressure_block(Pressure& pressure); | |
597 void adjust_high_pressure_index(Block* b, uint& hrp_index, Pressure& pressure); | |
598 | 494 |
599 // Build the interference graph using physical registers when available. | 495 // Build the interference graph using physical registers when available. |
600 // That is, if 2 live ranges are simultaneously alive but in their | 496 // That is, if 2 live ranges are simultaneously alive but in their |
601 // acceptable register sets do not overlap, then they do not interfere. | 497 // acceptable register sets do not overlap, then they do not interfere. |
602 uint build_ifg_physical( ResourceArea *a ); | 498 uint build_ifg_physical( ResourceArea *a ); |
656 void post_allocate_copy_removal(); | 552 void post_allocate_copy_removal(); |
657 Node *skip_copies( Node *c ); | 553 Node *skip_copies( Node *c ); |
658 // Replace the old node with the current live version of that value | 554 // Replace the old node with the current live version of that value |
659 // and yank the old value if it's dead. | 555 // and yank the old value if it's dead. |
660 int replace_and_yank_if_dead( Node *old, OptoReg::Name nreg, | 556 int replace_and_yank_if_dead( Node *old, OptoReg::Name nreg, |
661 Block *current_block, Node_List& value, Node_List& regnd ) { | 557 Block *current_block, Node_List& value, Node_List& regnd ) { |
662 Node* v = regnd[nreg]; | 558 Node* v = regnd[nreg]; |
663 assert(v->outcnt() != 0, "no dead values"); | 559 assert(v->outcnt() != 0, "no dead values"); |
664 old->replace_by(v); | 560 old->replace_by(v); |
665 return yank_if_dead(old, current_block, &value, ®nd); | 561 return yank_if_dead(old, current_block, &value, ®nd); |
666 } | 562 } |
667 | 563 |
668 int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) { | 564 int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) { |
669 return yank_if_dead_recurse(old, old, current_block, value, regnd); | 565 return yank_if_dead_recurse(old, old, current_block, value, regnd); |
670 } | 566 } |
671 int yank_if_dead_recurse(Node *old, Node *orig_old, Block *current_block, | 567 int yank_if_dead_recurse(Node *old, Node *orig_old, Block *current_block, |
672 Node_List *value, Node_List *regnd); | 568 Node_List *value, Node_List *regnd); |
673 int yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd ); | 569 int yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd ); |
674 int elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List ®nd, bool can_change_regs ); | 570 int elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List ®nd, bool can_change_regs ); |
675 int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List ®nd ); | 571 int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List ®nd ); |
676 bool may_be_copy_of_callee( Node *def ) const; | 572 bool may_be_copy_of_callee( Node *def ) const; |
677 | 573 |
678 // If nreg already contains the same constant as val then eliminate it | 574 // If nreg already contains the same constant as val then eliminate it |
679 bool eliminate_copy_of_constant(Node* val, Node* n, | 575 bool eliminate_copy_of_constant(Node* val, Node* n, |
680 Block *current_block, Node_List& value, Node_List ®nd, | 576 Block *current_block, Node_List& value, Node_List ®nd, |
681 OptoReg::Name nreg, OptoReg::Name nreg2); | 577 OptoReg::Name nreg, OptoReg::Name nreg2); |
682 // Extend the node to LRG mapping | 578 // Extend the node to LRG mapping |
683 void add_reference( const Node *node, const Node *old_node); | 579 void add_reference( const Node *node, const Node *old_node); |
684 | 580 |
685 private: | 581 private: |
686 | 582 |