8279570: IGV: Add source/destination property for load and store nodes with an associated field
Reviewed-by: kvn, thartmann
This commit is contained in:
parent
f180530935
commit
cf283e2a33
@ -482,6 +482,8 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
|
||||
print_prop("idealOpcode", (const char *)NodeClassNames[node->as_Mach()->ideal_Opcode()]);
|
||||
}
|
||||
|
||||
print_field(node);
|
||||
|
||||
buffer[0] = 0;
|
||||
stringStream s2(buffer, sizeof(buffer) - 1);
|
||||
|
||||
@ -630,9 +632,96 @@ void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
|
||||
}
|
||||
}
|
||||
|
||||
void IdealGraphPrinter::walk_nodes(Node *start, bool edges, VectorSet* temp_set) {
|
||||
void IdealGraphPrinter::print_field(const Node* node) {
|
||||
buffer[0] = 0;
|
||||
stringStream ss(buffer, sizeof(buffer) - 1);
|
||||
ciField* field = get_field(node);
|
||||
uint depth = 0;
|
||||
if (field == NULL) {
|
||||
depth++;
|
||||
field = find_source_field_of_array_access(node, depth);
|
||||
}
|
||||
|
||||
if (field != NULL) {
|
||||
// Either direct field access or array access
|
||||
field->print_name_on(&ss);
|
||||
for (uint i = 0; i < depth; i++) {
|
||||
// For arrays: Add [] for each dimension
|
||||
ss.print("[]");
|
||||
}
|
||||
if (node->is_Store()) {
|
||||
print_prop("destination", buffer);
|
||||
} else {
|
||||
print_prop("source", buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ciField* IdealGraphPrinter::get_field(const Node* node) {
|
||||
const TypePtr* adr_type = node->adr_type();
|
||||
Compile::AliasType* atp = NULL;
|
||||
if (C->have_alias_type(adr_type)) {
|
||||
atp = C->alias_type(adr_type);
|
||||
}
|
||||
if (atp != NULL) {
|
||||
ciField* field = atp->field();
|
||||
if (field != NULL) {
|
||||
// Found field associated with 'node'.
|
||||
return field;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Try to find the field that is associated with a memory node belonging to an array access.
|
||||
ciField* IdealGraphPrinter::find_source_field_of_array_access(const Node* node, uint& depth) {
|
||||
if (!node->is_Mem()) {
|
||||
// Not an array access
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do {
|
||||
if (node->adr_type() != NULL && node->adr_type()->isa_aryptr()) {
|
||||
// Only process array accesses. Pattern match to find actual field source access.
|
||||
node = get_load_node(node);
|
||||
if (node != NULL) {
|
||||
ciField* field = get_field(node);
|
||||
if (field != NULL) {
|
||||
return field;
|
||||
}
|
||||
// Could be a multi-dimensional array. Repeat loop.
|
||||
depth++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Not an array access with a field source.
|
||||
break;
|
||||
} while (depth < 256); // Cannot have more than 255 dimensions
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Pattern match on the inputs of 'node' to find load node for the field access.
|
||||
Node* IdealGraphPrinter::get_load_node(const Node* node) {
|
||||
Node* load = NULL;
|
||||
Node* addr = node->as_Mem()->in(MemNode::Address);
|
||||
if (addr != NULL && addr->is_AddP()) {
|
||||
Node* base = addr->as_AddP()->base_node();
|
||||
if (base != NULL) {
|
||||
base = base->uncast();
|
||||
if (base->is_Load()) {
|
||||
// Mem(AddP([ConstraintCast*](LoadP))) for non-compressed oops.
|
||||
load = base;
|
||||
} else if (base->is_DecodeN() && base->in(1)->is_Load()) {
|
||||
// Mem(AddP([ConstraintCast*](DecodeN(LoadN)))) for compressed oops.
|
||||
load = base->in(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return load;
|
||||
}
|
||||
|
||||
void IdealGraphPrinter::walk_nodes(Node* start, bool edges, VectorSet* temp_set) {
|
||||
VectorSet visited;
|
||||
GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, NULL);
|
||||
nodeStack.push(start);
|
||||
|
@ -99,6 +99,10 @@ 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 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 begin_elem(const char *s);
|
||||
void end_elem();
|
||||
|
Loading…
x
Reference in New Issue
Block a user