Skip to content
Permalink
Browse files
8264586: [lworld] C2 compilation fails due to infinite loop in PhaseI…
…terGVN::optimize
  • Loading branch information
TobiHartmann committed Apr 6, 2021
1 parent 28a4ec0 commit 937f9b340683cee80e8e3441d0acb7fe8d78632d
Showing 6 changed files with 58 additions and 11 deletions.
@@ -1955,9 +1955,6 @@ static bool return_val_keeps_allocations_alive(Node* ret_val) {
}

void Compile::process_inline_types(PhaseIterGVN &igvn, bool remove) {
if (_inline_type_nodes.length() == 0) {
return;
}
// Make sure that the return value does not keep an otherwise unused allocation alive
if (tf()->returns_inline_type_as_fields()) {
Node* ret = NULL;
@@ -1978,6 +1975,9 @@ void Compile::process_inline_types(PhaseIterGVN &igvn, bool remove) {
}
}
}
if (_inline_type_nodes.length() == 0) {
return;
}
if (remove) {
// Remove inline type nodes
while (_inline_type_nodes.length() > 0) {
@@ -3361,13 +3361,8 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist,
memnode_worklist.append_if_missing(use);
}
} else if (use->Opcode() == Op_Return) {
assert(_compile->tf()->returns_inline_type_as_fields(), "must return an inline type");
// Get InlineKlass by removing the tag bit from the metadata pointer
Node* klass = use->in(TypeFunc::Parms);
intptr_t ptr = igvn->type(klass)->isa_rawptr()->get_con();
clear_nth_bit(ptr, 0);
assert(Metaspace::contains((void*)ptr), "should be klass");
assert(((InlineKlass*)ptr)->contains_oops(), "returned inline type must contain a reference field");
// Allocation is referenced by field of returned inline type
assert(_compile->tf()->returns_inline_type_as_fields(), "EA: unexpected reference by ReturnNode");
} else {
uint op = use->Opcode();
if ((op == Op_StrCompressedCopy || op == Op_StrInflatedCopy) &&
@@ -379,7 +379,7 @@ InlineTypePtrNode* InlineTypeBaseNode::buffer(GraphKit* kit, bool safe_for_repla

// Oop is non-NULL, use it
region->init_req(1, kit->control());
PhiNode* oop = PhiNode::make(region, not_null_oop, inline_ptr());
PhiNode* oop = PhiNode::make(region, not_null_oop, inline_ptr()->join_speculative(TypePtr::NOTNULL));
PhiNode* io = PhiNode::make(region, kit->i_o(), Type::ABIO);
PhiNode* mem = PhiNode::make(region, kit->merged_memory(), Type::MEMORY, TypePtr::BOTTOM);

@@ -933,3 +933,35 @@ void InlineTypeNode::remove_redundant_allocations(PhaseIterGVN* igvn, PhaseIdeal
}
}
}

Node* InlineTypePtrNode::Ideal(PhaseGVN* phase, bool can_reshape) {
if (can_reshape) {
// Remove useless InlineTypePtr nodes that might keep other nodes alive
ResourceMark rm;
Unique_Node_List users;
users.push(this);
bool useless = true;
for (uint i = 0; i < users.size(); ++i) {
Node* use = users.at(i);
if (use->is_Cmp() || use->Opcode() == Op_Return || use->Opcode() == Op_CastP2X || (use == this && i != 0) ||
(use->is_Load() && use->outcnt() == 1 && use->unique_out() == this)) {
// No need to keep track of field values, we can just use the oop
continue;
}
if (use->is_Load() || use->is_Store() || (use->is_InlineTypeBase() && use != this) || use->is_SafePoint()) {
// We need to keep track of field values to allow the use to be folded/scalarized
useless = false;
break;
}
for (DUIterator_Fast jmax, j = use->fast_outs(jmax); j < jmax; j++) {
users.push(use->fast_out(j));
}
}
if (useless) {
phase->is_IterGVN()->replace_node(this, get_oop());
return NULL;
}
}

return InlineTypeBaseNode::Ideal(phase, can_reshape);
}
@@ -168,6 +168,8 @@ class InlineTypePtrNode : public InlineTypeBaseNode {
}
}

virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);

public:
virtual int Opcode() const;
};
@@ -2377,6 +2377,8 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
if (is_store) {
const Type* val_t = _gvn.type(val);
if (!val_t->isa_inlinetype() || val_t->inline_klass() != inline_klass) {
set_map(old_map);
set_sp(old_sp);
return false;
}
}
@@ -204,6 +204,21 @@ void test13(MyValue5[] array) {
}
}

void test14(boolean b, MyValue4 val) {
for (int i = 0; i < 10; ++i) {
if (b) {
val = MyValue4.default;
}
MyValue4[] array = new MyValue4[1];
array[0] = val;

for (int j = 0; j < 5; ++j) {
for (int k = 0; k < 5; ++k) {
}
}
}
}

public static void main(String[] args) {
TestGenerated t = new TestGenerated();
EmptyValue[] array1 = { new EmptyValue() };
@@ -227,6 +242,7 @@ public static void main(String[] args) {
t.test11(array4);
t.test12();
t.test13(array5);
t.test14(false, MyValue4.default);
}
}
}

0 comments on commit 937f9b3

Please sign in to comment.