Skip to content

Commit 450e93c

Browse files
author
duke
committedMay 6, 2024
Automatic merge of jdk:master into master
2 parents 9fe414d + 4bbd972 commit 450e93c

File tree

5 files changed

+70
-60
lines changed

5 files changed

+70
-60
lines changed
 

‎src/hotspot/share/opto/cfgnode.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,11 @@ class ParsePredicateNode : public IfNode {
493493
_useless = false;
494494
}
495495

496+
// Return the uncommon trap If projection of this Parse Predicate.
497+
ParsePredicateUncommonProj* uncommon_proj() const {
498+
return proj_out(0)->as_IfFalse();
499+
}
500+
496501
Node* uncommon_trap() const;
497502

498503
Node* Ideal(PhaseGVN* phase, bool can_reshape) {

‎src/hotspot/share/opto/loopPredicate.cpp

+60-55
Original file line numberDiff line numberDiff line change
@@ -99,40 +99,38 @@ void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred,
9999
// We will create a region to guard the uct call if there is no one there.
100100
// The continuation projection (if_cont) of the new_iff is returned which
101101
// is an IfTrue projection. This code is also used to clone predicates to cloned loops.
102-
IfProjNode* PhaseIdealLoop::create_new_if_for_predicate(ParsePredicateSuccessProj* parse_predicate_proj, Node* new_entry,
103-
Deoptimization::DeoptReason reason,
102+
IfTrueNode* PhaseIdealLoop::create_new_if_for_predicate(ParsePredicateSuccessProj* parse_predicate_success_proj,
103+
Node* new_entry, const Deoptimization::DeoptReason reason,
104104
const int opcode, const bool rewire_uncommon_proj_phi_inputs) {
105-
assert(parse_predicate_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
106-
ParsePredicateNode* parse_predicate = parse_predicate_proj->in(0)->as_ParsePredicate();
107-
108-
ProjNode* uncommon_proj = parse_predicate->proj_out(false);
109-
Node* uct_region = uncommon_proj->unique_ctrl_out();
110-
assert(uct_region->is_Region() || uct_region->is_Call(), "must be a region or call uct");
105+
assert(parse_predicate_success_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
106+
ParsePredicateNode* parse_predicate = parse_predicate_success_proj->in(0)->as_ParsePredicate();
107+
ParsePredicateUncommonProj* uncommon_proj = parse_predicate->uncommon_proj();
108+
Node* uncommon_trap = parse_predicate->uncommon_trap();
111109

112110
uint proj_index = 1; // region's edge corresponding to uncommon_proj
113-
if (!uct_region->is_Region()) { // create a region to guard the call
114-
assert(uct_region->is_Call(), "must be call uct");
115-
CallNode* call = uct_region->as_Call();
111+
if (!uncommon_trap->is_Region()) { // create a region to guard the call
112+
assert(uncommon_trap->is_Call(), "must be call uct");
113+
CallNode* call = uncommon_trap->as_Call();
116114
IdealLoopTree* loop = get_loop(call);
117-
uct_region = new RegionNode(1);
115+
uncommon_trap = new RegionNode(1);
118116
Node* uncommon_proj_orig = uncommon_proj;
119-
uncommon_proj = uncommon_proj->clone()->as_Proj();
117+
uncommon_proj = uncommon_proj->clone()->as_IfFalse();
120118
register_control(uncommon_proj, loop, parse_predicate);
121-
uct_region->add_req(uncommon_proj);
122-
register_control(uct_region, loop, uncommon_proj);
123-
_igvn.replace_input_of(call, 0, uct_region);
119+
uncommon_trap->add_req(uncommon_proj);
120+
register_control(uncommon_trap, loop, uncommon_proj);
121+
_igvn.replace_input_of(call, 0, uncommon_trap);
124122
// When called from beautify_loops() idom is not constructed yet.
125123
if (_idom != nullptr) {
126-
set_idom(call, uct_region, dom_depth(uct_region));
124+
set_idom(call, uncommon_trap, dom_depth(uncommon_trap));
127125
}
128126
// Move nodes pinned on the projection or whose control is set to
129127
// the projection to the region.
130-
lazy_replace(uncommon_proj_orig, uct_region);
128+
lazy_replace(uncommon_proj_orig, uncommon_trap);
131129
} else {
132130
// Find region's edge corresponding to uncommon_proj
133-
for (; proj_index < uct_region->req(); proj_index++)
134-
if (uct_region->in(proj_index) == uncommon_proj) break;
135-
assert(proj_index < uct_region->req(), "sanity");
131+
for (; proj_index < uncommon_trap->req(); proj_index++)
132+
if (uncommon_trap->in(proj_index) == uncommon_proj) break;
133+
assert(proj_index < uncommon_trap->req(), "sanity");
136134
}
137135

138136
Node* entry = parse_predicate->in(0);
@@ -157,22 +155,23 @@ IfProjNode* PhaseIdealLoop::create_new_if_for_predicate(ParsePredicateSuccessPro
157155
fatal("no other If variant here");
158156
}
159157
register_control(new_iff, lp, entry);
160-
IfProjNode* if_cont = new IfTrueNode(new_iff);
161-
IfProjNode* if_uct = new IfFalseNode(new_iff);
158+
159+
IfTrueNode* if_cont = new IfTrueNode(new_iff);
160+
IfFalseNode* if_uct = new IfFalseNode(new_iff);
162161

163162
register_control(if_cont, lp, new_iff);
164-
register_control(if_uct, get_loop(uct_region), new_iff);
163+
register_control(if_uct, get_loop(uncommon_trap), new_iff);
165164

166-
_igvn.add_input_to(uct_region, if_uct);
165+
_igvn.add_input_to(uncommon_trap, if_uct);
167166

168167
// If rgn has phis add new edges which has the same
169168
// value as on original uncommon_proj pass.
170-
assert(uct_region->in(uct_region->req() - 1) == if_uct, "new edge should be last");
169+
assert(uncommon_trap->in(uncommon_trap->req() - 1) == if_uct, "new edge should be last");
171170
bool has_phi = false;
172-
for (DUIterator_Fast imax, i = uct_region->fast_outs(imax); i < imax; i++) {
173-
Node* use = uct_region->fast_out(i);
171+
for (DUIterator_Fast imax, i = uncommon_trap->fast_outs(imax); i < imax; i++) {
172+
Node* use = uncommon_trap->fast_out(i);
174173
if (use->is_Phi() && use->outcnt() > 0) {
175-
assert(use->in(0) == uct_region, "");
174+
assert(use->in(0) == uncommon_trap, "");
176175
_igvn.rehash_node_delayed(use);
177176
Node* phi_input = use->in(proj_index);
178177

@@ -193,7 +192,7 @@ IfProjNode* PhaseIdealLoop::create_new_if_for_predicate(ParsePredicateSuccessPro
193192
has_phi = true;
194193
}
195194
}
196-
assert(!has_phi || uct_region->req() > 3, "no phis when region is created");
195+
assert(!has_phi || uncommon_trap->req() > 3, "no phis when region is created");
197196

198197
if (new_entry == nullptr) {
199198
// Attach if_cont to iff
@@ -205,12 +204,12 @@ IfProjNode* PhaseIdealLoop::create_new_if_for_predicate(ParsePredicateSuccessPro
205204

206205
// When called from beautify_loops() idom is not constructed yet.
207206
if (_idom != nullptr) {
208-
Node* ridom = idom(uct_region);
207+
Node* ridom = idom(uncommon_trap);
209208
Node* nrdom = dom_lca_internal(ridom, new_iff);
210-
set_idom(uct_region, nrdom, dom_depth(uct_region));
209+
set_idom(uncommon_trap, nrdom, dom_depth(uncommon_trap));
211210
}
212211

213-
return if_cont->as_IfProj();
212+
return if_cont;
214213
}
215214

216215
// Update ctrl and control inputs of all data nodes starting from 'node' to 'new_ctrl' which have 'old_ctrl' as
@@ -757,8 +756,8 @@ bool IdealLoopTree::is_range_check_if(IfProjNode* if_success_proj, PhaseIdealLoo
757756
// max(scale*i + offset) = scale*(limit-stride) + offset
758757
// (2) stride*scale < 0
759758
// max(scale*i + offset) = scale*init + offset
760-
BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree* loop, Node* ctrl, int scale, Node* offset, Node* init,
761-
Node* limit, jint stride, Node* range, bool upper, bool& overflow) {
759+
BoolNode* PhaseIdealLoop::rc_predicate(Node* ctrl, const int scale, Node* offset, Node* init, Node* limit,
760+
const jint stride, Node* range, const bool upper, bool& overflow) {
762761
jint con_limit = (limit != nullptr && limit->is_Con()) ? limit->get_int() : 0;
763762
jint con_init = init->is_Con() ? init->get_int() : 0;
764763
jint con_offset = offset->is_Con() ? offset->get_int() : 0;
@@ -1165,18 +1164,19 @@ bool PhaseIdealLoop::loop_predication_impl_helper(IdealLoopTree* loop, IfProjNod
11651164
reason,
11661165
iff->Opcode());
11671166
Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0);
1168-
BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool();
1167+
BoolNode* hoisted_check_predicate_bool = invar.clone(bol, ctrl)->as_Bool();
11691168

11701169
// Negate test if necessary (Parse Predicates always have IfTrue as success projection and IfFalse as uncommon trap)
11711170
bool negated = false;
11721171
if (if_success_proj->is_IfFalse()) {
1173-
new_predicate_bol = new BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate());
1174-
register_new_node(new_predicate_bol, ctrl);
1172+
hoisted_check_predicate_bool = new BoolNode(hoisted_check_predicate_bool->in(1),
1173+
hoisted_check_predicate_bool->_test.negate());
1174+
register_new_node(hoisted_check_predicate_bool, ctrl);
11751175
negated = true;
11761176
}
11771177
IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If();
11781178
_igvn.hash_delete(new_predicate_iff);
1179-
new_predicate_iff->set_req(1, new_predicate_bol);
1179+
new_predicate_iff->set_req(1, hoisted_check_predicate_bool);
11801180

11811181
C->print_method(PHASE_AFTER_LOOP_PREDICATION_IC, 4, new_predicate_proj->in(0));
11821182

@@ -1220,7 +1220,8 @@ bool PhaseIdealLoop::loop_predication_impl_helper(IdealLoopTree* loop, IfProjNod
12201220

12211221
// Perform cloning to keep Invariance state correct since the
12221222
// late schedule will place invariant things in the loop.
1223-
Node* ctrl = parse_predicate_proj->in(0)->as_If()->in(0);
1223+
ParsePredicateNode* parse_predicate = parse_predicate_proj->in(0)->as_ParsePredicate();
1224+
Node* ctrl = parse_predicate->in(0);
12241225
rng = invar.clone(rng, ctrl);
12251226
if (offset && offset != zero) {
12261227
assert(invar.is_invariant(offset), "offset must be loop invariant");
@@ -1229,25 +1230,28 @@ bool PhaseIdealLoop::loop_predication_impl_helper(IdealLoopTree* loop, IfProjNod
12291230
// If predicate expressions may overflow in the integer range, longs are used.
12301231
bool overflow = false;
12311232
// Test the lower bound
1232-
BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false, overflow);
1233+
BoolNode* lower_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, rng, false, overflow);
12331234

12341235
const int if_opcode = iff->Opcode();
12351236
IfProjNode* lower_bound_proj = create_new_if_for_predicate(parse_predicate_proj, nullptr, reason, overflow ? Op_If : if_opcode);
12361237
IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
12371238
_igvn.hash_delete(lower_bound_iff);
12381239
lower_bound_iff->set_req(1, lower_bound_bol);
1239-
if (TraceLoopPredicate) tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx);
1240+
if (TraceLoopPredicate) {
1241+
tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx);
1242+
}
12401243

12411244
// Test the upper bound
1242-
BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true,
1243-
overflow);
1245+
BoolNode* upper_bound_bol = rc_predicate(lower_bound_proj, scale, offset, init, limit, stride, rng, true, overflow);
12441246

12451247
IfProjNode* upper_bound_proj = create_new_if_for_predicate(parse_predicate_proj, nullptr, reason, overflow ? Op_If : if_opcode);
12461248
assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
12471249
IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
12481250
_igvn.hash_delete(upper_bound_iff);
12491251
upper_bound_iff->set_req(1, upper_bound_bol);
1250-
if (TraceLoopPredicate) tty->print_cr("upper bound check if: %d", upper_bound_iff->_idx);
1252+
if (TraceLoopPredicate) {
1253+
tty->print_cr("upper bound check if: %d", upper_bound_iff->_idx);
1254+
}
12511255

12521256
// Fall through into rest of the cleanup code which will move any dependent nodes to the skeleton predicates of the
12531257
// upper bound test. We always need to create skeleton predicates in order to properly remove dead loops when later
@@ -1294,7 +1298,7 @@ IfProjNode* PhaseIdealLoop::add_template_assertion_predicate(IfNode* iff, IdealL
12941298
Node* opaque_init = new OpaqueLoopInitNode(C, init);
12951299
register_new_node(opaque_init, upper_bound_proj);
12961300
bool negate = (if_proj->_con != parse_predicate_proj->_con);
1297-
BoolNode* bol = rc_predicate(loop, upper_bound_proj, scale, offset, opaque_init, limit, stride, rng,
1301+
BoolNode* bol = rc_predicate(upper_bound_proj, scale, offset, opaque_init, limit, stride, rng,
12981302
(stride > 0) != (scale > 0), overflow);
12991303
Node* opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1)); // This will go away once loop opts are over
13001304
C->add_template_assertion_predicate_opaq(opaque_bol);
@@ -1317,7 +1321,7 @@ IfProjNode* PhaseIdealLoop::add_template_assertion_predicate(IfNode* iff, IdealL
13171321
max_value = new CastIINode(max_value, loop->_head->as_CountedLoop()->phi()->bottom_type());
13181322
register_new_node(max_value, parse_predicate_proj);
13191323

1320-
bol = rc_predicate(loop, new_proj, scale, offset, max_value, limit, stride, rng, (stride > 0) != (scale > 0),
1324+
bol = rc_predicate(new_proj, scale, offset, max_value, limit, stride, rng, (stride > 0) != (scale > 0),
13211325
overflow);
13221326
opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1));
13231327
C->add_template_assertion_predicate_opaq(opaque_bol);
@@ -1340,10 +1344,6 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree* loop) {
13401344
return false;
13411345
}
13421346

1343-
if (head->is_OuterStripMinedLoop()) {
1344-
return false;
1345-
}
1346-
13471347
CountedLoopNode *cl = nullptr;
13481348
if (head->is_valid_counted_loop(T_INT)) {
13491349
cl = head->as_CountedLoop();
@@ -1514,25 +1514,30 @@ bool PhaseIdealLoop::can_create_loop_predicates(const PredicateBlock* profiled_l
15141514

15151515
//------------------------------loop_predication--------------------------------
15161516
// driver routine for loop predication optimization
1517-
bool IdealLoopTree::loop_predication( PhaseIdealLoop *phase) {
1517+
bool IdealLoopTree::loop_predication(PhaseIdealLoop* phase) {
15181518
bool hoisted = false;
15191519
// Recursively promote predicates
15201520
if (_child) {
15211521
hoisted = _child->loop_predication( phase);
15221522
}
15231523

1524-
// self
1524+
// Self
15251525
if (can_apply_loop_predication()) {
15261526
hoisted |= phase->loop_predication_impl(this);
15271527
}
15281528

1529-
if (_next) { //sibling
1529+
// Sibling
1530+
if (_next) {
15301531
hoisted |= _next->loop_predication( phase);
15311532
}
15321533

15331534
return hoisted;
15341535
}
15351536

15361537
bool IdealLoopTree::can_apply_loop_predication() {
1537-
return _head->is_Loop() && !_irreducible && !tail()->is_top();
1538+
return !_head->is_Root() &&
1539+
_head->is_Loop() &&
1540+
!_head->is_OuterStripMinedLoop() &&
1541+
!_irreducible &&
1542+
!tail()->is_top();
15381543
}

‎src/hotspot/share/opto/loopTransform.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2772,7 +2772,7 @@ Node* PhaseIdealLoop::add_range_check_elimination_assertion_predicate(IdealLoopT
27722772
Node* offset, Node* limit, jint stride_con,
27732773
Node* value) {
27742774
bool overflow = false;
2775-
BoolNode* bol = rc_predicate(loop, ctrl, scale_con, offset, value, nullptr, stride_con,
2775+
BoolNode* bol = rc_predicate(ctrl, scale_con, offset, value, nullptr, stride_con,
27762776
limit, (stride_con > 0) != (scale_con > 0), overflow);
27772777
Node* opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1));
27782778
register_new_node(opaque_bol, ctrl);

‎src/hotspot/share/opto/loopnode.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -4320,7 +4320,7 @@ void PhaseIdealLoop::mark_loop_associated_parse_predicates_useful() {
43204320
}
43214321

43224322
void PhaseIdealLoop::mark_useful_parse_predicates_for_loop(IdealLoopTree* loop) {
4323-
Node* entry = loop->_head->in(LoopNode::EntryControl);
4323+
Node* entry = loop->_head->as_Loop()->skip_strip_mined()->in(LoopNode::EntryControl);
43244324
const Predicates predicates(entry);
43254325
ParsePredicateIterator iterator(predicates);
43264326
while (iterator.has_next()) {
@@ -4359,7 +4359,7 @@ void PhaseIdealLoop::collect_useful_template_assertion_predicates(Unique_Node_Li
43594359

43604360
void PhaseIdealLoop::collect_useful_template_assertion_predicates_for_loop(IdealLoopTree* loop,
43614361
Unique_Node_List &useful_predicates) {
4362-
Node* entry = loop->_head->in(LoopNode::EntryControl);
4362+
Node* entry = loop->_head->as_Loop()->skip_strip_mined()->in(LoopNode::EntryControl);
43634363
const Predicates predicates(entry);
43644364
if (UseProfiledLoopPredicate) {
43654365
const PredicateBlock* profiled_loop_predicate_block = predicates.profiled_loop_predicate_block();

‎src/hotspot/share/opto/loopnode.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1337,7 +1337,7 @@ class PhaseIdealLoop : public PhaseTransform {
13371337
bool* p_short_scale, int depth);
13381338

13391339
// Create a new if above the uncommon_trap_if_pattern for the predicate to be promoted
1340-
IfProjNode* create_new_if_for_predicate(ParsePredicateSuccessProj* parse_predicate_proj, Node* new_entry,
1340+
IfTrueNode* create_new_if_for_predicate(ParsePredicateSuccessProj* parse_predicate_proj, Node* new_entry,
13411341
Deoptimization::DeoptReason reason, int opcode,
13421342
bool rewire_uncommon_proj_phi_inputs = false);
13431343

@@ -1360,7 +1360,7 @@ class PhaseIdealLoop : public PhaseTransform {
13601360
}
13611361

13621362
// Construct a range check for a predicate if
1363-
BoolNode* rc_predicate(IdealLoopTree* loop, Node* ctrl, int scale, Node* offset, Node* init, Node* limit,
1363+
BoolNode* rc_predicate(Node* ctrl, int scale, Node* offset, Node* init, Node* limit,
13641364
jint stride, Node* range, bool upper, bool& overflow);
13651365

13661366
// Implementation of the loop predication to promote checks outside the loop

0 commit comments

Comments
 (0)
Please sign in to comment.