Skip to content

Commit

Permalink
8344122: IGV: Extend c2 IdealGraphPrinter to send subgraphs to IGV
Browse files Browse the repository at this point in the history
Reviewed-by: chagedorn, epeter, rcastanedalo
  • Loading branch information
tobiasholenstein committed Nov 18, 2024
1 parent 00ff6a3 commit b9c6ce9
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 24 deletions.
26 changes: 20 additions & 6 deletions src/hotspot/share/opto/compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5162,7 +5162,7 @@ void Compile::print_method(CompilerPhaseType cpt, int level, Node* n) {

const char* name = ss.as_string();
if (should_print_igv(level)) {
_igv_printer->print_method(name, level);
_igv_printer->print_graph(name);
}
if (should_print_phase(cpt)) {
print_ideal_ir(CompilerPhaseTypeHelper::to_name(cpt));
Expand Down Expand Up @@ -5204,16 +5204,24 @@ bool Compile::should_print_phase(CompilerPhaseType cpt) {
return false;
}

#ifndef PRODUCT
void Compile::init_igv() {
if (_igv_printer == nullptr) {
_igv_printer = IdealGraphPrinter::printer();
_igv_printer->set_compile(this);
}
}
#endif

bool Compile::should_print_igv(const int level) {
#ifndef PRODUCT
if (PrintIdealGraphLevel < 0) { // disabled by the user
return false;
}

bool need = directive()->IGVPrintLevelOption >= level;
if (need && !_igv_printer) {
_igv_printer = IdealGraphPrinter::printer();
_igv_printer->set_compile(this);
if (need) {
Compile::init_igv();
}
return need;
#else
Expand Down Expand Up @@ -5281,17 +5289,23 @@ void Compile::igv_print_method_to_file(const char* phase_name, bool append) {
_debug_file_printer->update_compiled_method(C->method());
}
tty->print_cr("Method %s to %s", append ? "appended" : "printed", file_name);
_debug_file_printer->print(phase_name, (Node*)C->root());
_debug_file_printer->print_graph(phase_name);
}

void Compile::igv_print_method_to_network(const char* phase_name) {
ResourceMark rm;
GrowableArray<const Node*> empty_list;
igv_print_graph_to_network(phase_name, (Node*) C->root(), empty_list);
}

void Compile::igv_print_graph_to_network(const char* name, Node* node, GrowableArray<const Node*>& visible_nodes) {
if (_debug_network_printer == nullptr) {
_debug_network_printer = new IdealGraphPrinter(C);
} else {
_debug_network_printer->update_compiled_method(C->method());
}
tty->print_cr("Method printed over network stream to IGV");
_debug_network_printer->print(phase_name, (Node*)C->root());
_debug_network_printer->print(name, C->root(), visible_nodes);
}
#endif

Expand Down
4 changes: 3 additions & 1 deletion src/hotspot/share/opto/compile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -711,14 +711,16 @@ class Compile : public Phase {
void print_method(CompilerPhaseType cpt, int level, Node* n = nullptr);

#ifndef PRODUCT
void init_igv();
void dump_igv(const char* graph_name, int level = 3) {
if (should_print_igv(level)) {
_igv_printer->print_method(graph_name, level);
_igv_printer->print_graph(graph_name);
}
}

void igv_print_method_to_file(const char* phase_name = "Debug", bool append = false);
void igv_print_method_to_network(const char* phase_name = "Debug");
void igv_print_graph_to_network(const char* name, Node* node, GrowableArray<const Node*>& visible_nodes);
static IdealGraphPrinter* debug_file_printer() { return _debug_file_printer; }
static IdealGraphPrinter* debug_network_printer() { return _debug_network_printer; }
#endif
Expand Down
48 changes: 36 additions & 12 deletions src/hotspot/share/opto/idealGraphPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const char *IdealGraphPrinter::COMPILATION_OSR_PROPERTY = "osr";
const char *IdealGraphPrinter::METHOD_NAME_PROPERTY = "name";
const char *IdealGraphPrinter::METHOD_IS_PUBLIC_PROPERTY = "public";
const char *IdealGraphPrinter::METHOD_IS_STATIC_PROPERTY = "static";
const char *IdealGraphPrinter::FALSE_VALUE = "false";
const char *IdealGraphPrinter::TRUE_VALUE = "true";
const char *IdealGraphPrinter::NODE_NAME_PROPERTY = "name";
const char *IdealGraphPrinter::EDGE_NAME_PROPERTY = "name";
Expand All @@ -68,6 +69,12 @@ const char *IdealGraphPrinter::BYTECODES_ELEMENT = "bytecodes";
const char *IdealGraphPrinter::METHOD_BCI_PROPERTY = "bci";
const char *IdealGraphPrinter::METHOD_SHORT_NAME_PROPERTY = "shortName";
const char *IdealGraphPrinter::CONTROL_FLOW_ELEMENT = "controlFlow";
const char *IdealGraphPrinter::GRAPH_STATES_ELEMENT = "graphStates";
const char *IdealGraphPrinter::STATE_ELEMENT = "state";
const char *IdealGraphPrinter::DIFFERENCE_ELEMENT = "difference";
const char *IdealGraphPrinter::DIFFERENCE_VALUE_PROPERTY = "value";
const char *IdealGraphPrinter::VISIBLE_NODES_ELEMENT = "visibleNodes";
const char *IdealGraphPrinter::ALL_PROPERTY = "all";
const char *IdealGraphPrinter::BLOCK_NAME_PROPERTY = "name";
const char *IdealGraphPrinter::BLOCK_DOMINATOR_PROPERTY = "dom";
const char *IdealGraphPrinter::BLOCK_ELEMENT = "block";
Expand Down Expand Up @@ -349,7 +356,7 @@ void IdealGraphPrinter::set_traverse_outs(bool b) {
_traverse_outs = b;
}

void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
void IdealGraphPrinter::visit_node(Node* n, bool edges) {

if (edges) {

Expand Down Expand Up @@ -775,7 +782,7 @@ Node* IdealGraphPrinter::get_load_node(const Node* node) {
return load;
}

void IdealGraphPrinter::walk_nodes(Node* start, bool edges, VectorSet* temp_set) {
void IdealGraphPrinter::walk_nodes(Node* start, bool edges) {
VectorSet visited;
GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, nullptr);
nodeStack.push(start);
Expand All @@ -796,7 +803,7 @@ void IdealGraphPrinter::walk_nodes(Node* start, bool edges, VectorSet* temp_set)
continue;
}

visit_node(n, edges, temp_set);
visit_node(n, edges);

if (_traverse_outs) {
for (DUIterator i = n->outs(); n->has_out(i); i++) {
Expand All @@ -812,14 +819,14 @@ void IdealGraphPrinter::walk_nodes(Node* start, bool edges, VectorSet* temp_set)
}
}

void IdealGraphPrinter::print_method(const char *name, int level) {
if (C->should_print_igv(level)) {
print(name, (Node *) C->root());
}
void IdealGraphPrinter::print_graph(const char* name) {
ResourceMark rm;
GrowableArray<const Node*> empty_list;
print(name, (Node*) C->root(), empty_list);
}

// Print current ideal graph
void IdealGraphPrinter::print(const char *name, Node *node) {
void IdealGraphPrinter::print(const char* name, Node* node, GrowableArray<const Node*>& visible_nodes) {

if (!_current_method || !_should_send_method || node == nullptr) return;

Expand All @@ -830,8 +837,6 @@ void IdealGraphPrinter::print(const char *name, Node *node) {
print_attr(GRAPH_NAME_PROPERTY, (const char *)name);
end_head();

VectorSet temp_set;

head(NODES_ELEMENT);
if (C->cfg() != nullptr) {
// Compute the maximum estimated frequency in the current graph.
Expand All @@ -843,11 +848,11 @@ void IdealGraphPrinter::print(const char *name, Node *node) {
}
}
}
walk_nodes(node, false, &temp_set);
walk_nodes(node, false);
tail(NODES_ELEMENT);

head(EDGES_ELEMENT);
walk_nodes(node, true, &temp_set);
walk_nodes(node, true);
tail(EDGES_ELEMENT);
if (C->cfg() != nullptr) {
head(CONTROL_FLOW_ELEMENT);
Expand Down Expand Up @@ -877,6 +882,25 @@ void IdealGraphPrinter::print(const char *name, Node *node) {
}
tail(CONTROL_FLOW_ELEMENT);
}
if (visible_nodes.is_nonempty()) {
head(GRAPH_STATES_ELEMENT);
head(STATE_ELEMENT);
begin_elem(DIFFERENCE_ELEMENT);
print_attr(DIFFERENCE_VALUE_PROPERTY, "0");
end_elem();

begin_head(VISIBLE_NODES_ELEMENT);
print_attr(ALL_PROPERTY, FALSE_VALUE);
end_head();
for (int i = 0; i < visible_nodes.length(); ++i) {
begin_elem(NODE_ELEMENT);
print_attr(NODE_ID_PROPERTY, visible_nodes.at(i)->_igv_idx);
end_elem();
}
tail(VISIBLE_NODES_ELEMENT);
tail(STATE_ELEMENT);
tail(GRAPH_STATES_ELEMENT);
}
tail(GRAPH_ELEMENT);
_xml->flush();
}
Expand Down
15 changes: 11 additions & 4 deletions src/hotspot/share/opto/idealGraphPrinter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ class IdealGraphPrinter : public CHeapObj<mtCompiler> {
static const char *CONTROL_FLOW_ELEMENT;
static const char *REMOVE_EDGE_ELEMENT;
static const char *REMOVE_NODE_ELEMENT;
static const char *GRAPH_STATES_ELEMENT;
static const char *STATE_ELEMENT;
static const char *DIFFERENCE_ELEMENT;
static const char *DIFFERENCE_VALUE_PROPERTY;
static const char *VISIBLE_NODES_ELEMENT;
static const char *ALL_PROPERTY;
static const char *COMPILATION_ID_PROPERTY;
static const char *COMPILATION_OSR_PROPERTY;
static const char *METHOD_NAME_PROPERTY;
Expand All @@ -69,6 +75,7 @@ class IdealGraphPrinter : public CHeapObj<mtCompiler> {
static const char *SUCCESSOR_ELEMENT;
static const char *METHOD_IS_PUBLIC_PROPERTY;
static const char *METHOD_IS_STATIC_PROPERTY;
static const char *FALSE_VALUE;
static const char *TRUE_VALUE;
static const char *NODE_NAME_PROPERTY;
static const char *EDGE_NAME_PROPERTY;
Expand Down Expand Up @@ -101,13 +108,13 @@ class IdealGraphPrinter : public CHeapObj<mtCompiler> {

void print_method(ciMethod* method, int bci, InlineTree* tree);
void print_inline_tree(InlineTree* tree);
void visit_node(Node* n, bool edges, VectorSet* temp_set);
void visit_node(Node* n, bool edges);
void print_bci_and_line_number(JVMState* caller);
void print_field(const Node* node);
ciField* get_field(const Node* node);
ciField* find_source_field_of_array_access(const Node* node, uint& depth);
static Node* get_load_node(const Node* node);
void walk_nodes(Node *start, bool edges, VectorSet* temp_set);
void walk_nodes(Node* start, bool edges);
void begin_elem(const char *s);
void end_elem();
void begin_head(const char *s);
Expand Down Expand Up @@ -137,8 +144,8 @@ class IdealGraphPrinter : public CHeapObj<mtCompiler> {
void print_inlining();
void begin_method();
void end_method();
void print_method(const char *name, int level = 0);
void print(const char *name, Node *root);
void print_graph(const char* name);
void print(const char* name, Node* root, GrowableArray<const Node*>& hidden_nodes);
void set_compile(Compile* compile) {C = compile; }
void update_compiled_method(ciMethod* current_method);
};
Expand Down
11 changes: 11 additions & 0 deletions src/hotspot/share/opto/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1830,6 +1830,8 @@ class PrintBFS {
bool _print_blocks = false;
bool _print_old = false;
bool _dump_only = false;
bool _print_igv = false;

void print_options_help(bool print_examples);
bool parse_options();

Expand Down Expand Up @@ -2047,6 +2049,11 @@ void PrintBFS::print() {
const Node* n = _print_list.at(i);
print_node(n);
}
if (_print_igv) {
Compile* C = Compile::current();
C->init_igv();
C->igv_print_graph_to_network("PrintBFS", (Node*) C->root(), _print_list);
}
} else {
_output->print_cr("No nodes to print.");
}
Expand Down Expand Up @@ -2089,6 +2096,7 @@ void PrintBFS::print_options_help(bool print_examples) {
_output->print_cr(" @: print old nodes - before matching (if available)");
_output->print_cr(" B: print scheduling blocks (if available)");
_output->print_cr(" $: dump only, no header, no other columns");
_output->print_cr(" !: show nodes on IGV (sent over network stream)");
_output->print_cr("");
_output->print_cr("recursively follow edges to nodes with permitted visit types,");
_output->print_cr("on the boundary additionally display nodes allowed in boundary types");
Expand Down Expand Up @@ -2202,6 +2210,9 @@ bool PrintBFS::parse_options() {
case '$':
_dump_only = true;
break;
case '!':
_print_igv = true;
break;
case 'h':
print_options_help(false);
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/parse2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2836,7 +2836,7 @@ void Parse::do_one_bytecode() {
jio_snprintf(buffer, sizeof(buffer), "Bytecode %d: %s", bci(), Bytecodes::name(bc()));
bool old = printer->traverse_outs();
printer->set_traverse_outs(true);
printer->print_method(buffer, perBytecode);
printer->print_graph(buffer);
printer->set_traverse_outs(old);
}
#endif
Expand Down

1 comment on commit b9c6ce9

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.