8264063: Outer Safepoint poll load should not reference the head of inner strip mined loop.
Reviewed-by: roland, vlivanov
This commit is contained in:
parent
04fa1ed4d0
commit
81d35e439d
@ -1782,20 +1782,6 @@ int MachCallNativeNode::ret_addr_offset() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indicate if the safepoint node needs the polling page as an input
|
|
||||||
|
|
||||||
// the shared code plants the oop data at the start of the generated
|
|
||||||
// code for the safepoint node and that needs ot be at the load
|
|
||||||
// instruction itself. so we cannot plant a mov of the safepoint poll
|
|
||||||
// address followed by a load. setting this to true means the mov is
|
|
||||||
// scheduled as a prior instruction. that's better for scheduling
|
|
||||||
// anyway.
|
|
||||||
|
|
||||||
bool SafePointNode::needs_polling_address_input()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
@ -146,12 +146,6 @@ int MachNode::compute_padding(int current_offset) const {
|
|||||||
|
|
||||||
// REQUIRED FUNCTIONALITY
|
// REQUIRED FUNCTIONALITY
|
||||||
|
|
||||||
// Indicate if the safepoint node needs the polling page as an input.
|
|
||||||
// Since ARM does not have absolute addressing, it does.
|
|
||||||
bool SafePointNode::needs_polling_address_input() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// emit an interrupt that is caught by the debugger (for debugging compiler)
|
// emit an interrupt that is caught by the debugger (for debugging compiler)
|
||||||
void emit_break(CodeBuffer &cbuf) {
|
void emit_break(CodeBuffer &cbuf) {
|
||||||
C2_MacroAssembler _masm(&cbuf);
|
C2_MacroAssembler _masm(&cbuf);
|
||||||
|
@ -1159,14 +1159,6 @@ static int cc_to_biint(int cc, int flags_reg) {
|
|||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
// Indicate if the safepoint node needs the polling page as an input.
|
|
||||||
bool SafePointNode::needs_polling_address_input() {
|
|
||||||
// The address is loaded from thread by a seperate node.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
// Emit an interrupt that is caught by the debugger (for debugging compiler).
|
// Emit an interrupt that is caught by the debugger (for debugging compiler).
|
||||||
void emit_break(CodeBuffer &cbuf) {
|
void emit_break(CodeBuffer &cbuf) {
|
||||||
C2_MacroAssembler _masm(&cbuf);
|
C2_MacroAssembler _masm(&cbuf);
|
||||||
|
@ -671,12 +671,6 @@ int CallLeafNoFPDirectNode::compute_padding(int current_offset) const {
|
|||||||
return (12 - current_offset) & 2;
|
return (12 - current_offset) & 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indicate if the safepoint node needs the polling page as an input.
|
|
||||||
// Since z/Architecture does not have absolute addressing, it does.
|
|
||||||
bool SafePointNode::needs_polling_address_input() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void emit_nop(CodeBuffer &cbuf) {
|
void emit_nop(CodeBuffer &cbuf) {
|
||||||
C2_MacroAssembler _masm(&cbuf);
|
C2_MacroAssembler _masm(&cbuf);
|
||||||
__ z_nop();
|
__ z_nop();
|
||||||
|
@ -484,8 +484,6 @@ public:
|
|||||||
virtual const RegMask &out_RegMask() const;
|
virtual const RegMask &out_RegMask() const;
|
||||||
virtual uint match_edge(uint idx) const;
|
virtual uint match_edge(uint idx) const;
|
||||||
|
|
||||||
static bool needs_polling_address_input();
|
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
virtual void dump_spec(outputStream *st) const;
|
virtual void dump_spec(outputStream *st) const;
|
||||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||||
|
@ -3701,16 +3701,6 @@ bool PhaseIdealLoop::match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& st
|
|||||||
for (SimpleDUIterator iter(n); iter.has_next(); iter.next()) {
|
for (SimpleDUIterator iter(n); iter.has_next(); iter.next()) {
|
||||||
Node* use = iter.get();
|
Node* use = iter.get();
|
||||||
if (!lpt->_body.contains(use)) {
|
if (!lpt->_body.contains(use)) {
|
||||||
if (n->is_CountedLoop() && n->as_CountedLoop()->is_strip_mined()) {
|
|
||||||
// In strip-mined counted loops, the CountedLoopNode may be
|
|
||||||
// used by the address polling node of the outer safepoint.
|
|
||||||
// Skip this use because it's safe.
|
|
||||||
Node* sfpt = n->as_CountedLoop()->outer_safepoint();
|
|
||||||
Node* polladr = sfpt->in(TypeFunc::Parms+0);
|
|
||||||
if (use == polladr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
msg = "node is used outside loop";
|
msg = "node is used outside loop";
|
||||||
msg_node = n;
|
msg_node = n;
|
||||||
break;
|
break;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -1638,6 +1638,16 @@ bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*&loop, BasicType iv_
|
|||||||
Node* sfpt = sfpt2->clone();
|
Node* sfpt = sfpt2->clone();
|
||||||
sfpt->set_req(0, iffalse);
|
sfpt->set_req(0, iffalse);
|
||||||
outer_le->set_req(0, sfpt);
|
outer_le->set_req(0, sfpt);
|
||||||
|
|
||||||
|
Node* polladdr = sfpt->in(TypeFunc::Parms);
|
||||||
|
if (polladdr != nullptr && polladdr->is_Load()) {
|
||||||
|
// Polling load should be pinned outside inner loop.
|
||||||
|
Node* new_polladdr = polladdr->clone();
|
||||||
|
new_polladdr->set_req(0, iffalse);
|
||||||
|
_igvn.register_new_node_with_optimizer(new_polladdr, polladdr);
|
||||||
|
set_ctrl(new_polladdr, iffalse);
|
||||||
|
sfpt->set_req(TypeFunc::Parms, new_polladdr);
|
||||||
|
}
|
||||||
// When this code runs, loop bodies have not yet been populated.
|
// When this code runs, loop bodies have not yet been populated.
|
||||||
const bool body_populated = false;
|
const bool body_populated = false;
|
||||||
register_control(sfpt, outer_ilt, iffalse, body_populated);
|
register_control(sfpt, outer_ilt, iffalse, body_populated);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user