Skip to content

Commit 51ce312

Browse files
committed
8348645: IGV: visualize live ranges
Reviewed-by: thartmann, dfenacci
1 parent f8ae1d4 commit 51ce312

File tree

53 files changed

+2393
-194
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+2393
-194
lines changed

src/hotspot/share/opto/idealGraphPrinter.cpp

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ const char *IdealGraphPrinter::BLOCK_ELEMENT = "block";
8080
const char *IdealGraphPrinter::SUCCESSORS_ELEMENT = "successors";
8181
const char *IdealGraphPrinter::SUCCESSOR_ELEMENT = "successor";
8282
const char *IdealGraphPrinter::ASSEMBLY_ELEMENT = "assembly";
83+
const char *IdealGraphPrinter::LIVEOUT_ELEMENT = "liveOut";
84+
const char *IdealGraphPrinter::LIVE_RANGE_ELEMENT = "lrg";
85+
const char *IdealGraphPrinter::LIVE_RANGE_ID_PROPERTY = "id";
86+
const char *IdealGraphPrinter::LIVE_RANGES_ELEMENT = "liveRanges";
8387

8488
int IdealGraphPrinter::_file_count = 0;
8589

@@ -815,6 +819,12 @@ Node* IdealGraphPrinter::get_load_node(const Node* node) {
815819
return load;
816820
}
817821

822+
bool IdealGraphPrinter::has_liveness_info() const {
823+
return _chaitin &&
824+
_chaitin != (PhaseChaitin *)((intptr_t)0xdeadbeef) &&
825+
_chaitin->get_live() != nullptr;
826+
}
827+
818828
void IdealGraphPrinter::walk_nodes(Node* start, bool edges) {
819829
VectorSet visited;
820830
GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, nullptr);
@@ -911,6 +921,19 @@ void IdealGraphPrinter::print(const char* name, Node* node, GrowableArray<const
911921
}
912922
tail(NODES_ELEMENT);
913923

924+
if (has_liveness_info()) {
925+
head(LIVEOUT_ELEMENT);
926+
const IndexSet* liveout = _chaitin->get_live()->live(block);
927+
IndexSetIterator lrgs(liveout);
928+
uint lrg;
929+
while ((lrg = lrgs.next()) != 0) {
930+
begin_elem(LIVE_RANGE_ELEMENT);
931+
print_attr(LIVE_RANGE_ID_PROPERTY, lrg);
932+
end_elem();
933+
}
934+
tail(LIVEOUT_ELEMENT);
935+
}
936+
914937
tail(BLOCK_ELEMENT);
915938
}
916939
tail(CONTROL_FLOW_ELEMENT);
@@ -934,6 +957,91 @@ void IdealGraphPrinter::print(const char* name, Node* node, GrowableArray<const
934957
tail(STATE_ELEMENT);
935958
tail(GRAPH_STATES_ELEMENT);
936959
}
960+
961+
if (has_liveness_info()) {
962+
head(LIVE_RANGES_ELEMENT);
963+
for (uint i = 1; i < _chaitin->_lrg_map.max_lrg_id(); i++) {
964+
begin_head(LIVE_RANGE_ELEMENT);
965+
print_attr(LIVE_RANGE_ID_PROPERTY, i);
966+
end_head();
967+
head(PROPERTIES_ELEMENT);
968+
const LRG& lrg = _chaitin->lrgs(i);
969+
buffer[0] = 0;
970+
stringStream lrg_mask_stream(buffer, sizeof(buffer) - 1);
971+
lrg.mask().dump(&lrg_mask_stream);
972+
print_prop("mask", buffer);
973+
print_prop("mask_size", lrg.mask_size());
974+
if (lrg._degree_valid) {
975+
print_prop("degree", lrg.degree());
976+
}
977+
print_prop("num_regs", lrg.num_regs());
978+
print_prop("reg_pressure", lrg.reg_pressure());
979+
print_prop("cost", lrg._cost);
980+
print_prop("area", lrg._area);
981+
print_prop("score", lrg.score());
982+
if (lrg._risk_bias != 0) {
983+
print_prop("risk_bias", lrg._risk_bias);
984+
}
985+
if (lrg._copy_bias != 0) {
986+
print_prop("copy_bias", lrg._copy_bias);
987+
}
988+
if (lrg.is_singledef()) {
989+
print_prop("is_singledef", TRUE_VALUE);
990+
}
991+
if (lrg.is_multidef()) {
992+
print_prop("is_multidef", TRUE_VALUE);
993+
}
994+
if (lrg._is_oop) {
995+
print_prop("is_oop", TRUE_VALUE);
996+
}
997+
if (lrg._is_float) {
998+
print_prop("is_float", TRUE_VALUE);
999+
}
1000+
if (lrg._is_vector) {
1001+
print_prop("is_vector", TRUE_VALUE);
1002+
}
1003+
if (lrg._is_predicate) {
1004+
print_prop("is_predicate", TRUE_VALUE);
1005+
}
1006+
if (lrg._is_scalable) {
1007+
print_prop("is_scalable", TRUE_VALUE);
1008+
}
1009+
if (lrg._was_spilled1) {
1010+
print_prop("was_spilled1", TRUE_VALUE);
1011+
}
1012+
if (lrg._was_spilled2) {
1013+
print_prop("was_spilled2", TRUE_VALUE);
1014+
}
1015+
if (lrg._direct_conflict) {
1016+
print_prop("direct_conflict", TRUE_VALUE);
1017+
}
1018+
if (lrg._fat_proj) {
1019+
print_prop("fat_proj", TRUE_VALUE);
1020+
}
1021+
if (lrg._was_lo) {
1022+
print_prop("_was_lo", TRUE_VALUE);
1023+
}
1024+
if (lrg._has_copy) {
1025+
print_prop("has_copy", TRUE_VALUE);
1026+
}
1027+
if (lrg._at_risk) {
1028+
print_prop("at_risk", TRUE_VALUE);
1029+
}
1030+
if (lrg._must_spill) {
1031+
print_prop("must_spill", TRUE_VALUE);
1032+
}
1033+
if (lrg._is_bound) {
1034+
print_prop("is_bound", TRUE_VALUE);
1035+
}
1036+
if (lrg._msize_valid && lrg._degree_valid && lrg.lo_degree()) {
1037+
print_prop("trivial", TRUE_VALUE);
1038+
}
1039+
tail(PROPERTIES_ELEMENT);
1040+
tail(LIVE_RANGE_ELEMENT);
1041+
}
1042+
tail(LIVE_RANGES_ELEMENT);
1043+
}
1044+
9371045
tail(GRAPH_ELEMENT);
9381046
_xml->flush();
9391047
}

src/hotspot/share/opto/idealGraphPrinter.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ class IdealGraphPrinter : public CHeapObj<mtCompiler> {
9191
static const char *METHOD_BCI_PROPERTY;
9292
static const char *METHOD_SHORT_NAME_PROPERTY;
9393
static const char *ASSEMBLY_ELEMENT;
94+
static const char *LIVEOUT_ELEMENT;
95+
static const char *LIVE_RANGE_ELEMENT;
96+
static const char *LIVE_RANGE_ID_PROPERTY;
97+
static const char *LIVE_RANGES_ELEMENT;
9498

9599
static int _file_count;
96100
networkStream *_network_stream;
@@ -114,6 +118,7 @@ class IdealGraphPrinter : public CHeapObj<mtCompiler> {
114118
ciField* get_field(const Node* node);
115119
ciField* find_source_field_of_array_access(const Node* node, uint& depth);
116120
static Node* get_load_node(const Node* node);
121+
bool has_liveness_info() const;
117122
void walk_nodes(Node* start, bool edges);
118123
void begin_elem(const char *s);
119124
void end_elem();

src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@ protected void performAction(Node[] activatedNodes) {
4141
SelectBytecodesCookie c = activatedNodes[0].getCookie(SelectBytecodesCookie.class);
4242
InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);
4343
if (p != null) {
44-
p.clearSelectedNodes();
44+
p.clearSelectedElements();
4545
p.addSelectedNodes(c.getNodes(), true);
4646
p.centerSelectedNodes();
4747
}

src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@ public class InputBlock {
3535
private final String name;
3636
private final InputGraph graph;
3737
private final Set<InputBlock> successors;
38+
private Set<Integer> liveOut;
3839
private boolean artificial;
3940

4041
@Override
@@ -70,6 +71,15 @@ public boolean equals(Object o) {
7071
}
7172
}
7273

74+
if (this.liveOut.size() != b.liveOut.size()) {
75+
return false;
76+
}
77+
for (int liveRangeId : this.liveOut) {
78+
if (!b.liveOut.contains(liveRangeId)) {
79+
return false;
80+
}
81+
}
82+
7383
return true;
7484
}
7585

@@ -78,6 +88,7 @@ public boolean equals(Object o) {
7888
this.name = name;
7989
nodes = new ArrayList<>();
8090
successors = new LinkedHashSet<>(2);
91+
liveOut = new HashSet<Integer>(0);
8192
artificial = false;
8293
}
8394

@@ -99,6 +110,14 @@ public void addNode(int id) {
99110
nodes.add(node);
100111
}
101112

113+
public void addLiveOut(int liveRangeId) {
114+
liveOut.add(liveRangeId);
115+
}
116+
117+
public Set<Integer> getLiveOut() {
118+
return Collections.unmodifiableSet(liveOut);
119+
}
120+
102121
public Set<InputBlock> getSuccessors() {
103122
return Collections.unmodifiableSet(successors);
104123
}

src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,11 @@ public class InputGraph extends Properties.Entity implements FolderElement {
3838
private final Map<String, InputBlock> blocks;
3939
private final List<InputBlockEdge> blockEdges;
4040
private final Map<Integer, InputBlock> nodeToBlock;
41+
private final Map<Integer, InputLiveRange> liveRanges;
42+
private Map<Integer, LivenessInfo> livenessInfo;
43+
private Map<Integer, Set<InputNode>> relatedNodes;
44+
private Map<Integer, Set<InputNode>> defNodes;
45+
private Map<Integer, Set<InputNode>> useNodes;
4146
private final boolean isDiffGraph;
4247
private final InputGraph firstGraph;
4348
private final InputGraph secondGraph;
@@ -58,6 +63,11 @@ private InputGraph(String name, InputGraph firstGraph, InputGraph secondGraph) {
5863
nodes = new LinkedHashMap<>();
5964
edges = new ArrayList<>();
6065
blocks = new LinkedHashMap<>();
66+
liveRanges = new LinkedHashMap<>();
67+
livenessInfo = new LinkedHashMap<>();
68+
relatedNodes = new LinkedHashMap<>();
69+
defNodes = new LinkedHashMap<>();
70+
useNodes = new LinkedHashMap<>();
6171
blockEdges = new ArrayList<>();
6272
nodeToBlock = new LinkedHashMap<>();
6373
isDiffGraph = firstGraph != null && secondGraph != null;
@@ -304,12 +314,66 @@ public Group getGroup() {
304314
return parentGroup;
305315
}
306316

317+
public void addLiveRange(InputLiveRange lrg) {
318+
liveRanges.put(lrg.getId(), lrg);
319+
relatedNodes.put(lrg.getId(), new HashSet<>());
320+
defNodes.put(lrg.getId(), new HashSet<>());
321+
useNodes.put(lrg.getId(), new HashSet<>());
322+
}
323+
324+
public InputLiveRange getLiveRange(int liveRangeId) {
325+
return liveRanges.get(liveRangeId);
326+
}
327+
328+
public Collection<InputLiveRange> getLiveRanges() {
329+
return Collections.unmodifiableCollection(liveRanges.values());
330+
}
331+
332+
public void addLivenessInfo(InputNode node, LivenessInfo info) {
333+
livenessInfo.put(node.getId(), info);
334+
if (info.def != null) {
335+
relatedNodes.get(info.def).add(node);
336+
defNodes.get(info.def).add(node);
337+
}
338+
if (info.use != null) {
339+
for (int lrg : info.use) {
340+
relatedNodes.get(lrg).add(node);
341+
useNodes.get(lrg).add(node);
342+
}
343+
}
344+
if (info.join != null) {
345+
for (int lrg : info.join) {
346+
relatedNodes.get(lrg).add(node);
347+
useNodes.get(lrg).add(node);
348+
}
349+
}
350+
}
351+
352+
public LivenessInfo getLivenessInfoForNode(InputNode node) {
353+
return livenessInfo.get(node.getId());
354+
}
355+
356+
public Set<InputNode> getRelatedNodes(int liveRangeId) {
357+
return relatedNodes.get(liveRangeId);
358+
}
359+
360+
public Set<InputNode> getDefNodes(int liveRangeId) {
361+
return defNodes.get(liveRangeId);
362+
}
363+
364+
public Set<InputNode> getUseNodes(int liveRangeId) {
365+
return useNodes.get(liveRangeId);
366+
}
367+
307368
@Override
308369
public String toString() {
309370
StringBuilder sb = new StringBuilder();
310371
sb.append("Graph ").append(getName()).append(" ").append(getProperties().toString()).append("\n");
311372
for (InputNode n : nodes.values()) {
312373
sb.append(n.toString());
374+
if (livenessInfo.containsKey(n.getId())) {
375+
sb.append(" " + livenessInfo.get(n.getId()).toString());
376+
}
313377
sb.append("\n");
314378
}
315379

@@ -323,6 +387,11 @@ public String toString() {
323387
sb.append("\n");
324388
}
325389

390+
for (InputLiveRange l : liveRanges.values()) {
391+
sb.append(l.toString());
392+
sb.append("\n");
393+
}
394+
326395
return sb.toString();
327396
}
328397

0 commit comments

Comments
 (0)