mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 18:14:38 +02:00
8267988: C2: assert(!addp->is_AddP() || addp->in(AddPNode::Base)->is_top() || addp->in(AddPNode::Base) == n->in(AddPNode::Base)) failed: Base pointers must match (addp 1301)
Reviewed-by: chagedorn, vlivanov, kvn
This commit is contained in:
parent
b18de6cf79
commit
4d545a1f86
8 changed files with 148 additions and 63 deletions
|
@ -1406,7 +1406,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
|
||||||
}
|
}
|
||||||
if (addr->Opcode() == Op_AddP) {
|
if (addr->Opcode() == Op_AddP) {
|
||||||
Node* orig_base = addr->in(AddPNode::Base);
|
Node* orig_base = addr->in(AddPNode::Base);
|
||||||
Node* base = new CheckCastPPNode(ctrl, orig_base, orig_base->bottom_type(), true);
|
Node* base = new CheckCastPPNode(ctrl, orig_base, orig_base->bottom_type(), ConstraintCastNode::StrongDependency);
|
||||||
phase->register_new_node(base, ctrl);
|
phase->register_new_node(base, ctrl);
|
||||||
if (addr->in(AddPNode::Base) == addr->in((AddPNode::Address))) {
|
if (addr->in(AddPNode::Base) == addr->in((AddPNode::Address))) {
|
||||||
// Field access
|
// Field access
|
||||||
|
|
|
@ -39,7 +39,7 @@ Node* ConstraintCastNode::Identity(PhaseGVN* phase) {
|
||||||
if (dom != NULL) {
|
if (dom != NULL) {
|
||||||
return dom;
|
return dom;
|
||||||
}
|
}
|
||||||
if (_carry_dependency) {
|
if (_dependency != RegularDependency) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
return phase->type(in(1))->higher_equal_speculative(_type) ? in(1) : this;
|
return phase->type(in(1))->higher_equal_speculative(_type) ? in(1) : this;
|
||||||
|
@ -82,46 +82,46 @@ Node *ConstraintCastNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConstraintCastNode::cmp(const Node &n) const {
|
bool ConstraintCastNode::cmp(const Node &n) const {
|
||||||
return TypeNode::cmp(n) && ((ConstraintCastNode&)n)._carry_dependency == _carry_dependency;
|
return TypeNode::cmp(n) && ((ConstraintCastNode&)n)._dependency == _dependency;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint ConstraintCastNode::size_of() const {
|
uint ConstraintCastNode::size_of() const {
|
||||||
return sizeof(*this);
|
return sizeof(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t, bool carry_dependency) {
|
Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency) {
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
case Op_CastII: {
|
case Op_CastII: {
|
||||||
Node* cast = new CastIINode(n, t, carry_dependency);
|
Node* cast = new CastIINode(n, t, dependency);
|
||||||
cast->set_req(0, c);
|
cast->set_req(0, c);
|
||||||
return cast;
|
return cast;
|
||||||
}
|
}
|
||||||
case Op_CastLL: {
|
case Op_CastLL: {
|
||||||
Node* cast = new CastLLNode(n, t, carry_dependency);
|
Node* cast = new CastLLNode(n, t, dependency);
|
||||||
cast->set_req(0, c);
|
cast->set_req(0, c);
|
||||||
return cast;
|
return cast;
|
||||||
}
|
}
|
||||||
case Op_CastPP: {
|
case Op_CastPP: {
|
||||||
Node* cast = new CastPPNode(n, t, carry_dependency);
|
Node* cast = new CastPPNode(n, t, dependency);
|
||||||
cast->set_req(0, c);
|
cast->set_req(0, c);
|
||||||
return cast;
|
return cast;
|
||||||
}
|
}
|
||||||
case Op_CastFF: {
|
case Op_CastFF: {
|
||||||
Node* cast = new CastFFNode(n, t, carry_dependency);
|
Node* cast = new CastFFNode(n, t, dependency);
|
||||||
cast->set_req(0, c);
|
cast->set_req(0, c);
|
||||||
return cast;
|
return cast;
|
||||||
}
|
}
|
||||||
case Op_CastDD: {
|
case Op_CastDD: {
|
||||||
Node* cast = new CastDDNode(n, t, carry_dependency);
|
Node* cast = new CastDDNode(n, t, dependency);
|
||||||
cast->set_req(0, c);
|
cast->set_req(0, c);
|
||||||
return cast;
|
return cast;
|
||||||
}
|
}
|
||||||
case Op_CastVV: {
|
case Op_CastVV: {
|
||||||
Node* cast = new CastVVNode(n, t, carry_dependency);
|
Node* cast = new CastVVNode(n, t, dependency);
|
||||||
cast->set_req(0, c);
|
cast->set_req(0, c);
|
||||||
return cast;
|
return cast;
|
||||||
}
|
}
|
||||||
case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, carry_dependency);
|
case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency);
|
||||||
default:
|
default:
|
||||||
fatal("Bad opcode %d", opcode);
|
fatal("Bad opcode %d", opcode);
|
||||||
}
|
}
|
||||||
|
@ -131,10 +131,10 @@ Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node *n, const Type *t,
|
||||||
Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, BasicType bt) {
|
Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, BasicType bt) {
|
||||||
switch(bt) {
|
switch(bt) {
|
||||||
case T_INT: {
|
case T_INT: {
|
||||||
return make_cast(Op_CastII, c, n, t, false);
|
return make_cast(Op_CastII, c, n, t, RegularDependency);
|
||||||
}
|
}
|
||||||
case T_LONG: {
|
case T_LONG: {
|
||||||
return make_cast(Op_CastLL, c, n, t, false);
|
return make_cast(Op_CastLL, c, n, t, RegularDependency);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fatal("Bad basic type %s", type2name(bt));
|
fatal("Bad basic type %s", type2name(bt));
|
||||||
|
@ -143,6 +143,9 @@ Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, BasicType bt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const {
|
TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const {
|
||||||
|
if (_dependency == UnconditionalDependency) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
Node* val = in(1);
|
Node* val = in(1);
|
||||||
Node* ctl = in(0);
|
Node* ctl = in(0);
|
||||||
int opc = Opcode();
|
int opc = Opcode();
|
||||||
|
@ -183,8 +186,8 @@ TypeNode* ConstraintCastNode::dominating_cast(PhaseGVN* gvn, PhaseTransform* pt)
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
void ConstraintCastNode::dump_spec(outputStream *st) const {
|
void ConstraintCastNode::dump_spec(outputStream *st) const {
|
||||||
TypeNode::dump_spec(st);
|
TypeNode::dump_spec(st);
|
||||||
if (_carry_dependency) {
|
if (_dependency != RegularDependency) {
|
||||||
st->print(" carry dependency");
|
st->print(" %s dependency", _dependency == StrongDependency ? "strong" : "unconditional");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -194,7 +197,7 @@ const Type* CastIINode::Value(PhaseGVN* phase) const {
|
||||||
|
|
||||||
// Try to improve the type of the CastII if we recognize a CmpI/If
|
// Try to improve the type of the CastII if we recognize a CmpI/If
|
||||||
// pattern.
|
// pattern.
|
||||||
if (_carry_dependency) {
|
if (_dependency != RegularDependency) {
|
||||||
if (in(0) != NULL && in(0)->in(0) != NULL && in(0)->in(0)->is_If()) {
|
if (in(0) != NULL && in(0)->in(0) != NULL && in(0)->in(0)->is_If()) {
|
||||||
assert(in(0)->is_IfFalse() || in(0)->is_IfTrue(), "should be If proj");
|
assert(in(0)->is_IfFalse() || in(0)->is_IfTrue(), "should be If proj");
|
||||||
Node* proj = in(0);
|
Node* proj = in(0);
|
||||||
|
@ -255,8 +258,8 @@ const Type* CastIINode::Value(PhaseGVN* phase) const {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Node* find_or_make_CastII(PhaseIterGVN* igvn, Node* parent, Node* control, const TypeInt* type, bool carry_dependency) {
|
static Node* find_or_make_CastII(PhaseIterGVN* igvn, Node* parent, Node* control, const TypeInt* type, ConstraintCastNode::DependencyType dependency) {
|
||||||
Node* n = new CastIINode(parent, type, carry_dependency);
|
Node* n = new CastIINode(parent, type, dependency);
|
||||||
n->set_req(0, control);
|
n->set_req(0, control);
|
||||||
Node* existing = igvn->hash_find_insert(n);
|
Node* existing = igvn->hash_find_insert(n);
|
||||||
if (existing != NULL) {
|
if (existing != NULL) {
|
||||||
|
@ -289,8 +292,8 @@ Node *CastIINode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
Node* x = z->in(1);
|
Node* x = z->in(1);
|
||||||
Node* y = z->in(2);
|
Node* y = z->in(2);
|
||||||
|
|
||||||
Node* cx = find_or_make_CastII(igvn, x, in(0), rx->is_int(), _carry_dependency);
|
Node* cx = find_or_make_CastII(igvn, x, in(0), rx->is_int(), _dependency);
|
||||||
Node* cy = find_or_make_CastII(igvn, y, in(0), ry->is_int(), _carry_dependency);
|
Node* cy = find_or_make_CastII(igvn, y, in(0), ry->is_int(), _dependency);
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Op_AddI: return new AddINode(cx, cy);
|
case Op_AddI: return new AddINode(cx, cy);
|
||||||
case Op_SubI: return new SubINode(cx, cy);
|
case Op_SubI: return new SubINode(cx, cy);
|
||||||
|
@ -377,7 +380,7 @@ Node* CheckCastPPNode::Identity(PhaseGVN* phase) {
|
||||||
if (dom != NULL) {
|
if (dom != NULL) {
|
||||||
return dom;
|
return dom;
|
||||||
}
|
}
|
||||||
if (_carry_dependency) {
|
if (_dependency != RegularDependency) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
const Type* t = phase->type(in(1));
|
const Type* t = phase->type(in(1));
|
||||||
|
@ -573,20 +576,20 @@ Node* CastP2XNode::Identity(PhaseGVN* phase) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type) {
|
Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency) {
|
||||||
Node* cast= NULL;
|
Node* cast= NULL;
|
||||||
if (type->isa_int()) {
|
if (type->isa_int()) {
|
||||||
cast = make_cast(Op_CastII, c, in, type, true);
|
cast = make_cast(Op_CastII, c, in, type, dependency);
|
||||||
} else if (type->isa_long()) {
|
} else if (type->isa_long()) {
|
||||||
cast = make_cast(Op_CastLL, c, in, type, true);
|
cast = make_cast(Op_CastLL, c, in, type, dependency);
|
||||||
} else if (type->isa_float()) {
|
} else if (type->isa_float()) {
|
||||||
cast = make_cast(Op_CastFF, c, in, type, true);
|
cast = make_cast(Op_CastFF, c, in, type, dependency);
|
||||||
} else if (type->isa_double()) {
|
} else if (type->isa_double()) {
|
||||||
cast = make_cast(Op_CastDD, c, in, type, true);
|
cast = make_cast(Op_CastDD, c, in, type, dependency);
|
||||||
} else if (type->isa_vect()) {
|
} else if (type->isa_vect()) {
|
||||||
cast = make_cast(Op_CastVV, c, in, type, true);
|
cast = make_cast(Op_CastVV, c, in, type, dependency);
|
||||||
} else if (type->isa_ptr()) {
|
} else if (type->isa_ptr()) {
|
||||||
cast = make_cast(Op_CastPP, c, in, type, true);
|
cast = make_cast(Op_CastPP, c, in, type, dependency);
|
||||||
}
|
}
|
||||||
return cast;
|
return cast;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,15 +32,21 @@
|
||||||
//------------------------------ConstraintCastNode-----------------------------
|
//------------------------------ConstraintCastNode-----------------------------
|
||||||
// cast to a different range
|
// cast to a different range
|
||||||
class ConstraintCastNode: public TypeNode {
|
class ConstraintCastNode: public TypeNode {
|
||||||
|
public:
|
||||||
|
enum DependencyType {
|
||||||
|
RegularDependency, // if cast doesn't improve input type, cast can be removed
|
||||||
|
StrongDependency, // leave cast in even if _type doesn't improve input type, can be replaced by stricter dominating cast if one exist
|
||||||
|
UnconditionalDependency // leave cast in unconditionally
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Can this node be removed post CCP or does it carry a required dependency?
|
const DependencyType _dependency;
|
||||||
const bool _carry_dependency;
|
|
||||||
virtual bool cmp( const Node &n ) const;
|
virtual bool cmp( const Node &n ) const;
|
||||||
virtual uint size_of() const;
|
virtual uint size_of() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ConstraintCastNode(Node *n, const Type *t, bool carry_dependency)
|
ConstraintCastNode(Node *n, const Type *t, DependencyType dependency)
|
||||||
: TypeNode(t,2), _carry_dependency(carry_dependency) {
|
: TypeNode(t,2), _dependency(dependency) {
|
||||||
init_class_id(Class_ConstraintCast);
|
init_class_id(Class_ConstraintCast);
|
||||||
init_req(1, n);
|
init_req(1, n);
|
||||||
}
|
}
|
||||||
|
@ -49,10 +55,10 @@ class ConstraintCastNode: public TypeNode {
|
||||||
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
virtual uint ideal_reg() const = 0;
|
virtual uint ideal_reg() const = 0;
|
||||||
virtual bool depends_only_on_test() const { return !_carry_dependency; }
|
virtual bool depends_only_on_test() const { return _dependency == RegularDependency; }
|
||||||
bool carry_dependency() const { return _carry_dependency; }
|
bool carry_dependency() const { return _dependency != RegularDependency; }
|
||||||
TypeNode* dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const;
|
TypeNode* dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const;
|
||||||
static Node* make_cast(int opcode, Node* c, Node *n, const Type *t, bool carry_dependency);
|
static Node* make_cast(int opcode, Node* c, Node *n, const Type *t, DependencyType dependency);
|
||||||
static Node* make(Node* c, Node *n, const Type *t, BasicType bt);
|
static Node* make(Node* c, Node *n, const Type *t, BasicType bt);
|
||||||
virtual bool operates_on(BasicType bt, bool signed_int) const {
|
virtual bool operates_on(BasicType bt, bool signed_int) const {
|
||||||
assert(bt == T_INT || bt == T_LONG, "unsupported");
|
assert(bt == T_INT || bt == T_LONG, "unsupported");
|
||||||
|
@ -63,7 +69,7 @@ class ConstraintCastNode: public TypeNode {
|
||||||
virtual void dump_spec(outputStream *st) const;
|
virtual void dump_spec(outputStream *st) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Node* make_cast_for_type(Node* c, Node* in, const Type* type);
|
static Node* make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency);
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------------------------CastIINode-------------------------------------
|
//------------------------------CastIINode-------------------------------------
|
||||||
|
@ -76,12 +82,12 @@ class CastIINode: public ConstraintCastNode {
|
||||||
virtual uint size_of() const;
|
virtual uint size_of() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CastIINode(Node* n, const Type* t, bool carry_dependency = false, bool range_check_dependency = false)
|
CastIINode(Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false)
|
||||||
: ConstraintCastNode(n, t, carry_dependency), _range_check_dependency(range_check_dependency) {
|
: ConstraintCastNode(n, t, dependency), _range_check_dependency(range_check_dependency) {
|
||||||
init_class_id(Class_CastII);
|
init_class_id(Class_CastII);
|
||||||
}
|
}
|
||||||
CastIINode(Node* ctrl, Node* n, const Type* t, bool carry_dependency = false, bool range_check_dependency = false)
|
CastIINode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false)
|
||||||
: ConstraintCastNode(n, t, carry_dependency), _range_check_dependency(range_check_dependency) {
|
: ConstraintCastNode(n, t, dependency), _range_check_dependency(range_check_dependency) {
|
||||||
init_class_id(Class_CastII);
|
init_class_id(Class_CastII);
|
||||||
init_req(0, ctrl);
|
init_req(0, ctrl);
|
||||||
}
|
}
|
||||||
|
@ -110,13 +116,13 @@ class CastIINode: public ConstraintCastNode {
|
||||||
|
|
||||||
class CastLLNode: public ConstraintCastNode {
|
class CastLLNode: public ConstraintCastNode {
|
||||||
public:
|
public:
|
||||||
CastLLNode(Node* ctrl, Node* n, const Type* t, bool carry_dependency = false)
|
CastLLNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency)
|
||||||
: ConstraintCastNode(n, t, carry_dependency) {
|
: ConstraintCastNode(n, t, dependency) {
|
||||||
init_class_id(Class_CastLL);
|
init_class_id(Class_CastLL);
|
||||||
init_req(0, ctrl);
|
init_req(0, ctrl);
|
||||||
}
|
}
|
||||||
CastLLNode(Node* n, const Type* t, bool carry_dependency = false)
|
CastLLNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
|
||||||
: ConstraintCastNode(n, t, carry_dependency){
|
: ConstraintCastNode(n, t, dependency){
|
||||||
init_class_id(Class_CastLL);
|
init_class_id(Class_CastLL);
|
||||||
}
|
}
|
||||||
virtual bool operates_on(BasicType bt, bool signed_int) const {
|
virtual bool operates_on(BasicType bt, bool signed_int) const {
|
||||||
|
@ -129,8 +135,8 @@ public:
|
||||||
|
|
||||||
class CastFFNode: public ConstraintCastNode {
|
class CastFFNode: public ConstraintCastNode {
|
||||||
public:
|
public:
|
||||||
CastFFNode(Node* n, const Type* t, bool carry_dependency = false)
|
CastFFNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
|
||||||
: ConstraintCastNode(n, t, carry_dependency){
|
: ConstraintCastNode(n, t, dependency){
|
||||||
init_class_id(Class_CastFF);
|
init_class_id(Class_CastFF);
|
||||||
}
|
}
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
|
@ -139,8 +145,8 @@ public:
|
||||||
|
|
||||||
class CastDDNode: public ConstraintCastNode {
|
class CastDDNode: public ConstraintCastNode {
|
||||||
public:
|
public:
|
||||||
CastDDNode(Node* n, const Type* t, bool carry_dependency = false)
|
CastDDNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
|
||||||
: ConstraintCastNode(n, t, carry_dependency){
|
: ConstraintCastNode(n, t, dependency){
|
||||||
init_class_id(Class_CastDD);
|
init_class_id(Class_CastDD);
|
||||||
}
|
}
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
|
@ -149,8 +155,8 @@ public:
|
||||||
|
|
||||||
class CastVVNode: public ConstraintCastNode {
|
class CastVVNode: public ConstraintCastNode {
|
||||||
public:
|
public:
|
||||||
CastVVNode(Node* n, const Type* t, bool carry_dependency = false)
|
CastVVNode(Node* n, const Type* t, DependencyType dependency = RegularDependency)
|
||||||
: ConstraintCastNode(n, t, carry_dependency){
|
: ConstraintCastNode(n, t, dependency){
|
||||||
init_class_id(Class_CastVV);
|
init_class_id(Class_CastVV);
|
||||||
}
|
}
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
|
@ -162,8 +168,8 @@ public:
|
||||||
// cast pointer to pointer (different type)
|
// cast pointer to pointer (different type)
|
||||||
class CastPPNode: public ConstraintCastNode {
|
class CastPPNode: public ConstraintCastNode {
|
||||||
public:
|
public:
|
||||||
CastPPNode (Node *n, const Type *t, bool carry_dependency = false)
|
CastPPNode (Node *n, const Type *t, DependencyType dependency = RegularDependency)
|
||||||
: ConstraintCastNode(n, t, carry_dependency) {
|
: ConstraintCastNode(n, t, dependency) {
|
||||||
}
|
}
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
virtual uint ideal_reg() const { return Op_RegP; }
|
virtual uint ideal_reg() const { return Op_RegP; }
|
||||||
|
@ -173,8 +179,8 @@ class CastPPNode: public ConstraintCastNode {
|
||||||
// for _checkcast, cast pointer to pointer (different type), without JOIN,
|
// for _checkcast, cast pointer to pointer (different type), without JOIN,
|
||||||
class CheckCastPPNode: public ConstraintCastNode {
|
class CheckCastPPNode: public ConstraintCastNode {
|
||||||
public:
|
public:
|
||||||
CheckCastPPNode(Node *c, Node *n, const Type *t, bool carry_dependency = false)
|
CheckCastPPNode(Node *c, Node *n, const Type *t, DependencyType dependency = RegularDependency)
|
||||||
: ConstraintCastNode(n, t, carry_dependency) {
|
: ConstraintCastNode(n, t, dependency) {
|
||||||
init_class_id(Class_CheckCastPP);
|
init_class_id(Class_CheckCastPP);
|
||||||
init_req(0, c);
|
init_req(0, c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1975,7 +1975,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
if (phi_type->isa_ptr()) {
|
if (phi_type->isa_ptr()) {
|
||||||
const Type* uin_type = phase->type(uin);
|
const Type* uin_type = phase->type(uin);
|
||||||
if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) {
|
if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) {
|
||||||
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true);
|
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency);
|
||||||
} else {
|
} else {
|
||||||
// Use a CastPP for a cast to not null and a CheckCastPP for
|
// Use a CastPP for a cast to not null and a CheckCastPP for
|
||||||
// a cast to a new klass (and both if both null-ness and
|
// a cast to a new klass (and both if both null-ness and
|
||||||
|
@ -1985,7 +1985,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
// null, uin's type must be casted to not null
|
// null, uin's type must be casted to not null
|
||||||
if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() &&
|
if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() &&
|
||||||
uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) {
|
uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) {
|
||||||
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, true);
|
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, ConstraintCastNode::StrongDependency);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the type of phi and uin, both casted to not null,
|
// If the type of phi and uin, both casted to not null,
|
||||||
|
@ -1997,14 +1997,14 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||||
cast = phase->transform(cast);
|
cast = phase->transform(cast);
|
||||||
n = cast;
|
n = cast;
|
||||||
}
|
}
|
||||||
cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, true);
|
cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, ConstraintCastNode::StrongDependency);
|
||||||
}
|
}
|
||||||
if (cast == NULL) {
|
if (cast == NULL) {
|
||||||
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true);
|
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cast = ConstraintCastNode::make_cast_for_type(r, uin, phi_type);
|
cast = ConstraintCastNode::make_cast_for_type(r, uin, phi_type, ConstraintCastNode::StrongDependency);
|
||||||
}
|
}
|
||||||
assert(cast != NULL, "cast should be set");
|
assert(cast != NULL, "cast should be set");
|
||||||
cast = phase->transform(cast);
|
cast = phase->transform(cast);
|
||||||
|
|
|
@ -4135,7 +4135,7 @@ Node* Compile::conv_I2X_index(PhaseGVN* phase, Node* idx, const TypeInt* sizetyp
|
||||||
Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl, bool carry_dependency) {
|
Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl, bool carry_dependency) {
|
||||||
if (ctrl != NULL) {
|
if (ctrl != NULL) {
|
||||||
// Express control dependency by a CastII node with a narrow type.
|
// Express control dependency by a CastII node with a narrow type.
|
||||||
value = new CastIINode(value, itype, carry_dependency, true /* range check dependency */);
|
value = new CastIINode(value, itype, carry_dependency ? ConstraintCastNode::StrongDependency : ConstraintCastNode::RegularDependency, true /* range check dependency */);
|
||||||
// Make the CastII node dependent on the control input to prevent the narrowed ConvI2L
|
// Make the CastII node dependent on the control input to prevent the narrowed ConvI2L
|
||||||
// node from floating above the range check during loop optimizations. Otherwise, the
|
// node from floating above the range check during loop optimizations. Otherwise, the
|
||||||
// ConvI2L node may be eliminated independently of the range check, causing the data path
|
// ConvI2L node may be eliminated independently of the range check, causing the data path
|
||||||
|
|
|
@ -1193,7 +1193,7 @@ Node *PhaseIdealLoop::clone_up_backedge_goo(Node *back_ctrl, Node *preheader_ctr
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) {
|
Node* PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) {
|
||||||
Node* castii = new CastIINode(incr, TypeInt::INT, true);
|
Node* castii = new CastIINode(incr, TypeInt::INT, ConstraintCastNode::StrongDependency);
|
||||||
castii->set_req(0, ctrl);
|
castii->set_req(0, ctrl);
|
||||||
register_new_node(castii, ctrl);
|
register_new_node(castii, ctrl);
|
||||||
for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) {
|
for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) {
|
||||||
|
|
|
@ -1503,7 +1503,15 @@ void PhaseIdealLoop::try_sink_out_of_loop(Node* n) {
|
||||||
assert(!n_loop->is_member(get_loop(x_ctrl)), "should have moved out of loop");
|
assert(!n_loop->is_member(get_loop(x_ctrl)), "should have moved out of loop");
|
||||||
register_new_node(x, x_ctrl);
|
register_new_node(x, x_ctrl);
|
||||||
|
|
||||||
if (x->in(0) == NULL && !x->is_DecodeNarrowPtr()) {
|
// Chain of AddP: (AddP base (AddP base )) must keep the same base after sinking so:
|
||||||
|
// 1- We don't add a CastPP here when the first one is sunk so if the second one is not, their bases remain
|
||||||
|
// the same.
|
||||||
|
// (see 2- below)
|
||||||
|
assert(!x->is_AddP() || !x->in(AddPNode::Address)->is_AddP() ||
|
||||||
|
x->in(AddPNode::Address)->in(AddPNode::Base) == x->in(AddPNode::Base) ||
|
||||||
|
!x->in(AddPNode::Address)->in(AddPNode::Base)->eqv_uncast(x->in(AddPNode::Base)), "unexpected AddP shape");
|
||||||
|
if (x->in(0) == NULL && !x->is_DecodeNarrowPtr() &&
|
||||||
|
!(x->is_AddP() && x->in(AddPNode::Address)->is_AddP() && x->in(AddPNode::Address)->in(AddPNode::Base) == x->in(AddPNode::Base))) {
|
||||||
assert(!x->is_Load(), "load should be pinned");
|
assert(!x->is_Load(), "load should be pinned");
|
||||||
// Use a cast node to pin clone out of loop
|
// Use a cast node to pin clone out of loop
|
||||||
Node* cast = NULL;
|
Node* cast = NULL;
|
||||||
|
@ -1511,11 +1519,22 @@ void PhaseIdealLoop::try_sink_out_of_loop(Node* n) {
|
||||||
Node* in = x->in(k);
|
Node* in = x->in(k);
|
||||||
if (in != NULL && n_loop->is_member(get_loop(get_ctrl(in)))) {
|
if (in != NULL && n_loop->is_member(get_loop(get_ctrl(in)))) {
|
||||||
const Type* in_t = _igvn.type(in);
|
const Type* in_t = _igvn.type(in);
|
||||||
cast = ConstraintCastNode::make_cast_for_type(x_ctrl, in, in_t);
|
cast = ConstraintCastNode::make_cast_for_type(x_ctrl, in, in_t, ConstraintCastNode::UnconditionalDependency);
|
||||||
}
|
}
|
||||||
if (cast != NULL) {
|
if (cast != NULL) {
|
||||||
register_new_node(cast, x_ctrl);
|
register_new_node(cast, x_ctrl);
|
||||||
x->replace_edge(in, cast);
|
x->replace_edge(in, cast);
|
||||||
|
// Chain of AddP:
|
||||||
|
// 2- A CastPP of the base is only added now that both AddP nodes are sunk
|
||||||
|
if (x->is_AddP() && k == AddPNode::Base) {
|
||||||
|
for (DUIterator_Fast imax, i = x->fast_outs(imax); i < imax; i++) {
|
||||||
|
Node* u = x->fast_out(i);
|
||||||
|
if (u->is_AddP() && u->in(AddPNode::Base) == n->in(AddPNode::Base)) {
|
||||||
|
_igvn.replace_input_of(u, AddPNode::Base, cast);
|
||||||
|
assert(u->find_out_with(Op_AddP) == NULL, "more than 2 chained AddP nodes?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021, Red Hat, Inc. 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8267988
|
||||||
|
* @summary C2: assert(!addp->is_AddP() || addp->in(AddPNode::Base)->is_top() || addp->in(AddPNode::Base) == n->in(AddPNode::Base)) failed: Base pointers must match (addp 1301)
|
||||||
|
*
|
||||||
|
* @run main/othervm -Xcomp -XX:CompileOnly=TestAddPChainWithDifferentBase TestAddPChainWithDifferentBase
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TestAddPChainWithDifferentBase {
|
||||||
|
static int x;
|
||||||
|
static int iArrFld[] = new int[400];
|
||||||
|
|
||||||
|
public static void main(String[] strArr) {
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test() {
|
||||||
|
int i6, i7 = 9, i8, i9 = 138;
|
||||||
|
|
||||||
|
for (i6 = 7; i6 > 1; i6 -= 3) {
|
||||||
|
for (i8 = i6; i8 < 4; i8++) {
|
||||||
|
try {
|
||||||
|
iArrFld[i8] = (52691 / i8);
|
||||||
|
i7 = (iArrFld[i8 + 1] % i9);
|
||||||
|
i7 = (412419036 / iArrFld[i8]);
|
||||||
|
} catch (ArithmeticException a_e) {
|
||||||
|
}
|
||||||
|
i9 += 13;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x = i7;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue