提交 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) { ...@@ -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) { int PhaseChaitin::clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id) {
Block* bcon = _cfg.get_block_for_node(con); assert(b->find_node(copy) == (idx - 1), "incorrect insert index for copy kill projections");
uint cindex = bcon->find_node(con); DEBUG_ONLY( Block* borig = _cfg.get_block_for_node(orig); )
Node *con_next = bcon->_nodes[cindex+1]; int found_projs = 0;
if (con_next->in(0) != con || !con_next->is_MachProj()) { uint cnt = orig->outcnt();
return false; // No MachProj's follow for (uint i = 0; i < cnt; i++) {
} Node* proj = orig->raw_out(i);
if (proj->is_MachProj()) {
// Copy kills after the cloned constant assert(proj->outcnt() == 0, "only kill projections are expected here");
Node *kills = con_next->clone(); 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); kills->set_req(0, copy);
b->_nodes.insert(idx, kills); b->_nodes.insert(idx++, kills);
_cfg.map_node_to_block(kills, b); _cfg.map_node_to_block(kills, b);
new_lrg(kills, max_lrg_id); new_lrg(kills, max_lrg_id++);
return true; }
}
return found_projs;
} }
// Renumber the live ranges to compact them. Makes the IFG smaller. // Renumber the live ranges to compact them. Makes the IFG smaller.
......
...@@ -412,33 +412,22 @@ class PhaseChaitin : public PhaseRegAlloc { ...@@ -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_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 ); 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------------------------------------ //------------------------------clone_projs------------------------------------
// After cloning some rematerialized instruction, clone any MachProj's that // After cloning some rematerialized instruction, clone any MachProj's that
// follow it. Example: Intel zero is XOR, kills flags. Sparc FP constants // follow it. Example: Intel zero is XOR, kills flags. Sparc FP constants
// use G3 as an address temp. // use G3 as an address temp.
bool clone_projs(Block *b, uint idx, Node *con, Node *copy, uint &max_lrg_id) { int clone_projs(Block* b, uint idx, Node* orig, Node* copy, uint& max_lrg_id);
bool found_projs = clone_projs_shared(b, idx, con, copy, max_lrg_id);
if(found_projs) { int clone_projs(Block* b, uint idx, Node* orig, Node* copy, LiveRangeMap& lrg_map) {
max_lrg_id++; 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; 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, Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits,
int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru); int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru);
// True if lidx is used before any real register is def'd in the block // 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 ) { ...@@ -322,9 +322,7 @@ void PhaseAggressiveCoalesce::insert_copies( Matcher &matcher ) {
copy = m->clone(); copy = m->clone();
// Insert the copy in the basic block, just before us // Insert the copy in the basic block, just before us
b->_nodes.insert(l++, copy); b->_nodes.insert(l++, copy);
if(_phc.clone_projs(b, l, m, copy, _phc._lrg_map)) { l += _phc.clone_projs(b, l, m, copy, _phc._lrg_map);
l++;
}
} else { } else {
const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()]; const RegMask *rm = C->matcher()->idealreg2spillmask[m->ideal_reg()];
copy = new (C) MachSpillCopyNode(m, *rm, *rm); copy = new (C) MachSpillCopyNode(m, *rm, *rm);
......
...@@ -397,10 +397,15 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint ...@@ -397,10 +397,15 @@ Node *PhaseChaitin::split_Rematerialize( Node *def, Block *b, uint insidx, uint
#endif #endif
// See if the cloned def kills any flags, and copy those kills as well // See if the cloned def kills any flags, and copy those kills as well
uint i = insidx+1; 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 // Adjust the point where we go hi-pressure
if( i <= b->_ihrp_index ) b->_ihrp_index++; if (i <= b->_ihrp_index) {
if( i <= b->_fhrp_index ) b->_fhrp_index++; b->_ihrp_index += found_projs;
}
if (i <= b->_fhrp_index) {
b->_fhrp_index += found_projs;
}
} }
return spill; return spill;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
*/ */
#include "precompiled.hpp" #include "precompiled.hpp"
#include "compiler/abstractCompiler.hpp"
#include "compiler/disassembler.hpp" #include "compiler/disassembler.hpp"
#include "gc_interface/collectedHeap.inline.hpp" #include "gc_interface/collectedHeap.inline.hpp"
#include "interpreter/interpreter.hpp" #include "interpreter/interpreter.hpp"
...@@ -559,7 +560,7 @@ void frame::print_value_on(outputStream* st, JavaThread *thread) const { ...@@ -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()); st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), sp(), unextended_sp());
if (sp() != NULL) 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())) { if (StubRoutines::contains(pc())) {
st->print_cr(")"); st->print_cr(")");
...@@ -720,11 +721,14 @@ void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose ...@@ -720,11 +721,14 @@ void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose
} else if (_cb->is_buffer_blob()) { } else if (_cb->is_buffer_blob()) {
st->print("v ~BufferBlob::%s", ((BufferBlob *)_cb)->name()); st->print("v ~BufferBlob::%s", ((BufferBlob *)_cb)->name());
} else if (_cb->is_nmethod()) { } else if (_cb->is_nmethod()) {
Method* m = ((nmethod *)_cb)->method(); nmethod* nm = (nmethod*)_cb;
Method* m = nm->method();
if (m != NULL) { if (m != NULL) {
m->name_and_sig_as_C_string(buf, buflen); m->name_and_sig_as_C_string(buf, buflen);
st->print("J %s @ " PTR_FORMAT " [" PTR_FORMAT "+" SIZE_FORMAT "]", st->print("J %d%s %s %s (%d bytes) @ " PTR_FORMAT " [" PTR_FORMAT "+0x%x]",
buf, _pc, _cb->code_begin(), _pc - _cb->code_begin()); 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 { } else {
st->print("J " PTR_FORMAT, pc()); st->print("J " PTR_FORMAT, pc());
} }
......
...@@ -586,6 +586,13 @@ void VMError::report(outputStream* st) { ...@@ -586,6 +586,13 @@ void VMError::report(outputStream* st) {
while (count++ < StackPrintLimit) { while (count++ < StackPrintLimit) {
fr.print_on_error(st, buf, sizeof(buf)); fr.print_on_error(st, buf, sizeof(buf));
st->cr(); 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; if (os::is_first_C_frame(&fr)) break;
fr = os::get_sender_for_C_frame(&fr); 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.
先完成此消息的编辑!
想要评论请 注册