Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8240794: [BACKOUT] 8238384 CTW: C2 compilation fails with "assert(sto…
…re != load->find_exact_control(load->in(0))) failed: dependence cycle found"

Reviewed-by: thartmann
  • Loading branch information
rwestrel committed Mar 10, 2020
1 parent d112950 commit 43e0165eea6426a3530491e9901c6be826f23d97
@@ -1905,9 +1905,8 @@ bool Compile::must_alias(const TypePtr* adr_type, int alias_idx) {
bool Compile::can_alias(const TypePtr* adr_type, int alias_idx) {
if (alias_idx == AliasIdxTop) return false; // the empty category
if (adr_type == NULL) return false; // NULL serves as TypePtr::TOP
// Known instance doesn't alias with bottom memory
if (alias_idx == AliasIdxBot) return !adr_type->is_known_instance(); // the universal category
if (adr_type->base() == Type::AnyPtr) return !C->get_adr_type(alias_idx)->is_known_instance(); // TypePtr::BOTTOM or its twins
if (alias_idx == AliasIdxBot) return true; // the universal category
if (adr_type->base() == Type::AnyPtr) return true; // TypePtr::BOTTOM or its twins

// the only remaining possible overlap is identity
int adr_idx = get_alias_index(adr_type);
@@ -707,6 +707,19 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) {
// instead of control + memory.
if (mstore->ideal_Opcode() == Op_SafePoint)
continue;

// Check if the store is a membar on which the load is control dependent.
// Inserting an anti-dependency between that membar and the load would
// create a cycle that causes local scheduling to fail.
if (mstore->isa_MachMemBar()) {
Node* dom = load->find_exact_control(load->in(0));
while (dom != NULL && dom != dom->in(0) && dom != mstore) {
dom = dom->in(0);
}
if (dom == mstore) {
continue;
}
}
} else {
// Some raw memory, such as the load of "top" at an allocation,
// can be control dependent on the previous safepoint. See
@@ -31,7 +31,6 @@
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "opto/addnode.hpp"
#include "opto/arraycopynode.hpp"
#include "opto/callnode.hpp"
#include "opto/connode.hpp"
#include "opto/convertnode.hpp"
@@ -4090,16 +4089,8 @@ Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) {
}
} else {
Node *sctrl = has_ctrl(s) ? get_ctrl(s) : s->in(0);
const TypePtr* adr_type = s->adr_type();
if (s->is_ArrayCopy()) {
// Copy to known instance needs destination type to test for aliasing
const TypePtr* dest_type = s->as_ArrayCopy()->_dest_type;
if (dest_type != TypeOopPtr::BOTTOM) {
adr_type = dest_type;
}
}
assert(sctrl != NULL || !s->is_reachable_from_root(), "must have control");
if (sctrl != NULL && !sctrl->is_top() && C->can_alias(adr_type, load_alias_idx) && is_dominator(early, sctrl)) {
if (sctrl != NULL && !sctrl->is_top() && C->can_alias(s->adr_type(), load_alias_idx) && is_dominator(early, sctrl)) {
LCA = dom_lca_for_get_late_ctrl(LCA, sctrl, n);
}
}
@@ -119,7 +119,7 @@ class PhaseMacroExpand : public Phase {
void expand_unlock_node(UnlockNode *unlock);

// More helper methods modeled after GraphKit for array copy
void insert_mem_bar(Node** ctrl, Node** mem, int opcode, int alias_idx = Compile::AliasIdxBot, Node* precedent = NULL);
void insert_mem_bar(Node** ctrl, Node** mem, int opcode, Node* precedent = NULL);
Node* array_element_address(Node* ary, Node* idx, BasicType elembt);
Node* ConvI2L(Node* offset);

@@ -33,8 +33,8 @@
#include "utilities/align.hpp"
#include "utilities/powerOfTwo.hpp"

void PhaseMacroExpand::insert_mem_bar(Node** ctrl, Node** mem, int opcode, int alias_idx, Node* precedent) {
MemBarNode* mb = MemBarNode::make(C, opcode, alias_idx, precedent);
void PhaseMacroExpand::insert_mem_bar(Node** ctrl, Node** mem, int opcode, Node* precedent) {
MemBarNode* mb = MemBarNode::make(C, opcode, Compile::AliasIdxBot, precedent);
mb->init_req(TypeFunc::Control, *ctrl);
mb->init_req(TypeFunc::Memory, *mem);
transform_later(mb);
@@ -706,15 +706,7 @@ Node* PhaseMacroExpand::generate_arraycopy(ArrayCopyNode *ac, AllocateArrayNode*
// the membar also.
//
// Do not let reads from the cloned object float above the arraycopy.
if (ac->_dest_type != TypeOopPtr::BOTTOM && adr_type != ac->_dest_type) {
// Known instance: add memory of the destination type
MergeMemNode* mm = out_mem->clone()->as_MergeMem();
transform_later(mm);
uint dest_idx = C->get_alias_index(ac->_dest_type);
insert_mem_bar(ctrl, &out_mem, Op_MemBarCPUOrder, dest_idx);
mm->set_memory_at(dest_idx, out_mem);
out_mem = mm;
} else if (alloc != NULL && !alloc->initialization()->does_not_escape()) {
if (alloc != NULL && !alloc->initialization()->does_not_escape()) {
// Do not let stores that initialize this object be reordered with
// a subsequent store that would make this object accessible by
// other threads.
@@ -452,7 +452,6 @@ class Type {
const Type* maybe_remove_speculative(bool include_speculative) const;

virtual bool maybe_null() const { return true; }
virtual bool is_known_instance() const { return false; }

private:
// support arrays
@@ -1398,10 +1397,6 @@ class TypeNarrowPtr : public Type {
return _ptrtype;
}

bool is_known_instance() const {
return _ptrtype->is_known_instance();
}

#ifndef PRODUCT
virtual void dump2( Dict &d, uint depth, outputStream *st ) const;
#endif

This file was deleted.

0 comments on commit 43e0165

Please sign in to comment.