mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-19 18:07:49 +00:00
8219902: C2: MemNode::can_see_stored_value() ignores casts which carry control dependency
Reviewed-by: kvn
This commit is contained in:
parent
75d4f24c97
commit
2e0c5db11d
@ -1047,11 +1047,11 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
|
||||
// Try harder before giving up. Unify base pointers with casts (e.g., raw/non-raw pointers).
|
||||
intptr_t st_off = 0;
|
||||
Node* st_base = AddPNode::Ideal_base_and_offset(st_adr, phase, st_off);
|
||||
if (ld_base == NULL) return NULL;
|
||||
if (st_base == NULL) return NULL;
|
||||
if (ld_base->uncast() != st_base->uncast()) return NULL;
|
||||
if (ld_off != st_off) return NULL;
|
||||
if (ld_off == Type::OffsetBot) return NULL;
|
||||
if (ld_base == NULL) return NULL;
|
||||
if (st_base == NULL) return NULL;
|
||||
if (!ld_base->eqv_uncast(st_base, /*keep_deps=*/true)) return NULL;
|
||||
if (ld_off != st_off) return NULL;
|
||||
if (ld_off == Type::OffsetBot) return NULL;
|
||||
// Same base, same offset.
|
||||
// Possible improvement for arrays: check index value instead of absolute offset.
|
||||
|
||||
@ -1062,6 +1062,7 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
|
||||
// (Actually, we haven't yet proven the Q's are the same.)
|
||||
// In other words, we are loading from a casted version of
|
||||
// the same pointer-and-offset that we stored to.
|
||||
// Casted version may carry a dependency and it is respected.
|
||||
// Thus, we are able to replace L by V.
|
||||
}
|
||||
// Now prove that we have a LoadQ matched to a StoreQ, for some Q.
|
||||
|
||||
@ -891,13 +891,15 @@ int Node::disconnect_inputs(Node *n, Compile* C) {
|
||||
//-----------------------------uncast---------------------------------------
|
||||
// %%% Temporary, until we sort out CheckCastPP vs. CastPP.
|
||||
// Strip away casting. (It is depth-limited.)
|
||||
Node* Node::uncast() const {
|
||||
// Optionally, keep casts with dependencies.
|
||||
Node* Node::uncast(bool keep_deps) const {
|
||||
// Should be inline:
|
||||
//return is_ConstraintCast() ? uncast_helper(this) : (Node*) this;
|
||||
if (is_ConstraintCast())
|
||||
return uncast_helper(this);
|
||||
else
|
||||
if (is_ConstraintCast()) {
|
||||
return uncast_helper(this, keep_deps);
|
||||
} else {
|
||||
return (Node*) this;
|
||||
}
|
||||
}
|
||||
|
||||
// Find out of current node that matches opcode.
|
||||
@ -929,7 +931,7 @@ bool Node::has_out_with(int opcode1, int opcode2, int opcode3, int opcode4) {
|
||||
|
||||
|
||||
//---------------------------uncast_helper-------------------------------------
|
||||
Node* Node::uncast_helper(const Node* p) {
|
||||
Node* Node::uncast_helper(const Node* p, bool keep_deps) {
|
||||
#ifdef ASSERT
|
||||
uint depth_count = 0;
|
||||
const Node* orig_p = p;
|
||||
@ -947,6 +949,9 @@ Node* Node::uncast_helper(const Node* p) {
|
||||
if (p == NULL || p->req() != 2) {
|
||||
break;
|
||||
} else if (p->is_ConstraintCast()) {
|
||||
if (keep_deps && p->as_ConstraintCast()->carry_dependency()) {
|
||||
break; // stop at casts with dependencies
|
||||
}
|
||||
p = p->in(1);
|
||||
} else {
|
||||
break;
|
||||
|
||||
@ -456,10 +456,10 @@ protected:
|
||||
void setup_is_top();
|
||||
|
||||
// Strip away casting. (It is depth-limited.)
|
||||
Node* uncast() const;
|
||||
Node* uncast(bool keep_deps = false) const;
|
||||
// Return whether two Nodes are equivalent, after stripping casting.
|
||||
bool eqv_uncast(const Node* n) const {
|
||||
return (this->uncast() == n->uncast());
|
||||
bool eqv_uncast(const Node* n, bool keep_deps = false) const {
|
||||
return (this->uncast(keep_deps) == n->uncast(keep_deps));
|
||||
}
|
||||
|
||||
// Find out of current node that matches opcode.
|
||||
@ -470,7 +470,7 @@ protected:
|
||||
bool has_out_with(int opcode1, int opcode2, int opcode3, int opcode4);
|
||||
|
||||
private:
|
||||
static Node* uncast_helper(const Node* n);
|
||||
static Node* uncast_helper(const Node* n, bool keep_deps);
|
||||
|
||||
// Add an output edge to the end of the list
|
||||
void add_out( Node *n ) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user