OpenJDK / jdk / jdk
changeset 54722:f0bce2f93e72
8219902: C2: MemNode::can_see_stored_value() ignores casts which carry control dependency
Reviewed-by: kvn
author | vlivanov |
---|---|
date | Mon, 06 May 2019 12:15:55 -0700 |
parents | 3661ad97da8f |
children | 1abca1170080 |
files | src/hotspot/share/opto/memnode.cpp src/hotspot/share/opto/node.cpp src/hotspot/share/opto/node.hpp |
diffstat | 3 files changed, 20 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/share/opto/memnode.cpp Mon May 06 12:15:49 2019 -0700 +++ b/src/hotspot/share/opto/memnode.cpp Mon May 06 12:15:55 2019 -0700 @@ -1047,11 +1047,11 @@ // 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 @@ // (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.
--- a/src/hotspot/share/opto/node.cpp Mon May 06 12:15:49 2019 -0700 +++ b/src/hotspot/share/opto/node.cpp Mon May 06 12:15:55 2019 -0700 @@ -891,13 +891,15 @@ //-----------------------------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 @@ //---------------------------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 @@ 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;
--- a/src/hotspot/share/opto/node.hpp Mon May 06 12:15:49 2019 -0700 +++ b/src/hotspot/share/opto/node.hpp Mon May 06 12:15:55 2019 -0700 @@ -456,10 +456,10 @@ 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 @@ 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 ) {