mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8373420: C2: Add true/false_proj*() methods for IfNode as a replacement for proj_out*(true/false)
Reviewed-by: dfenacci, roland, epeter
This commit is contained in:
parent
9a23f8aa33
commit
e4636d69e7
@ -313,8 +313,7 @@ void CastIINode::remove_range_check_cast(Compile* C) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CastLLNode::is_inner_loop_backedge(ProjNode* proj) {
|
||||
bool CastLLNode::is_inner_loop_backedge(IfProjNode* proj) {
|
||||
if (proj != nullptr) {
|
||||
Node* ctrl_use = proj->unique_ctrl_out_or_null();
|
||||
if (ctrl_use != nullptr && ctrl_use->Opcode() == Op_Loop &&
|
||||
@ -333,8 +332,8 @@ bool CastLLNode::cmp_used_at_inner_loop_exit_test(CmpNode* cmp) {
|
||||
for (DUIterator_Fast jmax, j = bol->fast_outs(jmax); j < jmax; j++) {
|
||||
Node* iff = bol->fast_out(j);
|
||||
if (iff->Opcode() == Op_If) {
|
||||
ProjNode* true_proj = iff->as_If()->proj_out_or_null(true);
|
||||
ProjNode* false_proj = iff->as_If()->proj_out_or_null(false);
|
||||
IfTrueNode* true_proj = iff->as_If()->true_proj_or_null();
|
||||
IfFalseNode* false_proj = iff->as_If()->false_proj_or_null();
|
||||
if (is_inner_loop_backedge(true_proj) || is_inner_loop_backedge(false_proj)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -239,7 +239,7 @@ public:
|
||||
init_class_id(Class_CastLL);
|
||||
}
|
||||
|
||||
static bool is_inner_loop_backedge(ProjNode* proj);
|
||||
static bool is_inner_loop_backedge(IfProjNode* proj);
|
||||
|
||||
static bool cmp_used_at_inner_loop_exit_test(CmpNode* cmp);
|
||||
bool used_at_inner_loop_exit_test() const;
|
||||
|
||||
@ -354,7 +354,7 @@ class IfNode : public MultiBranchNode {
|
||||
static bool is_dominator_unc(CallStaticJavaNode* dom_unc, CallStaticJavaNode* unc);
|
||||
|
||||
protected:
|
||||
ProjNode* range_check_trap_proj(int& flip, Node*& l, Node*& r);
|
||||
IfProjNode* range_check_trap_proj(int& flip, Node*& l, Node*& r) const;
|
||||
Node* Ideal_common(PhaseGVN *phase, bool can_reshape);
|
||||
Node* search_identical(int dist, PhaseIterGVN* igvn);
|
||||
|
||||
@ -433,6 +433,24 @@ public:
|
||||
|
||||
static IfNode* make_with_same_profile(IfNode* if_node_profile, Node* ctrl, Node* bol);
|
||||
|
||||
IfTrueNode* true_proj() const {
|
||||
return proj_out(true)->as_IfTrue();
|
||||
}
|
||||
|
||||
IfTrueNode* true_proj_or_null() const {
|
||||
ProjNode* true_proj = proj_out_or_null(true);
|
||||
return true_proj == nullptr ? nullptr : true_proj->as_IfTrue();
|
||||
}
|
||||
|
||||
IfFalseNode* false_proj() const {
|
||||
return proj_out(false)->as_IfFalse();
|
||||
}
|
||||
|
||||
IfFalseNode* false_proj_or_null() const {
|
||||
ProjNode* false_proj = proj_out_or_null(false);
|
||||
return false_proj == nullptr ? nullptr : false_proj->as_IfFalse();
|
||||
}
|
||||
|
||||
virtual int Opcode() const;
|
||||
virtual bool pinned() const { return true; }
|
||||
virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; }
|
||||
@ -523,7 +541,7 @@ class ParsePredicateNode : public IfNode {
|
||||
|
||||
// Return the uncommon trap If projection of this Parse Predicate.
|
||||
ParsePredicateUncommonProj* uncommon_proj() const {
|
||||
return proj_out(0)->as_IfFalse();
|
||||
return false_proj();
|
||||
}
|
||||
|
||||
Node* uncommon_trap() const;
|
||||
|
||||
@ -487,7 +487,7 @@ IfNode* IfNode::make_with_same_profile(IfNode* if_node_profile, Node* ctrl, Node
|
||||
|
||||
// if this IfNode follows a range check pattern return the projection
|
||||
// for the failed path
|
||||
ProjNode* IfNode::range_check_trap_proj(int& flip_test, Node*& l, Node*& r) {
|
||||
IfProjNode* IfNode::range_check_trap_proj(int& flip_test, Node*& l, Node*& r) const {
|
||||
if (outcnt() != 2) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -515,8 +515,10 @@ ProjNode* IfNode::range_check_trap_proj(int& flip_test, Node*& l, Node*& r) {
|
||||
// Flip 1: If (Bool[<] CmpU(l, LoadRange)) ...
|
||||
// Flip 2: If (Bool[<=] CmpU(LoadRange, l)) ...
|
||||
|
||||
ProjNode* iftrap = proj_out_or_null(flip_test == 2 ? true : false);
|
||||
return iftrap;
|
||||
if (flip_test == 2) {
|
||||
return true_proj_or_null();
|
||||
}
|
||||
return false_proj_or_null();
|
||||
}
|
||||
|
||||
|
||||
@ -528,7 +530,7 @@ int RangeCheckNode::is_range_check(Node* &range, Node* &index, jint &offset) {
|
||||
int flip_test = 0;
|
||||
Node* l = nullptr;
|
||||
Node* r = nullptr;
|
||||
ProjNode* iftrap = range_check_trap_proj(flip_test, l, r);
|
||||
IfProjNode* iftrap = range_check_trap_proj(flip_test, l, r);
|
||||
|
||||
if (iftrap == nullptr) {
|
||||
return 0;
|
||||
@ -1875,8 +1877,8 @@ static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff) {
|
||||
assert(iff->in(0) != nullptr, "If must be live");
|
||||
|
||||
if (iff->outcnt() != 2) return nullptr; // Malformed projections.
|
||||
Node* old_if_f = iff->proj_out(false);
|
||||
Node* old_if_t = iff->proj_out(true);
|
||||
IfFalseNode* old_if_f = iff->false_proj();
|
||||
IfTrueNode* old_if_t = iff->true_proj();
|
||||
|
||||
// CountedLoopEnds want the back-control test to be TRUE, regardless of
|
||||
// whether they are testing a 'gt' or 'lt' condition. The 'gt' condition
|
||||
@ -2192,7 +2194,7 @@ void ParsePredicateNode::mark_useless(PhaseIterGVN& igvn) {
|
||||
}
|
||||
|
||||
Node* ParsePredicateNode::uncommon_trap() const {
|
||||
ParsePredicateUncommonProj* uncommon_proj = proj_out(0)->as_IfFalse();
|
||||
ParsePredicateUncommonProj* uncommon_proj = false_proj();
|
||||
Node* uct_region_or_call = uncommon_proj->unique_ctrl_out();
|
||||
assert(uct_region_or_call->is_Region() || uct_region_or_call->is_Call(), "must be a region or call uct");
|
||||
return uct_region_or_call;
|
||||
|
||||
@ -87,7 +87,7 @@ void IdealLoopTree::record_for_igvn() {
|
||||
Node* outer_safepoint = l->outer_safepoint();
|
||||
assert(outer_safepoint != nullptr, "missing piece of strip mined loop");
|
||||
_phase->_igvn._worklist.push(outer_safepoint);
|
||||
Node* cle_out = _head->as_CountedLoop()->loopexit()->proj_out(false);
|
||||
IfFalseNode* cle_out = _head->as_CountedLoop()->loopexit()->false_proj();
|
||||
assert(cle_out != nullptr, "missing piece of strip mined loop");
|
||||
_phase->_igvn._worklist.push(cle_out);
|
||||
}
|
||||
@ -1464,9 +1464,8 @@ void PhaseIdealLoop::insert_pre_post_loops(IdealLoopTree *loop, Node_List &old_n
|
||||
pre_end->_prob = PROB_FAIR;
|
||||
|
||||
// Find the pre-loop normal exit.
|
||||
Node* pre_exit = pre_end->proj_out(false);
|
||||
assert(pre_exit->Opcode() == Op_IfFalse, "");
|
||||
IfFalseNode *new_pre_exit = new IfFalseNode(pre_end);
|
||||
IfFalseNode* pre_exit = pre_end->false_proj();
|
||||
IfFalseNode* new_pre_exit = new IfFalseNode(pre_end);
|
||||
_igvn.register_new_node_with_optimizer(new_pre_exit);
|
||||
set_idom(new_pre_exit, pre_end, dd_main_head);
|
||||
set_loop(new_pre_exit, outer_loop->_parent);
|
||||
@ -1707,8 +1706,7 @@ Node *PhaseIdealLoop::insert_post_loop(IdealLoopTree* loop, Node_List& old_new,
|
||||
|
||||
//------------------------------
|
||||
// Step A: Create a new post-Loop.
|
||||
Node* main_exit = outer_main_end->proj_out(false);
|
||||
assert(main_exit->Opcode() == Op_IfFalse, "");
|
||||
IfFalseNode* main_exit = outer_main_end->false_proj();
|
||||
int dd_main_exit = dom_depth(main_exit);
|
||||
|
||||
// Step A1: Clone the loop body of main. The clone becomes the post-loop.
|
||||
@ -1721,7 +1719,7 @@ Node *PhaseIdealLoop::insert_post_loop(IdealLoopTree* loop, Node_List& old_new,
|
||||
post_head->set_post_loop(main_head);
|
||||
|
||||
// clone_loop() above changes the exit projection
|
||||
main_exit = outer_main_end->proj_out(false);
|
||||
main_exit = outer_main_end->false_proj();
|
||||
|
||||
// Reduce the post-loop trip count.
|
||||
CountedLoopEndNode* post_end = old_new[main_end->_idx]->as_CountedLoopEnd();
|
||||
@ -1786,7 +1784,7 @@ Node *PhaseIdealLoop::insert_post_loop(IdealLoopTree* loop, Node_List& old_new,
|
||||
// right after the execution of the inner CountedLoop.
|
||||
// We have to make sure that such stores in the post loop have the right memory inputs from the main loop
|
||||
// The moved store node is always attached right after the inner loop exit, and just before the safepoint
|
||||
const Node* if_false = main_end->proj_out(false);
|
||||
const IfFalseNode* if_false = main_end->false_proj();
|
||||
for (DUIterator j = if_false->outs(); if_false->has_out(j); j++) {
|
||||
Node* store = if_false->out(j);
|
||||
if (store->is_Store()) {
|
||||
@ -3944,7 +3942,7 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Node* exit = head->loopexit()->proj_out_or_null(0);
|
||||
IfFalseNode* exit = head->loopexit()->false_proj_or_null();
|
||||
if (exit == nullptr) {
|
||||
return false;
|
||||
}
|
||||
@ -3988,7 +3986,7 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) {
|
||||
|
||||
// If the store is on the backedge, it is not executed in the last
|
||||
// iteration, and we must subtract 1 from the len.
|
||||
Node* backedge = head->loopexit()->proj_out(1);
|
||||
IfTrueNode* backedge = head->loopexit()->true_proj();
|
||||
if (store->in(0) == backedge) {
|
||||
len = new SubINode(len, _igvn.intcon(1));
|
||||
_igvn.register_new_node_with_optimizer(len);
|
||||
|
||||
@ -488,7 +488,7 @@ IfTrueNode* PhaseIdealLoop::create_new_if_for_multiversion(IfTrueNode* multivers
|
||||
IfNode* multiversion_if = multiversioning_fast_proj->in(0)->as_If();
|
||||
Node* entry = multiversion_if->in(0);
|
||||
OpaqueMultiversioningNode* opaque = multiversion_if->in(1)->as_OpaqueMultiversioning();
|
||||
IfFalseNode* multiversion_slow_proj = multiversion_if->proj_out(0)->as_IfFalse();
|
||||
IfFalseNode* multiversion_slow_proj = multiversion_if->false_proj();
|
||||
Node* slow_path = multiversion_slow_proj->unique_ctrl_out();
|
||||
|
||||
// The slow_loop may still be delayed, and waiting for runtime-checks to be added to the
|
||||
|
||||
@ -79,11 +79,10 @@ bool LoopNode::is_valid_counted_loop(BasicType bt) const {
|
||||
BaseCountedLoopNode* l = as_BaseCountedLoop();
|
||||
BaseCountedLoopEndNode* le = l->loopexit_or_null();
|
||||
if (le != nullptr &&
|
||||
le->proj_out_or_null(1 /* true */) == l->in(LoopNode::LoopBackControl)) {
|
||||
le->true_proj_or_null() == l->in(LoopNode::LoopBackControl)) {
|
||||
Node* phi = l->phi();
|
||||
Node* exit = le->proj_out_or_null(0 /* false */);
|
||||
if (exit != nullptr && exit->Opcode() == Op_IfFalse &&
|
||||
phi != nullptr && phi->is_Phi() &&
|
||||
IfFalseNode* exit = le->false_proj_or_null();
|
||||
if (exit != nullptr && phi != nullptr && phi->is_Phi() &&
|
||||
phi->in(LoopNode::LoopBackControl) == l->incr() &&
|
||||
le->loopnode() == l && le->stride_is_con()) {
|
||||
return true;
|
||||
@ -942,7 +941,7 @@ bool PhaseIdealLoop::create_loop_nest(IdealLoopTree* loop, Node_List &old_new) {
|
||||
safepoint = find_safepoint(back_control, x, loop);
|
||||
}
|
||||
|
||||
Node* exit_branch = exit_test->proj_out(false);
|
||||
IfFalseNode* exit_branch = exit_test->false_proj();
|
||||
Node* entry_control = head->in(LoopNode::EntryControl);
|
||||
|
||||
// Clone the control flow of the loop to build an outer loop
|
||||
@ -3087,7 +3086,7 @@ IfFalseNode* OuterStripMinedLoopNode::outer_loop_exit() const {
|
||||
if (le == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
Node* c = le->proj_out_or_null(false);
|
||||
IfFalseNode* c = le->false_proj_or_null();
|
||||
if (c == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -3407,7 +3406,7 @@ void OuterStripMinedLoopNode::adjust_strip_mined_loop(PhaseIterGVN* igvn) {
|
||||
return;
|
||||
}
|
||||
|
||||
Node* cle_tail = inner_cle->proj_out(true);
|
||||
IfTrueNode* cle_tail = inner_cle->true_proj();
|
||||
ResourceMark rm;
|
||||
Node_List old_new;
|
||||
if (cle_tail->outcnt() > 1) {
|
||||
@ -3549,7 +3548,7 @@ void OuterStripMinedLoopNode::transform_to_counted_loop(PhaseIterGVN* igvn, Phas
|
||||
iloop->replace_node_and_forward_ctrl(outer_le, new_end);
|
||||
}
|
||||
// the backedge of the inner loop must be rewired to the new loop end
|
||||
Node* backedge = cle->proj_out(true);
|
||||
IfTrueNode* backedge = cle->true_proj();
|
||||
igvn->replace_input_of(backedge, 0, new_end);
|
||||
if (iloop != nullptr) {
|
||||
iloop->set_idom(backedge, new_end, iloop->dom_depth(new_end) + 1);
|
||||
@ -3630,7 +3629,7 @@ const Type* OuterStripMinedLoopEndNode::Value(PhaseGVN* phase) const {
|
||||
bool OuterStripMinedLoopEndNode::is_expanded(PhaseGVN *phase) const {
|
||||
// The outer strip mined loop head only has Phi uses after expansion
|
||||
if (phase->is_IterGVN()) {
|
||||
Node* backedge = proj_out_or_null(true);
|
||||
IfTrueNode* backedge = true_proj_or_null();
|
||||
if (backedge != nullptr) {
|
||||
Node* head = backedge->unique_ctrl_out_or_null();
|
||||
if (head != nullptr && head->is_OuterStripMinedLoop()) {
|
||||
|
||||
@ -607,7 +607,7 @@ public:
|
||||
virtual SafePointNode* outer_safepoint() const;
|
||||
CountedLoopNode* inner_counted_loop() const { return unique_ctrl_out()->as_CountedLoop(); }
|
||||
CountedLoopEndNode* inner_counted_loop_end() const { return inner_counted_loop()->loopexit(); }
|
||||
IfFalseNode* inner_loop_exit() const { return inner_counted_loop_end()->proj_out(false)->as_IfFalse(); }
|
||||
IfFalseNode* inner_loop_exit() const { return inner_counted_loop_end()->false_proj(); }
|
||||
|
||||
void adjust_strip_mined_loop(PhaseIterGVN* igvn);
|
||||
|
||||
|
||||
@ -1321,8 +1321,8 @@ bool PhaseIdealLoop::identical_backtoback_ifs(Node *n) {
|
||||
return false;
|
||||
}
|
||||
IfNode* dom_if = dom->as_If();
|
||||
Node* proj_true = dom_if->proj_out(1);
|
||||
Node* proj_false = dom_if->proj_out(0);
|
||||
IfTrueNode* proj_true = dom_if->true_proj();
|
||||
IfFalseNode* proj_false = dom_if->false_proj();
|
||||
|
||||
for (uint i = 1; i < region->req(); i++) {
|
||||
if (is_dominator(proj_true, region->in(i))) {
|
||||
@ -1585,8 +1585,8 @@ bool PhaseIdealLoop::try_merge_identical_ifs(Node* n) {
|
||||
dom_if->in(1)->in(1)->as_SubTypeCheck()->method() != nullptr), "only for subtype checks with profile data attached");
|
||||
_igvn.replace_input_of(n, 1, dom_if->in(1));
|
||||
}
|
||||
ProjNode* dom_proj_true = dom_if->proj_out(1);
|
||||
ProjNode* dom_proj_false = dom_if->proj_out(0);
|
||||
IfTrueNode* dom_proj_true = dom_if->true_proj();
|
||||
IfFalseNode* dom_proj_false = dom_if->false_proj();
|
||||
|
||||
// Now split the IF
|
||||
RegionNode* new_false_region;
|
||||
@ -1630,10 +1630,10 @@ bool PhaseIdealLoop::try_merge_identical_ifs(Node* n) {
|
||||
// unrelated control dependency.
|
||||
for (uint i = 1; i < new_false_region->req(); i++) {
|
||||
if (is_dominator(dom_proj_true, new_false_region->in(i))) {
|
||||
dominated_by(dom_proj_true->as_IfProj(), new_false_region->in(i)->in(0)->as_If());
|
||||
dominated_by(dom_proj_true, new_false_region->in(i)->in(0)->as_If());
|
||||
} else {
|
||||
assert(is_dominator(dom_proj_false, new_false_region->in(i)), "bad if");
|
||||
dominated_by(dom_proj_false->as_IfProj(), new_false_region->in(i)->in(0)->as_If());
|
||||
dominated_by(dom_proj_false, new_false_region->in(i)->in(0)->as_If());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -2394,7 +2394,7 @@ void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealL
|
||||
CountedLoopEndNode* cle = cl->loopexit();
|
||||
CountedLoopNode* new_cl = old_new[cl->_idx]->as_CountedLoop();
|
||||
CountedLoopEndNode* new_cle = new_cl->as_CountedLoop()->loopexit_or_null();
|
||||
Node* cle_out = cle->proj_out(false);
|
||||
IfFalseNode* cle_out = cle->false_proj();
|
||||
|
||||
Node* new_sfpt = nullptr;
|
||||
Node* new_cle_out = cle_out->clone();
|
||||
@ -2691,7 +2691,7 @@ void PhaseIdealLoop::fix_ctrl_uses(const Node_List& body, const IdealLoopTree* l
|
||||
if (use->in(0) == cle) {
|
||||
IfFalseNode* cle_out = use->as_IfFalse();
|
||||
IfNode* le = cl->outer_loop_end();
|
||||
use = le->proj_out(false);
|
||||
use = le->false_proj();
|
||||
use_loop = get_loop(use);
|
||||
if (mode == CloneIncludesStripMined) {
|
||||
nnn = old_new[le->_idx];
|
||||
|
||||
@ -2379,8 +2379,8 @@ void PhaseMacroExpand::expand_subtypecheck_node(SubTypeCheckNode *check) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Node* iftrue = iff->as_If()->proj_out(1);
|
||||
Node* iffalse = iff->as_If()->proj_out(0);
|
||||
IfTrueNode* iftrue = iff->as_If()->true_proj();
|
||||
IfFalseNode* iffalse = iff->as_If()->false_proj();
|
||||
Node* ctrl = iff->in(0);
|
||||
|
||||
Node* subklass = nullptr;
|
||||
|
||||
@ -255,7 +255,7 @@ void StringConcat::eliminate_unneeded_control() {
|
||||
Compile* C = _stringopts->C;
|
||||
C->gvn_replace_by(n, n->in(0)->in(0));
|
||||
// get rid of the other projection
|
||||
C->gvn_replace_by(n->in(0)->as_If()->proj_out(false), C->top());
|
||||
C->gvn_replace_by(n->in(0)->as_If()->false_proj(), C->top());
|
||||
} else if (n->is_Region()) {
|
||||
Node* iff = n->in(1)->in(0);
|
||||
assert(n->req() == 3 && n->in(2)->in(0) == iff, "not a diamond");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user