8257197: Add additional verification code to PhaseCCP
Reviewed-by: chagedorn, kvn, thartmann
This commit is contained in:
parent
7f9c6ce331
commit
11aece21f4
@ -1782,6 +1782,7 @@ void PhaseCCP::analyze() {
|
|||||||
// Push root onto worklist
|
// Push root onto worklist
|
||||||
Unique_Node_List worklist;
|
Unique_Node_List worklist;
|
||||||
worklist.push(C->root());
|
worklist.push(C->root());
|
||||||
|
DEBUG_ONLY(Unique_Node_List worklist_verify;)
|
||||||
|
|
||||||
assert(_root_and_safepoints.size() == 0, "must be empty (unused)");
|
assert(_root_and_safepoints.size() == 0, "must be empty (unused)");
|
||||||
_root_and_safepoints.push(C->root());
|
_root_and_safepoints.push(C->root());
|
||||||
@ -1790,6 +1791,7 @@ void PhaseCCP::analyze() {
|
|||||||
// This loop is the meat of CCP.
|
// This loop is the meat of CCP.
|
||||||
while (worklist.size() != 0) {
|
while (worklist.size() != 0) {
|
||||||
Node* n = fetch_next_node(worklist);
|
Node* n = fetch_next_node(worklist);
|
||||||
|
DEBUG_ONLY(worklist_verify.push(n);)
|
||||||
if (n->is_SafePoint()) {
|
if (n->is_SafePoint()) {
|
||||||
// Make sure safepoints are processed by PhaseCCP::transform even if they are
|
// Make sure safepoints are processed by PhaseCCP::transform even if they are
|
||||||
// not reachable from the bottom. Otherwise, infinite loops would be removed.
|
// not reachable from the bottom. Otherwise, infinite loops would be removed.
|
||||||
@ -1803,8 +1805,54 @@ void PhaseCCP::analyze() {
|
|||||||
push_child_nodes_to_worklist(worklist, n);
|
push_child_nodes_to_worklist(worklist, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DEBUG_ONLY(verify_analyze(worklist_verify);)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ASSERT
|
||||||
|
// For every node n on verify list, check if type(n) == n->Value()
|
||||||
|
// We have a list of exceptions, see comments in code.
|
||||||
|
void PhaseCCP::verify_analyze(Unique_Node_List& worklist_verify) {
|
||||||
|
bool failure = false;
|
||||||
|
while (worklist_verify.size()) {
|
||||||
|
Node* n = worklist_verify.pop();
|
||||||
|
const Type* told = type(n);
|
||||||
|
const Type* tnew = n->Value(this);
|
||||||
|
if (told != tnew) {
|
||||||
|
// Check special cases that are ok
|
||||||
|
if (told->isa_integer(tnew->basic_type()) != nullptr) { // both either int or long
|
||||||
|
const TypeInteger* t0 = told->is_integer(tnew->basic_type());
|
||||||
|
const TypeInteger* t1 = tnew->is_integer(tnew->basic_type());
|
||||||
|
if (t0->lo_as_long() == t1->lo_as_long() &&
|
||||||
|
t0->hi_as_long() == t1->hi_as_long()) {
|
||||||
|
continue; // ignore integer widen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n->is_Load()) {
|
||||||
|
// MemNode::can_see_stored_value looks up through many memory nodes,
|
||||||
|
// which means we would need to notify modifications from far up in
|
||||||
|
// the inputs all the way down to the LoadNode. We don't do that.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tty->cr();
|
||||||
|
tty->print_cr("Missed optimization (PhaseCCP):");
|
||||||
|
n->dump_bfs(1, 0, "");
|
||||||
|
tty->print_cr("Current type:");
|
||||||
|
told->dump_on(tty);
|
||||||
|
tty->cr();
|
||||||
|
tty->print_cr("Optimized type:");
|
||||||
|
tnew->dump_on(tty);
|
||||||
|
tty->cr();
|
||||||
|
failure = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we get this assert, check why the reported nodes were not processed again in CCP.
|
||||||
|
// We should either make sure that these nodes are properly added back to the CCP worklist
|
||||||
|
// in PhaseCCP::push_child_nodes_to_worklist() to update their type or add an exception
|
||||||
|
// in the verification code above if that is not possible for some reason (like Load nodes).
|
||||||
|
assert(!failure, "Missed optimization opportunity in PhaseCCP");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Fetch next node from worklist to be examined in this iteration.
|
// Fetch next node from worklist to be examined in this iteration.
|
||||||
Node* PhaseCCP::fetch_next_node(Unique_Node_List& worklist) {
|
Node* PhaseCCP::fetch_next_node(Unique_Node_List& worklist) {
|
||||||
if (StressCCP) {
|
if (StressCCP) {
|
||||||
|
@ -603,6 +603,10 @@ class PhaseCCP : public PhaseIterGVN {
|
|||||||
|
|
||||||
// Worklist algorithm identifies constants
|
// Worklist algorithm identifies constants
|
||||||
void analyze();
|
void analyze();
|
||||||
|
#ifdef ASSERT
|
||||||
|
// For every node n on verify list, check if type(n) == n->Value()
|
||||||
|
void verify_analyze(Unique_Node_List& worklist_verify);
|
||||||
|
#endif
|
||||||
// Recursive traversal of program. Used analysis to modify program.
|
// Recursive traversal of program. Used analysis to modify program.
|
||||||
virtual Node *transform( Node *n );
|
virtual Node *transform( Node *n );
|
||||||
// Do any transformation after analysis
|
// Do any transformation after analysis
|
||||||
|
Loading…
x
Reference in New Issue
Block a user