mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8373513: C2: Move ProjNode::other_if_proj() to IfProjNode
Reviewed-by: epeter, roland
This commit is contained in:
parent
39306d7ab9
commit
9862f8f0d3
@ -933,8 +933,8 @@ bool RegionNode::optimize_trichotomy(PhaseIterGVN* igvn) {
|
||||
}
|
||||
// At this point we know that region->in(idx1) and region->(idx2) map to the same
|
||||
// value and control flow. Now search for ifs that feed into these region inputs.
|
||||
ProjNode* proj1 = region->in(idx1)->isa_Proj();
|
||||
ProjNode* proj2 = region->in(idx2)->isa_Proj();
|
||||
IfProjNode* proj1 = region->in(idx1)->isa_IfProj();
|
||||
IfProjNode* proj2 = region->in(idx2)->isa_IfProj();
|
||||
if (proj1 == nullptr || proj1->outcnt() != 1 ||
|
||||
proj2 == nullptr || proj2->outcnt() != 1) {
|
||||
return false; // No projection inputs with region as unique user found
|
||||
|
||||
@ -342,15 +342,15 @@ class IfNode : public MultiBranchNode {
|
||||
// Helper methods for fold_compares
|
||||
bool cmpi_folds(PhaseIterGVN* igvn, bool fold_ne = false);
|
||||
bool is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn);
|
||||
bool has_shared_region(ProjNode* proj, ProjNode*& success, ProjNode*& fail);
|
||||
bool has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNode*& fail, PhaseIterGVN* igvn);
|
||||
Node* merge_uncommon_traps(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn);
|
||||
bool has_shared_region(IfProjNode* proj, IfProjNode*& success, IfProjNode*& fail) const;
|
||||
bool has_only_uncommon_traps(IfProjNode* proj, IfProjNode*& success, IfProjNode*& fail, PhaseIterGVN* igvn) const;
|
||||
Node* merge_uncommon_traps(IfProjNode* proj, IfProjNode* success, IfProjNode* fail, PhaseIterGVN* igvn);
|
||||
static void improve_address_types(Node* l, Node* r, ProjNode* fail, PhaseIterGVN* igvn);
|
||||
bool is_cmp_with_loadrange(ProjNode* proj);
|
||||
bool is_null_check(ProjNode* proj, PhaseIterGVN* igvn);
|
||||
bool is_side_effect_free_test(ProjNode* proj, PhaseIterGVN* igvn);
|
||||
void reroute_side_effect_free_unc(ProjNode* proj, ProjNode* dom_proj, PhaseIterGVN* igvn);
|
||||
bool fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn);
|
||||
bool is_cmp_with_loadrange(IfProjNode* proj) const;
|
||||
bool is_null_check(IfProjNode* proj, PhaseIterGVN* igvn) const;
|
||||
bool is_side_effect_free_test(IfProjNode* proj, PhaseIterGVN* igvn) const;
|
||||
static void reroute_side_effect_free_unc(IfProjNode* proj, IfProjNode* dom_proj, PhaseIterGVN* igvn);
|
||||
bool fold_compares_helper(IfProjNode* proj, IfProjNode* success, IfProjNode* fail, PhaseIterGVN* igvn);
|
||||
static bool is_dominator_unc(CallStaticJavaNode* dom_unc, CallStaticJavaNode* unc);
|
||||
|
||||
protected:
|
||||
@ -559,6 +559,11 @@ public:
|
||||
IfProjNode(IfNode *ifnode, uint idx) : CProjNode(ifnode,idx) {}
|
||||
virtual Node* Identity(PhaseGVN* phase);
|
||||
|
||||
// Return the other IfProj node.
|
||||
IfProjNode* other_if_proj() const {
|
||||
return in(0)->as_If()->proj_out(1 - _con)->as_IfProj();
|
||||
}
|
||||
|
||||
void pin_array_access_nodes(PhaseIterGVN* igvn);
|
||||
|
||||
protected:
|
||||
|
||||
@ -771,7 +771,7 @@ bool IfNode::cmpi_folds(PhaseIterGVN* igvn, bool fold_ne) {
|
||||
// Is a dominating control suitable for folding with this if?
|
||||
bool IfNode::is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn) {
|
||||
return ctrl != nullptr &&
|
||||
ctrl->is_Proj() &&
|
||||
ctrl->is_IfProj() &&
|
||||
ctrl->outcnt() == 1 && // No side-effects
|
||||
ctrl->in(0) != nullptr &&
|
||||
ctrl->in(0)->Opcode() == Op_If &&
|
||||
@ -784,8 +784,8 @@ bool IfNode::is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn) {
|
||||
}
|
||||
|
||||
// Do this If and the dominating If share a region?
|
||||
bool IfNode::has_shared_region(ProjNode* proj, ProjNode*& success, ProjNode*& fail) {
|
||||
ProjNode* otherproj = proj->other_if_proj();
|
||||
bool IfNode::has_shared_region(IfProjNode* proj, IfProjNode*& success, IfProjNode*& fail) const {
|
||||
IfProjNode* otherproj = proj->other_if_proj();
|
||||
Node* otherproj_ctrl_use = otherproj->unique_ctrl_out_or_null();
|
||||
RegionNode* region = (otherproj_ctrl_use != nullptr && otherproj_ctrl_use->is_Region()) ? otherproj_ctrl_use->as_Region() : nullptr;
|
||||
success = nullptr;
|
||||
@ -793,13 +793,14 @@ bool IfNode::has_shared_region(ProjNode* proj, ProjNode*& success, ProjNode*& fa
|
||||
|
||||
if (otherproj->outcnt() == 1 && region != nullptr && !region->has_phi()) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ProjNode* proj = proj_out(i);
|
||||
if (success == nullptr && proj->outcnt() == 1 && proj->unique_out() == region) {
|
||||
success = proj;
|
||||
IfProjNode* next_proj = proj_out(i)->as_IfProj();
|
||||
if (success == nullptr && next_proj->outcnt() == 1 && next_proj->unique_out() == region) {
|
||||
success = next_proj;
|
||||
} else if (fail == nullptr) {
|
||||
fail = proj;
|
||||
fail = next_proj;
|
||||
} else {
|
||||
success = fail = nullptr;
|
||||
success = nullptr;
|
||||
fail = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -850,8 +851,8 @@ ProjNode* IfNode::uncommon_trap_proj(CallStaticJavaNode*& call, Deoptimization::
|
||||
}
|
||||
|
||||
// Do this If and the dominating If both branch out to an uncommon trap
|
||||
bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNode*& fail, PhaseIterGVN* igvn) {
|
||||
ProjNode* otherproj = proj->other_if_proj();
|
||||
bool IfNode::has_only_uncommon_traps(IfProjNode* proj, IfProjNode*& success, IfProjNode*& fail, PhaseIterGVN* igvn) const {
|
||||
IfProjNode* otherproj = proj->other_if_proj();
|
||||
CallStaticJavaNode* dom_unc = otherproj->is_uncommon_trap_proj();
|
||||
|
||||
if (otherproj->outcnt() == 1 && dom_unc != nullptr) {
|
||||
@ -888,8 +889,8 @@ bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNod
|
||||
!igvn->C->too_many_traps(dom_method, dom_bci, Deoptimization::Reason_range_check) &&
|
||||
// Return true if c2 manages to reconcile with UnstableIf optimization. See the comments for it.
|
||||
igvn->C->remove_unstable_if_trap(dom_unc, true/*yield*/)) {
|
||||
success = unc_proj;
|
||||
fail = unc_proj->other_if_proj();
|
||||
success = unc_proj->as_IfProj();
|
||||
fail = unc_proj->as_IfProj()->other_if_proj();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -898,7 +899,7 @@ bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNod
|
||||
}
|
||||
|
||||
// Check that the 2 CmpI can be folded into as single CmpU and proceed with the folding
|
||||
bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn) {
|
||||
bool IfNode::fold_compares_helper(IfProjNode* proj, IfProjNode* success, IfProjNode* fail, PhaseIterGVN* igvn) {
|
||||
Node* this_cmp = in(1)->in(1);
|
||||
BoolNode* this_bool = in(1)->as_Bool();
|
||||
IfNode* dom_iff = proj->in(0)->as_If();
|
||||
@ -906,7 +907,7 @@ bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* f
|
||||
Node* lo = dom_iff->in(1)->in(1)->in(2);
|
||||
Node* hi = this_cmp->in(2);
|
||||
Node* n = this_cmp->in(1);
|
||||
ProjNode* otherproj = proj->other_if_proj();
|
||||
IfProjNode* otherproj = proj->other_if_proj();
|
||||
|
||||
const TypeInt* lo_type = IfNode::filtered_int_type(igvn, n, otherproj);
|
||||
const TypeInt* hi_type = IfNode::filtered_int_type(igvn, n, success);
|
||||
@ -1108,11 +1109,11 @@ bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* f
|
||||
// Merge the branches that trap for this If and the dominating If into
|
||||
// a single region that branches to the uncommon trap for the
|
||||
// dominating If
|
||||
Node* IfNode::merge_uncommon_traps(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn) {
|
||||
Node* IfNode::merge_uncommon_traps(IfProjNode* proj, IfProjNode* success, IfProjNode* fail, PhaseIterGVN* igvn) {
|
||||
Node* res = this;
|
||||
assert(success->in(0) == this, "bad projection");
|
||||
|
||||
ProjNode* otherproj = proj->other_if_proj();
|
||||
IfProjNode* otherproj = proj->other_if_proj();
|
||||
|
||||
CallStaticJavaNode* unc = success->is_uncommon_trap_proj();
|
||||
CallStaticJavaNode* dom_unc = otherproj->is_uncommon_trap_proj();
|
||||
@ -1239,7 +1240,7 @@ void IfNode::improve_address_types(Node* l, Node* r, ProjNode* fail, PhaseIterGV
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IfNode::is_cmp_with_loadrange(ProjNode* proj) {
|
||||
bool IfNode::is_cmp_with_loadrange(IfProjNode* proj) const {
|
||||
if (in(1) != nullptr &&
|
||||
in(1)->in(1) != nullptr &&
|
||||
in(1)->in(1)->in(2) != nullptr) {
|
||||
@ -1258,7 +1259,7 @@ bool IfNode::is_cmp_with_loadrange(ProjNode* proj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IfNode::is_null_check(ProjNode* proj, PhaseIterGVN* igvn) {
|
||||
bool IfNode::is_null_check(IfProjNode* proj, PhaseIterGVN* igvn) const {
|
||||
Node* other = in(1)->in(1)->in(2);
|
||||
if (other->in(MemNode::Address) != nullptr &&
|
||||
proj->in(0)->in(1) != nullptr &&
|
||||
@ -1275,7 +1276,7 @@ bool IfNode::is_null_check(ProjNode* proj, PhaseIterGVN* igvn) {
|
||||
|
||||
// Check that the If that is in between the 2 integer comparisons has
|
||||
// no side effect
|
||||
bool IfNode::is_side_effect_free_test(ProjNode* proj, PhaseIterGVN* igvn) {
|
||||
bool IfNode::is_side_effect_free_test(IfProjNode* proj, PhaseIterGVN* igvn) const {
|
||||
if (proj == nullptr) {
|
||||
return false;
|
||||
}
|
||||
@ -1315,9 +1316,9 @@ bool IfNode::is_side_effect_free_test(ProjNode* proj, PhaseIterGVN* igvn) {
|
||||
// won't be guarded by the first CmpI anymore. It can trap in cases
|
||||
// where the first CmpI would have prevented it from executing: on a
|
||||
// trap, we need to restart execution at the state of the first CmpI
|
||||
void IfNode::reroute_side_effect_free_unc(ProjNode* proj, ProjNode* dom_proj, PhaseIterGVN* igvn) {
|
||||
void IfNode::reroute_side_effect_free_unc(IfProjNode* proj, IfProjNode* dom_proj, PhaseIterGVN* igvn) {
|
||||
CallStaticJavaNode* dom_unc = dom_proj->is_uncommon_trap_if_pattern();
|
||||
ProjNode* otherproj = proj->other_if_proj();
|
||||
IfProjNode* otherproj = proj->other_if_proj();
|
||||
CallStaticJavaNode* unc = proj->is_uncommon_trap_if_pattern();
|
||||
Node* call_proj = dom_unc->unique_ctrl_out();
|
||||
Node* halt = call_proj->unique_ctrl_out();
|
||||
@ -1348,9 +1349,9 @@ Node* IfNode::fold_compares(PhaseIterGVN* igvn) {
|
||||
if (is_ctrl_folds(ctrl, igvn)) {
|
||||
// A integer comparison immediately dominated by another integer
|
||||
// comparison
|
||||
ProjNode* success = nullptr;
|
||||
ProjNode* fail = nullptr;
|
||||
ProjNode* dom_cmp = ctrl->as_Proj();
|
||||
IfProjNode* success = nullptr;
|
||||
IfProjNode* fail = nullptr;
|
||||
IfProjNode* dom_cmp = ctrl->as_IfProj();
|
||||
if (has_shared_region(dom_cmp, success, fail) &&
|
||||
// Next call modifies graph so must be last
|
||||
fold_compares_helper(dom_cmp, success, fail, igvn)) {
|
||||
@ -1364,11 +1365,11 @@ Node* IfNode::fold_compares(PhaseIterGVN* igvn) {
|
||||
return nullptr;
|
||||
} else if (ctrl->in(0) != nullptr &&
|
||||
ctrl->in(0)->in(0) != nullptr) {
|
||||
ProjNode* success = nullptr;
|
||||
ProjNode* fail = nullptr;
|
||||
IfProjNode* success = nullptr;
|
||||
IfProjNode* fail = nullptr;
|
||||
Node* dom = ctrl->in(0)->in(0);
|
||||
ProjNode* dom_cmp = dom->isa_Proj();
|
||||
ProjNode* other_cmp = ctrl->isa_Proj();
|
||||
IfProjNode* dom_cmp = dom->isa_IfProj();
|
||||
IfProjNode* other_cmp = ctrl->isa_IfProj();
|
||||
|
||||
// Check if it's an integer comparison dominated by another
|
||||
// integer comparison with another test in between
|
||||
|
||||
@ -6171,7 +6171,7 @@ LibraryCallKit::tightly_coupled_allocation(Node* ptr) {
|
||||
|
||||
CallStaticJavaNode* LibraryCallKit::get_uncommon_trap_from_success_proj(Node* node) {
|
||||
if (node->is_IfProj()) {
|
||||
Node* other_proj = node->as_IfProj()->other_if_proj();
|
||||
IfProjNode* other_proj = node->as_IfProj()->other_if_proj();
|
||||
for (DUIterator_Fast jmax, j = other_proj->fast_outs(jmax); j < jmax; j++) {
|
||||
Node* obs = other_proj->fast_out(j);
|
||||
if (obs->in(0) == other_proj && obs->is_CallStaticJava() &&
|
||||
|
||||
@ -3103,7 +3103,7 @@ MergePrimitiveStores::CFGStatus MergePrimitiveStores::cfg_status_for_pair(const
|
||||
ctrl_use->in(0)->outcnt() != 2) {
|
||||
return CFGStatus::Failure; // Not RangeCheck.
|
||||
}
|
||||
ProjNode* other_proj = ctrl_use->as_IfProj()->other_if_proj();
|
||||
IfProjNode* other_proj = ctrl_use->as_IfProj()->other_if_proj();
|
||||
Node* trap = other_proj->is_uncommon_trap_proj(Deoptimization::Reason_range_check);
|
||||
if (trap != merge_mem->unique_out() ||
|
||||
ctrl_use->in(0)->in(0) != ctrl_def) {
|
||||
|
||||
@ -260,12 +260,7 @@ CallStaticJavaNode* ProjNode::is_uncommon_trap_if_pattern(Deoptimization::DeoptR
|
||||
// Not a projection of an If or variation of a dead If node.
|
||||
return nullptr;
|
||||
}
|
||||
return other_if_proj()->is_uncommon_trap_proj(reason);
|
||||
}
|
||||
|
||||
ProjNode* ProjNode::other_if_proj() const {
|
||||
assert(_con == 0 || _con == 1, "not an if?");
|
||||
return in(0)->as_If()->proj_out(1-_con);
|
||||
return as_IfProj()->other_if_proj()->is_uncommon_trap_proj(reason);
|
||||
}
|
||||
|
||||
NarrowMemProjNode::NarrowMemProjNode(InitializeNode* src, const TypePtr* adr_type)
|
||||
|
||||
@ -200,9 +200,6 @@ public:
|
||||
// other_proj->[region->..]call_uct"
|
||||
// null otherwise
|
||||
CallStaticJavaNode* is_uncommon_trap_if_pattern(Deoptimization::DeoptReason reason = Deoptimization::Reason_none) const;
|
||||
|
||||
// Return other proj node when this is a If proj node
|
||||
ProjNode* other_if_proj() const;
|
||||
};
|
||||
|
||||
// A ProjNode variant that captures an adr_type(). Used as a projection of InitializeNode to have the right adr_type()
|
||||
|
||||
@ -65,7 +65,7 @@ bool AssertionPredicate::has_assertion_predicate_opaque(const Node* predicate_pr
|
||||
|
||||
// Check if the other projection (UCT projection) of `success_proj` has a Halt node as output.
|
||||
bool AssertionPredicate::has_halt(const IfTrueNode* success_proj) {
|
||||
ProjNode* other_proj = success_proj->other_if_proj();
|
||||
IfProjNode* other_proj = success_proj->other_if_proj();
|
||||
return other_proj->outcnt() == 1 && other_proj->unique_out()->Opcode() == Op_Halt;
|
||||
}
|
||||
|
||||
@ -396,7 +396,7 @@ bool InitializedAssertionPredicate::is_predicate(const Node* maybe_success_proj)
|
||||
|
||||
#ifdef ASSERT
|
||||
bool InitializedAssertionPredicate::has_halt(const IfTrueNode* success_proj) {
|
||||
ProjNode* other_proj = success_proj->other_if_proj();
|
||||
IfProjNode* other_proj = success_proj->other_if_proj();
|
||||
if (other_proj->outcnt() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user