New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8257498: Remove useless skeleton predicates #2075
Changes from 5 commits
4960139
0ed11ba
5b716bc
8472300
9109b28
0e26280
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3530,8 +3530,7 @@ void PhaseIdealLoop::log_loop_tree() { | |
//---------------------collect_potentially_useful_predicates----------------------- | ||
// Helper function to collect potentially useful predicates to prevent them from | ||
// being eliminated by PhaseIdealLoop::eliminate_useless_predicates | ||
void PhaseIdealLoop::collect_potentially_useful_predicates( | ||
IdealLoopTree * loop, Unique_Node_List &useful_predicates) { | ||
void PhaseIdealLoop::collect_potentially_useful_predicates(IdealLoopTree* loop, Unique_Node_List &useful_predicates) { | ||
if (loop->_child) { // child | ||
collect_potentially_useful_predicates(loop->_child, useful_predicates); | ||
} | ||
|
@@ -3542,22 +3541,28 @@ void PhaseIdealLoop::collect_potentially_useful_predicates( | |
!loop->tail()->is_top()) { | ||
LoopNode* lpn = loop->_head->as_Loop(); | ||
Node* entry = lpn->in(LoopNode::EntryControl); | ||
Node* predicate_proj = find_predicate(entry); // loop_limit_check first | ||
if (predicate_proj != NULL) { // right pattern that can be used by loop predication | ||
|
||
Node* predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); | ||
if (predicate != NULL) { // right pattern that can be used by loop predication | ||
assert(entry->in(0)->in(1)->in(1)->Opcode() == Op_Opaque1, "must be"); | ||
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one | ||
entry = skip_loop_predicates(entry); | ||
} | ||
if (UseProfiledLoopPredicate) { | ||
predicate_proj = find_predicate(entry); // Predicate | ||
if (predicate_proj != NULL) { | ||
predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_profile_predicate); | ||
if (predicate != NULL) { // right pattern that can be used by loop predication | ||
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one | ||
get_skeleton_predicates(entry, useful_predicates, true); | ||
entry = skip_loop_predicates(entry); | ||
} | ||
} | ||
predicate_proj = find_predicate(entry); // Predicate | ||
if (predicate_proj != NULL) { | ||
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one | ||
|
||
if (UseLoopPredicate) { | ||
predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't we need to do this for Deoptimization::Reason_profile_predicate as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right, we need that as well. I updated it. |
||
if (predicate != NULL) { // right pattern that can be used by loop predication | ||
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one | ||
get_skeleton_predicates(entry, useful_predicates, true); | ||
} | ||
} | ||
} | ||
|
||
|
@@ -3571,21 +3576,31 @@ void PhaseIdealLoop::collect_potentially_useful_predicates( | |
// Note: it will also eliminates loop limits check predicate since it also uses | ||
// Opaque1 node (see Parse::add_predicate()). | ||
void PhaseIdealLoop::eliminate_useless_predicates() { | ||
if (C->predicate_count() == 0) | ||
if (C->predicate_count() == 0 && C->skeleton_predicate_count() == 0) { | ||
return; // no predicate left | ||
} | ||
|
||
Unique_Node_List useful_predicates; // to store useful predicates | ||
if (C->has_loops()) { | ||
collect_potentially_useful_predicates(_ltree_root->_child, useful_predicates); | ||
} | ||
|
||
for (int i = C->predicate_count(); i > 0; i--) { | ||
Node * n = C->predicate_opaque1_node(i-1); | ||
Node* n = C->predicate_opaque1_node(i - 1); | ||
assert(n->Opcode() == Op_Opaque1, "must be"); | ||
if (!useful_predicates.member(n)) { // not in the useful list | ||
_igvn.replace_node(n, n->in(1)); | ||
} | ||
} | ||
|
||
for (int i = C->skeleton_predicate_count(); i > 0; i--) { | ||
const int idx = i - 1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be removed for consistency with above code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that was a left over from a previous commit where we needed |
||
Node* n = C->skeleton_predicate_opaque4_node(idx); | ||
assert(n->Opcode() == Op_Opaque4, "must be"); | ||
if (!useful_predicates.member(n)) { // not in the useful list | ||
_igvn.replace_node(n, n->in(2)); | ||
} | ||
} | ||
} | ||
|
||
//------------------------process_expensive_nodes----------------------------- | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove the get_opaque parameter, populate the list with projections (the get_opaque false case) and have the caller retrieve the opaque node (predicate->in(0)->in(1)) if that's what it needs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I updated it and removed the
get_opaque
flag.