Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8265587: IGV: track nodes across matching #3654

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -450,13 +450,10 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
} else {
print_prop("is_dontcare", "false");
}

#ifdef ASSERT
Node* old = C->matcher()->find_old_node(node);
if (old != NULL) {
print_prop("old_node_idx", old->_idx);
}
#endif
}

if (node->is_Proj()) {
@@ -71,10 +71,11 @@ Matcher::Matcher()
_end_inst_chain_rule(_END_INST_CHAIN_RULE),
_must_clone(must_clone),
_shared_nodes(C->comp_arena()),
#ifdef ASSERT
#ifndef PRODUCT
_old2new_map(C->comp_arena()),
_new2old_map(C->comp_arena()),
#endif
_reused(C->comp_arena()),
#endif // !PRODUCT
_allocation_started(false),
_ruleName(ruleName),
_register_save_policy(register_save_policy),
@@ -1098,16 +1099,12 @@ Node *Matcher::xform( Node *n, int max_stack ) {
if (n->is_Proj() && n->in(0) != NULL && n->in(0)->is_Multi()) { // Projections?
// Convert to machine-dependent projection
m = n->in(0)->as_Multi()->match( n->as_Proj(), this );
#ifdef ASSERT
_new2old_map.map(m->_idx, n);
#endif
NOT_PRODUCT(record_new2old(m, n);)
if (m->in(0) != NULL) // m might be top
collect_null_checks(m, n);
} else { // Else just a regular 'ol guy
m = n->clone(); // So just clone into new-space
#ifdef ASSERT
_new2old_map.map(m->_idx, n);
#endif
NOT_PRODUCT(record_new2old(m, n);)
// Def-Use edges will be added incrementally as Uses
// of this node are matched.
assert(m->outcnt() == 0, "no Uses of this clone yet");
@@ -1165,9 +1162,7 @@ Node *Matcher::xform( Node *n, int max_stack ) {
// || op == Op_BoxLock // %%%% enable this and remove (+++) in chaitin.cpp
) {
m = m->clone();
#ifdef ASSERT
_new2old_map.map(m->_idx, n);
#endif
NOT_PRODUCT(record_new2old(m, n));
mstack.push(m, Post_Visit, n, i); // Don't need to visit
mstack.push(m->in(0), Visit, m, 0);
} else {
@@ -1499,10 +1494,8 @@ MachNode *Matcher::match_tree( const Node *n ) {
}
// Reduce input tree based upon the state labels to machine Nodes
MachNode *m = ReduceInst(s, s->rule(mincost), mem);
#ifdef ASSERT
_old2new_map.map(n->_idx, m);
_new2old_map.map(m->_idx, (Node*)n);
#endif
// New-to-old mapping is done in ReduceInst, to cover complex instructions.
NOT_PRODUCT(_old2new_map.map(n->_idx, m);)

// Add any Matcher-ignored edges
uint cnt = n->req();
@@ -1759,6 +1752,7 @@ MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) {
mach->_opnds[0] = s->MachOperGenerator(_reduceOp[rule]);
assert( mach->_opnds[0] != NULL, "Missing result operand" );
Node *leaf = s->_leaf;
NOT_PRODUCT(record_new2old(mach, leaf);)
// Check for instruction or instruction chain rule
if( rule >= _END_INST_CHAIN_RULE || rule < _BEGIN_INST_CHAIN_RULE ) {
assert(C->node_arena()->contains(s->_leaf) || !has_new_node(s->_leaf),
@@ -1827,9 +1821,7 @@ MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) {
for( uint i=0; i<mach->req(); i++ ) {
mach->set_req(i,NULL);
}
#ifdef ASSERT
_new2old_map.map(ex->_idx, s->_leaf);
#endif
NOT_PRODUCT(record_new2old(ex, s->_leaf);)
}

// PhaseChaitin::fixup_spills will sometimes generate spill code
@@ -2427,12 +2419,22 @@ void Matcher::find_shared_post_visit(Node* n, uint opcode) {
}
}

#ifdef ASSERT
#ifndef PRODUCT
void Matcher::record_new2old(Node* newn, Node* old) {
_new2old_map.map(newn->_idx, old);
if (!_reused.test_set(old->_igv_idx)) {
// Reuse the Ideal-level IGV identifier so that the node can be tracked
// across matching. If there are multiple machine nodes expanded from the
// same Ideal node, only one will reuse its IGV identifier.
newn->_igv_idx = old->_igv_idx;
}
}

// machine-independent root to machine-dependent root
void Matcher::dump_old2new_map() {
_old2new_map.dump();
}
#endif
#endif // !PRODUCT

//---------------------------collect_null_checks-------------------------------
// Find null checks in the ideal graph; write a machine-specific node for
@@ -135,8 +135,11 @@ class Matcher : public PhaseTransform {

Node_Array _shared_nodes;

debug_only(Node_Array _old2new_map;) // Map roots of ideal-trees to machine-roots
debug_only(Node_Array _new2old_map;) // Maps machine nodes back to ideal
#ifndef PRODUCT
Node_Array _old2new_map; // Map roots of ideal-trees to machine-roots
Node_Array _new2old_map; // Maps machine nodes back to ideal
VectorSet _reused; // Ideal IGV identifiers reused by machine nodes
#endif // !PRODUCT

// Accessors for the inherited field PhaseTransform::_nodes:
void grow_new_node_array(uint idx_limit) {
@@ -556,13 +559,16 @@ class Matcher : public PhaseTransform {
// Does n lead to an uncommon trap that can cause deoptimization?
static bool branches_to_uncommon_trap(const Node *n);

#ifdef ASSERT
#ifndef PRODUCT
// Record mach-to-Ideal mapping, reusing the Ideal IGV identifier if possible.
void record_new2old(Node* newn, Node* old);

void dump_old2new_map(); // machine-independent to machine-dependent

Node* find_old_node(Node* new_node) {
return _new2old_map[new_node->_idx];
}
#endif
#endif // !PRODUCT
};

#endif // SHARE_OPTO_MATCHER_HPP
@@ -323,9 +323,11 @@ class Node {
// preserved in _parse_idx.
const node_idx_t _idx;
DEBUG_ONLY(const node_idx_t _parse_idx;)
// IGV node identifier. It is similar to Node::_debug_idx in that it is unique
// across all compilation phases, but different in that it is initialized in
// each compilation, for stability.
// IGV node identifier. Two nodes, possibly in different compilation phases,
// have the same IGV identifier if (and only if) they are the very same node
// (same memory address) or one is "derived" from the other (by e.g.
// renumbering or matching). This identifier makes it possible to follow the
// entire lifetime of a node in IGV even if its C2 identifier (_idx) changes.
NOT_PRODUCT(node_idx_t _igv_idx;)

// Get the (read-only) number of input edges