< prev index next >
src/hotspot/share/opto/loopnode.cpp
Print this page
rev 52710 : Upstream/backport Shenandoah to JDK11u
@@ -38,10 +38,14 @@
#include "opto/idealGraphPrinter.hpp"
#include "opto/loopnode.hpp"
#include "opto/mulnode.hpp"
#include "opto/rootnode.hpp"
#include "opto/superword.hpp"
+#include "utilities/macros.hpp"
+#if INCLUDE_SHENANDOAHGC
+#include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
+#endif
//=============================================================================
//------------------------------is_loop_iv-------------------------------------
// Determine if a node is Counted loop induction variable.
// The method is declared in node.hpp.
@@ -2711,11 +2715,16 @@
//=============================================================================
//----------------------------build_and_optimize-------------------------------
// Create a PhaseLoop. Build the ideal Loop tree. Map each Ideal Node to
// its corresponding LoopNode. If 'optimize' is true, do some loop cleanups.
-void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool skip_loop_opts, bool last_round) {
+void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
+ bool do_split_ifs = (mode == LoopOptsDefault || mode == LoopOptsZgcLastRound);
+ bool skip_loop_opts = (mode == LoopOptsNone) ;
+ bool shenandoah_opts = (mode == LoopOptsShenandoahExpand ||
+ mode == LoopOptsShenandoahPostExpand);
+
ResourceMark rm;
int old_progress = C->major_progress();
uint orig_worklist_size = _igvn._worklist.size();
@@ -2775,11 +2784,11 @@
}
return;
}
// Nothing to do, so get out
- bool stop_early = !C->has_loops() && !skip_loop_opts && !do_split_ifs && !_verify_me && !_verify_only;
+ bool stop_early = !C->has_loops() && !skip_loop_opts && !do_split_ifs && !_verify_me && !_verify_only && !shenandoah_opts;
bool do_expensive_nodes = C->should_optimize_expensive_nodes(_igvn);
if (stop_early && !do_expensive_nodes) {
_igvn.optimize(); // Cleanup NeverBranches
return;
}
@@ -2854,12 +2863,13 @@
visited.set( C->top()->_idx ); // Set C->top() as visited now
build_loop_early( visited, worklist, nstack );
// Given early legal placement, try finding counted loops. This placement
// is good enough to discover most loop invariants.
- if( !_verify_me && !_verify_only )
- _ltree_root->counted_loop( this );
+ if (!_verify_me && !_verify_only && !shenandoah_opts) {
+ _ltree_root->counted_loop(this);
+ }
// Find latest loop placement. Find ideal loop placement.
visited.Clear();
init_dom_lca_tags();
// Need C->root() on worklist when processing outs
@@ -2926,10 +2936,20 @@
log_loop_tree(_ltree_root, _ltree_root, C->log());
}
return;
}
+#if INCLUDE_SHENANDOAHGC
+ if (UseShenandoahGC && ((ShenandoahBarrierSetC2*) BarrierSet::barrier_set()->barrier_set_c2())->optimize_loops(this, mode, visited, nstack, worklist)) {
+ _igvn.optimize();
+ if (C->log() != NULL) {
+ log_loop_tree(_ltree_root, _ltree_root, C->log());
+ }
+ return;
+ }
+#endif
+
if (ReassociateInvariants) {
// Reassociate invariants and prep for split_thru_phi
for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) {
IdealLoopTree* lpt = iter.current();
bool is_counted = lpt->is_counted();
@@ -2953,13 +2973,13 @@
// Check for aggressive application of split-if and other transforms
// that require basic-block info (like cloning through Phi's)
if( SplitIfBlocks && do_split_ifs ) {
visited.Clear();
- split_if_with_blocks( visited, nstack, last_round );
+ split_if_with_blocks( visited, nstack, mode == LoopOptsZgcLastRound );
NOT_PRODUCT( if( VerifyLoopOptimizations ) verify(); );
- if (last_round) {
+ if (mode == LoopOptsZgcLastRound) {
C->set_major_progress();
}
}
if (!C->major_progress() && do_expensive_nodes && process_expensive_nodes()) {
@@ -3956,11 +3976,12 @@
Node* s = mem->fast_out(i);
worklist.push(s);
}
while(worklist.size() != 0 && LCA != early) {
Node* s = worklist.pop();
- if (s->is_Load() || s->Opcode() == Op_SafePoint) {
+ if (s->is_Load() || s->is_ShenandoahBarrier() || s->Opcode() == Op_SafePoint ||
+ (UseShenandoahGC && s->is_CallStaticJava() && s->as_CallStaticJava()->uncommon_trap_request() != 0)) {
continue;
} else if (s->is_MergeMem()) {
for (DUIterator_Fast imax, i = s->fast_outs(imax); i < imax; i++) {
Node* s1 = s->fast_out(i);
worklist.push(s1);
@@ -4144,11 +4165,13 @@
if (get_loop(least)->_nest == 0) {
return;
}
IdealLoopTree* loop = get_loop(least);
Node* head = loop->_head;
- if (head->is_OuterStripMinedLoop()) {
+ if (head->is_OuterStripMinedLoop() &&
+ // Verification can't be applied to fully built strip mined loops
+ head->as_Loop()->outer_loop_end()->in(1)->find_int_con(-1) == 0) {
Node* sfpt = head->as_Loop()->outer_safepoint();
ResourceMark rm;
Unique_Node_List wq;
wq.push(sfpt);
for (uint i = 0; i < wq.size(); i++) {
@@ -4224,10 +4247,13 @@
case Op_StrIndexOfChar:
case Op_AryEq:
case Op_HasNegatives:
pinned = false;
}
+ if (UseShenandoahGC && n->is_CMove()) {
+ pinned = false;
+ }
if( pinned ) {
IdealLoopTree *chosen_loop = get_loop(n->is_CFG() ? n : get_ctrl(n));
if( !chosen_loop->_child ) // Inner loop?
chosen_loop->_body.push(n); // Collect inner loops
return;
@@ -4488,10 +4514,11 @@
}
}
}
}
}
+#endif
// Collect a R-P-O for the whole CFG.
// Result list is in post-order (scan backwards for RPO)
void PhaseIdealLoop::rpo( Node *start, Node_Stack &stk, VectorSet &visited, Node_List &rpo_list ) const {
stk.push(start, 0);
@@ -4510,11 +4537,10 @@
rpo_list.push(m);
stk.pop();
}
}
}
-#endif
//=============================================================================
//------------------------------LoopTreeIterator-----------------------------------
< prev index next >