提交 fb43258c 编写于 作者: K kvn

8039298: assert(base == NULL || t_adr->isa_rawptr() ||...

8039298: assert(base == NULL || t_adr->isa_rawptr() || !phase->type(base)->higher_equal(TypePtr::NULL_PTR))
Summary: Convert the assert into the runtime check to skip IGVN optimizations for problematic memory nodes. Eliminate dead nodes more aggressively.
Reviewed-by: twisti, iveresov
上级 08bde2dc
......@@ -693,6 +693,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
#endif
set_print_inlining(PrintInlining || method()->has_option("PrintInlining") NOT_PRODUCT( || PrintOptoInlining));
set_print_intrinsics(PrintIntrinsics || method()->has_option("PrintIntrinsics"));
set_has_irreducible_loop(true); // conservative until build_loop_tree() reset it
if (ProfileTraps RTM_OPT_ONLY( || UseRTMLocking )) {
// Make sure the method being compiled gets its own MDO,
......@@ -977,6 +978,8 @@ Compile::Compile( ciEnv* ci_env,
set_print_assembly(PrintFrameConverterAssembly);
set_parsed_irreducible_loop(false);
#endif
set_has_irreducible_loop(false); // no loops
CompileWrapper cw(this);
Init(/*AliasLevel=*/ 0);
init_tf((*generator)());
......@@ -1147,7 +1150,7 @@ StartNode* Compile::start() const {
if( start->is_Start() )
return start->as_Start();
}
ShouldNotReachHere();
fatal("Did not find Start node!");
return NULL;
}
......
......@@ -319,6 +319,7 @@ class Compile : public Phase {
bool _trace_opto_output;
bool _parsed_irreducible_loop; // True if ciTypeFlow detected irreducible loops during parsing
#endif
bool _has_irreducible_loop; // Found irreducible loops
// JSR 292
bool _has_method_handle_invokes; // True if this method has MethodHandle invokes.
RTMState _rtm_state; // State of Restricted Transactional Memory usage
......@@ -605,6 +606,8 @@ class Compile : public Phase {
void set_parsed_irreducible_loop(bool z) { _parsed_irreducible_loop = z; }
int _in_dump_cnt; // Required for dumping ir nodes.
#endif
bool has_irreducible_loop() const { return _has_irreducible_loop; }
void set_has_irreducible_loop(bool z) { _has_irreducible_loop = z; }
// JSR 292
bool has_method_handle_invokes() const { return _has_method_handle_invokes; }
......
......@@ -266,9 +266,9 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
// Counted loop head must be a good RegionNode with only 3 not NULL
// control input edges: Self, Entry, LoopBack.
if (x->in(LoopNode::Self) == NULL || x->req() != 3)
if (x->in(LoopNode::Self) == NULL || x->req() != 3 || loop->_irreducible) {
return false;
}
Node *init_control = x->in(LoopNode::EntryControl);
Node *back_control = x->in(LoopNode::LoopBackControl);
if (init_control == NULL || back_control == NULL) // Partially dead
......@@ -1522,11 +1522,11 @@ bool IdealLoopTree::beautify_loops( PhaseIdealLoop *phase ) {
// If I have one hot backedge, peel off myself loop.
// I better be the outermost loop.
if( _head->req() > 3 ) {
if (_head->req() > 3 && !_irreducible) {
split_outer_loop( phase );
result = true;
} else if( !_head->is_Loop() && !_irreducible ) {
} else if (!_head->is_Loop() && !_irreducible) {
// Make a new LoopNode to replace the old loop head
Node *l = new (phase->C) LoopNode( _head->in(1), _head->in(2) );
l = igvn.register_new_node_with_optimizer(l, _head);
......@@ -2938,6 +2938,7 @@ int PhaseIdealLoop::build_loop_tree_impl( Node *n, int pre_order ) {
return pre_order;
}
}
C->set_has_irreducible_loop(_has_irreducible_loops);
}
// This Node might be a decision point for loops. It is only if
......
......@@ -306,33 +306,16 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) {
int alias_idx = phase->C->get_alias_index(t_adr->is_ptr());
}
#ifdef ASSERT
Node* base = NULL;
if (address->is_AddP())
if (address->is_AddP()) {
base = address->in(AddPNode::Base);
}
if (base != NULL && phase->type(base)->higher_equal(TypePtr::NULL_PTR) &&
!t_adr->isa_rawptr()) {
// Note: raw address has TOP base and top->higher_equal(TypePtr::NULL_PTR) is true.
Compile* C = phase->C;
tty->cr();
tty->print_cr("===== NULL+offs not RAW address =====");
if (C->is_dead_node(this->_idx)) tty->print_cr("'this' is dead");
if ((ctl != NULL) && C->is_dead_node(ctl->_idx)) tty->print_cr("'ctl' is dead");
if (C->is_dead_node(mem->_idx)) tty->print_cr("'mem' is dead");
if (C->is_dead_node(address->_idx)) tty->print_cr("'address' is dead");
if (C->is_dead_node(base->_idx)) tty->print_cr("'base' is dead");
tty->cr();
base->dump(1);
tty->cr();
this->dump(2);
tty->print("this->adr_type(): "); adr_type()->dump(); tty->cr();
tty->print("phase->type(address): "); t_adr->dump(); tty->cr();
tty->print("phase->type(base): "); phase->type(address)->dump(); tty->cr();
tty->cr();
}
assert(base == NULL || t_adr->isa_rawptr() ||
!phase->type(base)->higher_equal(TypePtr::NULL_PTR), "NULL+offs not RAW address?");
#endif
// Skip this node optimization if its address has TOP base.
return NodeSentinel; // caller will return NULL
}
// Avoid independent memory operations
Node* old_mem = mem;
......
......@@ -27,6 +27,7 @@
#include "memory/allocation.inline.hpp"
#include "opto/cfgnode.hpp"
#include "opto/connode.hpp"
#include "opto/loopnode.hpp"
#include "opto/machnode.hpp"
#include "opto/matcher.hpp"
#include "opto/node.hpp"
......@@ -1255,6 +1256,7 @@ static void kill_dead_code( Node *dead, PhaseIterGVN *igvn ) {
Node *top = igvn->C->top();
nstack.push(dead);
bool has_irreducible_loop = igvn->C->has_irreducible_loop();
while (nstack.size() > 0) {
dead = nstack.pop();
......@@ -1269,13 +1271,31 @@ static void kill_dead_code( Node *dead, PhaseIterGVN *igvn ) {
assert (!use->is_Con(), "Control for Con node should be Root node.");
use->set_req(0, top); // Cut dead edge to prevent processing
nstack.push(use); // the dead node again.
} else if (!has_irreducible_loop && // Backedge could be alive in irreducible loop
use->is_Loop() && !use->is_Root() && // Don't kill Root (RootNode extends LoopNode)
use->in(LoopNode::EntryControl) == dead) { // Dead loop if its entry is dead
use->set_req(LoopNode::EntryControl, top); // Cut dead edge to prevent processing
use->set_req(0, top); // Cut self edge
nstack.push(use);
} else { // Else found a not-dead user
// Dead if all inputs are top or null
bool dead_use = !use->is_Root(); // Keep empty graph alive
for (uint j = 1; j < use->req(); j++) {
if (use->in(j) == dead) { // Turn all dead inputs into TOP
Node* in = use->in(j);
if (in == dead) { // Turn all dead inputs into TOP
use->set_req(j, top);
} else if (in != NULL && !in->is_top()) {
dead_use = false;
}
}
igvn->_worklist.push(use);
if (dead_use) {
if (use->is_Region()) {
use->set_req(0, top); // Cut self edge
}
nstack.push(use);
} else {
igvn->_worklist.push(use);
}
}
// Refresh the iterator, since any number of kills might have happened.
k = dead->last_outs(kmin);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册