提交 52d94e03 编写于 作者: K kvn

8021898: Broken JIT compiler optimization for loop unswitching

Summary: fix method clone_projs() to clone all related MachProj nodes.
Reviewed-by: roland, adlertz
上级 7d4df657
......@@ -287,21 +287,26 @@ void PhaseChaitin::new_lrg(const Node *x, uint lrg) {
}
bool PhaseChaitin::clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id) {
Block* bcon = _cfg.get_block_for_node(con);
uint cindex = bcon->find_node(con);
Node *con_next = bcon->_nodes[cindex+1];
if (con_next->in(0) != con || !con_next->is_MachProj()) {
return false; // No MachProj's follow
}
// Copy kills after the cloned constant
Node *kills = con_next->clone();
kills->set_req(0, copy);
b->_nodes.insert(idx, kills);
_cfg.map_node_to_block(kills, b);
new_lrg(kills, max_lrg_id);
return true;
int PhaseChaitin::clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id) {
assert(b->find_node(copy) == (idx - 1), "incorrect insert index for copy kill projections");
DEBUG_ONLY( Block* borig = _cfg.get_block_for_node(orig); )
int found_projs = 0;
uint cnt = orig->outcnt();
for (uint i = 0; i < cnt; i++) {
Node* proj = orig->raw_out(i);
if (proj->is_MachProj()) {
assert(proj->outcnt() == 0, "only kill projections are expected here");
assert(_cfg.get_block_for_node(proj) == borig, "incorrect block for kill projections");
found_projs++;
// Copy kill projections after the cloned node
Node* kills = proj->clone();
kills->set_req(0, copy);
b->_nodes.insert(idx++, kills);
_cfg.map_node_to_block(kills, b);
new_lrg(kills, max_lrg_id++);
}
}
return found_projs;
}
// Renumber the live ranges to compact them. Makes the IFG smaller.
......
......@@ -412,33 +412,22 @@ class PhaseChaitin : public PhaseRegAlloc {
uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray<uint> splits, int slidx );
uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx );
bool clone_projs(Block *b, uint idx, Node *con, Node *copy, LiveRangeMap &lrg_map) {
bool found_projs = clone_projs_shared(b, idx, con, copy, lrg_map.max_lrg_id());
if(found_projs) {
uint max_lrg_id = lrg_map.max_lrg_id();
lrg_map.set_max_lrg_id(max_lrg_id + 1);
}
return found_projs;
}
//------------------------------clone_projs------------------------------------
// After cloning some rematerialized instruction, clone any MachProj's that
// follow it. Example: Intel zero is XOR, kills flags. Sparc FP constants
// use G3 as an address temp.
bool clone_projs(Block *b, uint idx, Node *con, Node *copy, uint &max_lrg_id) {
bool found_projs = clone_projs_shared(b, idx, con, copy, max_lrg_id);
if(found_projs) {
max_lrg_id++;
int clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id);
int clone_projs(Block* b, uint idx, Node* orig, Node* copy, LiveRangeMap& lrg_map) {
uint max_lrg_id = lrg_map.max_lrg_id();
int found_projs = clone_projs(b, idx, orig, copy, max_lrg_id);
if (found_projs > 0) {
// max_lrg_id is updated during call above
lrg_map.set_max_lrg_id(max_lrg_id);
}
return found_projs;
}
bool clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id);
Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits,
int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru);
// True if lidx is used before any real register is def'd in the block
......
......@@ -322,9 +322,7 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
copy = m->clone();
// Insert the copy in the basic block, just before us
b->_nodes.insert(l++, copy);
if(_phc.clone_projs(b, l, m, copy, _phc._lrg_map)) {
l++;
}
l += _phc.clone_projs(b, l, m, copy, _phc._lrg_map);
} else {
const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
copy = new (C) MachSpillCopyNode(m, *rm, *rm);
......
......@@ -397,10 +397,15 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint
#endif
// See if the cloned def kills any flags, and copy those kills as well
uint i = insidx+1;
if( clone_projs( b, i, def, spill, maxlrg) ) {
int found_projs = clone_projs( b, i, def, spill, maxlrg);
if (found_projs > 0) {
// Adjust the point where we go hi-pressure
if( i <= b->_ihrp_index ) b->_ihrp_index++;
if( i <= b->_fhrp_index ) b->_fhrp_index++;
if (i <= b->_ihrp_index) {
b->_ihrp_index += found_projs;
}
if (i <= b->_fhrp_index) {
b->_fhrp_index += found_projs;
}
}
return spill;
......
......@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
#include "compiler/abstractCompiler.hpp"
#include "compiler/disassembler.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp"
......@@ -559,7 +560,7 @@ void frame::print_value_on(outputStream* st, JavaThread *thread) const {
st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), sp(), unextended_sp());
if (sp() != NULL)
st->print(", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), pc());
st->print(", fp=" INTPTR_FORMAT ", real_fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), real_fp(), pc());
if (StubRoutines::contains(pc())) {
st->print_cr(")");
......@@ -720,11 +721,14 @@ void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose
} else if (_cb->is_buffer_blob()) {
st->print("v ~BufferBlob::%s", ((BufferBlob *)_cb)->name());
} else if (_cb->is_nmethod()) {
Method* m = ((nmethod *)_cb)->method();
nmethod* nm = (nmethod*)_cb;
Method* m = nm->method();
if (m != NULL) {
m->name_and_sig_as_C_string(buf, buflen);
st->print("J %s @ " PTR_FORMAT " [" PTR_FORMAT "+" SIZE_FORMAT "]",
buf, _pc, _cb->code_begin(), _pc - _cb->code_begin());
st->print("J %d%s %s %s (%d bytes) @ " PTR_FORMAT " [" PTR_FORMAT "+0x%x]",
nm->compile_id(), (nm->is_osr_method() ? "%" : ""),
((nm->compiler() != NULL) ? nm->compiler()->name() : ""),
buf, m->code_size(), _pc, _cb->code_begin(), _pc - _cb->code_begin());
} else {
st->print("J " PTR_FORMAT, pc());
}
......
......@@ -586,6 +586,13 @@ void VMError::report(outputStream* st) {
while (count++ < StackPrintLimit) {
fr.print_on_error(st, buf, sizeof(buf));
st->cr();
// Compiled code may use EBP register on x86 so it looks like
// non-walkable C frame. Use frame.sender() for java frames.
if (_thread && _thread->is_Java_thread() && fr.is_java_frame()) {
RegisterMap map((JavaThread*)_thread, false); // No update
fr = fr.sender(&map);
continue;
}
if (os::is_first_C_frame(&fr)) break;
fr = os::get_sender_for_C_frame(&fr);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册