Skip to content

Commit cf283e2

Browse files
committed
8279570: IGV: Add source/destination property for load and store nodes with an associated field
Reviewed-by: kvn, thartmann
1 parent f180530 commit cf283e2

File tree

2 files changed

+94
-1
lines changed

2 files changed

+94
-1
lines changed

src/hotspot/share/opto/idealGraphPrinter.cpp

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,8 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
482482
print_prop("idealOpcode", (const char *)NodeClassNames[node->as_Mach()->ideal_Opcode()]);
483483
}
484484

485+
print_field(node);
486+
485487
buffer[0] = 0;
486488
stringStream s2(buffer, sizeof(buffer) - 1);
487489

@@ -630,9 +632,96 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
630632
}
631633
}
632634

633-
void IdealGraphPrinter::walk_nodes(Node *start, bool edges, VectorSet* temp_set) {
635+
void IdealGraphPrinter::print_field(const Node* node) {
636+
buffer[0] = 0;
637+
stringStream ss(buffer, sizeof(buffer) - 1);
638+
ciField* field = get_field(node);
639+
uint depth = 0;
640+
if (field == NULL) {
641+
depth++;
642+
field = find_source_field_of_array_access(node, depth);
643+
}
644+
645+
if (field != NULL) {
646+
// Either direct field access or array access
647+
field->print_name_on(&ss);
648+
for (uint i = 0; i < depth; i++) {
649+
// For arrays: Add [] for each dimension
650+
ss.print("[]");
651+
}
652+
if (node->is_Store()) {
653+
print_prop("destination", buffer);
654+
} else {
655+
print_prop("source", buffer);
656+
}
657+
}
658+
}
659+
660+
ciField* IdealGraphPrinter::get_field(const Node* node) {
661+
const TypePtr* adr_type = node->adr_type();
662+
Compile::AliasType* atp = NULL;
663+
if (C->have_alias_type(adr_type)) {
664+
atp = C->alias_type(adr_type);
665+
}
666+
if (atp != NULL) {
667+
ciField* field = atp->field();
668+
if (field != NULL) {
669+
// Found field associated with 'node'.
670+
return field;
671+
}
672+
}
673+
return NULL;
674+
}
675+
676+
// Try to find the field that is associated with a memory node belonging to an array access.
677+
ciField* IdealGraphPrinter::find_source_field_of_array_access(const Node* node, uint& depth) {
678+
if (!node->is_Mem()) {
679+
// Not an array access
680+
return NULL;
681+
}
682+
683+
do {
684+
if (node->adr_type() != NULL && node->adr_type()->isa_aryptr()) {
685+
// Only process array accesses. Pattern match to find actual field source access.
686+
node = get_load_node(node);
687+
if (node != NULL) {
688+
ciField* field = get_field(node);
689+
if (field != NULL) {
690+
return field;
691+
}
692+
// Could be a multi-dimensional array. Repeat loop.
693+
depth++;
694+
continue;
695+
}
696+
}
697+
// Not an array access with a field source.
698+
break;
699+
} while (depth < 256); // Cannot have more than 255 dimensions
634700

701+
return NULL;
702+
}
703+
704+
// Pattern match on the inputs of 'node' to find load node for the field access.
705+
Node* IdealGraphPrinter::get_load_node(const Node* node) {
706+
Node* load = NULL;
707+
Node* addr = node->as_Mem()->in(MemNode::Address);
708+
if (addr != NULL && addr->is_AddP()) {
709+
Node* base = addr->as_AddP()->base_node();
710+
if (base != NULL) {
711+
base = base->uncast();
712+
if (base->is_Load()) {
713+
// Mem(AddP([ConstraintCast*](LoadP))) for non-compressed oops.
714+
load = base;
715+
} else if (base->is_DecodeN() && base->in(1)->is_Load()) {
716+
// Mem(AddP([ConstraintCast*](DecodeN(LoadN)))) for compressed oops.
717+
load = base->in(1);
718+
}
719+
}
720+
}
721+
return load;
722+
}
635723

724+
void IdealGraphPrinter::walk_nodes(Node* start, bool edges, VectorSet* temp_set) {
636725
VectorSet visited;
637726
GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, NULL);
638727
nodeStack.push(start);

src/hotspot/share/opto/idealGraphPrinter.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ class IdealGraphPrinter : public CHeapObj<mtCompiler> {
9999
void print_method(ciMethod *method, int bci, InlineTree *tree);
100100
void print_inline_tree(InlineTree *tree);
101101
void visit_node(Node *n, bool edges, VectorSet* temp_set);
102+
void print_field(const Node* node);
103+
ciField* get_field(const Node* node);
104+
ciField* find_source_field_of_array_access(const Node* node, uint& depth);
105+
static Node* get_load_node(const Node* node);
102106
void walk_nodes(Node *start, bool edges, VectorSet* temp_set);
103107
void begin_elem(const char *s);
104108
void end_elem();

0 commit comments

Comments
 (0)