提交 7b36652c 编写于 作者: S shshahma

8148786: xml.tranform fails on x86-64

Summary: CCP computes wrong type for CountedLoop iv Phi
Reviewed-by: kvn
上级 909c2ad8
/*
* Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -257,19 +257,29 @@ public:
Node *incr() const { Node *tmp = cmp_node(); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; }
Node *limit() const { Node *tmp = cmp_node(); return (tmp && tmp->req()==3) ? tmp->in(2) : NULL; }
Node *stride() const { Node *tmp = incr (); return (tmp && tmp->req()==3) ? tmp->in(2) : NULL; }
Node *phi() const { Node *tmp = incr (); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; }
Node *init_trip() const { Node *tmp = phi (); return (tmp && tmp->req()==3) ? tmp->in(1) : NULL; }
int stride_con() const;
bool stride_is_con() const { Node *tmp = stride (); return (tmp != NULL && tmp->is_Con()); }
BoolTest::mask test_trip() const { return in(TestValue)->as_Bool()->_test._test; }
PhiNode *phi() const {
Node *tmp = incr();
if (tmp && tmp->req() == 3) {
Node* phi = tmp->in(1);
if (phi->is_Phi()) {
return phi->as_Phi();
}
}
return NULL;
}
CountedLoopNode *loopnode() const {
// The CountedLoopNode that goes with this CountedLoopEndNode may
// have been optimized out by the IGVN so be cautious with the
// pattern matching on the graph
if (phi() == NULL) {
PhiNode* iv_phi = phi();
if (iv_phi == NULL) {
return NULL;
}
Node *ln = phi()->in(0);
Node *ln = iv_phi->in(0);
if (ln->is_CountedLoop() && ln->as_CountedLoop()->loopexit() == this) {
return (CountedLoopNode*)ln;
}
......
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -1416,6 +1416,27 @@ void PhaseIterGVN::add_users_to_worklist0( Node *n ) {
}
}
// Return counted loop Phi if as a counted loop exit condition, cmp
// compares the the induction variable with n
static PhiNode* countedloop_phi_from_cmp(CmpINode* cmp, Node* n) {
for (DUIterator_Fast imax, i = cmp->fast_outs(imax); i < imax; i++) {
Node* bol = cmp->fast_out(i);
for (DUIterator_Fast i2max, i2 = bol->fast_outs(i2max); i2 < i2max; i2++) {
Node* iff = bol->fast_out(i2);
if (iff->is_CountedLoopEnd()) {
CountedLoopEndNode* cle = iff->as_CountedLoopEnd();
if (cle->limit() == n) {
PhiNode* phi = cle->phi();
if (phi != NULL) {
return phi;
}
}
}
}
}
return NULL;
}
void PhaseIterGVN::add_users_to_worklist( Node *n ) {
add_users_to_worklist0(n);
......@@ -1445,18 +1466,7 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) {
Node* bol = use->raw_out(0);
if (bol->outcnt() > 0) {
Node* iff = bol->raw_out(0);
if (use_op == Op_CmpI &&
iff->is_CountedLoopEnd()) {
CountedLoopEndNode* cle = iff->as_CountedLoopEnd();
if (cle->limit() == n && cle->phi() != NULL) {
// If an opaque node feeds into the limit condition of a
// CountedLoop, we need to process the Phi node for the
// induction variable when the opaque node is removed:
// the range of values taken by the Phi is now known and
// so its type is also known.
_worklist.push(cle->phi());
}
} else if (iff->outcnt() == 2) {
if (iff->outcnt() == 2) {
// Look for the 'is_x2logic' pattern: "x ? : 0 : 1" and put the
// phi merging either 0 or 1 onto the worklist
Node* ifproj0 = iff->raw_out(0);
......@@ -1471,6 +1481,15 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) {
}
}
if (use_op == Op_CmpI) {
Node* phi = countedloop_phi_from_cmp((CmpINode*)use, n);
if (phi != NULL) {
// If an opaque node feeds into the limit condition of a
// CountedLoop, we need to process the Phi node for the
// induction variable when the opaque node is removed:
// the range of values taken by the Phi is now known and
// so its type is also known.
_worklist.push(phi);
}
Node* in1 = use->in(1);
for (uint i = 0; i < in1->outcnt(); i++) {
if (in1->raw_out(i)->Opcode() == Op_CastII) {
......@@ -1659,6 +1678,15 @@ void PhaseCCP::analyze() {
}
}
}
// If n is used in a counted loop exit condition then the type
// of the counted loop's Phi depends on the type of n. See
// PhiNode::Value().
if (m_op == Op_CmpI) {
PhiNode* phi = countedloop_phi_from_cmp((CmpINode*)m, n);
if (phi != NULL) {
worklist.push(phi);
}
}
}
}
}
......
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -417,7 +417,7 @@ public:
// Phase for iteratively performing local, pessimistic GVN-style optimizations.
// and ideal transformations on the graph.
class PhaseIterGVN : public PhaseGVN {
private:
private:
bool _delay_transform; // When true simply register the node when calling transform
// instead of actually optimizing it
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册