From 159721f4935b85cc90ecadecf36b6c171efd59d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Sun, 26 Jan 2025 20:45:54 +0100 Subject: [PATCH 01/48] Dump live range info from HotSpot --- src/hotspot/share/opto/idealGraphPrinter.cpp | 55 ++++++++++++++++++++ src/hotspot/share/opto/idealGraphPrinter.hpp | 5 ++ 2 files changed, 60 insertions(+) diff --git a/src/hotspot/share/opto/idealGraphPrinter.cpp b/src/hotspot/share/opto/idealGraphPrinter.cpp index 6a28074f4d954..61e9b2e71d92a 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.cpp +++ b/src/hotspot/share/opto/idealGraphPrinter.cpp @@ -80,6 +80,10 @@ const char *IdealGraphPrinter::BLOCK_ELEMENT = "block"; const char *IdealGraphPrinter::SUCCESSORS_ELEMENT = "successors"; const char *IdealGraphPrinter::SUCCESSOR_ELEMENT = "successor"; const char *IdealGraphPrinter::ASSEMBLY_ELEMENT = "assembly"; +const char *IdealGraphPrinter::LIVEOUT_ELEMENT = "liveOut"; +const char *IdealGraphPrinter::LIVE_RANGE_ELEMENT = "lrg"; +const char *IdealGraphPrinter::LIVE_RANGE_ID_PROPERTY = "id"; +const char *IdealGraphPrinter::LIVE_RANGES_ELEMENT = "liveRanges"; int IdealGraphPrinter::_file_count = 0; @@ -781,6 +785,12 @@ Node* IdealGraphPrinter::get_load_node(const Node* node) { return load; } +bool IdealGraphPrinter::has_liveness_info() const { + return _chaitin && + _chaitin != (PhaseChaitin *)((intptr_t)0xdeadbeef) && + _chaitin->get_live() != nullptr; +} + void IdealGraphPrinter::walk_nodes(Node* start, bool edges) { VectorSet visited; GrowableArray nodeStack(Thread::current()->resource_area(), 0, 0, nullptr); @@ -877,6 +887,19 @@ void IdealGraphPrinter::print(const char* name, Node* node, GrowableArrayget_live()->live(block); + IndexSetIterator lrgs(liveout); + uint lrg; + while ((lrg = lrgs.next()) != 0) { + begin_elem(LIVE_RANGE_ELEMENT); + print_attr(LIVE_RANGE_ID_PROPERTY, lrg); + end_elem(); + } + tail(LIVEOUT_ELEMENT); + } + tail(BLOCK_ELEMENT); } tail(CONTROL_FLOW_ELEMENT); @@ -900,6 +923,38 @@ void IdealGraphPrinter::print(const char* name, Node* node, GrowableArray_lrg_map.max_lrg_id(); i++) { + begin_head(LIVE_RANGE_ELEMENT); + print_attr(LIVE_RANGE_ID_PROPERTY, i); + end_head(); + head(PROPERTIES_ELEMENT); + const LRG& lrg = _chaitin->lrgs(i); + if (lrg._degree_valid) { + print_prop("degree", lrg.degree()); + } + print_prop("num_regs", lrg.num_regs()); + print_prop("reg_pressure", lrg.reg_pressure()); + print_prop("score", lrg.score()); + print_prop("mask_size", lrg.mask_size()); + if (lrg._risk_bias != 0) { + print_prop("risk_bias", lrg._risk_bias); + } + if (lrg._copy_bias != 0) { + print_prop("copy_bias", lrg._copy_bias); + } + buffer[0] = 0; + stringStream lrg_mask_stream(buffer, sizeof(buffer) - 1); + lrg.mask().dump(&lrg_mask_stream); + print_prop("mask", buffer); + tail(PROPERTIES_ELEMENT); + tail(LIVE_RANGE_ELEMENT); + } + tail(LIVE_RANGES_ELEMENT); + } + tail(GRAPH_ELEMENT); _xml->flush(); } diff --git a/src/hotspot/share/opto/idealGraphPrinter.hpp b/src/hotspot/share/opto/idealGraphPrinter.hpp index 042ac694843cc..f5528507362ca 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.hpp +++ b/src/hotspot/share/opto/idealGraphPrinter.hpp @@ -91,6 +91,10 @@ class IdealGraphPrinter : public CHeapObj { static const char *METHOD_BCI_PROPERTY; static const char *METHOD_SHORT_NAME_PROPERTY; static const char *ASSEMBLY_ELEMENT; + static const char *LIVEOUT_ELEMENT; + static const char *LIVE_RANGE_ELEMENT; + static const char *LIVE_RANGE_ID_PROPERTY; + static const char *LIVE_RANGES_ELEMENT; static int _file_count; networkStream *_network_stream; @@ -114,6 +118,7 @@ class IdealGraphPrinter : public CHeapObj { 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); + bool has_liveness_info() const; void walk_nodes(Node* start, bool edges); void begin_elem(const char *s); void end_elem(); From 1efce3d351363c0de4d6f094655ab2d7a015b2f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Sun, 26 Jan 2025 21:14:18 +0100 Subject: [PATCH 02/48] Parse, compute, and represent liveness information at the data level --- .../com/sun/hotspot/igv/data/InputBlock.java | 21 +++ .../com/sun/hotspot/igv/data/InputGraph.java | 48 ++++++ .../sun/hotspot/igv/data/InputLiveRange.java | 71 ++++++++ .../sun/hotspot/igv/data/LivenessInfo.java | 49 ++++++ .../igv/data/serialization/Parser.java | 48 ++++++ .../igv/data/services/PreProcessor.java | 31 ++++ .../igv/data/serialization/graphdocument.xsd | 12 +- .../hotspot/igv/difference/Difference.java | 3 + .../com/sun/hotspot/igv/filter/helper.js | 5 + .../ServerCompilerPreProcessor.java | 161 ++++++++++++++++++ .../filters/showLiveness.filter | 44 +++++ .../filters/showRegisterAllocationOnly.filter | 5 + .../sun/hotspot/igv/servercompiler/layer.xml | 8 + .../hotspot/igv/view/DiagramViewModel.java | 3 + 14 files changed, 508 insertions(+), 1 deletion(-) create mode 100644 src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputLiveRange.java create mode 100644 src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/LivenessInfo.java create mode 100644 src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/PreProcessor.java create mode 100644 src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java create mode 100644 src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showLiveness.filter create mode 100644 src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showRegisterAllocationOnly.filter diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java index 7f3d1a514ef87..e76a028156458 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java @@ -35,8 +35,11 @@ public class InputBlock { private final String name; private final InputGraph graph; private final Set successors; + private Set liveOut; private boolean artificial; + public static final boolean USE_LIVE_RANGE_IDENTIFIERS = true; + @Override public int hashCode() { return name.hashCode(); @@ -70,6 +73,15 @@ public boolean equals(Object o) { } } + if (this.liveOut.size() != b.liveOut.size()) { + return false; + } + for (int liveRangeId : this.liveOut) { + if (!b.liveOut.contains(liveRangeId)) { + return false; + } + } + return true; } @@ -78,6 +90,7 @@ public boolean equals(Object o) { this.name = name; nodes = new ArrayList<>(); successors = new LinkedHashSet<>(2); + liveOut = new HashSet(0); artificial = false; } @@ -99,6 +112,14 @@ public void addNode(int id) { nodes.add(node); } + public void addLiveOut(int liveRangeId) { + liveOut.add(liveRangeId); + } + + public Set getLiveOut() { + return Collections.unmodifiableSet(liveOut); + } + public Set getSuccessors() { return Collections.unmodifiableSet(successors); } diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java index 3105a817f07ca..fc80723b3d05e 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java @@ -38,6 +38,9 @@ public class InputGraph extends Properties.Entity implements FolderElement { private final Map blocks; private final List blockEdges; private final Map nodeToBlock; + private final Map liveRanges; + private Map livenessInfo; + private Map> relatedNodes; private final boolean isDiffGraph; private final InputGraph firstGraph; private final InputGraph secondGraph; @@ -58,6 +61,9 @@ private InputGraph(String name, InputGraph firstGraph, InputGraph secondGraph) { nodes = new LinkedHashMap<>(); edges = new ArrayList<>(); blocks = new LinkedHashMap<>(); + liveRanges = new LinkedHashMap<>(); + livenessInfo = new LinkedHashMap<>(); + relatedNodes = new LinkedHashMap<>(); blockEdges = new ArrayList<>(); nodeToBlock = new LinkedHashMap<>(); isDiffGraph = firstGraph != null && secondGraph != null; @@ -304,12 +310,49 @@ public Group getGroup() { return parentGroup; } + public void addLiveRange(InputLiveRange lrg) { + liveRanges.put(lrg.getId(), lrg); + relatedNodes.put(lrg.getId(), new HashSet<>()); + } + + public Collection getLiveRanges() { + return Collections.unmodifiableCollection(liveRanges.values()); + } + + public void addLivenessInfo(InputNode node, LivenessInfo info) { + livenessInfo.put(node.getId(), info); + if (info.def != null) { + relatedNodes.get(info.def).add(node); + } + if (info.use != null) { + for (int lrg : info.use) { + relatedNodes.get(lrg).add(node); + } + } + if (info.join != null) { + for (int lrg : info.join) { + relatedNodes.get(lrg).add(node); + } + } + } + + public LivenessInfo getLivenessInfoForNode(InputNode node) { + return livenessInfo.get(node.getId()); + } + + public Set getRelatedNodes(int liveRangeId) { + return relatedNodes.get(liveRangeId); + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Graph ").append(getName()).append(" ").append(getProperties().toString()).append("\n"); for (InputNode n : nodes.values()) { sb.append(n.toString()); + if (livenessInfo.containsKey(n.getId())) { + sb.append(" " + livenessInfo.get(n.getId()).toString()); + } sb.append("\n"); } @@ -323,6 +366,11 @@ public String toString() { sb.append("\n"); } + for (InputLiveRange l : liveRanges.values()) { + sb.append(l.toString()); + sb.append("\n"); + } + return sb.toString(); } diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputLiveRange.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputLiveRange.java new file mode 100644 index 0000000000000..dcb796aa32bbc --- /dev/null +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputLiveRange.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.data; + +import java.util.Objects; + +public class InputLiveRange extends Properties.Entity { + + private int id; + + public InputLiveRange(InputLiveRange n) { + super(n); + setId(n.id); + } + + public InputLiveRange(int id) { + setId(id); + } + + public void setId(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + InputLiveRange other = (InputLiveRange) obj; + return id == other.id && + Objects.equals(getProperties(), other.getProperties()); + } + + @Override + public int hashCode() { + return Objects.hash(id, getProperties()); + } + + @Override + public String toString() { + return "L" + id + " " + getProperties().toString(); + } +} diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/LivenessInfo.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/LivenessInfo.java new file mode 100644 index 0000000000000..156a4a865f7a8 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/LivenessInfo.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.data; + +import java.util.*; + +public class LivenessInfo { + + public Integer def; + public Set use; + public Set kill; + public Set join; + public Set livein; + public Set liveout; + + public LivenessInfo() {} + + @Override + public String toString() { + return "def: " + def + + ", use: " + use + + ", kill: " + kill + + ", join: " + join + + ", livein: " + livein + + ", liveout: " + liveout; + } + +} diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Parser.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Parser.java index 9db0d83e0ebf7..4ae6e23cbb1c4 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Parser.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Parser.java @@ -64,6 +64,9 @@ public class Parser implements GraphParser { public static final String EDGE_ELEMENT = "edge"; public static final String NODE_ELEMENT = "node"; public static final String NODES_ELEMENT = "nodes"; + public static final String LIVE_RANGE_ELEMENT = "lrg"; + public static final String LIVE_RANGES_ELEMENT = "liveRanges"; + public static final String LIVE_RANGE_ID_PROPERTY = "id"; public static final String VISIBLE_NODES_ELEMENT = "visibleNodes"; public static final String ALL_PROPERTY = "all"; public static final String REMOVE_EDGE_ELEMENT = "removeEdge"; @@ -89,6 +92,7 @@ public class Parser implements GraphParser { public static final String BLOCK_ELEMENT = "block"; public static final String SUCCESSORS_ELEMENT = "successors"; public static final String SUCCESSOR_ELEMENT = "successor"; + public static final String LIVEOUT_ELEMENT = "liveOut"; public static final String DIFFERENCE_PROPERTY = "difference"; private final TopElementHandler xmlData = new TopElementHandler<>(); private final Map differenceEncoding = new HashMap<>(); @@ -150,6 +154,9 @@ protected GraphContext start() { return graphContext; } }; + // + private final HandoverElementHandler liveRangesHandler = new HandoverElementHandler<>(LIVE_RANGES_ELEMENT); + // private final ElementHandler visibleNodesHandler = new ElementHandler<>(VISIBLE_NODES_ELEMENT) { @Override @@ -222,6 +229,41 @@ protected InputBlock start() throws SAXException { return getParentObject(); } }; + // + private final HandoverElementHandler liveOutHandler = new HandoverElementHandler<>(LIVEOUT_ELEMENT); + // + private final ElementHandler liveRangeHandler = new ElementHandler<>(LIVE_RANGE_ELEMENT) { + + @Override + protected InputLiveRange start() throws SAXException { + String s = readRequiredAttribute(NODE_ID_PROPERTY); + int id; + try { + id = lookupID(s); + } catch (NumberFormatException e) { + throw new SAXException(e); + } + InputLiveRange lrg = new InputLiveRange(id); + getParentObject().addLiveRange(lrg); + return lrg; + } + }; + + private final ElementHandler blockLiveRangeHandler = new ElementHandler<>(LIVE_RANGE_ELEMENT) { + + @Override + protected InputBlock start() throws SAXException { + String s = readRequiredAttribute(LIVE_RANGE_ID_PROPERTY); + int liveRangeId; + try { + liveRangeId = Integer.parseInt(s); + } catch (Exception e) { + throw new SAXException(e); + } + getParentObject().addLiveOut(liveRangeId); + return getParentObject(); + } + }; // private final HandoverElementHandler edgesHandler = new HandoverElementHandler<>(EDGES_ELEMENT); // @@ -482,6 +524,7 @@ public Parser(ReadableByteChannel channel, ParseMonitor monitor, GraphDocument c graphHandler.addChild(nodesHandler); graphHandler.addChild(edgesHandler); graphHandler.addChild(controlFlowHandler); + graphHandler.addChild(liveRangesHandler); graphHandler.addChild(graphStatesHandler); controlFlowHandler.addChild(blockHandler); @@ -495,6 +538,10 @@ public Parser(ReadableByteChannel channel, ParseMonitor monitor, GraphDocument c successorsHandler.addChild(successorHandler); blockHandler.addChild(blockNodesHandler); blockNodesHandler.addChild(blockNodeHandler); + blockHandler.addChild(liveOutHandler); + liveOutHandler.addChild(blockLiveRangeHandler); + + liveRangesHandler.addChild(liveRangeHandler); nodesHandler.addChild(nodeHandler); nodesHandler.addChild(removeNodeHandler); @@ -509,6 +556,7 @@ public Parser(ReadableByteChannel channel, ParseMonitor monitor, GraphDocument c nodeHandler.addChild(propertiesHandler); propertiesHandler.addChild(propertyHandler); groupPropertiesHandler.addChild(propertyHandler); + liveRangeHandler.addChild(propertiesHandler); } private int lookupID(String i) { diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/PreProcessor.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/PreProcessor.java new file mode 100644 index 0000000000000..dc96e887786ae --- /dev/null +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/PreProcessor.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.hotspot.igv.data.services; + +import com.sun.hotspot.igv.data.InputGraph; + +public interface PreProcessor { + public void preProcess(InputGraph graph); +} diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/resources/com/sun/hotspot/igv/data/serialization/graphdocument.xsd b/src/utils/IdealGraphVisualizer/Data/src/main/resources/com/sun/hotspot/igv/data/serialization/graphdocument.xsd index 4e02fb64bb911..2d485024f3f26 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/resources/com/sun/hotspot/igv/data/serialization/graphdocument.xsd +++ b/src/utils/IdealGraphVisualizer/Data/src/main/resources/com/sun/hotspot/igv/data/serialization/graphdocument.xsd @@ -143,8 +143,18 @@ + + + + + + + + + + + - diff --git a/src/utils/IdealGraphVisualizer/Difference/src/main/java/com/sun/hotspot/igv/difference/Difference.java b/src/utils/IdealGraphVisualizer/Difference/src/main/java/com/sun/hotspot/igv/difference/Difference.java index 185d219c8deb7..c7d20e84f241e 100644 --- a/src/utils/IdealGraphVisualizer/Difference/src/main/java/com/sun/hotspot/igv/difference/Difference.java +++ b/src/utils/IdealGraphVisualizer/Difference/src/main/java/com/sun/hotspot/igv/difference/Difference.java @@ -26,6 +26,7 @@ import com.sun.hotspot.igv.data.Properties; import com.sun.hotspot.igv.data.*; +import com.sun.hotspot.igv.data.services.PreProcessor; import com.sun.hotspot.igv.data.services.Scheduler; import java.util.*; import org.openide.util.Lookup; @@ -84,6 +85,8 @@ private static void ensureScheduled(InputGraph a) { s.schedule(a); a.ensureNodesInBlocks(); } + PreProcessor p = Lookup.getDefault().lookup(PreProcessor.class); + p.preProcess(a); } private static InputGraph createDiff(InputGraph a, InputGraph b, Set pairs) { diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js b/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js index b68a027d945e7..802fc00297189 100644 --- a/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js @@ -67,6 +67,11 @@ function matches(property, regexp) { return new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)); } +// Select the nodes for which the given property is defined. +function hasProperty(property) { + return new MatcherSelector(new Properties.InvertPropertyMatcher(new Properties.RegexpPropertyMatcher(property, ""))); +} + // Color the selected nodes. function colorize(selector, color) { var f = new ColorFilter(""); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java new file mode 100644 index 0000000000000..396ccb0df1f24 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.hotspot.igv.servercompiler; + +import com.sun.hotspot.igv.data.*; +import com.sun.hotspot.igv.data.services.PreProcessor; +import org.openide.util.lookup.ServiceProvider; +import java.util.*; +import java.util.stream.*; + +@ServiceProvider(service = PreProcessor.class) +public class ServerCompilerPreProcessor implements PreProcessor { + + // Map from input live range ids to regular node ids. Note that this is + // possible only at the 'Initial liveness' phase, where there is still a + // one-to-one relation between these. Later on, C2 might assign the same + // live range to multiple regular node ids when coalescing. + Map liveRangeIdToNodeId = new HashMap<>(42); + + private static boolean isPhi(InputNode node) { + String nodeName = node.getProperties().get("name"); + if (nodeName == null) { + return false; + } + return nodeName.equals("Phi"); + } + + private static int getNumericPropertyOrZero(InputNode node, String k) { + int v = 0; + try { + v = Integer.parseInt(node.getProperties().get(k)); + } catch (Exception e) { + } + return v; + } + + private static boolean isAllocatableLiveRange(int liveRangeId) { + return liveRangeId > 0; + } + + private int liveRangeIdentifier(int liveRangeId) { + return InputBlock.USE_LIVE_RANGE_IDENTIFIERS ? liveRangeId : liveRangeIdToNodeId.get(liveRangeId); + } + + private String liveRangeList(Stream s) { + return s.sorted().map(String::valueOf).collect(Collectors.joining(", ")); + } + + @Override + public void preProcess(InputGraph graph) { + boolean empty = true; + for (InputBlock b : graph.getBlocks()) { + if (!b.getLiveOut().isEmpty()) { + empty = false; + break; + } + } + if (empty) { // No block-level liveness information available, move on. + return; + } + if (!InputBlock.USE_LIVE_RANGE_IDENTIFIERS) { + liveRangeIdToNodeId.clear(); + for (InputNode n : graph.getNodes()) { + int lrg = getNumericPropertyOrZero(n, "lrg"); + assert !liveRangeIdToNodeId.containsKey(lrg); + if (lrg > 0) { + int idx = getNumericPropertyOrZero(n, "idx"); + liveRangeIdToNodeId.put(lrg, idx); + } + } + } + + // Build a map from nodes to live ranges used. + Map> usedLiveRanges = new HashMap<>(graph.getNodes().size()); + for (InputEdge e : graph.getEdges()) { + int liveRangeId = getNumericPropertyOrZero(graph.getNode(e.getFrom()), "lrg"); + if (isAllocatableLiveRange(liveRangeId)) { + int toId = e.getTo(); + if (usedLiveRanges.get(toId) == null) { + usedLiveRanges.put(toId, new ArrayList()); + } + usedLiveRanges.get(toId).add(liveRangeIdentifier(liveRangeId)); + } + } + // Propagate block-level live-out information to each node. + for (InputBlock b : graph.getBlocks()) { + Set liveOut = new HashSet<>(); + for (int lrg : b.getLiveOut()) { + liveOut.add(liveRangeIdentifier(lrg)); + } + for (int i = b.getNodes().size() - 1; i >= 0; i--) { + LivenessInfo livenessInfo = new LivenessInfo(); + InputNode n = b.getNodes().get(i); + String liveOutList = liveRangeList(liveOut.stream()); + n.getProperties().setProperty("liveout", liveOutList); + livenessInfo.liveout = new HashSet<>(liveOut); + int defLiveRange = getNumericPropertyOrZero(n, "lrg"); + if (isAllocatableLiveRange(defLiveRange)) { + livenessInfo.def = defLiveRange; + // Otherwise it is missing or a non-allocatable live range. + liveOut.remove(liveRangeIdentifier(defLiveRange)); + } + List uses = usedLiveRanges.get(n.getId()); + if (uses != null) { + String useList = liveRangeList(uses.stream()); + if (isPhi(n)) { + // A phi's uses are not live simultaneously. + // Conceptually, they die at the block's incoming egdes. + n.getProperties().setProperty("joins", useList); + livenessInfo.join = new HashSet<>(uses); + } else { + n.getProperties().setProperty("uses", useList); + livenessInfo.use = new HashSet<>(uses); + // Compute kill set: all uses that are not in the + // live-out set of the node. + Set kills = new HashSet<>(); + for (int useLiveRange : uses) { + if (!liveOut.contains(useLiveRange) && useLiveRange != defLiveRange) { + kills.add(useLiveRange); + } + } + if (!kills.isEmpty()) { + String killList = liveRangeList(kills.stream()); + n.getProperties().setProperty("kills", killList); + livenessInfo.kill = new HashSet<>(kills); + } + for (int useLiveRange : uses) { + liveOut.add(useLiveRange); + } + } + } + String liveInList = liveRangeList(liveOut.stream()); + n.getProperties().setProperty("livein", liveInList); + livenessInfo.livein = new HashSet<>(liveOut); + graph.addLivenessInfo(n, livenessInfo); + } + } + } +} diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showLiveness.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showLiveness.filter new file mode 100644 index 0000000000000..cc25aef6a4c64 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showLiveness.filter @@ -0,0 +1,44 @@ +// This filter replaces the extra-label line with liveness information such as +// uses, defs, and live-out sets, if available. + +function formatLiveRange(lrg) { + flrg = "" + if (InputBlock.USE_LIVE_RANGE_IDENTIFIERS) { + flrg += "L"; + } + flrg += lrg.trim(); + return flrg; +} + +function liveRangeSet(integerList) { + return "{" + (integerList.split(",").map(function(lrg) {return formatLiveRange(lrg);})).join(", ") + "}"; +} + +// Replace extra label with liveness info. +function addLivenessInfo(lrg, idx, liveout, uses, joins, kills) { + if (lrg == null || liveout == null) { + return ""; + } + elements = []; + if (Number(lrg) > 0) { + elements.push("def: " + (InputBlock.USE_LIVE_RANGE_IDENTIFIERS ? ("L" + lrg) : idx)); + } + if (uses != null) { + elements.push("use: " + liveRangeSet(uses)); + } + if (joins != null) { + elements.push("join: " + liveRangeSet(joins)); + } + if (kills != null) { + elements.push("kill: " + liveRangeSet(kills)); + } + if (liveout.length > 0) { + elements.push("liveout: " + liveRangeSet(liveout)); + } + return elements.join(", "); +} + +editProperty(matches("name", ".*"), + ["lrg", "idx", "liveout", "uses", "joins", "kills"], + "extra_label", + function(propertyValues) {return addLivenessInfo(propertyValues[0], propertyValues[1], propertyValues[2], propertyValues[3], propertyValues[4], propertyValues[5]);}); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showRegisterAllocationOnly.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showRegisterAllocationOnly.filter new file mode 100644 index 0000000000000..d4625d864392a --- /dev/null +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showRegisterAllocationOnly.filter @@ -0,0 +1,5 @@ +// Remove all nodes except those that affect register allocation. +remove(and([matches("lrg", "0"), + not(hasProperty("uses")), + not(hasProperty("joins")), + not(hasProperty("kills"))])); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml index 808a281fee4e1..155ab64b71646 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml @@ -85,5 +85,13 @@ + + + + + + + + diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index 710c5c125f61a..f9cdec59b55aa 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -26,6 +26,7 @@ import com.sun.hotspot.igv.data.Properties; import com.sun.hotspot.igv.data.*; +import com.sun.hotspot.igv.data.services.PreProcessor; import com.sun.hotspot.igv.data.services.Scheduler; import com.sun.hotspot.igv.difference.Difference; import com.sun.hotspot.igv.filter.ColorFilter; @@ -398,6 +399,8 @@ private void rebuildDiagram() { s.schedule(graph); graph.ensureNodesInBlocks(); } + PreProcessor p = Lookup.getDefault().lookup(PreProcessor.class); + p.preProcess(graph); diagram = new Diagram(graph, Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT), Settings.get().get(Settings.NODE_SHORT_TEXT, Settings.NODE_SHORT_TEXT_DEFAULT), From e40342dae4002278550736b0b33bf0c7f226d40b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 27 Jan 2025 11:04:39 +0100 Subject: [PATCH 03/48] Add button and define action to enable live range visualization --- .../hotspot/igv/view/DiagramViewModel.java | 12 +++ .../hotspot/igv/view/EditorTopComponent.java | 1 + .../view/actions/ShowLiveRangesAction.java | 85 ++++++++++++++++++ .../igv/view/images/showLiveRanges.png | Bin 0 -> 5028 bytes .../com/sun/hotspot/igv/view/layer.xml | 1 + 5 files changed, 99 insertions(+) create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/showLiveRanges.png diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index f9cdec59b55aa..ff3d62a0bc367 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -71,6 +71,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene private boolean showCFG; private boolean showNodeHull; private boolean showEmptyBlocks; + private boolean showLiveRanges; private static boolean globalSelection = false; private static boolean cutEdges = false; @@ -180,6 +181,15 @@ public void setShowEmptyBlocks(boolean b) { diagramChangedEvent.fire(); } + public boolean getShowLiveRanges() { + return showLiveRanges; + } + + public void setShowLiveRanges(boolean b) { + showLiveRanges = b; + diagramChangedEvent.fire(); + } + private void initGroup() { group.getChangedEvent().addListener(g -> { assert g == group; @@ -219,6 +229,7 @@ public DiagramViewModel(DiagramViewModel model) { showBlocks = model.getShowBlocks(); showNodeHull = model.getShowNodeHull(); showEmptyBlocks = model.getShowEmptyBlocks(); + showLiveRanges = model.getShowLiveRanges(); hiddenNodes = new HashSet<>(model.getHiddenNodes()); selectedNodes = new HashSet<>(); @@ -244,6 +255,7 @@ public DiagramViewModel(InputGraph graph) { showCFG = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CONTROL_FLOW_GRAPH; showNodeHull = true; showEmptyBlocks = true; + showLiveRanges = true; hiddenNodes = new HashSet<>(); selectedNodes = new HashSet<>(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java index ff51b8928f676..d3c7c1a6f71d8 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java @@ -205,6 +205,7 @@ public void mouseMoved(MouseEvent e) {} toolBar.addSeparator(); toolBar.add(new JToggleButton(new PredSuccAction(diagramViewModel.getShowNodeHull()))); toolBar.add(new JToggleButton(new ShowEmptyBlocksAction(cfgLayoutAction, diagramViewModel.getShowEmptyBlocks()))); + toolBar.add(new JToggleButton(new ShowLiveRangesAction(cfgLayoutAction, diagramViewModel.getShowLiveRanges()))); toolBar.addSeparator(); UndoAction undoAction = UndoAction.get(UndoAction.class); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java new file mode 100644 index 0000000000000..5a964d25a337f --- /dev/null +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.view.actions; + +import com.sun.hotspot.igv.view.EditorTopComponent; +import java.awt.event.ActionEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.AbstractAction; +import javax.swing.ImageIcon; +import org.openide.util.ImageUtilities; + +public class ShowLiveRangesAction extends AbstractAction implements PropertyChangeListener { + + private boolean selected; + private AbstractAction parentAction; + + public ShowLiveRangesAction(AbstractAction action, boolean select) { + this.parentAction = action; + this.selected = select; + this.parentAction.addPropertyChangeListener(this); + putValue(SELECTED_KEY, this.selected); + putValue(SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource()))); + putValue(SHORT_DESCRIPTION, "Show live ranges in control-flow graph view (if liveness information is available)"); + enableIfParentSelected(); + } + + @Override + public void actionPerformed(ActionEvent ev) { + this.selected = isSelected(); + EditorTopComponent editor = EditorTopComponent.getActive(); + if (editor != null) { + editor.getModel().setShowLiveRanges(this.selected); + } + } + + protected String iconResource() { + return "com/sun/hotspot/igv/view/images/showLiveRanges.png"; + } + + private boolean isSelected() { + return (Boolean)getValue(SELECTED_KEY); + } + + private void enableIfParentSelected() { + boolean enable = parentAction.isEnabled() && (Boolean)parentAction.getValue(SELECTED_KEY); + if (enable != this.isEnabled()) { + if (enable) { + putValue(SELECTED_KEY, this.selected); + } else { + this.selected = isSelected(); + putValue(SELECTED_KEY, false); + } + } + this.setEnabled(enable); + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getSource() == this.parentAction) { + enableIfParentSelected(); + } + } +} diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/showLiveRanges.png b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/showLiveRanges.png new file mode 100644 index 0000000000000000000000000000000000000000..3f4e9edc5b8e531329da06c6e1e6664b34a0c3ff GIT binary patch literal 5028 zcmeHKc~leU79Rvz0u*p5pjbi>Wy>~6$Wp>$f)FqP0TmF0Niqpj$YK&m1gR24EehJY z^ytG4M3MSzMf6Y=5v7V7E*L3GsSl;{uvl6Y(1N~6K*iJk<2kSYnVgx--0ydP_q)IE z&doPp#0bLeF|#lL0NC>)xUuN3qw%n|M9=PnuOI-hz~sayXksBPR;f}*kW3h>S*3)r zunv&`fUf<NUj~x0hgJ)uhpPBLq$Nf;ux;E7FQ5Np zASPc=@_Vcw>8-m2mlv0k9P3h6b@4h@r8?xecQzS**L#4yH-=nRU77vRr6s52noa+U zGY2llU1&;Kaj@p$^QC*g4&9l{vCThlUrYy zA3u$5=$0pLxbJ!CLc3+-iI4WzDNEOPete7bUGQ&Jc8fagT#L_;Z7W=ZGwy7CP;y*f z7U1L{KesmBaz#O82ymy?%`4AhkQMN?OI>ZVf7C^ug7duSWR$-1m&@cb=RbB>T4i*% z+Nz_z847PZ{i&kgza46ODHmlr;csmwT?`|X`aWyg!eY~g=e%Z4hhJ3akl zV|QuKZT%2t=hTARxZS-6ZBJ{9Qf{eJ47c7ltPQ1K^iN2;lPH^4T^^;{#jD9L1EO3(gT?IR0S}AC9_!~WJj(ce8h37F zk(>P~h4bRWi-ntg8W4TYx;7h(58OPjz5rftUO4*>VhyG+Yf9x6QA)6jX}?vYc~1#-ygP(ek5i%U)Mk6EnR<=1@#uk01R zO%IFfVS#<0032@WpxoG0tJ3+)Sxx2ME#l+~dDP{Gtjbe8(>9bDq-;CR&6G!9w~bEO(cZacOJto*Q+Vaw z=iX(Bh>d%`NtT`x1=ak|YA9G+F_eLMBh5Vzu!=H1IGKWFT^yYE7+_HfsW zKY=~02mRN^de>lvqQ_cicR;-b4kd>lx7P>X9Wqn(>DF{Sh_(-^9#ABX+18!#8Xl=S zAO!%kbqI$O!{cyXcLlT;l;(ZOj<^`&_CxCOidf${{t1m9oUCfBZ+GPq?*)Z1el>k* zs{cAuk%-u2x2diA0{2ZztemAObCRcq4wyH#HSlhSMUJM%raL`oSQ*^)Q*LLS`REPb zxEp&{h8X-kw?$&UAFXm+9cE3oAaC5*xF}CBqh-J?b$HX)5hWT^`G@d3x^0q082eol}$SJ6;Bz>c3~> zsIxp)Q&NA=LK4JNXlh2B9NR1j$3ESC)++f4aD09WI5!+~>#6gm^MAVL#eL#ZJ9R;Z zT+yFb8U!Tv`R19sxlJkey1HUmr%lx=UhPGOhs~KIs;!mh?QGHRJqtm*bOL`7OQety zAhALS6Lc~q+Qk7NFj%LAL>aIKD}<$poQ?bKOg#>Zh}pPhG(L&10ctyW9WQV0r_lt^YWnM4vu1VKECz^hlu zHINQ3S9=;M#yPmKTBJgh8bl$-8aW}MB1^-@;m~pH>-ou)eEu7Hxq3ncR1cyKQWD7o z5>X~2PWDi1!m?44i3$C!hdLhpvm?gBYDJbx1cznAa*gL?3bE*ozcNdeX-Y>dBEp%l z427!EsN{D-hV%F_Z#;|=ND-OR9fpbS6&(b$`SA4*GTOCNPTP z^I2SlD9boK9+!t+_W-uA=va1ymjTTbD zp;9zcG#j*lOxa+)O;Y;2i`J&YMx96?6_3^vNR1~kSu`pOr1_CR7Kwx-P9#h;KGm-? z4kZ3XlRy(-QX4@1#%*YOLAw?4O}m=V%qZhO_?cLXe=q_{{UOME>H9&h4|2Vi0`CR> zP+cG7dM^du3;dzF{%>+&-oEg_a&#A@MPFxREp6oHT6a?SHnDI&I1;^XQ|03+ALCMJ-x1OpyJsz|`hKnN sijipSeHY}(luKsz=0)~tZUft`fs}Y_+|{J^Ehrbj3lngUElAV<4@?S)RsaA1 literal 0 HcmV?d00001 diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml index d50f7c914ccfe..78d056e845151 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml +++ b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml @@ -14,6 +14,7 @@ + From 7a3814d6865cb1b54e91c515d14d02b3172f2885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 27 Jan 2025 11:14:57 +0100 Subject: [PATCH 04/48] Generalize clearSelectedNodes to different elements (also live ranges) --- .../sun/hotspot/igv/bytecodes/SelectBytecodesAction.java | 2 +- .../sun/hotspot/igv/data/services/InputGraphProvider.java | 2 +- .../java/com/sun/hotspot/igv/view/BlockQuickSearch.java | 2 +- .../main/java/com/sun/hotspot/igv/view/DiagramScene.java | 6 +++--- .../main/java/com/sun/hotspot/igv/view/DiagramViewer.java | 2 +- .../com/sun/hotspot/igv/view/EditorInputGraphProvider.java | 4 ++-- .../java/com/sun/hotspot/igv/view/EditorTopComponent.java | 4 ++-- .../main/java/com/sun/hotspot/igv/view/NodeQuickSearch.java | 4 ++-- .../java/com/sun/hotspot/igv/view/widgets/BlockWidget.java | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java index ef9546bbe13f6..9399c7869f26a 100644 --- a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java +++ b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java @@ -41,7 +41,7 @@ protected void performAction(Node[] activatedNodes) { SelectBytecodesCookie c = activatedNodes[0].getCookie(SelectBytecodesCookie.class); InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class); if (p != null) { - p.clearSelectedNodes(); + p.clearSelectedElements(); p.addSelectedNodes(c.getNodes(), true); p.centerSelectedNodes(); } diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/InputGraphProvider.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/InputGraphProvider.java index b11b29b3d1b55..4a0a915c88ba9 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/InputGraphProvider.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/InputGraphProvider.java @@ -40,7 +40,7 @@ public interface InputGraphProvider { void addSelectedNodes(Collection nodes, boolean showIfHidden); - void clearSelectedNodes(); + void clearSelectedElements(); /** * @return an iterator walking forward through the {@link InputGraph}s following the {@link #getGraph()} diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java index 79727ad902851..54db33405b5cc 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java @@ -92,7 +92,7 @@ public void evaluate(SearchRequest request, SearchResponse response) { if (theGraph != null) { editor.getModel().selectGraph(theGraph); } - editor.clearSelectedNodes(); + editor.clearSelectedElements(); editor.addSelectedNodes(b.getNodes(), true); editor.centerSelectedNodes(); editor.requestActive(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 99ae3380bb39d..6e94b023b6e08 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -374,7 +374,7 @@ public void select(Widget widget, Point localLocation, boolean invertSelection) rectangle.height *= -1; } - clearSelectedNodes(); + clearSelectedElements(); Set selectedObjects = new HashSet<>(); for (Figure f : getModel().getDiagram().getFigures()) { FigureWidget w = getWidget(f); @@ -1210,7 +1210,7 @@ public void setInteractionMode(InteractionMode mode) { @Override public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) { - clearSelectedNodes(); + clearSelectedElements(); } private class ConnectionSet { @@ -1253,7 +1253,7 @@ public void addSelectedNodes(Collection nodes, boolean showIfHidden) } @Override - public void clearSelectedNodes() { + public void clearSelectedElements() { setSelectedObjects(Collections.emptySet()); } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java index e8cfd2968dc29..4a24e3e13d015 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java @@ -79,7 +79,7 @@ enum InteractionMode { void addSelectedNodes(Collection nodes, boolean showIfHidden); - void clearSelectedNodes(); + void clearSelectedElements(); void setInteractionMode(InteractionMode mode); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java index ade73d9f1e5cb..d06375856cfb0 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java @@ -73,9 +73,9 @@ public void addSelectedNodes(Collection nodes, boolean showIfHidden) } @Override - public void clearSelectedNodes() { + public void clearSelectedElements() { if (editor != null && EditorTopComponent.isOpen(editor)) { - editor.clearSelectedNodes(); + editor.clearSelectedElements(); editor.requestActive(); } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java index d3c7c1a6f71d8..ecd0edbf2c38d 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java @@ -358,8 +358,8 @@ public void centerSelectedNodes() { scene.centerSelectedFigures(); } - public void clearSelectedNodes() { - scene.clearSelectedNodes(); + public void clearSelectedElements() { + scene.clearSelectedElements(); } public Rectangle getSceneBounds() { diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/NodeQuickSearch.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/NodeQuickSearch.java index fb8ef8535b765..654d8c123645a 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/NodeQuickSearch.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/NodeQuickSearch.java @@ -121,7 +121,7 @@ public void evaluate(SearchRequest request, SearchResponse response) { if (theGraph != null) { editor.getModel().selectGraph(theGraph); } - editor.clearSelectedNodes(); + editor.clearSelectedElements(); editor.addSelectedNodes(nodeSet, true); editor.centerSelectedNodes(); editor.requestActive(); @@ -151,7 +151,7 @@ public void run() { if (theGraph != null) { editor.getModel().selectGraph(theGraph); } - editor.clearSelectedNodes(); + editor.clearSelectedElements(); editor.addSelectedNodes(tmpSet, true); editor.centerSelectedNodes(); editor.requestActive(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java index 941836f5bb703..ebfc7deded65f 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java @@ -82,7 +82,7 @@ private void addToSelection(BlockWidget blockWidget, boolean additiveSelection) InputGraphProvider graphProvider = LookupHistory.getLast(InputGraphProvider.class); if (graphProvider != null) { if (!additiveSelection) { - graphProvider.clearSelectedNodes(); + graphProvider.clearSelectedElements(); } graphProvider.addSelectedNodes(blockWidget.getBlockNode().getNodes(), false); } From 322c97dc1d5d40f2b0ea254fb2796cc42c4ef0d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 27 Jan 2025 11:40:44 +0100 Subject: [PATCH 05/48] Represent live ranges at the diagram graph and abstract layout level --- .../java/com/sun/hotspot/igv/graph/Block.java | 20 +++ .../com/sun/hotspot/igv/graph/Diagram.java | 78 +++++++++- .../hotspot/igv/graph/LiveRangeSegment.java | 136 ++++++++++++++++++ .../igv/hierarchicallayout/LayoutGraph.java | 14 +- .../com/sun/hotspot/igv/layout/Cluster.java | 2 + .../com/sun/hotspot/igv/layout/Segment.java | 40 ++++++ 6 files changed, 288 insertions(+), 2 deletions(-) create mode 100644 src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java create mode 100644 src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Segment.java diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Block.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Block.java index 319f41a924928..1abaa3a47a00f 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Block.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Block.java @@ -40,6 +40,8 @@ public class Block implements Cluster { protected final InputBlock inputBlock; private Rectangle bounds; private final Diagram diagram; + private List liveRangeIds; + int liveRangeSeparation = -1; public Block(InputBlock inputBlock, Diagram diagram) { this.inputBlock = inputBlock; @@ -70,6 +72,11 @@ public List getVertices() { return vertices; } + public int getLiveRangeSeparation() { + assert liveRangeSeparation > 0; + return liveRangeSeparation; + } + public void setBounds(Rectangle r) { this.bounds = r; } @@ -91,6 +98,19 @@ public Rectangle getBounds() { return bounds; } + public List getLiveRangeIds() { + return liveRangeIds; + } + + public void setLiveRangeIds(List liveRangeIds) { + this.liveRangeIds = liveRangeIds; + int extraDigits = 0; + if (!liveRangeIds.isEmpty()) { + extraDigits = (int)java.lang.Math.log10(Collections.max(liveRangeIds)); + } + liveRangeSeparation = 20 + extraDigits * 7; + } + public int compareTo(Cluster o) { return toString().compareTo(o.toString()); } diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java index b42dec7eb396e..17fb5a66b1e83 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java @@ -35,7 +35,9 @@ public class Diagram { private final Map figures; + private final Hashtable figureHash; private final Map blocks; + private List liveRangeSegments; private final InputGraph inputGraph; private final String nodeText; private final String shortNodeText; @@ -65,7 +67,9 @@ public Diagram(InputGraph graph, String nodeText, String shortNodeText, this.shortNodeText = shortNodeText; this.tinyNodeText = tinyNodeText; this.figures = new LinkedHashMap<>(); + this.figureHash = new Hashtable<>(); this.blocks = new LinkedHashMap<>(8); + this.liveRangeSegments = new ArrayList<>(); this.blockConnections = new HashSet<>(); this.inputGraph = graph; this.cfg = false; @@ -76,7 +80,6 @@ public Diagram(InputGraph graph, String nodeText, String shortNodeText, } Collection nodes = graph.getNodes(); - Hashtable figureHash = new Hashtable<>(); for (InputNode n : nodes) { Figure f = new Figure(this, curId, n); curId++; @@ -128,6 +131,75 @@ public Diagram(InputGraph graph, String nodeText, String shortNodeText, Block s = getBlock(e.getTo()); blockConnections.add(new BlockConnection(p, s, e.getLabel())); } + + Hashtable liveRangeHash = new Hashtable<>(); + for (InputLiveRange lrg : graph.getLiveRanges()) { + liveRangeHash.put(lrg.getId(), lrg); + } + + for (InputBlock b : graph.getBlocks()) { + if (b.getNodes().isEmpty()) { + continue; + } + Map active = new HashMap<>(); + Set instant = new HashSet<>(); + InputNode header = b.getNodes().get(0); + if (graph.getLivenessInfoForNode(header) == null) { + // No liveness information available, skip. + continue; + } + for (int liveRangeId : graph.getLivenessInfoForNode(header).livein) { + active.put(liveRangeId, null); + } + for (InputNode n : b.getNodes()) { + LivenessInfo l = graph.getLivenessInfoForNode(n); + // Commit segments killed by n. + if (l.kill != null) { + for (int liveRangeId : l.kill) { + InputNode startNode = active.get(liveRangeId); + Figure start = startNode == null ? null : figureHash.get(startNode.getId()); + InputNode endNode = n; + Figure end = figureHash.get(endNode.getId()); + liveRangeSegments + .add(new LiveRangeSegment(liveRangeHash.get(liveRangeId), getBlock(b), start, end)); + active.remove(liveRangeId); + } + } + // Activate new segments. + if (l.def != null && !active.containsKey(l.def)) { + active.put(l.def, n); + if (!l.liveout.contains(l.def)) { + instant.add(l.def); + } + } + } + // Commit segments live out the block. + for (Integer liveRangeId : active.keySet()) { + InputNode startNode = active.get(liveRangeId); + Figure start = startNode == null ? null : figureHash.get(startNode.getId()); + LiveRangeSegment s = new LiveRangeSegment(liveRangeHash.get(liveRangeId), getBlock(b), start, null); + if (instant.contains(liveRangeId)) { + s.setInstantaneous(true); + } + liveRangeSegments.add(s); + } + } + liveRangeSegments.sort(Comparator.comparingInt(s -> s.getLiveRange().getId())); + for (InputBlock inputBlock : graph.getBlocks()) { + // This loop could be sped up by fusing it with the above one. + List liveRangeSegmentIds = new ArrayList<>(); + int lastAddedLiveRangeId = -1; + for (LiveRangeSegment s : getLiveRangeSegments()) { + if (s.getCluster().getInputBlock().getName().equals(inputBlock.getName())) { + int thisLiveRangeId = s.getLiveRange().getId(); + if (thisLiveRangeId != lastAddedLiveRangeId) { + liveRangeSegmentIds.add(thisLiveRangeId); + lastAddedLiveRangeId = thisLiveRangeId; + } + } + } + blocks.get(inputBlock).setLiveRangeIds(liveRangeSegmentIds); + } } public InputGraph getInputGraph() { @@ -176,6 +248,10 @@ public List
getFigures() { return Collections.unmodifiableList(new ArrayList<>(figures.values())); } + public List getLiveRangeSegments() { + return Collections.unmodifiableList(liveRangeSegments); + } + public FigureConnection createConnection(InputSlot inputSlot, OutputSlot outputSlot, String label) { assert inputSlot.getFigure().getDiagram() == this; assert outputSlot.getFigure().getDiagram() == this; diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java new file mode 100644 index 0000000000000..2eed887981dee --- /dev/null +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.graph; + +import com.sun.hotspot.igv.data.InputLiveRange; +import com.sun.hotspot.igv.data.Properties; +import com.sun.hotspot.igv.layout.Segment; +import java.awt.Point; + +public class LiveRangeSegment extends Properties.Entity implements Segment { + + private InputLiveRange liveRange; + private Block block; + private Figure start; + private Figure end; + private Point startPoint; + private Point endPoint; + private boolean lastOfLiveRange; + private boolean instantaneous; + + protected LiveRangeSegment(InputLiveRange liveRange, Block block, Figure start, Figure end) { + this.block = block; + this.liveRange = liveRange; + this.start = start; + this.end = end; + assert(start == null || end == null || (start.getBlock() == end.getBlock())); + lastOfLiveRange = true; + } + + public InputLiveRange getLiveRange() { + return liveRange; + } + + public Block getCluster() { + return block; + } + + public Figure getStart() { + return start; + } + + public Figure getEnd() { + return end; + } + + public Point getStartPoint() { + return startPoint; + } + + public void setStartPoint(Point startPoint) { + this.startPoint = startPoint; + } + + public Point getEndPoint() { + return endPoint; + } + + public void setEndPoint(Point endPoint) { + this.endPoint = endPoint; + } + + public void setLastOfLiveRange(boolean lastOfLiveRange) { + this.lastOfLiveRange = lastOfLiveRange; + } + + public boolean isLastOfLiveRange() { + return lastOfLiveRange; + } + + public int parentId() { + return this.liveRange.getId(); + } + + public void setInstantaneous(boolean instantaneous) { + this.instantaneous = instantaneous; + } + + public boolean isInstantaneous() { + return instantaneous; + } + + @Override + public String toString() { + return "LiveRangeSegment(" + liveRange + "@B" + block + ", " + start + ", " + end + ")"; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof LiveRangeSegment)) { + return false; + } + LiveRangeSegment other = (LiveRangeSegment)o; + if (getStart() == null && other.getStart() != null) { + return false; + } + if (getStart() != null && other.getStart() == null) { + return false; + } + if (getEnd() == null && other.getEnd() != null) { + return false; + } + if (getEnd() != null && other.getEnd() == null) { + return false; + } + return getLiveRange().equals(((LiveRangeSegment)o).getLiveRange()) + && (getStart() == null || getStart().equals(((LiveRangeSegment)o).getStart())) + && (getEnd() == null || getEnd().equals(((LiveRangeSegment)o).getEnd())); + } + + @Override + public Properties getProperties() { + return liveRange.getProperties(); + } + +} diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java index 956d72924b991..07cfd69e56dd0 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java @@ -27,6 +27,7 @@ import com.sun.hotspot.igv.layout.Link; import com.sun.hotspot.igv.layout.Port; import com.sun.hotspot.igv.layout.Vertex; +import com.sun.hotspot.igv.layout.Segment; import java.util.*; import java.util.stream.Collectors; @@ -49,12 +50,14 @@ public class LayoutGraph { .thenComparingInt(l -> l.getFrom().getRelativePosition().x) .thenComparingInt(l -> l.getTo().getRelativePosition().x); - // Registered Graph Components: Links, Vertices, and Port Mappings + // Registered Graph Components: Links, Vertices, and Port Mappings. + // Optionally, live range segments for the CFG view. private final Set links; private final SortedSet vertices; private final LinkedHashMap> inputPorts; private final LinkedHashMap> outputPorts; private final LinkedHashMap> portLinks; + private List segments; // Layout Management: LayoutNodes and LayoutLayers private final LinkedHashMap layoutNodes; @@ -75,6 +78,7 @@ public LayoutGraph(Collection links, Collection(links.size()); inputPorts = new LinkedHashMap<>(links.size()); outputPorts = new LinkedHashMap<>(links.size()); + segments = new ArrayList<>(); for (Link link : links) { assert link.getFrom() != null; @@ -447,6 +451,14 @@ public List getOutputLinks(Vertex vertex) { return outputLinks; } + public List getSegments() { + return segments; + } + + public void setSegments(List s) { + segments = new ArrayList<>(s); + } + /** * Checks if the given predecessorVertex is a direct predecessor of the specified vertex. * diff --git a/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Cluster.java b/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Cluster.java index 84ddd5dd69522..dc991bd6b2197 100644 --- a/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Cluster.java +++ b/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Cluster.java @@ -45,4 +45,6 @@ public interface Cluster extends Comparable { List getVertices(); Set getSuccessors(); + + int getLiveRangeSeparation(); } diff --git a/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Segment.java b/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Segment.java new file mode 100644 index 0000000000000..41e4d2c1acbfb --- /dev/null +++ b/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Segment.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.layout; + +import java.awt.Point; + +public interface Segment { + Cluster getCluster(); + Vertex getStart(); + Vertex getEnd(); + Point getStartPoint(); + void setStartPoint(Point startPoint); + Point getEndPoint(); + void setEndPoint(Point endPoint); + boolean isLastOfLiveRange(); + void setLastOfLiveRange(boolean lastOfLiveRange); + int parentId(); + boolean isInstantaneous(); +} From 33db9a48f9a08c4e8c36290e2e708249b12942da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 27 Jan 2025 13:47:57 +0100 Subject: [PATCH 06/48] Compute live range segment subsets and their layout --- .../igv/hierarchicallayout/ClusterNode.java | 53 ++++++++++++++- .../HierarchicalCFGLayoutManager.java | 67 ++++++++++++++++++- 2 files changed, 114 insertions(+), 6 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java index 0de4dfc47ebb5..5928147613ed4 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java @@ -26,6 +26,7 @@ import com.sun.hotspot.igv.layout.Cluster; import com.sun.hotspot.igv.layout.Link; import com.sun.hotspot.igv.layout.Port; +import com.sun.hotspot.igv.layout.Segment; import com.sun.hotspot.igv.layout.Vertex; import java.awt.Dimension; import java.awt.Point; @@ -45,14 +46,18 @@ public class ClusterNode implements Vertex { private Dimension size; private Point position; private final Set subEdges; + private final List subSegments; private boolean root; private final String name; private final int headerVerticalSpace; private final Dimension emptySize; + public static final int EMPTY_BLOCK_LIVE_RANGE_OFFSET = 20; + public ClusterNode(Cluster cluster, String name, int headerVerticalSpace, Dimension emptySize) { this.subNodes = new HashSet<>(); this.subEdges = new HashSet<>(); + this.subSegments = new ArrayList<>(); this.cluster = cluster; this.position = new Point(0, 0); this.name = name; @@ -83,6 +88,20 @@ public Set getSubEdges() { return Collections.unmodifiableSet(subEdges); } + public void addSubSegment(Segment s) { + subSegments.add(s); + } + + public void groupSegments() { + for (int i = 1; i < subSegments.size(); i++) { + if (subSegments.get(i).parentId() == subSegments.get(i - 1).parentId()) { + subSegments.get(i - 1).setLastOfLiveRange(false); + } else { + subSegments.get(i - 1).setLastOfLiveRange(true); + } + } + } + public void updateSize() { calculateSize(); @@ -106,7 +125,7 @@ public String toString() { private void calculateSize() { - if (subNodes.isEmpty()) { + if (subNodes.isEmpty() && subSegments.isEmpty()) { size = emptySize; return; } @@ -137,6 +156,18 @@ private void calculateSize() { } } + for (Segment segment : subSegments) { + Point s = segment.getStartPoint(); + minX = Math.min(minX, s.x); + maxX = Math.max(maxX, s.x + cluster.getLiveRangeSeparation()); + } + if (!subSegments.isEmpty()) { + maxX += cluster.getLiveRangeSeparation(); + } + if (subNodes.isEmpty()) { + maxX += ClusterNode.EMPTY_BLOCK_LIVE_RANGE_OFFSET; + } + size = new Dimension(maxX - minX, maxY - minY + headerVerticalSpace); // Normalize coordinates @@ -144,6 +175,7 @@ private void calculateSize() { n.setPosition(new Point(n.getPosition().x - minX, n.getPosition().y - minY + headerVerticalSpace)); } + // FIXME: nodeOffset does not exist anymore, do we need to normalize segment coordinates? for (Link l : subEdges) { List points = new ArrayList<>(l.getControlPoints()); @@ -173,11 +205,14 @@ public Point getPosition() { } public void setPosition(Point pos) { + int startX = pos.x + PADDING; + int startY = pos.y + PADDING; + int minY = Integer.MAX_VALUE; this.position = pos; for (Vertex n : subNodes) { Point cur = new Point(n.getPosition()); - cur.translate(pos.x + PADDING, pos.y + PADDING); + cur.translate(startX, startY); n.setPosition(cur); } @@ -187,7 +222,7 @@ public void setPosition(Point pos) { for (Point p : arr) { if (p != null) { Point p2 = new Point(p); - p2.translate(pos.x + PADDING, pos.y + PADDING); + p2.translate(startX, startY); newArr.add(p2); } else { newArr.add(null); @@ -196,6 +231,14 @@ public void setPosition(Point pos) { e.setControlPoints(newArr); } + + if (subNodes.isEmpty()) { + minY = startY + 12; + } + for (Segment s : subSegments) { + s.getStartPoint().translate(startX + cluster.getLiveRangeSeparation(), minY); + s.getEndPoint().translate(startX + cluster.getLiveRangeSeparation(), minY); + } } public Cluster getCluster() { @@ -227,6 +270,10 @@ public Set getSubNodes() { return subNodes; } + public List getSubSegments() { + return subSegments; + } + @Override public boolean equals(Object obj) { if (this == obj) return true; diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java index 74a7b07441494..ea688912687e0 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java @@ -25,8 +25,13 @@ import com.sun.hotspot.igv.layout.Cluster; import com.sun.hotspot.igv.layout.Link; +import com.sun.hotspot.igv.layout.Segment; import com.sun.hotspot.igv.layout.Vertex; -import java.awt.*; +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Point; import java.util.*; public class HierarchicalCFGLayoutManager extends LayoutManager { @@ -37,10 +42,12 @@ public class HierarchicalCFGLayoutManager extends LayoutManager { private final Set clusterLinks; Map clusterNodesMap; Map clusterEdgesMap; + private List segments; public HierarchicalCFGLayoutManager(Set clusterLinks, Set clusters) { this.clusterLinks = clusterLinks; this.clusters = clusters; + this.segments = new ArrayList<>(); // Anticipate block label sizes to dimension blocks appropriately. Canvas canvas = new Canvas(); Font font = new Font("Arial", Font.BOLD, 14); @@ -54,19 +61,66 @@ public void setCutEdges(boolean enable) { manager.setCutEdges(enable); } - private static void doLinearLayout(ClusterNode clusterNode) { + private void doLinearLayout(ClusterNode clusterNode) { Cluster cluster = clusterNode.getCluster(); + clusterNode.groupSegments(); LayoutGraph graph = new LayoutGraph(clusterNode.getSubEdges(), clusterNode.getSubNodes()); + Set clusterSegments = new HashSet<>(); + for (Segment s : segments) { + if (s.getCluster().equals(cluster)) { + clusterSegments.add(s); + } + } + graph.setSegments(clusterNode.getSubSegments()); + int curY = 0; - for (Vertex vertex : cluster.getVertices()) { + List vertices = new ArrayList<>(cluster.getVertices()); + for (Vertex vertex : vertices) { if (graph.containsVertex(vertex)) { vertex.setPosition(new Point(0, curY)); curY += vertex.getSize().height; } } + + // If live segments are available, compute their position. + if (vertices.isEmpty()) { + int x = ClusterNode.EMPTY_BLOCK_LIVE_RANGE_OFFSET; + for (Segment s : graph.getSegments()) { + s.setStartPoint(new Point(x, 0)); + s.setEndPoint(new Point(x, 0)); + if (s.isLastOfLiveRange()) { + x += s.getCluster().getLiveRangeSeparation(); + } + } + } else { + Vertex first = vertices.get(0); + int x = (int)first.getSize().getWidth(); + int entryY = (int)first.getPosition().getY(); + Vertex last = vertices.get(vertices.size() - 1); + int exitY = (int)last.getPosition().getY() + (int)last.getSize().getHeight(); + for (Segment s : graph.getSegments()) { + Vertex start = s.getStart(); + Vertex end = s.getEnd(); + int startY = s.getStart() == null ? entryY : (start.getPosition().y + (int)(start.getSize().getHeight() / 2)); + s.setStartPoint(new Point(x, startY)); + int endY = end == null ? exitY : (end.getPosition().y + (int)(end.getSize().getHeight() / 2)); + if (s.isInstantaneous()) { + endY = startY; + } + s.setEndPoint(new Point(x, endY)); + if (s.isLastOfLiveRange()) { + x += s.getCluster().getLiveRangeSeparation(); + } + } + } + clusterNode.updateSize(); } + public void setSegments(List segments) { + this.segments = segments; + } + public void doLayout(LayoutGraph graph) { // Create cluster-level nodes and edges. clusterNodesMap = createClusterNodes(graph.getVertices()); @@ -74,6 +128,13 @@ public void doLayout(LayoutGraph graph) { clusterEdgesMap = createClusterEdges(clusterNodesMap); assert clusterEdgesMap.size() == clusterLinks.size(); + // Compute sub-segments in every cluster. + for (Segment s : segments) { + Cluster c = s.getCluster(); + assert c != null : "Cluster of segment " + s + " is null!"; + clusterNodesMap.get(c).addSubSegment(s); + } + // Compute layout for each cluster. for (ClusterNode clusterNode : clusterNodesMap.values()) { doLinearLayout(clusterNode); From 4aca9b5e74cdb261854cd40a801d1b33a926c060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 27 Jan 2025 14:34:26 +0100 Subject: [PATCH 07/48] Compute live range segments to be laid out --- .../sun/hotspot/igv/view/DiagramScene.java | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 6e94b023b6e08..b47b006970d0d 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -850,6 +850,7 @@ private void relayout() { Set
visibleFigures = getVisibleFigures(); Set visibleConnections = getVisibleConnections(); + List visibleLiveRangeSegments = getVisibleLiveRangeSegments(); if (getModel().getShowFreeInteractive()) { doFreeInteractiveLayout(visibleFigures, visibleConnections); } else if (getModel().getShowStableSea()) { @@ -859,7 +860,7 @@ private void relayout() { } else if (getModel().getShowBlocks()) { doClusteredLayout(visibleFigures, visibleConnections); } else if (getModel().getShowCFG()) { - doCFGLayout(visibleFigures, visibleConnections); + doCFGLayout(visibleFigures, visibleConnections, visibleLiveRangeSegments); } rebuildConnectionLayer(); @@ -922,6 +923,33 @@ private boolean isVisibleFigureConnection(FigureConnection figureConnection) { return w1.isVisible() && w2.isVisible(); } + private boolean isVisibleBlock(Block b) { + BlockWidget bw = getWidget(b); + return bw != null && getWidget(b, BlockWidget.class).isVisible(); + } + + private boolean isVisibleLiveRange(int liveRangeId) { + if (!getModel().getShowLiveRanges()) { + return false; + } + Set relatedNodes = getModel().getGraph().getRelatedNodes(liveRangeId); + for (InputNode n : relatedNodes) { + Figure f = getModel().getDiagram().getFigure(n); + FigureWidget fw = getWidget(f); + if (isVisibleBlock(f.getBlock()) && + (fw == null || !fw.isVisible())) { + return false; + } + } + return true; + } + + private boolean isVisibleLiveRangeSegment(LiveRangeSegment s) { + return isVisibleLiveRange(s.getLiveRange().getId()) && + isVisibleBlock(s.getCluster()); + } + + private void doFreeInteractiveLayout(Set
visibleFigures, Set visibleConnections) { layoutMover = freeInteractiveLayoutManager; freeInteractiveLayoutManager.setCutEdges(model.getCutEdges()); @@ -954,10 +982,11 @@ private void doClusteredLayout(Set
visibleFigures, Set visib clusterLayoutManager.doLayout(new LayoutGraph(visibleConnections, visibleFigures)); } - private void doCFGLayout(Set
visibleFigures, Set visibleConnections) { + private void doCFGLayout(Set
visibleFigures, Set visibleConnections, List segments) { layoutMover = null; HierarchicalCFGLayoutManager cfgLayoutManager = new HierarchicalCFGLayoutManager(getVisibleBlockConnections(), getVisibleBlocks()); cfgLayoutManager.setCutEdges(model.getCutEdges()); + cfgLayoutManager.setSegments(new ArrayList<>(segments)); cfgLayoutManager.doLayout(new LayoutGraph(visibleConnections, visibleFigures)); } @@ -1509,6 +1538,16 @@ private HashSet getVisibleConnections() { return visibleConnections; } + private List getVisibleLiveRangeSegments() { + List visibleLiveRangeSegments = new ArrayList<>(); + for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { + if (isVisibleLiveRangeSegment(segment)) { + visibleLiveRangeSegments.add(segment); + } + } + return visibleLiveRangeSegments; + } + private void updateFigureWidgetLocations(Set oldVisibleFigureWidgets) { boolean doAnimation = shouldAnimate(); for (Figure figure : getModel().getDiagram().getFigures()) { From f43dbf6db7221c4571888c0fa68d852edd8e84e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 27 Jan 2025 15:24:58 +0100 Subject: [PATCH 08/48] Show live range ids on top of basic blocks --- .../sun/hotspot/igv/view/DiagramScene.java | 30 +++++++++++++++++++ .../hotspot/igv/view/widgets/BlockWidget.java | 26 ++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index b47b006970d0d..a7c354defc743 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -863,6 +863,9 @@ private void relayout() { doCFGLayout(visibleFigures, visibleConnections, visibleLiveRangeSegments); } rebuildConnectionLayer(); + if (getModel().getShowCFG()) { + updateLiveRangeIdsInBlockWidgets(); + } updateFigureWidgetLocations(oldVisibleFigureWidgets); updateBlockWidgetBounds(oldVisibleBlockWidgets); @@ -1492,6 +1495,18 @@ private void updateVisibleBlockWidgets() { !(getModel().getShowCFG() && (block.getInputBlock().isArtificial() || block.getInputBlock().getNodes().isEmpty())); BlockWidget blockWidget = getWidget(block); blockWidget.setVisible(visibleAfter); + + // Update node width for live range layout. + int nodeWidth = ClusterNode.EMPTY_BLOCK_LIVE_RANGE_OFFSET; + for (InputNode n : block.getInputBlock().getNodes()) { + Figure f = getModel().getDiagram().getFigure(n); + FigureWidget figureWidget = getWidget(f); + if (figureWidget != null && figureWidget.isVisible()) { + nodeWidth = f.getWidth(); + break; + } + } + blockWidget.setNodeWidth(nodeWidth); } } } @@ -1580,6 +1595,21 @@ private void updateBlockWidgetBounds(Set oldVisibleBlockWidgets) { } } + private void updateLiveRangeIdsInBlockWidgets() { + for (Block block : getModel().getDiagram().getBlocks()) { + BlockWidget blockWidget = getWidget(block); + if (blockWidget != null && blockWidget.isVisible()) { + List liveRangeIds = new ArrayList<>(); + for (Integer liveRangeId : block.getLiveRangeIds()) { + if (isVisibleLiveRange(liveRangeId)) { + liveRangeIds.add(liveRangeId); + } + } + blockWidget.setLiveRangeIds(liveRangeIds); + } + } + } + public JPopupMenu createPopupMenu() { JPopupMenu menu = new JPopupMenu(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java index ebfc7deded65f..3eba13a406b36 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java @@ -31,6 +31,7 @@ import java.awt.*; import java.awt.event.MouseEvent; import java.awt.geom.Rectangle2D; +import java.util.List; import org.netbeans.api.visual.action.WidgetAction; import org.netbeans.api.visual.widget.Scene; import org.netbeans.api.visual.widget.Widget; @@ -46,6 +47,10 @@ public class BlockWidget extends Widget implements DoubleClickHandler { private static final Font TITLE_FONT = new Font("Arial", Font.BOLD, 14); public static final Color TITLE_COLOR = new Color(42, 42, 171); private final Block block; + private static final Font LIVE_RANGE_FONT = new Font("Arial", Font.BOLD, 12); + public static final Color LIVE_RANGE_COLOR = Color.BLACK; + private int nodeWidth; + private List liveRangeIds; public BlockWidget(Scene scene, Block block) { super(scene); @@ -55,6 +60,14 @@ public BlockWidget(Scene scene, Block block) { this.setCheckClipping(true); } + public void setLiveRangeIds(List liveRangeIds) { + this.liveRangeIds = liveRangeIds; + } + + public void setNodeWidth(int nodeWidth) { + this.nodeWidth = nodeWidth; + } + @Override protected void paintWidget() { super.paintWidget(); @@ -75,6 +88,19 @@ protected void paintWidget() { String s = "B" + getBlockNode().getName(); Rectangle2D r1 = g.getFontMetrics().getStringBounds(s, g); g.drawString(s, r.x + 5, r.y + (int) r1.getHeight()); + + g.setColor(LIVE_RANGE_COLOR); + g.setFont(LIVE_RANGE_FONT); + if (liveRangeIds != null) { + int x = nodeWidth + block.getLiveRangeSeparation(); + for (int liveRangeId : liveRangeIds) { + String ls = "L" + String.valueOf(liveRangeId); + Rectangle2D lr = g.getFontMetrics().getStringBounds(ls, g); + g.drawString(ls, r.x + x, r.y + (int) lr.getHeight() + 2); + x += block.getLiveRangeSeparation(); + } + } + g.setStroke(old); } From 3d25cd47b2a7972e11a960f3be7e32b1a946cf26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 27 Jan 2025 15:41:00 +0100 Subject: [PATCH 09/48] Add live range widgets and logic for selecting and centering them --- .../sun/hotspot/igv/view/DiagramScene.java | 52 ++++++ .../hotspot/igv/view/DiagramViewModel.java | 22 +++ .../sun/hotspot/igv/view/DiagramViewer.java | 5 + .../hotspot/igv/view/EditorTopComponent.java | 9 ++ .../igv/view/widgets/LiveRangeWidget.java | 151 ++++++++++++++++++ 5 files changed, 239 insertions(+) create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index a7c354defc743..1c9994fd44263 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -224,6 +224,7 @@ public void filteredChanged(SelectionCoordinator coordinator) { } setFigureSelection(selectedFigures); centerSelectedFigures(); + centerSelectedLiveRanges(); validateAll(); } } @@ -830,6 +831,7 @@ private void update() { rebuildMainLayer(); rebuildBlockLayer(); relayout(); + setLiveRangeSegmentSelection(model.getSelectedLiveRangeSegments()); rebuilding = false; } @@ -872,6 +874,7 @@ private void relayout() { validateAll(); setFigureSelection(model.getSelectedFigures()); centerSelectedFigures(); + centerSelectedLiveRanges(); rebuilding = false; } @@ -1284,6 +1287,26 @@ public void addSelectedNodes(Collection nodes, boolean showIfHidden) } } + @Override + public void addSelectedLiveRanges(Collection liveRanges, boolean showIfHidden) { + // TBD: ensure all related nodes are visible. + Set liveRangeIds = new HashSet<>(); + for (InputLiveRange liveRange : liveRanges) { + liveRangeIds.add(liveRange.getId()); + } + Map representativeSegments = new HashMap<>(); + for (LiveRangeSegment segment : model.getDiagram().getLiveRangeSegments()) { + if (liveRangeIds.contains(segment.getLiveRange().getId())) { + representativeSegments.put(segment.getLiveRange().getId(), segment); + } + } + setLiveRangeSegmentSelection(new HashSet<>(representativeSegments.values())); + // TBD: + // if (showIfHidden) { + // model.showLiveRangeSegments(model.getSelectedLiveRangeSegments()); + // } + } + @Override public void clearSelectedElements() { setSelectedObjects(Collections.emptySet()); @@ -1313,6 +1336,31 @@ public void centerSelectedFigures() { } } + @Override + public void centerSelectedLiveRanges() { + // TODO: double check that this works as intended + Set selectedLiveRanges = model.getSelectedLiveRangeSegments(); + Rectangle overallRect = null; + for (LiveRangeSegment segment : selectedLiveRanges) { + LiveRangeWidget liveRangeWidget = getWidget(segment); + if (liveRangeWidget != null) { + Rectangle bounds = liveRangeWidget.getBounds(); + if (bounds != null) { + Point location = liveRangeWidget.getLocation(); + Rectangle rect = new Rectangle(location.x, location.y, bounds.width, bounds.height); + if (overallRect == null) { + overallRect = rect; + } else { + overallRect = overallRect.union(rect); + } + } + } + } + if (overallRect != null) { + centerRectangle(overallRect); + } + } + private void centerRectangle(Rectangle r) { Rectangle rect = convertSceneToView(r); Rectangle viewRect = scrollPane.getViewport().getViewRect(); @@ -1343,6 +1391,10 @@ private void setFigureSelection(Set
list) { super.setSelectedObjects(new HashSet<>(list)); } + private void setLiveRangeSegmentSelection(Set list) { + super.setSelectedObjects(new HashSet<>(list)); + } + @Override public void resetUndoRedoManager() { undoRedoManager = new UndoRedo.Manager(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index ff3d62a0bc367..6895d2ac0203d 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -34,6 +34,7 @@ import com.sun.hotspot.igv.filter.FilterChainProvider; import com.sun.hotspot.igv.graph.Diagram; import com.sun.hotspot.igv.graph.Figure; +import com.sun.hotspot.igv.graph.LiveRangeSegment; import com.sun.hotspot.igv.graph.MatcherSelector; import com.sun.hotspot.igv.settings.Settings; import com.sun.hotspot.igv.util.RangeSliderModel; @@ -54,6 +55,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene private ArrayList graphs; private Set hiddenNodes; private Set selectedNodes; + private Set selectedLiveRanges; private FilterChain filterChain; private final FilterChain customFilterChain; private final FilterChain filtersOrder; @@ -233,6 +235,7 @@ public DiagramViewModel(DiagramViewModel model) { hiddenNodes = new HashSet<>(model.getHiddenNodes()); selectedNodes = new HashSet<>(); + selectedLiveRanges = new HashSet<>(); changed(this); } @@ -259,6 +262,7 @@ public DiagramViewModel(InputGraph graph) { hiddenNodes = new HashSet<>(); selectedNodes = new HashSet<>(); + selectedLiveRanges = new HashSet<>(); selectGraph(graph); } @@ -327,6 +331,14 @@ public void setSelectedNodes(Set nodes) { selectedNodesChangedEvent.fire(); } + public Set getSelectedLiveRanges() { + return selectedLiveRanges; + } + + public void setSelectedLiveRanges(Set liveRanges) { + selectedLiveRanges = liveRanges; + } + public void showFigures(Collection
figures) { boolean somethingChanged = false; for (Figure f : figures) { @@ -349,6 +361,16 @@ public Set
getSelectedFigures() { return result; } + public Set getSelectedLiveRangeSegments() { + Set result = new HashSet<>(); + for (LiveRangeSegment segment : diagram.getLiveRangeSegments()) { + if (getSelectedLiveRanges().contains(segment.getLiveRange().getId())) { + result.add(segment); + } + } + return result; + } + public void showOnly(final Set nodes) { final HashSet allNodes = new HashSet<>(getGroup().getAllNodes()); allNodes.removeAll(nodes); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java index 4a24e3e13d015..49967cc6164c2 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java @@ -25,6 +25,7 @@ package com.sun.hotspot.igv.view; import com.sun.hotspot.igv.data.ChangedEvent; +import com.sun.hotspot.igv.data.InputLiveRange; import com.sun.hotspot.igv.data.InputNode; import java.awt.*; import java.util.Collection; @@ -77,8 +78,12 @@ enum InteractionMode { void centerSelectedFigures(); + void centerSelectedLiveRanges(); + void addSelectedNodes(Collection nodes, boolean showIfHidden); + void addSelectedLiveRanges(Collection liveRanges, boolean showIfHidden); + void clearSelectedElements(); void setInteractionMode(InteractionMode mode); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java index ecd0edbf2c38d..c06115cf09cb5 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java @@ -26,6 +26,7 @@ import com.sun.hotspot.igv.data.GraphDocument; import com.sun.hotspot.igv.data.Group; import com.sun.hotspot.igv.data.InputGraph; +import com.sun.hotspot.igv.data.InputLiveRange; import com.sun.hotspot.igv.data.InputNode; import com.sun.hotspot.igv.data.services.InputGraphProvider; import com.sun.hotspot.igv.graph.Figure; @@ -354,10 +355,18 @@ public void colorSelectedFigures(Color color) { scene.colorSelectedFigures(color); } + public void addSelectedLiveRanges(Collection liveRanges, boolean showIfHidden) { + scene.addSelectedLiveRanges(liveRanges, showIfHidden); + } + public void centerSelectedNodes() { scene.centerSelectedFigures(); } + public void centerSelectedLiveRanges() { + scene.centerSelectedLiveRanges(); + } + public void clearSelectedElements() { scene.clearSelectedElements(); } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java new file mode 100644 index 0000000000000..0ce1fc324e956 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.view.widgets; + +import com.sun.hotspot.igv.data.Properties; +import com.sun.hotspot.igv.graph.LiveRangeSegment; +import com.sun.hotspot.igv.util.PropertiesConverter; +import com.sun.hotspot.igv.util.PropertiesSheet; +import com.sun.hotspot.igv.view.DiagramScene; +import java.awt.*; +import org.netbeans.api.visual.model.ObjectState; +import org.netbeans.api.visual.widget.Widget; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; +import org.openide.nodes.Node; +import org.openide.nodes.Sheet; + +public class LiveRangeWidget extends Widget implements Properties.Provider { + + private final LiveRangeSegment liveRangeSegment; + private final DiagramScene scene; + private int length; + private LiveRangeWidget next; + private Rectangle clientArea; + private final Node node; + private static final float NORMAL_THICKNESS = 1.4f; + private static final float SELECTED_THICKNESS = 2.2f; + private boolean highlighted; + private boolean selected; + private static final Color NORMAL_COLOR = Color.BLACK; + private static final Color HIGHLIGHTED_COLOR = Color.BLUE; + + private static final int RANGE_WIDTH = 4; + + public LiveRangeWidget(LiveRangeSegment liveRangeSegment, DiagramScene scene, int length, LiveRangeWidget next) { + super(scene); + this.liveRangeSegment = liveRangeSegment; + this.scene = scene; + this.length = length; + this.next = next; + + updateClientArea(); + + // Initialize node for property sheet + node = new AbstractNode(Children.LEAF) { + @Override + protected Sheet createSheet() { + Sheet s = super.createSheet(); + PropertiesSheet.initializeSheet(liveRangeSegment.getProperties(), s); + return s; + } + }; + node.setDisplayName("L" + liveRangeSegment.getLiveRange().getId()); + + this.setToolTipText(PropertiesConverter.convertToHTML(liveRangeSegment.getProperties())); + } + + public void setLength(int length) { + this.length = length; + updateClientArea(); + } + + private void updateClientArea() { + clientArea = new Rectangle(RANGE_WIDTH * 2, length); + clientArea.grow(RANGE_WIDTH * 2, RANGE_WIDTH * 2); + } + + public void setNext(LiveRangeWidget next) { + this.next = next; + } + + @Override + protected Rectangle calculateClientArea() { + return clientArea; + } + + @Override + protected void paintWidget() { + if (scene.getZoomFactor() < 0.1) { + return; + } + Graphics2D g = getScene().getGraphics(); + g.setPaint(this.getBackground()); + g.setStroke(new BasicStroke(selected ? SELECTED_THICKNESS : NORMAL_THICKNESS)); + g.setColor(highlighted ? HIGHLIGHTED_COLOR : NORMAL_COLOR); + g.drawLine(- RANGE_WIDTH, 0, RANGE_WIDTH, 0); + if (length != 0) { + g.drawLine(0, 0, 0, length); + g.drawLine(- RANGE_WIDTH, length, RANGE_WIDTH, length); + } + } + + @Override + protected void notifyStateChanged(ObjectState previousState, ObjectState state) { + super.notifyStateChanged(previousState, state); + if (previousState.isSelected() != state.isSelected()) { + setSelected(state.isSelected()); + } + if (previousState.isHighlighted() != state.isHighlighted()) { + setHighlighted(state.isHighlighted()); + } + } + + private void setSelected(boolean enable) { + if (enable == selected) { + return; // end recursion + } + selected = enable; + revalidate(true); + if (next != null) { + next.setSelected(enable); + } + } + + private void setHighlighted(boolean enable) { + if (enable == highlighted) { + return; // end recursion + } + highlighted = enable; + revalidate(true); + if (next != null) { + next.setHighlighted(enable); + } + } + + @Override + public Properties getProperties() { + return liveRangeSegment.getProperties(); + } +} From 990c54c7c4b04d56a9daee8437a43380149adb61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Tue, 28 Jan 2025 12:11:59 +0100 Subject: [PATCH 10/48] Actually draw the live ranges --- .../igv/hierarchicallayout/ClusterNode.java | 1 + .../HierarchicalCFGLayoutManager.java | 23 ++-- .../igv/hierarchicallayout/LayoutGraph.java | 12 -- .../sun/hotspot/igv/view/DiagramScene.java | 121 +++++++++++++++++- 4 files changed, 128 insertions(+), 29 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java index 5928147613ed4..98b82c20bc344 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java @@ -214,6 +214,7 @@ public void setPosition(Point pos) { Point cur = new Point(n.getPosition()); cur.translate(startX, startY); n.setPosition(cur); + minY = Math.min(minY, cur.y); } for (Link e : subEdges) { diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java index ea688912687e0..2e4fc6d14e762 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java @@ -65,27 +65,24 @@ private void doLinearLayout(ClusterNode clusterNode) { Cluster cluster = clusterNode.getCluster(); clusterNode.groupSegments(); LayoutGraph graph = new LayoutGraph(clusterNode.getSubEdges(), clusterNode.getSubNodes()); - Set clusterSegments = new HashSet<>(); - for (Segment s : segments) { - if (s.getCluster().equals(cluster)) { - clusterSegments.add(s); + + // Compute list of vertices that are actually laid out. + List vertices = new ArrayList<>(cluster.getVertices().size()); + for (Vertex vertex : cluster.getVertices()) { + if (graph.containsVertex(vertex)) { // The vertex is visible. + vertices.add(vertex); } } - graph.setSegments(clusterNode.getSubSegments()); - int curY = 0; - List vertices = new ArrayList<>(cluster.getVertices()); for (Vertex vertex : vertices) { - if (graph.containsVertex(vertex)) { - vertex.setPosition(new Point(0, curY)); - curY += vertex.getSize().height; - } + vertex.setPosition(new Point(0, curY)); + curY += vertex.getSize().height; } // If live segments are available, compute their position. if (vertices.isEmpty()) { int x = ClusterNode.EMPTY_BLOCK_LIVE_RANGE_OFFSET; - for (Segment s : graph.getSegments()) { + for (Segment s : clusterNode.getSubSegments()) { s.setStartPoint(new Point(x, 0)); s.setEndPoint(new Point(x, 0)); if (s.isLastOfLiveRange()) { @@ -98,7 +95,7 @@ private void doLinearLayout(ClusterNode clusterNode) { int entryY = (int)first.getPosition().getY(); Vertex last = vertices.get(vertices.size() - 1); int exitY = (int)last.getPosition().getY() + (int)last.getSize().getHeight(); - for (Segment s : graph.getSegments()) { + for (Segment s : clusterNode.getSubSegments()) { Vertex start = s.getStart(); Vertex end = s.getEnd(); int startY = s.getStart() == null ? entryY : (start.getPosition().y + (int)(start.getSize().getHeight() / 2)); diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java index 07cfd69e56dd0..e224088c49055 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java @@ -27,7 +27,6 @@ import com.sun.hotspot.igv.layout.Link; import com.sun.hotspot.igv.layout.Port; import com.sun.hotspot.igv.layout.Vertex; -import com.sun.hotspot.igv.layout.Segment; import java.util.*; import java.util.stream.Collectors; @@ -51,13 +50,11 @@ public class LayoutGraph { .thenComparingInt(l -> l.getTo().getRelativePosition().x); // Registered Graph Components: Links, Vertices, and Port Mappings. - // Optionally, live range segments for the CFG view. private final Set links; private final SortedSet vertices; private final LinkedHashMap> inputPorts; private final LinkedHashMap> outputPorts; private final LinkedHashMap> portLinks; - private List segments; // Layout Management: LayoutNodes and LayoutLayers private final LinkedHashMap layoutNodes; @@ -78,7 +75,6 @@ public LayoutGraph(Collection links, Collection(links.size()); inputPorts = new LinkedHashMap<>(links.size()); outputPorts = new LinkedHashMap<>(links.size()); - segments = new ArrayList<>(); for (Link link : links) { assert link.getFrom() != null; @@ -451,14 +447,6 @@ public List getOutputLinks(Vertex vertex) { return outputLinks; } - public List getSegments() { - return segments; - } - - public void setSegments(List s) { - segments = new ArrayList<>(s); - } - /** * Checks if the given predecessorVertex is a direct predecessor of the specified vertex. * diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 1c9994fd44263..ec6ac3746092f 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -81,6 +81,7 @@ public class DiagramScene extends ObjectScene implements DiagramViewer, DoubleCl private final LayerWidget mainLayer; private final LayerWidget blockLayer; private final LayerWidget connectionLayer; + private final LayerWidget segmentLayer; private final Widget shadowWidget; private final Widget pointerWidget; private final DiagramViewModel model; @@ -343,6 +344,10 @@ public void select(Widget widget, Point localLocation, boolean invertSelection) connectionLayer.setBorder(emptyBorder); addChild(connectionLayer); + segmentLayer = new LayerWidget(this); + segmentLayer.setBorder(emptyBorder); + addChild(segmentLayer); + mainLayer = new LayerWidget(this); mainLayer.setBorder(emptyBorder); addChild(mainLayer); @@ -433,6 +438,7 @@ public void selectionChanged(ObjectSceneEvent e, Set oldSet, Set content.set(newSet, null); Set nodeSelection = new HashSet<>(); + Set liveRangeSelection = new HashSet<>(); for (Object o : newSet) { if (o instanceof Properties.Provider) { final Properties.Provider provider = (Properties.Provider) o; @@ -445,7 +451,14 @@ protected Sheet createSheet() { return s; } }; - node.setDisplayName(provider.getProperties().get("name")); + String displayName = null; + if (o instanceof Figure || o instanceof Slot) { + displayName = provider.getProperties().get("idx") + " " + + provider.getProperties().get("name"); + } else if (o instanceof LiveRangeSegment) { + displayName = "L" + ((LiveRangeSegment) o).getLiveRange().getId(); + } + node.setDisplayName(displayName); content.add(node); } @@ -454,10 +467,14 @@ protected Sheet createSheet() { nodeSelection.add(((Figure) o).getInputNode().getId()); } else if (o instanceof Slot) { nodeSelection.addAll(((Slot) o).getSource().getSourceNodesAsSet()); + } else if (o instanceof LiveRangeSegment) { + liveRangeSelection.add(((LiveRangeSegment) o).getLiveRange().getId()); } } getModel().setSelectedNodes(nodeSelection); + getModel().setSelectedLiveRanges(liveRangeSelection); + // TODO: extend with live ranges? boolean b = selectedCoordinatorListener.isEnabled(); selectedCoordinatorListener.setEnabled(false); SelectionCoordinator.getInstance().setSelectedObjects(nodeSelection); @@ -830,6 +847,7 @@ private void update() { updateFigureWidths(); rebuildMainLayer(); rebuildBlockLayer(); + rebuildSegmentLayer(); relayout(); setLiveRangeSegmentSelection(model.getSelectedLiveRangeSegments()); rebuilding = false; @@ -843,11 +861,13 @@ private void hiddenNodesChanged() { private void relayout() { rebuilding = true; Set oldVisibleFigureWidgets = getVisibleFigureWidgets(); + Set oldVisibleLiveRangeWidgets = getVisibleLiveRangeWidgets(); Set oldVisibleBlockWidgets = getVisibleBlockWidgets(); updateVisibleFigureWidgets(); updateNodeHull(); updateVisibleBlockWidgets(); + updateVisibleLiveRangeWidgets(); validateAll(); Set
visibleFigures = getVisibleFigures(); @@ -867,9 +887,11 @@ private void relayout() { rebuildConnectionLayer(); if (getModel().getShowCFG()) { updateLiveRangeIdsInBlockWidgets(); + repaintLiveRangeWidgets(); } updateFigureWidgetLocations(oldVisibleFigureWidgets); + updateLiveRangeWidgetLocations(oldVisibleLiveRangeWidgets); updateBlockWidgetBounds(oldVisibleBlockWidgets); validateAll(); setFigureSelection(model.getSelectedFigures()); @@ -1289,7 +1311,7 @@ public void addSelectedNodes(Collection nodes, boolean showIfHidden) @Override public void addSelectedLiveRanges(Collection liveRanges, boolean showIfHidden) { - // TBD: ensure all related nodes are visible. + // TODO: ensure all related nodes are visible. Set liveRangeIds = new HashSet<>(); for (InputLiveRange liveRange : liveRanges) { liveRangeIds.add(liveRange.getId()); @@ -1301,7 +1323,7 @@ public void addSelectedLiveRanges(Collection liveRanges, boolean } } setLiveRangeSegmentSelection(new HashSet<>(representativeSegments.values())); - // TBD: + // TODO: // if (showIfHidden) { // model.showLiveRangeSegments(model.getSelectedLiveRangeSegments()); // } @@ -1455,7 +1477,39 @@ private void rebuildConnectionLayer() { newWidgets.clear(); } - private Set getVisibleFigureWidgets() { + private void rebuildSegmentLayer() { + segmentLayer.removeChildren(); + Map> segments = new HashMap<>(); + for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { + int liveRangeId = segment.getLiveRange().getId(); + if (!segments.containsKey(liveRangeId)) { + segments.put(liveRangeId, new HashSet<>()); + } + segments.get(liveRangeId).add(segment); + } + for (Set segmentSet : segments.values()) { + LiveRangeWidget firstSegmentWidget = null; + LiveRangeWidget nextSegmentWidget = null; + for (LiveRangeSegment segment : segmentSet) { + // Segments are not yet laid out. + assert segment.getStartPoint() == null && segment.getEndPoint() == null; + LiveRangeWidget segmentWidget = + new LiveRangeWidget(segment, this, 0, nextSegmentWidget); + segmentWidget.setVisible(false); + if (firstSegmentWidget == null) { + firstSegmentWidget = segmentWidget; + } + addObject(segment, segmentWidget); + segmentWidget.getActions().addAction(selectAction); + segmentWidget.getActions().addAction(hoverAction); + segmentLayer.addChild(segmentWidget); + nextSegmentWidget = segmentWidget; + } + firstSegmentWidget.setNext(nextSegmentWidget); + } + } + + private Set getVisibleFigureWidgets() { Set visibleFigureWidgets = new HashSet<>(); for (Figure figure : getModel().getDiagram().getFigures()) { FigureWidget figureWidget = getWidget(figure); @@ -1466,6 +1520,17 @@ private Set getVisibleFigureWidgets() { return visibleFigureWidgets; } + private Set getVisibleLiveRangeWidgets() { + Set visibleLiveRangeWidgets = new HashSet<>(); + for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { + LiveRangeWidget liveRangeWidget = getWidget(segment); + if (liveRangeWidget != null && liveRangeWidget.isVisible()) { + visibleLiveRangeWidgets.add(liveRangeWidget); + } + } + return visibleLiveRangeWidgets; + } + private Set getVisibleBlockWidgets() { Set visibleBlockWidgets = new HashSet<>(); if (getModel().getShowBlocks() || getModel().getShowCFG()) { @@ -1487,6 +1552,23 @@ private void updateVisibleFigureWidgets() { } } + private void updateVisibleLiveRangeWidgets() { + // TODO: pre-compute visibility for each live range, to avoid + // re-computing it for each segment in each live range. + for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { + LiveRangeWidget liveRangeWidget = getWidget(segment); + boolean visible = true; + for (InputNode n : getModel().getDiagram().getInputGraph().getRelatedNodes(segment.getLiveRange().getId())) { + FigureWidget f = getWidget(getModel().getDiagram().getFigure(n)); + if (!f.isVisible()) { + visible = false; + break; + } + } + liveRangeWidget.setVisible(visible); + } + } + private void updateNodeHull() { if (getModel().getShowNodeHull()) { List boundaries = new ArrayList<>(); @@ -1517,6 +1599,21 @@ private void updateNodeHull() { } } + private void updateLiveRangeWidgetLocations(Set oldVisibleLiveRangeWidgets) { + boolean doAnimation = shouldAnimate(); + for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { + LiveRangeWidget liveRangeWidget = getWidget(segment); + if (liveRangeWidget.isVisible()) { + Point location = new Point(segment.getStartPoint()); + if (doAnimation && oldVisibleLiveRangeWidgets.contains(liveRangeWidget)) { + getSceneAnimator().animatePreferredLocation(liveRangeWidget, location); + } else { + liveRangeWidget.setPreferredLocation(location); + } + } + } + } + private void updateVisibleBlockWidgets() { if (getModel().getShowBlocks() || getModel().getShowCFG()) { Set visibleBlocks = new HashSet<>(); @@ -1551,6 +1648,10 @@ private void updateVisibleBlockWidgets() { // Update node width for live range layout. int nodeWidth = ClusterNode.EMPTY_BLOCK_LIVE_RANGE_OFFSET; for (InputNode n : block.getInputBlock().getNodes()) { + if (!getModel().getDiagram().hasFigure(n)) { + // n might not be visible (e.g. filtered out). + continue; + } Figure f = getModel().getDiagram().getFigure(n); FigureWidget figureWidget = getWidget(f); if (figureWidget != null && figureWidget.isVisible()) { @@ -1662,6 +1763,18 @@ private void updateLiveRangeIdsInBlockWidgets() { } } + private void repaintLiveRangeWidgets() { + for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { + LiveRangeWidget liveRangeWidget = getWidget(segment); + if (liveRangeWidget.isVisible()) { + assert segment.getStartPoint().x == segment.getEndPoint().x; + int length = segment.getEndPoint().y - segment.getStartPoint().y; + liveRangeWidget.setLength(length); + liveRangeWidget.repaint(); + } + } + } + public JPopupMenu createPopupMenu() { JPopupMenu menu = new JPopupMenu(); From b4fada7d70f90a52ed77240fcef32e22006b8177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Tue, 28 Jan 2025 13:52:24 +0100 Subject: [PATCH 11/48] Add quick live range search --- .../igv/view/LiveRangeQuickSearch.java | 152 ++++++++++++++++++ .../com/sun/hotspot/igv/view/layer.xml | 5 + 2 files changed, 157 insertions(+) create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/LiveRangeQuickSearch.java diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/LiveRangeQuickSearch.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/LiveRangeQuickSearch.java new file mode 100644 index 0000000000000..2c2482677a72a --- /dev/null +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/LiveRangeQuickSearch.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.view; + +import com.sun.hotspot.igv.data.InputGraph; +import com.sun.hotspot.igv.data.InputLiveRange; +import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher; +import com.sun.hotspot.igv.data.services.InputGraphProvider; +import com.sun.hotspot.igv.util.LookupHistory; +import com.sun.hotspot.igv.util.StringUtils; +import java.util.ArrayList; +import java.util.List; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Pattern; +import org.netbeans.spi.quicksearch.SearchProvider; +import org.netbeans.spi.quicksearch.SearchRequest; +import org.netbeans.spi.quicksearch.SearchResponse; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.NotifyDescriptor.Message; + +public class LiveRangeQuickSearch implements SearchProvider { + + @Override + public void evaluate(SearchRequest request, SearchResponse response) { + String rawValue = request.getText(); + if (rawValue.trim().isEmpty()) { + return; + } + String value = ".*" + Pattern.quote(rawValue) + ".*"; + + final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class); + if (p == null || p.getGraph() == null) { + return; + } + + InputGraph matchGraph = p.getGraph(); + // Search the current graph + List matches = findMatches(value, p.getGraph(), response); + if (matches == null) { + // See if the it hits in a later graph + for (InputGraph graph : p.searchForward()) { + matches = findMatches(value, graph, response); + if (matches != null) { + matchGraph = graph; + break; + } + } + } + if (matches == null) { + // See if it hits in a earlier graph + for (InputGraph graph : p.searchBackward()) { + matches = findMatches(value, graph, response); + if (matches != null) { + matchGraph = graph; + break; + } + } + } + if (matches != null) { + // Rank the matches. + matches.sort((InputLiveRange a, InputLiveRange b) -> + compareByRankThenNumVal(rawValue, + "L" + a.getId(), + "L" + b.getId())); + + final InputGraph theGraph = p.getGraph() != matchGraph ? matchGraph : null; + for (final InputLiveRange liveRange : matches) { + if (!response.addResult(() -> { + final EditorTopComponent editor = EditorTopComponent.getActive(); + assert(editor != null); + if (theGraph != null) { + editor.getModel().selectGraph(theGraph); + } + Set liveRangeSingleton = new HashSet<>(); + liveRangeSingleton.add(liveRange); + editor.clearSelectedElements(); + editor.addSelectedLiveRanges(liveRangeSingleton, true); + editor.centerSelectedLiveRanges(); + editor.requestActive(); + }, + "L" + liveRange.getId() + (theGraph != null ? " in " + theGraph.getName() : ""))) { + return; + } + } + } + } + + private List findMatches(String liveRangeName, InputGraph inputGraph, SearchResponse response) { + try { + RegexpPropertyMatcher matcher = new RegexpPropertyMatcher("", liveRangeName, Pattern.CASE_INSENSITIVE); + List matches = new ArrayList<>(); + for (InputLiveRange liveRange : inputGraph.getLiveRanges()) { + if (matcher.match("L" + liveRange.getId())) { + matches.add(liveRange); + } + } + return matches.size() == 0 ? null : matches; + } catch (Exception e) { + final String msg = e.getMessage(); + response.addResult(() -> { + Message desc = new NotifyDescriptor.Message("An exception occurred during the search, " + + "perhaps due to a malformed query string:\n" + msg, + NotifyDescriptor.WARNING_MESSAGE); + DialogDisplayer.getDefault().notify(desc); + }, + "(Error during search)" + ); + } + return null; + } + + private int compareByRankThenNumVal(String qry, String l1, String l2) { + int key1 = StringUtils.rankMatch(qry, l1); + int key2 = StringUtils.rankMatch(qry, l2); + if (key1 == key2) { + // If the matches have the same rank, compare the numeric values of + // their first words, if applicable. + try { + key1 = Integer.parseInt(l1.replace("L", "")); + key2 = Integer.parseInt(l2.replace("L", "")); + } catch (Exception e) { + // Not applicable, return equality value. + return 0; + } + } + return Integer.compare(key1, key2); + } + +} diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml index 78d056e845151..adeb462a2650e 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml +++ b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/layer.xml @@ -46,6 +46,11 @@ + + + + + From 39aab9cad59f871d76b693db48a8899d42380e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Tue, 28 Jan 2025 14:34:18 +0100 Subject: [PATCH 12/48] Factor out block and live range search functionality --- .../hotspot/igv/view/BlockQuickSearch.java | 128 ++------------- .../igv/view/LiveRangeQuickSearch.java | 134 +++------------ .../hotspot/igv/view/SimpleQuickSearch.java | 155 ++++++++++++++++++ 3 files changed, 191 insertions(+), 226 deletions(-) create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/SimpleQuickSearch.java diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java index 54db33405b5cc..1ef13fa124c26 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java @@ -25,124 +25,30 @@ import com.sun.hotspot.igv.data.InputBlock; import com.sun.hotspot.igv.data.InputGraph; -import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher; -import com.sun.hotspot.igv.data.services.InputGraphProvider; -import com.sun.hotspot.igv.util.LookupHistory; -import com.sun.hotspot.igv.util.StringUtils; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Pattern; -import org.netbeans.spi.quicksearch.SearchProvider; -import org.netbeans.spi.quicksearch.SearchRequest; -import org.netbeans.spi.quicksearch.SearchResponse; -import org.openide.DialogDisplayer; -import org.openide.NotifyDescriptor; -import org.openide.NotifyDescriptor.Message; +import java.util.*; -public class BlockQuickSearch implements SearchProvider { +public class BlockQuickSearch extends SimpleQuickSearch { @Override - public void evaluate(SearchRequest request, SearchResponse response) { - String rawValue = request.getText(); - if (rawValue.trim().isEmpty()) { - return; - } - String value = ".*" + Pattern.quote(rawValue) + ".*"; - - final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class); - if (p == null || p.getGraph() == null) { - return; - } - - InputGraph matchGraph = p.getGraph(); - // Search the current graph - List matches = findMatches(value, p.getGraph(), response); - if (matches == null) { - // See if the it hits in a later graph - for (InputGraph graph : p.searchForward()) { - matches = findMatches(value, graph, response); - if (matches != null) { - matchGraph = graph; - break; - } - } - } - if (matches == null) { - // See if it hits in a earlier graph - for (InputGraph graph : p.searchBackward()) { - matches = findMatches(value, graph, response); - if (matches != null) { - matchGraph = graph; - break; - } - } - } - if (matches != null) { - // Rank the matches. - matches.sort((InputBlock a, InputBlock b) -> - compareByRankThenNumVal(rawValue, - "B" + a.getName(), - "B" + b.getName())); - - final InputGraph theGraph = p.getGraph() != matchGraph ? matchGraph : null; - for (final InputBlock b : matches) { - if (!response.addResult(() -> { - final EditorTopComponent editor = EditorTopComponent.getActive(); - assert(editor != null); - if (theGraph != null) { - editor.getModel().selectGraph(theGraph); - } - editor.clearSelectedElements(); - editor.addSelectedNodes(b.getNodes(), true); - editor.centerSelectedNodes(); - editor.requestActive(); - }, - "B" + b.getName() + (theGraph != null ? " in " + theGraph.getName() : ""))) { - return; - } - } - } + String prefix() { + return "B"; } - private List findMatches(String blockName, InputGraph inputGraph, SearchResponse response) { - try { - RegexpPropertyMatcher matcher = new RegexpPropertyMatcher("", blockName, Pattern.CASE_INSENSITIVE); - List matches = new ArrayList<>(); - for (InputBlock b : inputGraph.getBlocks()) { - if (matcher.match("B" + b.getName())) { - matches.add(b); - } - } - return matches.size() == 0 ? null : matches; - } catch (Exception e) { - final String msg = e.getMessage(); - response.addResult(() -> { - Message desc = new NotifyDescriptor.Message("An exception occurred during the search, " - + "perhaps due to a malformed query string:\n" + msg, - NotifyDescriptor.WARNING_MESSAGE); - DialogDisplayer.getDefault().notify(desc); - }, - "(Error during search)" - ); - } - return null; + @Override + String id(Object entity) { + assert entity instanceof InputBlock; + return ((InputBlock)entity).getName(); } - private int compareByRankThenNumVal(String qry, String b1, String b2) { - int key1 = StringUtils.rankMatch(qry, b1); - int key2 = StringUtils.rankMatch(qry, b2); - if (key1 == key2) { - // If the matches have the same rank, compare the numeric values of - // their first words, if applicable. - try { - key1 = Integer.parseInt(b1.replace("B", "")); - key2 = Integer.parseInt(b2.replace("B", "")); - } catch (Exception e) { - // Not applicable, return equality value. - return 0; - } - } - return Integer.compare(key1, key2); + @Override + Collection getAllEntities(InputGraph inputGraph) { + return new ArrayList<>(inputGraph.getBlocks()); } + @Override + void selectEntity(EditorTopComponent editor, Object entity) { + assert entity instanceof InputBlock; + editor.addSelectedNodes(((InputBlock)entity).getNodes(), true); + editor.centerSelectedNodes(); + } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/LiveRangeQuickSearch.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/LiveRangeQuickSearch.java index 2c2482677a72a..bfa3900a6488d 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/LiveRangeQuickSearch.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/LiveRangeQuickSearch.java @@ -25,128 +25,32 @@ import com.sun.hotspot.igv.data.InputGraph; import com.sun.hotspot.igv.data.InputLiveRange; -import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher; -import com.sun.hotspot.igv.data.services.InputGraphProvider; -import com.sun.hotspot.igv.util.LookupHistory; -import com.sun.hotspot.igv.util.StringUtils; -import java.util.ArrayList; -import java.util.List; -import java.util.HashSet; -import java.util.Set; -import java.util.regex.Pattern; -import org.netbeans.spi.quicksearch.SearchProvider; -import org.netbeans.spi.quicksearch.SearchRequest; -import org.netbeans.spi.quicksearch.SearchResponse; -import org.openide.DialogDisplayer; -import org.openide.NotifyDescriptor; -import org.openide.NotifyDescriptor.Message; +import java.util.*; -public class LiveRangeQuickSearch implements SearchProvider { +public class LiveRangeQuickSearch extends SimpleQuickSearch { @Override - public void evaluate(SearchRequest request, SearchResponse response) { - String rawValue = request.getText(); - if (rawValue.trim().isEmpty()) { - return; - } - String value = ".*" + Pattern.quote(rawValue) + ".*"; - - final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class); - if (p == null || p.getGraph() == null) { - return; - } - - InputGraph matchGraph = p.getGraph(); - // Search the current graph - List matches = findMatches(value, p.getGraph(), response); - if (matches == null) { - // See if the it hits in a later graph - for (InputGraph graph : p.searchForward()) { - matches = findMatches(value, graph, response); - if (matches != null) { - matchGraph = graph; - break; - } - } - } - if (matches == null) { - // See if it hits in a earlier graph - for (InputGraph graph : p.searchBackward()) { - matches = findMatches(value, graph, response); - if (matches != null) { - matchGraph = graph; - break; - } - } - } - if (matches != null) { - // Rank the matches. - matches.sort((InputLiveRange a, InputLiveRange b) -> - compareByRankThenNumVal(rawValue, - "L" + a.getId(), - "L" + b.getId())); - - final InputGraph theGraph = p.getGraph() != matchGraph ? matchGraph : null; - for (final InputLiveRange liveRange : matches) { - if (!response.addResult(() -> { - final EditorTopComponent editor = EditorTopComponent.getActive(); - assert(editor != null); - if (theGraph != null) { - editor.getModel().selectGraph(theGraph); - } - Set liveRangeSingleton = new HashSet<>(); - liveRangeSingleton.add(liveRange); - editor.clearSelectedElements(); - editor.addSelectedLiveRanges(liveRangeSingleton, true); - editor.centerSelectedLiveRanges(); - editor.requestActive(); - }, - "L" + liveRange.getId() + (theGraph != null ? " in " + theGraph.getName() : ""))) { - return; - } - } - } + String prefix() { + return "L"; } - private List findMatches(String liveRangeName, InputGraph inputGraph, SearchResponse response) { - try { - RegexpPropertyMatcher matcher = new RegexpPropertyMatcher("", liveRangeName, Pattern.CASE_INSENSITIVE); - List matches = new ArrayList<>(); - for (InputLiveRange liveRange : inputGraph.getLiveRanges()) { - if (matcher.match("L" + liveRange.getId())) { - matches.add(liveRange); - } - } - return matches.size() == 0 ? null : matches; - } catch (Exception e) { - final String msg = e.getMessage(); - response.addResult(() -> { - Message desc = new NotifyDescriptor.Message("An exception occurred during the search, " - + "perhaps due to a malformed query string:\n" + msg, - NotifyDescriptor.WARNING_MESSAGE); - DialogDisplayer.getDefault().notify(desc); - }, - "(Error during search)" - ); - } - return null; + @Override + String id(Object entity) { + assert entity instanceof InputLiveRange; + return Integer.toString(((InputLiveRange)entity).getId()); } - private int compareByRankThenNumVal(String qry, String l1, String l2) { - int key1 = StringUtils.rankMatch(qry, l1); - int key2 = StringUtils.rankMatch(qry, l2); - if (key1 == key2) { - // If the matches have the same rank, compare the numeric values of - // their first words, if applicable. - try { - key1 = Integer.parseInt(l1.replace("L", "")); - key2 = Integer.parseInt(l2.replace("L", "")); - } catch (Exception e) { - // Not applicable, return equality value. - return 0; - } - } - return Integer.compare(key1, key2); + @Override + Collection getAllEntities(InputGraph inputGraph) { + return new ArrayList<>(inputGraph.getLiveRanges()); } + @Override + void selectEntity(EditorTopComponent editor, Object entity) { + assert entity instanceof InputLiveRange; + Set entitySingleton = new HashSet<>(); + entitySingleton.add((InputLiveRange)entity); + editor.addSelectedLiveRanges(entitySingleton, true); + editor.centerSelectedLiveRanges(); + } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/SimpleQuickSearch.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/SimpleQuickSearch.java new file mode 100644 index 0000000000000..ab3c439ad3a68 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/SimpleQuickSearch.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.view; + +import com.sun.hotspot.igv.data.InputGraph; +import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher; +import com.sun.hotspot.igv.data.services.InputGraphProvider; +import com.sun.hotspot.igv.util.LookupHistory; +import com.sun.hotspot.igv.util.StringUtils; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.regex.Pattern; +import org.netbeans.spi.quicksearch.SearchProvider; +import org.netbeans.spi.quicksearch.SearchRequest; +import org.netbeans.spi.quicksearch.SearchResponse; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.NotifyDescriptor.Message; + +public abstract class SimpleQuickSearch implements SearchProvider { + + abstract String prefix(); + + abstract String id(Object entity); + + abstract Collection getAllEntities(InputGraph inputGraph); + + abstract void selectEntity(EditorTopComponent editor, Object entity); + + @Override + public void evaluate(SearchRequest request, SearchResponse response) { + String rawValue = request.getText(); + if (rawValue.trim().isEmpty()) { + return; + } + String value = ".*" + Pattern.quote(rawValue) + ".*"; + + final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class); + if (p == null || p.getGraph() == null) { + return; + } + + InputGraph matchGraph = p.getGraph(); + // Search the current graph + List matches = findMatches(value, p.getGraph(), response); + if (matches == null) { + // See if the it hits in a later graph + for (InputGraph graph : p.searchForward()) { + matches = findMatches(value, graph, response); + if (matches != null) { + matchGraph = graph; + break; + } + } + } + if (matches == null) { + // See if it hits in a earlier graph + for (InputGraph graph : p.searchBackward()) { + matches = findMatches(value, graph, response); + if (matches != null) { + matchGraph = graph; + break; + } + } + } + if (matches != null) { + // Rank the matches. + matches.sort((Object a, Object b) -> + compareByRankThenNumVal(rawValue, + prefix() + id(a), + prefix() + id(b))); + + final InputGraph theGraph = p.getGraph() != matchGraph ? matchGraph : null; + for (final Object entity : matches) { + if (!response.addResult(() -> { + final EditorTopComponent editor = EditorTopComponent.getActive(); + assert(editor != null); + if (theGraph != null) { + editor.getModel().selectGraph(theGraph); + } + editor.clearSelectedElements(); + selectEntity(editor, entity); + editor.requestActive(); + }, + prefix() + id(entity) + (theGraph != null ? " in " + theGraph.getName() : ""))) { + return; + } + } + } + } + + private List findMatches(String entityName, InputGraph inputGraph, SearchResponse response) { + try { + RegexpPropertyMatcher matcher = new RegexpPropertyMatcher("", entityName, Pattern.CASE_INSENSITIVE); + List matches = new ArrayList<>(); + for (Object entity : getAllEntities(inputGraph)) { + if (matcher.match(prefix() + id(entity))) { + matches.add(entity); + } + } + return matches.size() == 0 ? null : matches; + } catch (Exception e) { + final String msg = e.getMessage(); + response.addResult(() -> { + Message desc = new NotifyDescriptor.Message("An exception occurred during the search, " + + "perhaps due to a malformed query string:\n" + msg, + NotifyDescriptor.WARNING_MESSAGE); + DialogDisplayer.getDefault().notify(desc); + }, + "(Error during search)" + ); + } + return null; + } + + private int compareByRankThenNumVal(String qry, String l1, String l2) { + int key1 = StringUtils.rankMatch(qry, l1); + int key2 = StringUtils.rankMatch(qry, l2); + if (key1 == key2) { + // If the matches have the same rank, compare the numeric values of + // their first words, if applicable. + try { + key1 = Integer.parseInt(l1.replace(prefix(), "")); + key2 = Integer.parseInt(l2.replace(prefix(), "")); + } catch (Exception e) { + // Not applicable, return equality value. + return 0; + } + } + return Integer.compare(key1, key2); + } + +} From ce8b3cbdcafa75be3f82fb57e7d98edb59734175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Tue, 28 Jan 2025 20:28:23 +0100 Subject: [PATCH 13/48] Fix crashes when disabling live ranges or switching mode --- .../java/com/sun/hotspot/igv/graph/Diagram.java | 13 +++++++++++++ .../java/com/sun/hotspot/igv/view/DiagramScene.java | 4 ++-- .../com/sun/hotspot/igv/view/DiagramViewModel.java | 2 ++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java index 17fb5a66b1e83..5f44e55f7b1bb 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java @@ -49,6 +49,8 @@ public class Diagram { // Whether widgets derived from this diagram should be adapted for the // control-flow graph view. private boolean cfg; + // Whether live range drawing is enabled. + private boolean liveRanges; private final Set blockConnections; public boolean isCFG() { @@ -59,6 +61,14 @@ public void setCFG(boolean cfg) { this.cfg = cfg; } + public boolean isLiveRanges() { + return liveRanges; + } + + public void setLiveRanges(boolean liveRanges) { + this.liveRanges = liveRanges; + } + public Diagram(InputGraph graph, String nodeText, String shortNodeText, String tinyNodeText) { assert graph != null; @@ -249,6 +259,9 @@ public List
getFigures() { } public List getLiveRangeSegments() { + if (!isCFG() || !isLiveRanges()) { + return new ArrayList<>(0); + } return Collections.unmodifiableList(liveRangeSegments); } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index ec6ac3746092f..dc99cb4cd1c34 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -1491,8 +1491,8 @@ private void rebuildSegmentLayer() { LiveRangeWidget firstSegmentWidget = null; LiveRangeWidget nextSegmentWidget = null; for (LiveRangeSegment segment : segmentSet) { - // Segments are not yet laid out. - assert segment.getStartPoint() == null && segment.getEndPoint() == null; + segment.setStartPoint(null); + segment.setEndPoint(null); LiveRangeWidget segmentWidget = new LiveRangeWidget(segment, this, 0, nextSegmentWidget); segmentWidget.setVisible(false); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index 6895d2ac0203d..6e09d96011970 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -189,6 +189,7 @@ public boolean getShowLiveRanges() { public void setShowLiveRanges(boolean b) { showLiveRanges = b; + diagram.setLiveRanges(b); diagramChangedEvent.fire(); } @@ -440,6 +441,7 @@ private void rebuildDiagram() { Settings.get().get(Settings.NODE_SHORT_TEXT, Settings.NODE_SHORT_TEXT_DEFAULT), Settings.get().get(Settings.NODE_TINY_TEXT, Settings.NODE_TINY_TEXT_DEFAULT)); diagram.setCFG(getShowCFG()); + diagram.setLiveRanges(getShowLiveRanges()); filterChain.applyInOrder(diagram, filtersOrder); if (graph.isDiffGraph()) { ColorFilter f = new ColorFilter(""); From f551f4948dd4f241889baac13bba3d5da6ec67c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Wed, 29 Jan 2025 09:44:46 +0100 Subject: [PATCH 14/48] Enable/disable live range widgets similarly to block widgets --- .../com/sun/hotspot/igv/graph/Diagram.java | 13 --- .../sun/hotspot/igv/view/DiagramScene.java | 94 ++++++++++--------- .../hotspot/igv/view/DiagramViewModel.java | 2 - 3 files changed, 50 insertions(+), 59 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java index 5f44e55f7b1bb..17fb5a66b1e83 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java @@ -49,8 +49,6 @@ public class Diagram { // Whether widgets derived from this diagram should be adapted for the // control-flow graph view. private boolean cfg; - // Whether live range drawing is enabled. - private boolean liveRanges; private final Set blockConnections; public boolean isCFG() { @@ -61,14 +59,6 @@ public void setCFG(boolean cfg) { this.cfg = cfg; } - public boolean isLiveRanges() { - return liveRanges; - } - - public void setLiveRanges(boolean liveRanges) { - this.liveRanges = liveRanges; - } - public Diagram(InputGraph graph, String nodeText, String shortNodeText, String tinyNodeText) { assert graph != null; @@ -259,9 +249,6 @@ public List
getFigures() { } public List getLiveRangeSegments() { - if (!isCFG() || !isLiveRanges()) { - return new ArrayList<>(0); - } return Collections.unmodifiableList(liveRangeSegments); } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index dc99cb4cd1c34..6ca7030d5f7ca 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -885,7 +885,7 @@ private void relayout() { doCFGLayout(visibleFigures, visibleConnections, visibleLiveRangeSegments); } rebuildConnectionLayer(); - if (getModel().getShowCFG()) { + if (getModel().getShowCFG() && getModel().getShowLiveRanges()) { updateLiveRangeIdsInBlockWidgets(); repaintLiveRangeWidgets(); } @@ -1479,33 +1479,35 @@ private void rebuildConnectionLayer() { private void rebuildSegmentLayer() { segmentLayer.removeChildren(); - Map> segments = new HashMap<>(); - for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { - int liveRangeId = segment.getLiveRange().getId(); - if (!segments.containsKey(liveRangeId)) { - segments.put(liveRangeId, new HashSet<>()); - } - segments.get(liveRangeId).add(segment); - } - for (Set segmentSet : segments.values()) { - LiveRangeWidget firstSegmentWidget = null; - LiveRangeWidget nextSegmentWidget = null; - for (LiveRangeSegment segment : segmentSet) { - segment.setStartPoint(null); - segment.setEndPoint(null); - LiveRangeWidget segmentWidget = - new LiveRangeWidget(segment, this, 0, nextSegmentWidget); - segmentWidget.setVisible(false); - if (firstSegmentWidget == null) { - firstSegmentWidget = segmentWidget; + if (getModel().getShowCFG() && getModel().getShowLiveRanges()) { + Map> segments = new HashMap<>(); + for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { + int liveRangeId = segment.getLiveRange().getId(); + if (!segments.containsKey(liveRangeId)) { + segments.put(liveRangeId, new HashSet<>()); + } + segments.get(liveRangeId).add(segment); + } + for (Set segmentSet : segments.values()) { + LiveRangeWidget firstSegmentWidget = null; + LiveRangeWidget nextSegmentWidget = null; + for (LiveRangeSegment segment : segmentSet) { + segment.setStartPoint(null); + segment.setEndPoint(null); + LiveRangeWidget segmentWidget = + new LiveRangeWidget(segment, this, 0, nextSegmentWidget); + segmentWidget.setVisible(false); + if (firstSegmentWidget == null) { + firstSegmentWidget = segmentWidget; + } + addObject(segment, segmentWidget); + segmentWidget.getActions().addAction(selectAction); + segmentWidget.getActions().addAction(hoverAction); + segmentLayer.addChild(segmentWidget); + nextSegmentWidget = segmentWidget; } - addObject(segment, segmentWidget); - segmentWidget.getActions().addAction(selectAction); - segmentWidget.getActions().addAction(hoverAction); - segmentLayer.addChild(segmentWidget); - nextSegmentWidget = segmentWidget; + firstSegmentWidget.setNext(nextSegmentWidget); } - firstSegmentWidget.setNext(nextSegmentWidget); } } @@ -1555,17 +1557,19 @@ private void updateVisibleFigureWidgets() { private void updateVisibleLiveRangeWidgets() { // TODO: pre-compute visibility for each live range, to avoid // re-computing it for each segment in each live range. - for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { - LiveRangeWidget liveRangeWidget = getWidget(segment); - boolean visible = true; - for (InputNode n : getModel().getDiagram().getInputGraph().getRelatedNodes(segment.getLiveRange().getId())) { - FigureWidget f = getWidget(getModel().getDiagram().getFigure(n)); - if (!f.isVisible()) { - visible = false; - break; + if (getModel().getShowCFG() && getModel().getShowLiveRanges()) { + for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { + LiveRangeWidget liveRangeWidget = getWidget(segment); + boolean visible = true; + for (InputNode n : getModel().getDiagram().getInputGraph().getRelatedNodes(segment.getLiveRange().getId())) { + FigureWidget f = getWidget(getModel().getDiagram().getFigure(n)); + if (!f.isVisible()) { + visible = false; + break; + } } + liveRangeWidget.setVisible(visible); } - liveRangeWidget.setVisible(visible); } } @@ -1600,15 +1604,17 @@ private void updateNodeHull() { } private void updateLiveRangeWidgetLocations(Set oldVisibleLiveRangeWidgets) { - boolean doAnimation = shouldAnimate(); - for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { - LiveRangeWidget liveRangeWidget = getWidget(segment); - if (liveRangeWidget.isVisible()) { - Point location = new Point(segment.getStartPoint()); - if (doAnimation && oldVisibleLiveRangeWidgets.contains(liveRangeWidget)) { - getSceneAnimator().animatePreferredLocation(liveRangeWidget, location); - } else { - liveRangeWidget.setPreferredLocation(location); + if (getModel().getShowCFG() && getModel().getShowLiveRanges()) { + boolean doAnimation = shouldAnimate(); + for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { + LiveRangeWidget liveRangeWidget = getWidget(segment); + if (liveRangeWidget.isVisible()) { + Point location = new Point(segment.getStartPoint()); + if (doAnimation && oldVisibleLiveRangeWidgets.contains(liveRangeWidget)) { + getSceneAnimator().animatePreferredLocation(liveRangeWidget, location); + } else { + liveRangeWidget.setPreferredLocation(location); + } } } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index 6e09d96011970..6895d2ac0203d 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -189,7 +189,6 @@ public boolean getShowLiveRanges() { public void setShowLiveRanges(boolean b) { showLiveRanges = b; - diagram.setLiveRanges(b); diagramChangedEvent.fire(); } @@ -441,7 +440,6 @@ private void rebuildDiagram() { Settings.get().get(Settings.NODE_SHORT_TEXT, Settings.NODE_SHORT_TEXT_DEFAULT), Settings.get().get(Settings.NODE_TINY_TEXT, Settings.NODE_TINY_TEXT_DEFAULT)); diagram.setCFG(getShowCFG()); - diagram.setLiveRanges(getShowLiveRanges()); filterChain.applyInOrder(diagram, filtersOrder); if (graph.isDiffGraph()) { ColorFilter f = new ColorFilter(""); From 64804443ad99b8003b54c262bd32c10f842d27ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Wed, 29 Jan 2025 15:57:52 +0100 Subject: [PATCH 15/48] Fix crashes when filtering out live range-related nodes --- .../main/java/com/sun/hotspot/igv/view/DiagramScene.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 6ca7030d5f7ca..255e5dc5e597e 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -962,6 +962,9 @@ private boolean isVisibleLiveRange(int liveRangeId) { } Set relatedNodes = getModel().getGraph().getRelatedNodes(liveRangeId); for (InputNode n : relatedNodes) { + if (!getModel().getDiagram().hasFigure(n)) { + return false; + } Figure f = getModel().getDiagram().getFigure(n); FigureWidget fw = getWidget(f); if (isVisibleBlock(f.getBlock()) && @@ -1562,6 +1565,10 @@ private void updateVisibleLiveRangeWidgets() { LiveRangeWidget liveRangeWidget = getWidget(segment); boolean visible = true; for (InputNode n : getModel().getDiagram().getInputGraph().getRelatedNodes(segment.getLiveRange().getId())) { + if (!getModel().getDiagram().hasFigure(n)) { + visible = false; + break; + } FigureWidget f = getWidget(getModel().getDiagram().getFigure(n)); if (!f.isVisible()) { visible = false; From 05f3a30a6e72059a3b5e21f143a4356eb2434bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 30 Jan 2025 09:55:44 +0100 Subject: [PATCH 16/48] Position live ranges in empty blocks properly --- .../sun/hotspot/igv/hierarchicallayout/ClusterNode.java | 6 +++--- .../hierarchicallayout/HierarchicalCFGLayoutManager.java | 7 ++++--- .../main/java/com/sun/hotspot/igv/view/DiagramScene.java | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java index 98b82c20bc344..d52ac8a98d78b 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java @@ -52,7 +52,8 @@ public class ClusterNode implements Vertex { private final int headerVerticalSpace; private final Dimension emptySize; - public static final int EMPTY_BLOCK_LIVE_RANGE_OFFSET = 20; + public static final int EMPTY_BLOCK_LIVE_RANGE_X_OFFSET = 20; + public static final int EMPTY_BLOCK_LIVE_RANGE_Y_OFFSET = 6; public ClusterNode(Cluster cluster, String name, int headerVerticalSpace, Dimension emptySize) { this.subNodes = new HashSet<>(); @@ -165,7 +166,7 @@ private void calculateSize() { maxX += cluster.getLiveRangeSeparation(); } if (subNodes.isEmpty()) { - maxX += ClusterNode.EMPTY_BLOCK_LIVE_RANGE_OFFSET; + maxX += ClusterNode.EMPTY_BLOCK_LIVE_RANGE_X_OFFSET; } size = new Dimension(maxX - minX, maxY - minY + headerVerticalSpace); @@ -175,7 +176,6 @@ private void calculateSize() { n.setPosition(new Point(n.getPosition().x - minX, n.getPosition().y - minY + headerVerticalSpace)); } - // FIXME: nodeOffset does not exist anymore, do we need to normalize segment coordinates? for (Link l : subEdges) { List points = new ArrayList<>(l.getControlPoints()); diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java index 2e4fc6d14e762..bb29a1a8f262b 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java @@ -81,10 +81,11 @@ private void doLinearLayout(ClusterNode clusterNode) { // If live segments are available, compute their position. if (vertices.isEmpty()) { - int x = ClusterNode.EMPTY_BLOCK_LIVE_RANGE_OFFSET; + int x = ClusterNode.EMPTY_BLOCK_LIVE_RANGE_X_OFFSET; + final int y = ClusterNode.EMPTY_BLOCK_LIVE_RANGE_Y_OFFSET; for (Segment s : clusterNode.getSubSegments()) { - s.setStartPoint(new Point(x, 0)); - s.setEndPoint(new Point(x, 0)); + s.setStartPoint(new Point(x, y)); + s.setEndPoint(new Point(x, y)); if (s.isLastOfLiveRange()) { x += s.getCluster().getLiveRangeSeparation(); } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 255e5dc5e597e..e6f16c36b1429 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -1659,7 +1659,7 @@ private void updateVisibleBlockWidgets() { blockWidget.setVisible(visibleAfter); // Update node width for live range layout. - int nodeWidth = ClusterNode.EMPTY_BLOCK_LIVE_RANGE_OFFSET; + int nodeWidth = ClusterNode.EMPTY_BLOCK_LIVE_RANGE_X_OFFSET; for (InputNode n : block.getInputBlock().getNodes()) { if (!getModel().getDiagram().hasFigure(n)) { // n might not be visible (e.g. filtered out). From a04fc9bdfefcaf2b1d51a49fdd5e2ce4633b459e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 30 Jan 2025 10:16:27 +0100 Subject: [PATCH 17/48] Enable predecessor and successor expansion only if some node is selected --- .../igv/view/actions/ExpandAdjacentAction.java | 11 +++++++---- .../igv/view/actions/ExpandPredecessorsAction.java | 8 +++++++- .../igv/view/actions/ExpandSuccessorsAction.java | 8 +++++++- .../hotspot/igv/view/actions/ModelAwareAction.java | 2 -- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandAdjacentAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandAdjacentAction.java index daceaa708bd97..0b8de7983f696 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandAdjacentAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandAdjacentAction.java @@ -24,16 +24,16 @@ package com.sun.hotspot.igv.view.actions; import com.sun.hotspot.igv.graph.Figure; +import com.sun.hotspot.igv.view.DiagramViewModel; import com.sun.hotspot.igv.view.EditorTopComponent; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.function.Function; import org.openide.util.HelpCtx; -import org.openide.util.actions.CallableSystemAction; -public abstract class ExpandAdjacentAction extends CallableSystemAction { +public abstract class ExpandAdjacentAction extends ModelAwareAction { protected void expandFigures(Function> getAdjacentFigures) { EditorTopComponent editor = EditorTopComponent.getActive(); @@ -47,10 +47,13 @@ protected void expandFigures(Function> getAdjacentFigures) } } - public abstract void performAction(); - public abstract String getName(); + @Override + public boolean isEnabled(DiagramViewModel model) { + return model != null && !model.getSelectedNodes().isEmpty(); + } + @Override public HelpCtx getHelpCtx() { return HelpCtx.DEFAULT_HELP; diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java index 481bb58aef54d..bf745786a497b 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java @@ -24,6 +24,7 @@ package com.sun.hotspot.igv.view.actions; import com.sun.hotspot.igv.graph.Figure; +import com.sun.hotspot.igv.view.DiagramViewModel; /** * @@ -32,7 +33,7 @@ public final class ExpandPredecessorsAction extends ExpandAdjacentAction { @Override - public void performAction() { + public void performAction(DiagramViewModel model) { expandFigures(Figure::getPredecessors); } @@ -40,4 +41,9 @@ public void performAction() { public String getName() { return "Expand Above"; } + + @Override + public String getDescription() { + return "Expand predecessors of current set of selected nodes"; + } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java index 340a2d400d3b9..9acad3a0c8bc4 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java @@ -24,6 +24,7 @@ package com.sun.hotspot.igv.view.actions; import com.sun.hotspot.igv.graph.Figure; +import com.sun.hotspot.igv.view.DiagramViewModel; /** * @@ -32,7 +33,7 @@ public final class ExpandSuccessorsAction extends ExpandAdjacentAction { @Override - public void performAction() { + public void performAction(DiagramViewModel model) { expandFigures(Figure::getSuccessors); } @@ -40,4 +41,9 @@ public void performAction() { public String getName() { return "Expand Below"; } + + @Override + public String getDescription() { + return "Expand successors of current set of selected nodes"; + } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java index ce373436d9395..29a3bec588a40 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java @@ -37,8 +37,6 @@ public ModelAwareAction() { putValue(Action.SHORT_DESCRIPTION, getDescription()); } - protected abstract String iconResource(); - protected abstract String getDescription(); public abstract String getName(); From cad79081cf6e2b5b7b222afd12fd7b04036dee5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 30 Jan 2025 10:55:56 +0100 Subject: [PATCH 18/48] Enable extraction of live ranges via related nodes --- .../hotspot/igv/view/DiagramViewModel.java | 10 ++++++---- .../igv/view/actions/ExtractAction.java | 19 ++++++++++++++++--- .../igv/view/actions/ModelAwareAction.java | 4 ++-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index 6895d2ac0203d..27bec297bcf0f 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -63,7 +63,8 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene private InputGraph cachedInputGraph; private final ChangedEvent diagramChangedEvent = new ChangedEvent<>(this); private final ChangedEvent graphChangedEvent = new ChangedEvent<>(this); - private final ChangedEvent selectedNodesChangedEvent = new ChangedEvent<>(this); + // This event signals a change in the selection of nodes and/or live ranges. + private final ChangedEvent selectedElementsChangedEvent = new ChangedEvent<>(this); private final ChangedEvent hiddenNodesChangedEvent = new ChangedEvent<>(this); private ChangedListener titleChangedListener = g -> {}; private boolean showFreeInteractive; @@ -274,8 +275,8 @@ public ChangedEvent getGraphChangedEvent() { return graphChangedEvent; } - public ChangedEvent getSelectedNodesChangedEvent() { - return selectedNodesChangedEvent; + public ChangedEvent getSelectedElementsChangedEvent() { + return selectedElementsChangedEvent; } public ChangedEvent getHiddenNodesChangedEvent() { @@ -328,7 +329,7 @@ public void setSelectedNodes(Set nodes) { } } setColors(colors); - selectedNodesChangedEvent.fire(); + selectedElementsChangedEvent.fire(); } public Set getSelectedLiveRanges() { @@ -337,6 +338,7 @@ public Set getSelectedLiveRanges() { public void setSelectedLiveRanges(Set liveRanges) { selectedLiveRanges = liveRanges; + selectedElementsChangedEvent.fire(); } public void showFigures(Collection
figures) { diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExtractAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExtractAction.java index 24547b19b6a30..c1720c376ede5 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExtractAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExtractAction.java @@ -23,6 +23,11 @@ */ package com.sun.hotspot.igv.view.actions; +import java.util.HashSet; +import java.util.Set; + +import com.sun.hotspot.igv.data.InputGraph; +import com.sun.hotspot.igv.data.InputNode; import com.sun.hotspot.igv.view.DiagramViewModel; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; @@ -43,7 +48,7 @@ }) @Messages({ "CTL_ExtractAction=Extract", - "HINT_ExtractAction=Extract current set of selected nodes" + "HINT_ExtractAction=Extract current set of selected nodes or live ranges" }) public final class ExtractAction extends ModelAwareAction { @@ -64,11 +69,19 @@ public String getName() { @Override public void performAction(DiagramViewModel model) { - model.showOnly(model.getSelectedNodes()); + Set nodes = new HashSet<>(model.getSelectedNodes()); + InputGraph graph = model.getDiagram().getInputGraph(); + for (int liveRangeId : model.getSelectedLiveRanges()) { + for (InputNode node : graph.getRelatedNodes(liveRangeId)) { + nodes.add(node.getId()); + } + } + model.showOnly(nodes); } @Override public boolean isEnabled(DiagramViewModel model) { - return model != null && !model.getSelectedNodes().isEmpty(); + return model != null && + !(model.getSelectedNodes().isEmpty() && model.getSelectedLiveRanges().isEmpty()); } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java index 29a3bec588a40..eccd9fc8ced89 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java @@ -52,7 +52,7 @@ public Class contextClass() { @Override public void addContextListener(DiagramViewModel model) { - model.getSelectedNodesChangedEvent().addListener(this); + model.getSelectedElementsChangedEvent().addListener(this); model.getDiagramChangedEvent().addListener(this); model.getGraphChangedEvent().addListener(this); model.getHiddenNodesChangedEvent().addListener(this); @@ -60,7 +60,7 @@ public void addContextListener(DiagramViewModel model) { @Override public void removeContextListener(DiagramViewModel model) { - model.getSelectedNodesChangedEvent().removeListener(this); + model.getSelectedElementsChangedEvent().removeListener(this); model.getDiagramChangedEvent().removeListener(this); model.getGraphChangedEvent().removeListener(this); model.getHiddenNodesChangedEvent().removeListener(this); From 8b619bdae0e2d8d6f0c048a897c077a8320b6711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 30 Jan 2025 12:37:31 +0100 Subject: [PATCH 19/48] Preserve combine node and live range selection across relayouts --- .../com/sun/hotspot/igv/data/InputGraph.java | 4 ++ .../sun/hotspot/igv/view/DiagramScene.java | 59 ++++++++++++------- .../sun/hotspot/igv/view/DiagramViewer.java | 2 + .../hotspot/igv/view/EditorTopComponent.java | 12 +++- 4 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java index fc80723b3d05e..c308cf5728891 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java @@ -315,6 +315,10 @@ public void addLiveRange(InputLiveRange lrg) { relatedNodes.put(lrg.getId(), new HashSet<>()); } + public InputLiveRange getLiveRange(int liveRangeId) { + return liveRanges.get(liveRangeId); + } + public Collection getLiveRanges() { return Collections.unmodifiableCollection(liveRanges.values()); } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index e6f16c36b1429..c587accd926b6 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -849,7 +849,6 @@ private void update() { rebuildBlockLayer(); rebuildSegmentLayer(); relayout(); - setLiveRangeSegmentSelection(model.getSelectedLiveRangeSegments()); rebuilding = false; } @@ -894,7 +893,8 @@ private void relayout() { updateLiveRangeWidgetLocations(oldVisibleLiveRangeWidgets); updateBlockWidgetBounds(oldVisibleBlockWidgets); validateAll(); - setFigureSelection(model.getSelectedFigures()); + setElementSelection(model.getSelectedFigures(), + model.getSelectedLiveRangeSegments()); centerSelectedFigures(); centerSelectedLiveRanges(); rebuilding = false; @@ -1294,8 +1294,21 @@ private void gotoBlock(final Block block) { } } - @Override - public void addSelectedNodes(Collection nodes, boolean showIfHidden) { + private Set liveRangeSegmentSet(Collection liveRanges) { + Set liveRangeIds = new HashSet<>(); + for (InputLiveRange liveRange : liveRanges) { + liveRangeIds.add(liveRange.getId()); + } + Map representativeSegments = new HashMap<>(); + for (LiveRangeSegment segment : model.getDiagram().getLiveRangeSegments()) { + if (liveRangeIds.contains(segment.getLiveRange().getId())) { + representativeSegments.put(segment.getLiveRange().getId(), segment); + } + } + return new HashSet<>(representativeSegments.values()); + } + + private Set
figureSet(Collection nodes) { Set nodeIds = new HashSet<>(model.getSelectedNodes()); for (InputNode inputNode : nodes) { nodeIds.add(inputNode.getId()); @@ -1306,7 +1319,12 @@ public void addSelectedNodes(Collection nodes, boolean showIfHidden) selectedFigures.add(figure); } } - setFigureSelection(selectedFigures); + return selectedFigures; + } + + @Override + public void addSelectedNodes(Collection nodes, boolean showIfHidden) { + setFigureSelection(figureSet(nodes)); if (showIfHidden) { model.showFigures(model.getSelectedFigures()); } @@ -1314,22 +1332,17 @@ public void addSelectedNodes(Collection nodes, boolean showIfHidden) @Override public void addSelectedLiveRanges(Collection liveRanges, boolean showIfHidden) { - // TODO: ensure all related nodes are visible. - Set liveRangeIds = new HashSet<>(); - for (InputLiveRange liveRange : liveRanges) { - liveRangeIds.add(liveRange.getId()); - } - Map representativeSegments = new HashMap<>(); - for (LiveRangeSegment segment : model.getDiagram().getLiveRangeSegments()) { - if (liveRangeIds.contains(segment.getLiveRange().getId())) { - representativeSegments.put(segment.getLiveRange().getId(), segment); - } + setLiveRangeSegmentSelection(liveRangeSegmentSet(liveRanges)); + } + + @Override + public void addSelectedElements(Collection nodes, + Collection liveRanges, + boolean showIfHidden) { + setElementSelection(figureSet(nodes), liveRangeSegmentSet(liveRanges)); + if (showIfHidden) { + model.showFigures(model.getSelectedFigures()); } - setLiveRangeSegmentSelection(new HashSet<>(representativeSegments.values())); - // TODO: - // if (showIfHidden) { - // model.showLiveRangeSegments(model.getSelectedLiveRangeSegments()); - // } } @Override @@ -1420,6 +1433,12 @@ private void setLiveRangeSegmentSelection(Set list) { super.setSelectedObjects(new HashSet<>(list)); } + private void setElementSelection(Set
figures, Set segments) { + Set elements = new HashSet<>(figures); + elements.addAll(segments); + super.setSelectedObjects(elements); + } + @Override public void resetUndoRedoManager() { undoRedoManager = new UndoRedo.Manager(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java index 49967cc6164c2..5c9e1ce65f15f 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java @@ -84,6 +84,8 @@ enum InteractionMode { void addSelectedLiveRanges(Collection liveRanges, boolean showIfHidden); + void addSelectedElements(Collection nodes, Collection liveRanges, boolean showIfHidden); + void clearSelectedElements(); void setInteractionMode(InteractionMode mode); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java index c06115cf09cb5..f50649b069c51 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java @@ -359,6 +359,12 @@ public void addSelectedLiveRanges(Collection liveRanges, boolean scene.addSelectedLiveRanges(liveRanges, showIfHidden); } + public void addSelectedElements(Collection nodes, + Collection liveRanges, + boolean showIfHidden) { + scene.addSelectedElements(nodes, liveRanges, showIfHidden); + } + public void centerSelectedNodes() { scene.centerSelectedFigures(); } @@ -460,7 +466,11 @@ public TopComponent cloneComponent() { for (Figure figure : getModel().getSelectedFigures()) { selectedNodes.add(figure.getInputNode()); } - etc.addSelectedNodes(selectedNodes, false); + Set selectedLiveRanges = new HashSet<>(); + for (int liveRangeId : getModel().getSelectedLiveRanges()) { + selectedLiveRanges.add(getModel().getGraph().getLiveRange(liveRangeId)); + } + etc.addSelectedElements(selectedNodes, selectedLiveRanges, false); model.setGlobalSelection(GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected(), false); model.setCutEdges(CutEdgesAction.get(CutEdgesAction.class).isSelected(), false); etc.resetUndoRedo(); From e25b13d8f2f2fe360c90db890e944e56a245bddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 30 Jan 2025 12:57:30 +0100 Subject: [PATCH 20/48] Make it possible to hide live ranges --- .../hotspot/igv/view/actions/ExtractAction.java | 2 +- .../sun/hotspot/igv/view/actions/HideAction.java | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExtractAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExtractAction.java index c1720c376ede5..bd5e4077ac530 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExtractAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExtractAction.java @@ -48,7 +48,7 @@ }) @Messages({ "CTL_ExtractAction=Extract", - "HINT_ExtractAction=Extract current set of selected nodes or live ranges" + "HINT_ExtractAction=Extract selected nodes and live ranges" }) public final class ExtractAction extends ModelAwareAction { diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/HideAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/HideAction.java index cac2d167426cd..695749b08de7f 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/HideAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/HideAction.java @@ -23,6 +23,8 @@ */ package com.sun.hotspot.igv.view.actions; +import com.sun.hotspot.igv.data.InputGraph; +import com.sun.hotspot.igv.data.InputNode; import com.sun.hotspot.igv.view.DiagramViewModel; import java.util.HashSet; import java.util.Set; @@ -44,8 +46,8 @@ @ActionReference(path = "Shortcuts", name = "D-H") }) @Messages({ - "CTL_HideAction=Hide nodes", - "HINT_HideAction=Hide selected nodes" + "CTL_HideAction=Hide", + "HINT_HideAction=Hide selected nodes and live ranges" }) public final class HideAction extends ModelAwareAction { @@ -69,11 +71,18 @@ public void performAction(DiagramViewModel model) { Set selectedNodes = model.getSelectedNodes(); HashSet nodes = new HashSet<>(model.getHiddenNodes()); nodes.addAll(selectedNodes); + InputGraph graph = model.getDiagram().getInputGraph(); + for (int liveRangeId : model.getSelectedLiveRanges()) { + for (InputNode node : graph.getRelatedNodes(liveRangeId)) { + nodes.add(node.getId()); + } + } model.setHiddenNodes(nodes); } @Override public boolean isEnabled(DiagramViewModel model) { - return model != null && !model.getSelectedNodes().isEmpty(); + return model != null && + !(model.getSelectedNodes().isEmpty() && model.getSelectedLiveRanges().isEmpty()); } } From 5937be69fd17e2fca626f45324fddf6aac1f82c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 30 Jan 2025 13:59:51 +0100 Subject: [PATCH 21/48] Do not show duplicate live ranges in properties, deselect live ranges when switching view or disabling --- .../sun/hotspot/igv/view/DiagramScene.java | 21 +++++++++++++++++-- .../hotspot/igv/view/DiagramViewModel.java | 7 +++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index c587accd926b6..2f28debfba119 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -435,11 +435,28 @@ public void selectionChanged(ObjectSceneEvent e, Set oldSet, Set return; } - content.set(newSet, null); + // Remove duplicate live range segments (i.e. segments that + // represent the same live range in different basic blocks). + Set newUnique = new HashSet<>(); + Set visitedLiveRanges = new HashSet<>(); + for (Object o : newSet) { + if (o instanceof Properties.Provider && + o instanceof LiveRangeSegment) { + int liveRangeId = ((LiveRangeSegment) o).getLiveRange().getId(); + if (!visitedLiveRanges.contains(liveRangeId)) { + newUnique.add(o); + visitedLiveRanges.add(liveRangeId); + } + } else { + newUnique.add(o); + } + } + + content.set(newUnique, null); Set nodeSelection = new HashSet<>(); Set liveRangeSelection = new HashSet<>(); - for (Object o : newSet) { + for (Object o : newUnique) { if (o instanceof Properties.Provider) { final Properties.Provider provider = (Properties.Provider) o; AbstractNode node = new AbstractNode(Children.LEAF) { diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index 27bec297bcf0f..f37a44ae8565a 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -117,6 +117,7 @@ public boolean getShowFreeInteractive() { public void setShowFreeInteractive(boolean enable) { showFreeInteractive = enable; if (enable) { + selectedLiveRanges.clear(); diagramChangedEvent.fire(); } } @@ -128,6 +129,7 @@ public boolean getShowStableSea() { public void setShowStableSea(boolean enable) { showStableSea = enable; if (enable) { + selectedLiveRanges.clear(); diagramChangedEvent.fire(); } } @@ -139,6 +141,7 @@ public boolean getShowSea() { public void setShowSea(boolean enable) { showSea = enable; if (enable) { + selectedLiveRanges.clear(); diagramChangedEvent.fire(); } } @@ -150,6 +153,7 @@ public boolean getShowBlocks() { public void setShowBlocks(boolean enable) { showBlocks = enable; if (enable) { + selectedLiveRanges.clear(); diagramChangedEvent.fire(); } } @@ -190,6 +194,9 @@ public boolean getShowLiveRanges() { public void setShowLiveRanges(boolean b) { showLiveRanges = b; + if (!showLiveRanges) { + selectedLiveRanges.clear(); + } diagramChangedEvent.fire(); } From add4fb83247e225cc2cd21bca56060a7bd8e9ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 30 Jan 2025 14:38:34 +0100 Subject: [PATCH 22/48] Extract on live range double-click --- .../igv/view/widgets/LiveRangeWidget.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index 0ce1fc324e956..5c182781ecc27 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -23,12 +23,22 @@ */ package com.sun.hotspot.igv.view.widgets; +import com.sun.hotspot.igv.data.InputGraph; +import com.sun.hotspot.igv.data.InputNode; import com.sun.hotspot.igv.data.Properties; import com.sun.hotspot.igv.graph.LiveRangeSegment; +import com.sun.hotspot.igv.util.DoubleClickAction; +import com.sun.hotspot.igv.util.DoubleClickHandler; import com.sun.hotspot.igv.util.PropertiesConverter; import com.sun.hotspot.igv.util.PropertiesSheet; import com.sun.hotspot.igv.view.DiagramScene; +import com.sun.hotspot.igv.view.DiagramViewModel; + import java.awt.*; +import java.util.HashSet; +import java.util.Set; + +import org.netbeans.api.visual.action.WidgetAction; import org.netbeans.api.visual.model.ObjectState; import org.netbeans.api.visual.widget.Widget; import org.openide.nodes.AbstractNode; @@ -36,7 +46,7 @@ import org.openide.nodes.Node; import org.openide.nodes.Sheet; -public class LiveRangeWidget extends Widget implements Properties.Provider { +public class LiveRangeWidget extends Widget implements Properties.Provider, DoubleClickHandler { private final LiveRangeSegment liveRangeSegment; private final DiagramScene scene; @@ -60,6 +70,8 @@ public LiveRangeWidget(LiveRangeSegment liveRangeSegment, DiagramScene scene, in this.length = length; this.next = next; + getActions().addAction(new DoubleClickAction(this)); + updateClientArea(); // Initialize node for property sheet @@ -144,6 +156,18 @@ private void setHighlighted(boolean enable) { } } + @Override + public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) { + DiagramViewModel model = this.scene.getModel(); + Set nodes = new HashSet<>(); + InputGraph graph = model.getDiagram().getInputGraph(); + int liveRangeId = liveRangeSegment.getLiveRange().getId(); + for (InputNode node : graph.getRelatedNodes(liveRangeId)) { + nodes.add(node.getId()); + } + model.showOnly(nodes); + } + @Override public Properties getProperties() { return liveRangeSegment.getProperties(); From b1c2a944c01b521ad1c2084773b1654c9b8f486c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 30 Jan 2025 15:03:46 +0100 Subject: [PATCH 23/48] Add pop-up menu to live ranges --- .../com/sun/hotspot/igv/data/InputGraph.java | 17 ++++++++++++ .../igv/view/widgets/LiveRangeWidget.java | 26 ++++++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java index c308cf5728891..98d3e9b80d563 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java @@ -41,6 +41,8 @@ public class InputGraph extends Properties.Entity implements FolderElement { private final Map liveRanges; private Map livenessInfo; private Map> relatedNodes; + private Map> defNodes; + private Map> useNodes; private final boolean isDiffGraph; private final InputGraph firstGraph; private final InputGraph secondGraph; @@ -64,6 +66,8 @@ private InputGraph(String name, InputGraph firstGraph, InputGraph secondGraph) { liveRanges = new LinkedHashMap<>(); livenessInfo = new LinkedHashMap<>(); relatedNodes = new LinkedHashMap<>(); + defNodes = new LinkedHashMap<>(); + useNodes = new LinkedHashMap<>(); blockEdges = new ArrayList<>(); nodeToBlock = new LinkedHashMap<>(); isDiffGraph = firstGraph != null && secondGraph != null; @@ -313,6 +317,8 @@ public Group getGroup() { public void addLiveRange(InputLiveRange lrg) { liveRanges.put(lrg.getId(), lrg); relatedNodes.put(lrg.getId(), new HashSet<>()); + defNodes.put(lrg.getId(), new HashSet<>()); + useNodes.put(lrg.getId(), new HashSet<>()); } public InputLiveRange getLiveRange(int liveRangeId) { @@ -327,15 +333,18 @@ public void addLivenessInfo(InputNode node, LivenessInfo info) { livenessInfo.put(node.getId(), info); if (info.def != null) { relatedNodes.get(info.def).add(node); + defNodes.get(info.def).add(node); } if (info.use != null) { for (int lrg : info.use) { relatedNodes.get(lrg).add(node); + useNodes.get(lrg).add(node); } } if (info.join != null) { for (int lrg : info.join) { relatedNodes.get(lrg).add(node); + useNodes.get(lrg).add(node); } } } @@ -348,6 +357,14 @@ public Set getRelatedNodes(int liveRangeId) { return relatedNodes.get(liveRangeId); } + public Set getDefNodes(int liveRangeId) { + return defNodes.get(liveRangeId); + } + + public Set getUseNodes(int liveRangeId) { + return useNodes.get(liveRangeId); + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index 5c182781ecc27..9401696f5c53f 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -26,6 +26,7 @@ import com.sun.hotspot.igv.data.InputGraph; import com.sun.hotspot.igv.data.InputNode; import com.sun.hotspot.igv.data.Properties; +import com.sun.hotspot.igv.graph.Diagram; import com.sun.hotspot.igv.graph.LiveRangeSegment; import com.sun.hotspot.igv.util.DoubleClickAction; import com.sun.hotspot.igv.util.DoubleClickHandler; @@ -33,11 +34,12 @@ import com.sun.hotspot.igv.util.PropertiesSheet; import com.sun.hotspot.igv.view.DiagramScene; import com.sun.hotspot.igv.view.DiagramViewModel; - import java.awt.*; import java.util.HashSet; import java.util.Set; - +import javax.swing.JPopupMenu; +import org.netbeans.api.visual.action.ActionFactory; +import org.netbeans.api.visual.action.PopupMenuProvider; import org.netbeans.api.visual.action.WidgetAction; import org.netbeans.api.visual.model.ObjectState; import org.netbeans.api.visual.widget.Widget; @@ -46,7 +48,7 @@ import org.openide.nodes.Node; import org.openide.nodes.Sheet; -public class LiveRangeWidget extends Widget implements Properties.Provider, DoubleClickHandler { +public class LiveRangeWidget extends Widget implements Properties.Provider, PopupMenuProvider, DoubleClickHandler { private final LiveRangeSegment liveRangeSegment; private final DiagramScene scene; @@ -71,6 +73,7 @@ public LiveRangeWidget(LiveRangeSegment liveRangeSegment, DiagramScene scene, in this.next = next; getActions().addAction(new DoubleClickAction(this)); + getActions().addAction(ActionFactory.createPopupMenuAction(this)); updateClientArea(); @@ -156,6 +159,23 @@ private void setHighlighted(boolean enable) { } } + @Override + public JPopupMenu getPopupMenu(Widget widget, Point point) { + JPopupMenu menu = scene.createPopupMenu(); + menu.addSeparator(); + int liveRangeId = liveRangeSegment.getLiveRange().getId(); + Diagram diagram = this.scene.getModel().getDiagram(); + InputGraph graph = diagram.getInputGraph(); + for (InputNode node : graph.getDefNodes(liveRangeId)) { + menu.add(scene.createGotoAction(diagram.getFigure(node))); + } + menu.addSeparator(); + for (InputNode node : graph.getUseNodes(liveRangeId)) { + menu.add(scene.createGotoAction(diagram.getFigure(node))); + } + return menu; + } + @Override public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) { DiagramViewModel model = this.scene.getModel(); From 8a76facc7af11d315012a807f8299763267fadac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 30 Jan 2025 15:34:53 +0100 Subject: [PATCH 24/48] Add pop-up option to select definers and users --- .../com/sun/hotspot/igv/view/DiagramScene.java | 14 ++++++++++++++ .../hotspot/igv/view/widgets/LiveRangeWidget.java | 15 ++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 2f28debfba119..7468029142821 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -608,6 +608,20 @@ public void actionPerformed(ActionEvent e) { return action; } + public Action createGotoAction(String name, Set
figures) { + Action action = new AbstractAction(name) { + @Override + public void actionPerformed(ActionEvent e) { + setFigureSelection(figures); + model.showFigures(model.getSelectedFigures()); + centerSelectedFigures(); + } + }; + + action.setEnabled(true); + return action; + } + private void clearObjects() { Set objectSet = new HashSet<>(getObjects()); for (Object object : objectSet) { diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index 9401696f5c53f..d0fe98030336e 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -27,6 +27,7 @@ import com.sun.hotspot.igv.data.InputNode; import com.sun.hotspot.igv.data.Properties; import com.sun.hotspot.igv.graph.Diagram; +import com.sun.hotspot.igv.graph.Figure; import com.sun.hotspot.igv.graph.LiveRangeSegment; import com.sun.hotspot.igv.util.DoubleClickAction; import com.sun.hotspot.igv.util.DoubleClickHandler; @@ -34,6 +35,7 @@ import com.sun.hotspot.igv.util.PropertiesSheet; import com.sun.hotspot.igv.view.DiagramScene; import com.sun.hotspot.igv.view.DiagramViewModel; + import java.awt.*; import java.util.HashSet; import java.util.Set; @@ -161,11 +163,18 @@ private void setHighlighted(boolean enable) { @Override public JPopupMenu getPopupMenu(Widget widget, Point point) { - JPopupMenu menu = scene.createPopupMenu(); - menu.addSeparator(); - int liveRangeId = liveRangeSegment.getLiveRange().getId(); Diagram diagram = this.scene.getModel().getDiagram(); InputGraph graph = diagram.getInputGraph(); + int liveRangeId = liveRangeSegment.getLiveRange().getId(); + + JPopupMenu menu = scene.createPopupMenu(); + menu.addSeparator(); + Set
figures = new HashSet<>(); + for (InputNode node : graph.getRelatedNodes(liveRangeId)) { + figures.add((diagram.getFigure(node))); + } + menu.add(scene.createGotoAction("Select definer and user nodes", figures)); + menu.addSeparator(); for (InputNode node : graph.getDefNodes(liveRangeId)) { menu.add(scene.createGotoAction(diagram.getFigure(node))); } From 1ce35528fae9e13bbd1ee728f1f882743be247bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Fri, 31 Jan 2025 10:49:36 +0100 Subject: [PATCH 25/48] Add actions to select live ranges for a node --- .../sun/hotspot/igv/view/DiagramScene.java | 29 +++++++++++- .../igv/view/widgets/FigureWidget.java | 46 +++++++++++++++++++ .../igv/view/widgets/LiveRangeWidget.java | 2 +- 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 7468029142821..08a69517db599 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -622,6 +622,33 @@ public void actionPerformed(ActionEvent e) { return action; } + public Action createGotoLiveRangeAction(String name, Set segments) { + Action action = new AbstractAction(name) { + @Override + public void actionPerformed(ActionEvent e) { + setLiveRangeSegmentSelection(segments); + centerSelectedLiveRanges(); + } + }; + + action.setEnabled(true); + return action; + } + + public Action createGotoLiveRangeAction(InputLiveRange liveRange) { + String name = "L" + liveRange.getId(); + Action action = new AbstractAction(name) { + @Override + public void actionPerformed(ActionEvent e) { + setLiveRangeSegmentSelection(liveRangeSegmentSet(Collections.singleton(liveRange))); + centerSelectedLiveRanges(); + } + }; + + action.setEnabled(true); + return action; + } + private void clearObjects() { Set objectSet = new HashSet<>(getObjects()); for (Object object : objectSet) { @@ -1325,7 +1352,7 @@ private void gotoBlock(final Block block) { } } - private Set liveRangeSegmentSet(Collection liveRanges) { + public Set liveRangeSegmentSet(Collection liveRanges) { Set liveRangeIds = new HashSet<>(); for (InputLiveRange liveRange : liveRanges) { liveRangeIds.add(liveRange.getId()); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java index 5578c4505cf29..131331d1c55bf 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java @@ -23,9 +23,13 @@ */ package com.sun.hotspot.igv.view.widgets; +import com.sun.hotspot.igv.data.InputGraph; +import com.sun.hotspot.igv.data.InputLiveRange; +import com.sun.hotspot.igv.data.LivenessInfo; import com.sun.hotspot.igv.data.Properties; import com.sun.hotspot.igv.graph.Diagram; import com.sun.hotspot.igv.graph.Figure; +import com.sun.hotspot.igv.graph.LiveRangeSegment; import com.sun.hotspot.igv.graph.Slot; import com.sun.hotspot.igv.util.DoubleClickAction; import com.sun.hotspot.igv.util.DoubleClickHandler; @@ -317,6 +321,48 @@ public JPopupMenu getPopupMenu(Widget widget, Point point) { menu.addSeparator(); build(menu, getFigure(), this, true, diagramScene); + if (diagramScene.getModel().getShowCFG() && + diagramScene.getModel().getShowLiveRanges()) { + InputGraph graph = diagramScene.getModel().getGraph(); + LivenessInfo l = graph.getLivenessInfoForNode(getFigure().getInputNode()); + if (l != null) { + Set liveRanges = new HashSet<>(); + if (l.def != null) { + liveRanges.add(graph.getLiveRange(l.def)); + } + if (l.use != null) { + for (int use : l.use) { + liveRanges.add(graph.getLiveRange(use)); + } + } + if (l.join != null) { + for (int join : l.join) { + liveRanges.add(graph.getLiveRange(join)); + } + } + if (!liveRanges.isEmpty()) { + Set segments = diagramScene.liveRangeSegmentSet(liveRanges); + menu.addSeparator(); + menu.add(diagramScene.createGotoLiveRangeAction("Select live ranges", segments)); + menu.addSeparator(); + if (l.def != null) { + menu.add(diagramScene.createGotoLiveRangeAction(graph.getLiveRange(l.def))); + } + menu.addSeparator(); + if (l.use != null) { + for (int use : l.use) { + menu.add(diagramScene.createGotoLiveRangeAction(graph.getLiveRange(use))); + } + } + if (l.join != null) { + for (int join : l.join) { + menu.add(diagramScene.createGotoLiveRangeAction(graph.getLiveRange(join))); + } + } + } + } + } + return menu; } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index d0fe98030336e..20010fde2732e 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -173,7 +173,7 @@ public JPopupMenu getPopupMenu(Widget widget, Point point) { for (InputNode node : graph.getRelatedNodes(liveRangeId)) { figures.add((diagram.getFigure(node))); } - menu.add(scene.createGotoAction("Select definer and user nodes", figures)); + menu.add(scene.createGotoAction("Select nodes", figures)); menu.addSeparator(); for (InputNode node : graph.getDefNodes(liveRangeId)) { menu.add(scene.createGotoAction(diagram.getFigure(node))); From 4043b61c8aa1c1dd5a36f2f86a8a4f33f05f5670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Fri, 31 Jan 2025 11:47:16 +0100 Subject: [PATCH 26/48] Add pretty icons --- .../com/sun/hotspot/igv/view/DiagramScene.java | 12 ++++++++---- .../igv/view/widgets/LiveRangeWidget.java | 2 +- .../sun/hotspot/igv/view/images/liveRange.png | Bin 0 -> 5092 bytes .../hotspot/igv/view/images/selectLiveRanges.png | Bin 0 -> 5135 bytes .../sun/hotspot/igv/view/images/selectNodes.png | Bin 0 -> 5231 bytes 5 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/liveRange.png create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/selectLiveRanges.png create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/selectNodes.png diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 08a69517db599..3528187c0c559 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -59,6 +59,7 @@ import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Sheet; +import org.openide.util.ImageUtilities; import org.openide.util.Lookup; import org.openide.util.lookup.AbstractLookup; import org.openide.util.lookup.InstanceContent; @@ -608,8 +609,9 @@ public void actionPerformed(ActionEvent e) { return action; } - public Action createGotoAction(String name, Set
figures) { - Action action = new AbstractAction(name) { + public Action createGotoNodesAction(String name, Set
figures) { + String iconResource = "com/sun/hotspot/igv/view/images/selectNodes.png"; + Action action = new AbstractAction(name, new ImageIcon(ImageUtilities.loadImage(iconResource))) { @Override public void actionPerformed(ActionEvent e) { setFigureSelection(figures); @@ -623,7 +625,8 @@ public void actionPerformed(ActionEvent e) { } public Action createGotoLiveRangeAction(String name, Set segments) { - Action action = new AbstractAction(name) { + String iconResource = "com/sun/hotspot/igv/view/images/selectLiveRanges.png"; + Action action = new AbstractAction(name, new ImageIcon(ImageUtilities.loadImage(iconResource))) { @Override public void actionPerformed(ActionEvent e) { setLiveRangeSegmentSelection(segments); @@ -637,7 +640,8 @@ public void actionPerformed(ActionEvent e) { public Action createGotoLiveRangeAction(InputLiveRange liveRange) { String name = "L" + liveRange.getId(); - Action action = new AbstractAction(name) { + String iconResource = "com/sun/hotspot/igv/view/images/liveRange.png"; + Action action = new AbstractAction(name, new ImageIcon(ImageUtilities.loadImage(iconResource))) { @Override public void actionPerformed(ActionEvent e) { setLiveRangeSegmentSelection(liveRangeSegmentSet(Collections.singleton(liveRange))); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index 20010fde2732e..1937c89ad25fe 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -173,7 +173,7 @@ public JPopupMenu getPopupMenu(Widget widget, Point point) { for (InputNode node : graph.getRelatedNodes(liveRangeId)) { figures.add((diagram.getFigure(node))); } - menu.add(scene.createGotoAction("Select nodes", figures)); + menu.add(scene.createGotoNodesAction("Select nodes", figures)); menu.addSeparator(); for (InputNode node : graph.getDefNodes(liveRangeId)) { menu.add(scene.createGotoAction(diagram.getFigure(node))); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/liveRange.png b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/liveRange.png new file mode 100644 index 0000000000000000000000000000000000000000..b9f06161d8bdb6247e7d48e83cbe8be991dfcf51 GIT binary patch literal 5092 zcmeHKX;c$g77i^c(t-;pGzyl5fGt#(%AQU{B>{p4n1Bkxv{ovWP?C+L0s+MhcW~bo z7sLg{9T0cLR#9n}9&H_M9Ti)kT^b$RrQ3yh6%g@spEJif<3CfUl6v>u`@MU=d*4mH zS@E$^9`1hb3&rS)&YF?dD?_A813Mk#3V|MWkD9JSw|WOh|0DQ5aA$o z42I+Sqh%=z9|m`xek)nAbW*>mC#>w{TOUF-7rLBU^Na0#V(_vV(()~Wq@_VcaeGR? z`@Om`@b&b(;!X1}OP3V}&P`O`nLVxgf#}K#&8Yg^ZjC4NrBb0UTorbexPyfEtzP-u zel51)%25y5ngJvJ$SA&ognxUlT5$SpagqPzi}%FO-y9S4I}{jm)&5hrd$rH^RQzji zeYxW8lcAbI{-U5luc)%rU72&w%)cFYeX4SEOHoa2LNt6H{(ZK(E^ebH zxKPpmaq9W}a#QNof4axRuJTcPi~ZJWC!9YQHTQ_`^6lO3oE~|^xlpI)d8B2612+q&Vq^3<5@kbmmijU zzd6&Rw)WcUnQ-^V7dnlFhTtK?M^0&ca+kB;-R*u%8J@=vxPxZ&&-GpwcJT|v$?Z)cB_leuF z=H`vV4kXoerx|IuRJ(EUs5|AyttT(_aIXj$e|mwZ?BCdoK0&=JipGx`d)-=Ax4r!O z{-IHMFK%of$2z=*TEF-_b$>vwe?O?e%VpnWznMk5LdqHzcaO6!`szqjgFE56#VdBRva{WyBoj8;^jJnnD1-Eka-yS>-{h{aXQV+elc-<>Y({E?Lt*?JpBYwT) zcvgL7QQNEOXb~r};iZr7Ti5oTPKMamXY^q(T&9u{5%J21huXXh8+9%Xr~-+ljf?Y7dqQpoM? zqbCpGk0-u1!yNAYkHs0*$Hpl(awjIfXE*ZJ2ht0fpW2 zXZ6{?!}0pm{)RorxW&3)SzPa+p85XUD0b)yzbD=q!+xaB`s@iPEvyu!FY!yix#%c+ z;nk5#_s6FDD#J9Ly36~Q6cxA|PLNlXyXS9uI(6Q})6a(ftUf)wLtyn6TQ5QfCp->+ zDN8A3i|+&}x(|Ahe|LPr7e#+xmz-7Dh*y(q7*+b)G3HmL9%Jej{g#uG@9&cP)3KBG zl!WJ#YW&AMJ~Ll+ZON4KsY6^G;l<{&E^jIaInJ$0dC+@vmqF8YOAferdQRRA6FXlW zI=IB0=gT6Aq{s}Fg%^0 zAPu1>O)|Lg;87SNwK8}lU&U5gB8W6HI>$;Rz(`OSo8nHIBP$f-i5%ittcJQQKJ5)hBcW3my2gUm$Xf$oshs?|x<^2inlFp|M( z6lIaHSXo(F%q%X`Y}KJZK5y-VzLF&5X~5J!iHN(3q_hu5RHjx z%yvo!!(bkI=bzD{QnkXHY%MGRK3ERS!s0O5ETfUt*1|?9G66`7Lw{*uO9X!cEHz;> z+pRdE$RtcuU|R?+-fC~LTMf=|v^a|}5JsSC1FLdASTahfif^@`DbSNfi_;2_{edP$ z>fV#}fp7GTGn}@L0P|Md547LK?o6fcCRgAzr_&+tG>N#t-OJidf02n9oS z8-25u)MfuSZF=)S(&m&$lQyt^wo}x+qY{XW=27#|KsvV)1UWZ_1jCy{uwj{m*6Am} zYM#Q=Fq57D-J_*k-^t0pC#ODe*BC+U0bema6 zWnorgupaOTxB}(rf7{C=kEGhH9Wz(*;6uCC8? zeG~&9rTn?N{%>@-zdtb&Ch(${1_{n9ijKdy^l?Y}UHhhD91wj)DUzrNvynb{Fr4qhgciyosWgawA09c` z(+4PpDCL6_MK$;s-?U>h6%WI|&RL%J=y=oARQc{NBRzaOcj)|faWp_9%3ZyWWL%ic1xjO5X%TJncE(@jIXYnK_fpyYJrLyZ3kR zyP2006%pFqrLPMFLESZBs%Y@rgTI}-fbahInn?)i=$RQC$3>Iru*GU-*kl^!GAuMq z+gS#J?5A!m(#^Z+{q|?);?-YH9gtmZ#l9-J3D+Hcr)K$e+mTrBMV|*$e&+|T8*pEf zmP#}?Wo4hUq@3tAZ^_kpw(5n$e8%F9_D}YI9}|9K$G|%t+YapAxU0uonN{D+-10QL zA9d>9hP-3jn@8P`D{;HNe`uL*^0wOivVy-t)u%fa)md*onN}8NpSYkrF+MI(ujt+Kr&#Q}GHF`+@-O8O?#FH+@gdu+*kM2fa ziCkSg@Qiv;W4|MsJ(YTS*{;wP+1(l|lY?c0cR%g7G~X>NCF^S3yCF4l|0%@}=E4<^ z?##Z{?NP*x&zD@?4p+oclOK<()tJ=}rw61pZKTcl4X#xODgFLy@BM*)pP!moSp3cG zxXW2EsKt`;SXpjMk0y%vV-N)Yo>RvqPVybUSyJ zs9Eb(d@XYAdDo-AXS>dwIwh^X3nER6O6}Za3jB0_>C_eF*nb3Zm);fj{`{v<>%k6a z{hDhPB?E8hoQ8Hf?vfBSCP(i*qPFqCS9#9UIH<(p-cZxkxxgo#IJjod+r%0{eT^g} z$=7$Be%nZ|&L=E=Ixa`E__Xr=j zUXWRDv^tG=8o9Oey?uGjXchKj*8DR^&rDXA9j#F5s>{WNL3z`E-~0Ib!tFAh_!`;f9<{-hzuDVq%rj?x4NKi@83lN4snRfg@2 z>NPVmW_7fWpii%N4@E7zS&YmXGZTq*-ZZpS;4S)VhIe;O?yQyP$5jsa~!YxG7!oEpo z=kLVkogDpTRYa1T=41U^JynC&6wP)?u4Yea))#zpFFSwAfj@^|jy^E5i|76hCCA_& zCN~B)DRrfo{DPOd=a7f9E=`))gjT9xTxQx^Q}B_E0B#;7W6?(_dSL*bgt&-RSr2J3~HW7Jly}5KLQ- z&=pU%{qU{L)cm0G%EOKuA?vQ(keHqjB+#*-eZ^_R6_nX1Bn@UgEwmdgpuIs*K%m`1 zQb{xi>*)m6q(pB2uoHn`>v7lt`R53Jx|~X;>7*RYG4%6s*qL) zFj69k9A{C8MCs}2!gPtyY)ug1a=BcDiA7>D3N%n#hKVEXsLAHZL$qM1Xd7i^EgWk$ z!8|6ZH>Yw+1OfB#bN`GMt+ox`WNT#s@FB9377;GQL`I{iy@icarvZ>whyK;V77P9b zMA5X(oNA?LbsBBrJljJUs5W~`sx{dWj)4-<$+Quu+Q6##OG}1ov{7vqJOv4?(c-WI zWWS`zvCIpyUh<8fafH*}5n$ei`;zwa*d5A1ORH6=%v37xo<^la`1KVAGsPMdjz@n3 zB@r`n8r2gxhDs&=1gfWH3@Vd|F^U#57)40hL1|1jjx*dUS14KhDcFLyv0C`E|bY9v8AStFT1i!7!D#{^HfA}C6uM8rbug(NDObLYB46o{0SL>zfc-QTWz2cc}yG=N?M}f)1m;u0AfkL zP62?!0>q*Sw$dbLw#J&x$x4KG3Fa-^rnO)@8Ay&)ksJ*`F|ka6;R*>Ji{lEZL?M>? zf+5yU-)vx+jQ^(1Zyq?HCFNnP4XmHx5Vh>67&@h8)G|zF9a{;89h*WyQY|6a$TZsE z@DpIQOi_uXDS-yvqqSV0%h`V^1v!b6I4zZ;QbHm}r66snULq#=YQhPb#2+W*#LMV5 zGsC5mRyrsF@Cdj9<>}xG9^^>WM=xuqC(?WtFtHQ`)hd?8VseE{su0V3F)>e===Fz4 zNevWXAmpe&&G@5I5|^QJIYFS99@pz}O2%OREs1L*@P7 z8@gVJfmc#~Q(gZzx?EnI7-x=*tzG)=AFq~ehJD`&nnH`b1b~m7t6PPrO_b1TYbo}pL%|> zZXz@=Jn6!!du3gJESUP?koE4loqAdKc#xfk3+6T3y+0Zl8s4y8(5Lw7`@I1;q)|tx J%7>1h{x{uhfGGd~ literal 0 HcmV?d00001 diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/selectNodes.png b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/selectNodes.png new file mode 100644 index 0000000000000000000000000000000000000000..73de4eb899362e7b00f935e867eef7e6ea0b3f25 GIT binary patch literal 5231 zcmeHKc~lcu7Y{B72#S^}Rgg5OMKH-^gCr6`0z!}=LJBCK$|RYD5weg>LO^g~YZcs! zm5K{RWK$Fbks=DMphB&zZWOgruqcWiDQI2zUV;mr_MGo{&e#8(oFwz^yZ86*{oVWS zyxA1s?`>f=!wiSRS@3*31Hr$g{%c|ke(jzN!#Lcyz&JrD76`}Sl`4e24ei2`jztVE*E&qr~*gtvo3npvXvm*AGuQ<`UxVq0mI}qD>{?p{4 z$5lD@fgYDTXB{f*d)B=FTQ1SfmN+i8;zD7uY2%LOi90$UHhTP?ll)a~dnus<+1YXV zyMxtFY~~jS7g@%8t}ZJzioar1Hr+PQzG6z8_2Bb_eB-&D<}*`@DC@Xr{pHN$-O-Fx z-nNIQN+AE%*{c@$y5m|-jhUm_9((!HmYiK(4W(9z1J1^`3baeMpMSxOix;j&mHBhm zaiDFbj_b?F5Bjv;&&R6IH4p8`wb^0Uw{=2NMbg9Wht<9Z(&`;|{(1YyV_pxIWOC9Q zlj>NFUFHp+lm<6_COtRLu^=(4u<&3D^{*X_vi_(_)tz5tCsQWkS9D_TMVilLhnL|4 z+mN0V+b?2l{pjr`)Wbj9lrFXl)unEs{Rdu_AwbOA&86w{&Mxe|S98;wNO5AF8bjg~ ze&S%oebpRpZS~t3AI+}YFJHu(ue7kjc1dc->}n{hys%Yq5jossJl6Kc(R-}6Zk*NU zWn-sV{u>E=qYvbL32LqD&;x+TL zQ>#sz=6*M>KdM z)3#1ua4ksUN=T>HacGElGEYGOLBHD3s-NA#hBP;K6 zt8#5N)}8%+=J?DXdWVZ_EP6?fLq|HC+VAO>d{b~OI5kOt1SIHg&PI7%f5zQt=`iA4 z?8$NJD4CM`>~;ZT&e|LG?Q5!zqXn0wl}RV&FJ0H|I<9(a^tm;~QN>OsKl;a-W%!q@ zGtD@2sLRSRVd?$I`~l9x!eFAm;0u>fS!_-u!H0CQ-D>< z(xBWx$4S$yru-bRukU-p))grPfl0YX(WJTLmq~Lic$?F5Zm&>2l9t@NedkC~QW4(d z)rM0O{Wp^W?hC(ec2a-m1d}ahtw)NNySK_{`~1GX{%fIioEOgCM1+gZ zTwb3wJNI_j>Y+BiX8PUbuM*Y=AN#Jt+R}29G!wpYZsxhxy(ep94=@{iOMT=0UF9v~ zH`!Gd>t57X{!v;(%aP3GEVY?4EzR}_203NUcx)Bz*N!zzFP&ACRl$tRm=W2z>nybM zYRK+N|43`ze4*)7Plx>MbhD^)=v7|H_QOw-x2?bM=aSz8FMMfie|}716TWKQBe$oV zup)@{+Z?Z{?n7x^@#$l-R~}p*lhrRekM76SN^koro)=k!_v{*o3rn*#O6aJm(}V>L zZfLX(e{^v>|9VDZS+a+b&MimLVDz%WU3Y13*nOM4$?mC=j3109P1;yOK#n~>U6rSn z4-c0042?a3Q`Kx<95fX?1#~Fr_Mv<~wn!l(!D59FA?ajF@HD{TT-|g^SQLq1cp)N1 z|t73_iqHa*+tsCr*U~#rX?FagidHnBcb1%vHw*05SxF@j6+QT+P;T z2nJj>xYvux1iV27i{ubO`2l#YLWSVzBsvKqdg)Ltm9WqZ@2V0@*nyslUqgTqhY*2b zN;a7s6B9#oYLN<6VyHrn*JHv$ zg$Cmg2w)!n#y^>o&wmRqSHETf@IltWN-~86k!3RSXbUywr3E0b9r{NLwE#Rc$$^Mk zp;3ttFD)X+>_75f>VO64Hq< z1XGAik&9SNqp|4DE)oNjSj1keP|0ABPE-a<5wcP)HB9IUXD4A+uzsvTG_s?Dkm!-o$S?{uY$ZJ2uqoKEXe0zR ztVP5IKLOUrlqdq0OA*jLUYF||Ir_N@Vqg`rND6oaT!Hd5aD{g;Bx>IK+A$G`J_~>_B19qnoiOt2fXVuv@g`zd z^4~adH7JZ~GQe&`2AUV>h2*!*@HJ=pw(~DuuXFJ)t^lAvF7iSAex&OoT_4222PuE7 zu8(wm5Cb2i{IR)dAoqbROz!^ zjl+@b^XjoZ+yDi19Hf7J=6v z7DF~pnhun}A$yU4*(ef+hd;f%VJ1Yi#LYJcS3kQ2nw{(@p;(UHW9=}`YG#cOY7I4Y zj2~{U3$+H=B;$UzjQ1cmMzZ literal 0 HcmV?d00001 From 77bdc773f37926b2ac70ab2fd380f54458b9f940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Fri, 31 Jan 2025 13:27:08 +0100 Subject: [PATCH 27/48] Restart filter defaults --- .../resources/com/sun/hotspot/igv/servercompiler/layer.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml index 155ab64b71646..3627b9d6899d1 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml @@ -86,11 +86,11 @@ - + - + From 0a321e9f35dc443a31d7d6c27a030f620aa239a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Wed, 5 Feb 2025 16:24:24 +0100 Subject: [PATCH 28/48] Fix live range selection/deselection inconsistencies --- .../hotspot/igv/graph/LiveRangeSegment.java | 10 ++++++ .../sun/hotspot/igv/view/DiagramScene.java | 2 +- .../igv/view/widgets/LiveRangeWidget.java | 35 +++++++++++-------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java index 2eed887981dee..1fad2a57e2c04 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java @@ -27,6 +27,7 @@ import com.sun.hotspot.igv.data.Properties; import com.sun.hotspot.igv.layout.Segment; import java.awt.Point; +import java.util.Set; public class LiveRangeSegment extends Properties.Entity implements Segment { @@ -38,6 +39,7 @@ public class LiveRangeSegment extends Properties.Entity implements Segment { private Point endPoint; private boolean lastOfLiveRange; private boolean instantaneous; + private Set segmentSet; protected LiveRangeSegment(InputLiveRange liveRange, Block block, Figure start, Figure end) { this.block = block; @@ -100,6 +102,14 @@ public boolean isInstantaneous() { return instantaneous; } + public Set getSegmentSet() { + return segmentSet; + } + + public void setSegmentSet(Set segmentSet) { + this.segmentSet = segmentSet; + } + @Override public String toString() { return "LiveRangeSegment(" + liveRange + "@B" + block + ", " + start + ", " + end + ")"; diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 3528187c0c559..26569789d1eba 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -1576,6 +1576,7 @@ private void rebuildSegmentLayer() { LiveRangeWidget firstSegmentWidget = null; LiveRangeWidget nextSegmentWidget = null; for (LiveRangeSegment segment : segmentSet) { + segment.setSegmentSet(segmentSet); segment.setStartPoint(null); segment.setEndPoint(null); LiveRangeWidget segmentWidget = @@ -1585,7 +1586,6 @@ private void rebuildSegmentLayer() { firstSegmentWidget = segmentWidget; } addObject(segment, segmentWidget); - segmentWidget.getActions().addAction(selectAction); segmentWidget.getActions().addAction(hoverAction); segmentLayer.addChild(segmentWidget); nextSegmentWidget = segmentWidget; diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index 1937c89ad25fe..e1ad9149ec42b 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -35,6 +35,7 @@ import com.sun.hotspot.igv.util.PropertiesSheet; import com.sun.hotspot.igv.view.DiagramScene; import com.sun.hotspot.igv.view.DiagramViewModel; +import com.sun.hotspot.igv.view.actions.CustomSelectAction; import java.awt.*; import java.util.HashSet; @@ -42,6 +43,7 @@ import javax.swing.JPopupMenu; import org.netbeans.api.visual.action.ActionFactory; import org.netbeans.api.visual.action.PopupMenuProvider; +import org.netbeans.api.visual.action.SelectProvider; import org.netbeans.api.visual.action.WidgetAction; import org.netbeans.api.visual.model.ObjectState; import org.netbeans.api.visual.widget.Widget; @@ -61,7 +63,6 @@ public class LiveRangeWidget extends Widget implements Properties.Provider, Popu private static final float NORMAL_THICKNESS = 1.4f; private static final float SELECTED_THICKNESS = 2.2f; private boolean highlighted; - private boolean selected; private static final Color NORMAL_COLOR = Color.BLACK; private static final Color HIGHLIGHTED_COLOR = Color.BLUE; @@ -91,6 +92,23 @@ protected Sheet createSheet() { node.setDisplayName("L" + liveRangeSegment.getLiveRange().getId()); this.setToolTipText(PropertiesConverter.convertToHTML(liveRangeSegment.getProperties())); + + getActions().addAction(new CustomSelectAction(new SelectProvider() { + @Override + public boolean isAimingAllowed(Widget widget, Point localLocation, boolean invertSelection) { + return true; + } + + @Override + public boolean isSelectionAllowed(Widget widget, Point localLocation, boolean invertSelection) { + return true; + } + + @Override + public void select(Widget widget, Point localLocation, boolean invertSelection) { + scene.userSelectionSuggested(liveRangeSegment.getSegmentSet(), invertSelection); + } + })); } public void setLength(int length) { @@ -119,6 +137,7 @@ protected void paintWidget() { } Graphics2D g = getScene().getGraphics(); g.setPaint(this.getBackground()); + boolean selected = scene.getSelectedObjects().contains(liveRangeSegment); g.setStroke(new BasicStroke(selected ? SELECTED_THICKNESS : NORMAL_THICKNESS)); g.setColor(highlighted ? HIGHLIGHTED_COLOR : NORMAL_COLOR); g.drawLine(- RANGE_WIDTH, 0, RANGE_WIDTH, 0); @@ -131,25 +150,11 @@ protected void paintWidget() { @Override protected void notifyStateChanged(ObjectState previousState, ObjectState state) { super.notifyStateChanged(previousState, state); - if (previousState.isSelected() != state.isSelected()) { - setSelected(state.isSelected()); - } if (previousState.isHighlighted() != state.isHighlighted()) { setHighlighted(state.isHighlighted()); } } - private void setSelected(boolean enable) { - if (enable == selected) { - return; // end recursion - } - selected = enable; - revalidate(true); - if (next != null) { - next.setSelected(enable); - } - } - private void setHighlighted(boolean enable) { if (enable == highlighted) { return; // end recursion From 9ea960ebac98d46a74323e329c5e285019524d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 6 Feb 2025 22:14:05 +0100 Subject: [PATCH 29/48] Simplify live range highlighting --- .../sun/hotspot/igv/view/DiagramScene.java | 12 ++------ .../igv/view/widgets/LiveRangeWidget.java | 29 ++++++------------- 2 files changed, 11 insertions(+), 30 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 26569789d1eba..af88c6f8470dd 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -1573,24 +1573,16 @@ private void rebuildSegmentLayer() { segments.get(liveRangeId).add(segment); } for (Set segmentSet : segments.values()) { - LiveRangeWidget firstSegmentWidget = null; - LiveRangeWidget nextSegmentWidget = null; for (LiveRangeSegment segment : segmentSet) { - segment.setSegmentSet(segmentSet); segment.setStartPoint(null); segment.setEndPoint(null); - LiveRangeWidget segmentWidget = - new LiveRangeWidget(segment, this, 0, nextSegmentWidget); + segment.setSegmentSet(segmentSet); + LiveRangeWidget segmentWidget = new LiveRangeWidget(segment, this, 0); segmentWidget.setVisible(false); - if (firstSegmentWidget == null) { - firstSegmentWidget = segmentWidget; - } addObject(segment, segmentWidget); segmentWidget.getActions().addAction(hoverAction); segmentLayer.addChild(segmentWidget); - nextSegmentWidget = segmentWidget; } - firstSegmentWidget.setNext(nextSegmentWidget); } } } diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index e1ad9149ec42b..79ad52efb7f20 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -57,7 +57,6 @@ public class LiveRangeWidget extends Widget implements Properties.Provider, Popu private final LiveRangeSegment liveRangeSegment; private final DiagramScene scene; private int length; - private LiveRangeWidget next; private Rectangle clientArea; private final Node node; private static final float NORMAL_THICKNESS = 1.4f; @@ -68,12 +67,11 @@ public class LiveRangeWidget extends Widget implements Properties.Provider, Popu private static final int RANGE_WIDTH = 4; - public LiveRangeWidget(LiveRangeSegment liveRangeSegment, DiagramScene scene, int length, LiveRangeWidget next) { + public LiveRangeWidget(LiveRangeSegment liveRangeSegment, DiagramScene scene, int length) { super(scene); this.liveRangeSegment = liveRangeSegment; this.scene = scene; this.length = length; - this.next = next; getActions().addAction(new DoubleClickAction(this)); getActions().addAction(ActionFactory.createPopupMenuAction(this)); @@ -92,7 +90,6 @@ protected Sheet createSheet() { node.setDisplayName("L" + liveRangeSegment.getLiveRange().getId()); this.setToolTipText(PropertiesConverter.convertToHTML(liveRangeSegment.getProperties())); - getActions().addAction(new CustomSelectAction(new SelectProvider() { @Override public boolean isAimingAllowed(Widget widget, Point localLocation, boolean invertSelection) { @@ -121,10 +118,6 @@ private void updateClientArea() { clientArea.grow(RANGE_WIDTH * 2, RANGE_WIDTH * 2); } - public void setNext(LiveRangeWidget next) { - this.next = next; - } - @Override protected Rectangle calculateClientArea() { return clientArea; @@ -140,6 +133,9 @@ protected void paintWidget() { boolean selected = scene.getSelectedObjects().contains(liveRangeSegment); g.setStroke(new BasicStroke(selected ? SELECTED_THICKNESS : NORMAL_THICKNESS)); g.setColor(highlighted ? HIGHLIGHTED_COLOR : NORMAL_COLOR); + if (highlighted) { + g.setStroke(new BasicStroke(2)); + } g.drawLine(- RANGE_WIDTH, 0, RANGE_WIDTH, 0); if (length != 0) { g.drawLine(0, 0, 0, length); @@ -151,18 +147,11 @@ protected void paintWidget() { protected void notifyStateChanged(ObjectState previousState, ObjectState state) { super.notifyStateChanged(previousState, state); if (previousState.isHighlighted() != state.isHighlighted()) { - setHighlighted(state.isHighlighted()); - } - } - - private void setHighlighted(boolean enable) { - if (enable == highlighted) { - return; // end recursion - } - highlighted = enable; - revalidate(true); - if (next != null) { - next.setHighlighted(enable); + for (LiveRangeSegment segment : liveRangeSegment.getSegmentSet()) { + LiveRangeWidget figureWidget = scene.getWidget(segment); + figureWidget.highlighted = state.isHighlighted(); + figureWidget.revalidate(true); + } } } From 7992c0448b41b1b9eb2b6c39826c8d7ba100138a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Fri, 7 Feb 2025 15:13:00 +0100 Subject: [PATCH 30/48] Add basic filter support for live ranges --- .../igv/filter/ColorLiveRangeFilter.java | 97 +++++++++++++++++++ .../com/sun/hotspot/igv/filter/helper.js | 12 +++ .../igv/graph/LiveRangeMatcherSelector.java | 44 +++++++++ .../hotspot/igv/graph/LiveRangeSegment.java | 11 +++ .../hotspot/igv/graph/LiveRangeSelector.java | 30 ++++++ .../filters/colorLiveRanges.filter | 3 + .../sun/hotspot/igv/servercompiler/layer.xml | 10 +- .../igv/view/widgets/LiveRangeWidget.java | 2 +- 8 files changed, 205 insertions(+), 4 deletions(-) create mode 100644 src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/ColorLiveRangeFilter.java create mode 100644 src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeMatcherSelector.java create mode 100644 src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSelector.java create mode 100644 src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/colorLiveRanges.filter diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/ColorLiveRangeFilter.java b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/ColorLiveRangeFilter.java new file mode 100644 index 0000000000000..14fb9461c9721 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/java/com/sun/hotspot/igv/filter/ColorLiveRangeFilter.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.filter; + +import com.sun.hotspot.igv.graph.*; +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; + +public class ColorLiveRangeFilter extends AbstractFilter { + + private List colorRules; + private String name; + + public ColorLiveRangeFilter(String name) { + this.name = name; + colorRules = new ArrayList<>(); + } + + @Override + public String getName() { + return name; + } + + @Override + public void apply(Diagram diagram) { + for (ColorRule rule : colorRules) { + if (rule.getSelector() != null) { + List segments = rule.getSelector().selected(diagram); + for (LiveRangeSegment s : segments) { + applyRule(rule, s); + if (rule.getColor() != null) { + s.setColor(rule.getColor()); + } + } + } else { + for (LiveRangeSegment s : diagram.getLiveRangeSegments()) { + applyRule(rule, s); + } + } + } + } + + private void applyRule(ColorRule rule, LiveRangeSegment s) { + if (rule.getColor() != null) { + s.setColor(rule.getColor()); + } + } + + public void addRule(ColorRule r) { + colorRules.add(r); + } + + public static class ColorRule { + + private Color color; + private LiveRangeSelector selector; + + public ColorRule(LiveRangeSelector selector, Color c) { + this.selector = selector; + this.color = c; + } + + public ColorRule(Color c) { + this(null, c); + } + + public Color getColor() { + return color; + } + + public LiveRangeSelector getSelector() { + return selector; + } + } +} diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js b/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js index 802fc00297189..fbce14124dc2b 100644 --- a/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js @@ -230,3 +230,15 @@ function removeBlock(selector) { f.addRule(new RemoveBlockFilter.RemoveBlockRule(selector)); f.apply(graph); } + +// Color the selected live ranges. +function colorizeLiveRange(selector, color) { + var f = new ColorLiveRangeFilter(""); + f.addRule(new ColorLiveRangeFilter.ColorRule(selector, color)); + f.apply(graph); +} + +// Select the live ranges whose given property matches a given regular expression. +function matchesLiveRange(property, regexp) { + return new LiveRangeMatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)); +} diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeMatcherSelector.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeMatcherSelector.java new file mode 100644 index 0000000000000..5fc456535fa9f --- /dev/null +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeMatcherSelector.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.graph; + +import com.sun.hotspot.igv.data.Properties; +import com.sun.hotspot.igv.data.Properties.PropertyMatcher; +import java.util.List; + +public class LiveRangeMatcherSelector implements LiveRangeSelector { + + private PropertyMatcher matcher; + + public LiveRangeMatcherSelector(PropertyMatcher matcher) { + this.matcher = matcher; + } + + @Override + public List selected(Diagram d) { + Properties.PropertySelector selector = new Properties.PropertySelector<>(d.getLiveRangeSegments()); + List list = selector.selectMultiple(matcher); + return list; + } +} diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java index 1fad2a57e2c04..11ba5e53d390f 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java @@ -26,6 +26,7 @@ import com.sun.hotspot.igv.data.InputLiveRange; import com.sun.hotspot.igv.data.Properties; import com.sun.hotspot.igv.layout.Segment; +import java.awt.Color; import java.awt.Point; import java.util.Set; @@ -40,6 +41,7 @@ public class LiveRangeSegment extends Properties.Entity implements Segment { private boolean lastOfLiveRange; private boolean instantaneous; private Set segmentSet; + private Color color; protected LiveRangeSegment(InputLiveRange liveRange, Block block, Figure start, Figure end) { this.block = block; @@ -48,6 +50,7 @@ protected LiveRangeSegment(InputLiveRange liveRange, Block block, Figure start, this.end = end; assert(start == null || end == null || (start.getBlock() == end.getBlock())); lastOfLiveRange = true; + this.color = Color.BLACK; } public InputLiveRange getLiveRange() { @@ -110,6 +113,14 @@ public void setSegmentSet(Set segmentSet) { this.segmentSet = segmentSet; } + public void setColor(Color color) { + this.color = color; + } + + public Color getColor() { + return color; + } + @Override public String toString() { return "LiveRangeSegment(" + liveRange + "@B" + block + ", " + start + ", " + end + ")"; diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSelector.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSelector.java new file mode 100644 index 0000000000000..777bc81286e93 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSelector.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.graph; + +import java.util.List; + +public interface LiveRangeSelector { + List selected(Diagram d); +} diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/colorLiveRanges.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/colorLiveRanges.filter new file mode 100644 index 0000000000000..4e5883ab7555d --- /dev/null +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/colorLiveRanges.filter @@ -0,0 +1,3 @@ +// Fade out live ranges allocated to stack lots. + +colorizeLiveRange(matchesLiveRange("mask", "\\[rS.+\\]"), Color.LIGHT_GRAY); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml index 3627b9d6899d1..db4682f1cab86 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml @@ -85,13 +85,17 @@ - - + + + + + + - + diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index 79ad52efb7f20..c015c7f11f9ff 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -132,7 +132,7 @@ protected void paintWidget() { g.setPaint(this.getBackground()); boolean selected = scene.getSelectedObjects().contains(liveRangeSegment); g.setStroke(new BasicStroke(selected ? SELECTED_THICKNESS : NORMAL_THICKNESS)); - g.setColor(highlighted ? HIGHLIGHTED_COLOR : NORMAL_COLOR); + g.setColor(highlighted ? HIGHLIGHTED_COLOR : liveRangeSegment.getColor()); if (highlighted) { g.setStroke(new BasicStroke(2)); } From 4f89c6ee06ce503a9ab5882684384b122bde443d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Fri, 7 Feb 2025 15:14:53 +0100 Subject: [PATCH 31/48] Remove unused definition --- .../java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index c015c7f11f9ff..b784e4a22a25f 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -62,7 +62,6 @@ public class LiveRangeWidget extends Widget implements Properties.Provider, Popu private static final float NORMAL_THICKNESS = 1.4f; private static final float SELECTED_THICKNESS = 2.2f; private boolean highlighted; - private static final Color NORMAL_COLOR = Color.BLACK; private static final Color HIGHLIGHTED_COLOR = Color.BLUE; private static final int RANGE_WIDTH = 4; From 4d36f221b32460bc0b71501a49edaf7b897e2940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Fri, 7 Feb 2025 15:28:14 +0100 Subject: [PATCH 32/48] Close live ranges only on first definitions and kills --- .../com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index b784e4a22a25f..7450ce060cbb4 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -135,10 +135,14 @@ protected void paintWidget() { if (highlighted) { g.setStroke(new BasicStroke(2)); } - g.drawLine(- RANGE_WIDTH, 0, RANGE_WIDTH, 0); + if (liveRangeSegment.getStart() != null) { + g.drawLine(-RANGE_WIDTH, 0, RANGE_WIDTH, 0); + } if (length != 0) { g.drawLine(0, 0, 0, length); - g.drawLine(- RANGE_WIDTH, length, RANGE_WIDTH, length); + if (liveRangeSegment.getEnd() != null) { + g.drawLine(-RANGE_WIDTH, length, RANGE_WIDTH, length); + } } } From 7a3e992ae08b12c4e4dfd3d09adbcb7459aa9fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Fri, 7 Feb 2025 16:47:15 +0100 Subject: [PATCH 33/48] Complete dump of live range properties --- src/hotspot/share/opto/idealGraphPrinter.cpp | 63 ++++++++++++++++++-- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/src/hotspot/share/opto/idealGraphPrinter.cpp b/src/hotspot/share/opto/idealGraphPrinter.cpp index 61e9b2e71d92a..e78178b50d7a9 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.cpp +++ b/src/hotspot/share/opto/idealGraphPrinter.cpp @@ -932,23 +932,76 @@ void IdealGraphPrinter::print(const char* name, Node* node, GrowableArraylrgs(i); + buffer[0] = 0; + stringStream lrg_mask_stream(buffer, sizeof(buffer) - 1); + lrg.mask().dump(&lrg_mask_stream); + print_prop("mask", buffer); + print_prop("mask_size", lrg.mask_size()); if (lrg._degree_valid) { print_prop("degree", lrg.degree()); } print_prop("num_regs", lrg.num_regs()); print_prop("reg_pressure", lrg.reg_pressure()); + print_prop("cost", lrg._cost); + print_prop("area", lrg._area); print_prop("score", lrg.score()); - print_prop("mask_size", lrg.mask_size()); if (lrg._risk_bias != 0) { print_prop("risk_bias", lrg._risk_bias); } if (lrg._copy_bias != 0) { print_prop("copy_bias", lrg._copy_bias); } - buffer[0] = 0; - stringStream lrg_mask_stream(buffer, sizeof(buffer) - 1); - lrg.mask().dump(&lrg_mask_stream); - print_prop("mask", buffer); + if (lrg.is_singledef()) { + print_prop("is_singledef", TRUE_VALUE); + } + if (lrg.is_multidef()) { + print_prop("is_multidef", TRUE_VALUE); + } + if (lrg._is_oop) { + print_prop("is_oop", TRUE_VALUE); + } + if (lrg._is_float) { + print_prop("is_float", TRUE_VALUE); + } + if (lrg._is_vector) { + print_prop("is_vector", TRUE_VALUE); + } + if (lrg._is_predicate) { + print_prop("is_predicate", TRUE_VALUE); + } + if (lrg._is_scalable) { + print_prop("is_scalable", TRUE_VALUE); + } + if (lrg._was_spilled1) { + print_prop("was_spilled1", TRUE_VALUE); + } + if (lrg._was_spilled2) { + print_prop("was_spilled2", TRUE_VALUE); + } + if (lrg._direct_conflict) { + print_prop("direct_conflict", TRUE_VALUE); + } + if (lrg._fat_proj) { + print_prop("fat_proj", TRUE_VALUE); + } + if (lrg._was_lo) { + print_prop("_was_lo", TRUE_VALUE); + } + if (lrg._has_copy) { + print_prop("has_copy", TRUE_VALUE); + } + if (lrg._at_risk) { + print_prop("at_risk", TRUE_VALUE); + } + if (lrg._must_spill) { + print_prop("must_spill", TRUE_VALUE); + } + if (lrg._is_bound) { + print_prop("is_bound", TRUE_VALUE); + } + if (lrg._msize_valid && lrg._degree_valid && lrg.lo_degree()) { + print_prop("trivial", TRUE_VALUE); + } tail(PROPERTIES_ELEMENT); tail(LIVE_RANGE_ELEMENT); } From 66073d31746ed388316b058480ccc69224211296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Sat, 8 Feb 2025 16:51:01 +0100 Subject: [PATCH 34/48] Draw segments in empty blocks --- .../com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index 7450ce060cbb4..e7dcc07f96e81 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -144,6 +144,12 @@ protected void paintWidget() { g.drawLine(-RANGE_WIDTH, length, RANGE_WIDTH, length); } } + if (liveRangeSegment.getStart() == null && + liveRangeSegment.getEnd() == null && + length == 0) { + // Continuation segment in empty basic block. + g.drawLine(0, -2, 0, 3); + } } @Override From a30893b79ae4e21fca8fda85d1c86692641580af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Sat, 8 Feb 2025 17:12:11 +0100 Subject: [PATCH 35/48] Let phi-defined live ranges start at the top of the basic block --- .../src/main/java/com/sun/hotspot/igv/graph/Diagram.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java index 17fb5a66b1e83..221d03e0daf36 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java @@ -167,7 +167,13 @@ public Diagram(InputGraph graph, String nodeText, String shortNodeText, } // Activate new segments. if (l.def != null && !active.containsKey(l.def)) { - active.put(l.def, n); + InputNode startNode = n; + if (l.join != null && !l.join.isEmpty()) { + // Start of a "joined" live range. These start always at + // the beginning of the basic block. + startNode = null; + } + active.put(l.def, startNode); if (!l.liveout.contains(l.def)) { instant.add(l.def); } From 2647f1cb84824419540bbbdb109625358456aa4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 10 Feb 2025 10:39:23 +0100 Subject: [PATCH 36/48] Update copyright headers --- src/hotspot/share/opto/idealGraphPrinter.hpp | 2 +- .../com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java | 2 +- .../Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java | 2 +- .../Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java | 2 +- .../src/main/java/com/sun/hotspot/igv/data/InputLiveRange.java | 2 +- .../src/main/java/com/sun/hotspot/igv/data/LivenessInfo.java | 2 +- .../java/com/sun/hotspot/igv/data/serialization/Parser.java | 2 +- .../com/sun/hotspot/igv/data/services/InputGraphProvider.java | 2 +- .../java/com/sun/hotspot/igv/data/services/PreProcessor.java | 2 +- .../main/java/com/sun/hotspot/igv/difference/Difference.java | 2 +- .../src/main/resources/com/sun/hotspot/igv/filter/helper.js | 2 +- .../Graph/src/main/java/com/sun/hotspot/igv/graph/Block.java | 2 +- .../Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java | 2 +- .../main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java | 2 +- .../com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java | 2 +- .../igv/hierarchicallayout/HierarchicalCFGLayoutManager.java | 2 +- .../com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java | 2 +- .../src/main/java/com/sun/hotspot/igv/layout/Cluster.java | 2 +- .../src/main/java/com/sun/hotspot/igv/layout/Segment.java | 2 +- .../hotspot/igv/servercompiler/ServerCompilerPreProcessor.java | 2 +- .../main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java | 2 +- .../src/main/java/com/sun/hotspot/igv/view/DiagramScene.java | 2 +- .../main/java/com/sun/hotspot/igv/view/DiagramViewModel.java | 2 +- .../src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java | 2 +- .../java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java | 2 +- .../main/java/com/sun/hotspot/igv/view/EditorTopComponent.java | 2 +- .../src/main/java/com/sun/hotspot/igv/view/NodeQuickSearch.java | 2 +- .../com/sun/hotspot/igv/view/actions/ExpandAdjacentAction.java | 2 +- .../sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java | 2 +- .../sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java | 2 +- .../java/com/sun/hotspot/igv/view/actions/ExtractAction.java | 2 +- .../main/java/com/sun/hotspot/igv/view/actions/HideAction.java | 2 +- .../java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java | 2 +- .../com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java | 2 +- .../main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java | 2 +- .../java/com/sun/hotspot/igv/view/widgets/FigureWidget.java | 2 +- .../java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java | 2 +- 37 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/hotspot/share/opto/idealGraphPrinter.hpp b/src/hotspot/share/opto/idealGraphPrinter.hpp index f5528507362ca..739f918fab453 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.hpp +++ b/src/hotspot/share/opto/idealGraphPrinter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java index 9399c7869f26a..d45412cce53ef 100644 --- a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java +++ b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java index e76a028156458..6021534d1ddb5 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java index 98d3e9b80d563..987c0e5576e42 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputGraph.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputLiveRange.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputLiveRange.java index dcb796aa32bbc..5c65d42afd029 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputLiveRange.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputLiveRange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/LivenessInfo.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/LivenessInfo.java index 156a4a865f7a8..4df9838646f9a 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/LivenessInfo.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/LivenessInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Parser.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Parser.java index 4ae6e23cbb1c4..dfe60372eda3b 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Parser.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Parser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/InputGraphProvider.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/InputGraphProvider.java index 4a0a915c88ba9..a13a48b638045 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/InputGraphProvider.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/InputGraphProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/PreProcessor.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/PreProcessor.java index dc96e887786ae..7176a2c06ddb1 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/PreProcessor.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/services/PreProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Difference/src/main/java/com/sun/hotspot/igv/difference/Difference.java b/src/utils/IdealGraphVisualizer/Difference/src/main/java/com/sun/hotspot/igv/difference/Difference.java index c7d20e84f241e..c904e8c6083e8 100644 --- a/src/utils/IdealGraphVisualizer/Difference/src/main/java/com/sun/hotspot/igv/difference/Difference.java +++ b/src/utils/IdealGraphVisualizer/Difference/src/main/java/com/sun/hotspot/igv/difference/Difference.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js b/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js index fbce14124dc2b..a1298cb6ff3f3 100644 --- a/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js +++ b/src/utils/IdealGraphVisualizer/Filter/src/main/resources/com/sun/hotspot/igv/filter/helper.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Block.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Block.java index 1abaa3a47a00f..c1d04c01c8d6e 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Block.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Block.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java index 221d03e0daf36..268b714659ff2 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java index 11ba5e53d390f..188bb43863622 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java index d52ac8a98d78b..29ce31c928717 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java index bb29a1a8f262b..0b6c71064bdff 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java index e224088c49055..956d72924b991 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LayoutGraph.java @@ -49,7 +49,7 @@ public class LayoutGraph { .thenComparingInt(l -> l.getFrom().getRelativePosition().x) .thenComparingInt(l -> l.getTo().getRelativePosition().x); - // Registered Graph Components: Links, Vertices, and Port Mappings. + // Registered Graph Components: Links, Vertices, and Port Mappings private final Set links; private final SortedSet vertices; private final LinkedHashMap> inputPorts; diff --git a/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Cluster.java b/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Cluster.java index dc991bd6b2197..5dee43f9224c2 100644 --- a/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Cluster.java +++ b/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Cluster.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Segment.java b/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Segment.java index 41e4d2c1acbfb..6591fcb4a1dae 100644 --- a/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Segment.java +++ b/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/Segment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java index 396ccb0df1f24..e8930c1115361 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java index 1ef13fa124c26..715b95598656c 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/BlockQuickSearch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index af88c6f8470dd..3f37251daf29b 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index f37a44ae8565a..8e81c522503d0 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java index 5c9e1ce65f15f..26c69a4488c83 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java index d06375856cfb0..2ff4b20f038f6 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java index f50649b069c51..35e440322d870 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/NodeQuickSearch.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/NodeQuickSearch.java index 654d8c123645a..254b8ca15efec 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/NodeQuickSearch.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/NodeQuickSearch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandAdjacentAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandAdjacentAction.java index 0b8de7983f696..ce37b4b8e1d3b 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandAdjacentAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandAdjacentAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java index bf745786a497b..e8520004b25cc 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java index 9acad3a0c8bc4..c89924a5b45e7 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExtractAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExtractAction.java index bd5e4077ac530..d9a198ee951d8 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExtractAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ExtractAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/HideAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/HideAction.java index 695749b08de7f..9a4b0bfc45c7b 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/HideAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/HideAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java index eccd9fc8ced89..4de588f6357a3 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ModelAwareAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java index 5a964d25a337f..9beebdd30a037 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java index 3eba13a406b36..5e6e80d31b77f 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/BlockWidget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java index 131331d1c55bf..95775d4de5f0e 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index e7dcc07f96e81..b728b6b16a074 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it From 8336f677c1e5f44ae4f93346b7991fb1016f2cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 10 Feb 2025 10:55:54 +0100 Subject: [PATCH 37/48] Remove unused option to use definer node ids instead of live range ids --- .../com/sun/hotspot/igv/data/InputBlock.java | 2 -- .../ServerCompilerPreProcessor.java | 28 ++----------------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java index 6021534d1ddb5..6670470b5e8ae 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/InputBlock.java @@ -38,8 +38,6 @@ public class InputBlock { private Set liveOut; private boolean artificial; - public static final boolean USE_LIVE_RANGE_IDENTIFIERS = true; - @Override public int hashCode() { return name.hashCode(); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java index e8930c1115361..9cbc36328f756 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java @@ -33,12 +33,6 @@ @ServiceProvider(service = PreProcessor.class) public class ServerCompilerPreProcessor implements PreProcessor { - // Map from input live range ids to regular node ids. Note that this is - // possible only at the 'Initial liveness' phase, where there is still a - // one-to-one relation between these. Later on, C2 might assign the same - // live range to multiple regular node ids when coalescing. - Map liveRangeIdToNodeId = new HashMap<>(42); - private static boolean isPhi(InputNode node) { String nodeName = node.getProperties().get("name"); if (nodeName == null) { @@ -60,10 +54,6 @@ private static boolean isAllocatableLiveRange(int liveRangeId) { return liveRangeId > 0; } - private int liveRangeIdentifier(int liveRangeId) { - return InputBlock.USE_LIVE_RANGE_IDENTIFIERS ? liveRangeId : liveRangeIdToNodeId.get(liveRangeId); - } - private String liveRangeList(Stream s) { return s.sorted().map(String::valueOf).collect(Collectors.joining(", ")); } @@ -80,18 +70,6 @@ public void preProcess(InputGraph graph) { if (empty) { // No block-level liveness information available, move on. return; } - if (!InputBlock.USE_LIVE_RANGE_IDENTIFIERS) { - liveRangeIdToNodeId.clear(); - for (InputNode n : graph.getNodes()) { - int lrg = getNumericPropertyOrZero(n, "lrg"); - assert !liveRangeIdToNodeId.containsKey(lrg); - if (lrg > 0) { - int idx = getNumericPropertyOrZero(n, "idx"); - liveRangeIdToNodeId.put(lrg, idx); - } - } - } - // Build a map from nodes to live ranges used. Map> usedLiveRanges = new HashMap<>(graph.getNodes().size()); for (InputEdge e : graph.getEdges()) { @@ -101,14 +79,14 @@ public void preProcess(InputGraph graph) { if (usedLiveRanges.get(toId) == null) { usedLiveRanges.put(toId, new ArrayList()); } - usedLiveRanges.get(toId).add(liveRangeIdentifier(liveRangeId)); + usedLiveRanges.get(toId).add(liveRangeId); } } // Propagate block-level live-out information to each node. for (InputBlock b : graph.getBlocks()) { Set liveOut = new HashSet<>(); for (int lrg : b.getLiveOut()) { - liveOut.add(liveRangeIdentifier(lrg)); + liveOut.add(lrg); } for (int i = b.getNodes().size() - 1; i >= 0; i--) { LivenessInfo livenessInfo = new LivenessInfo(); @@ -120,7 +98,7 @@ public void preProcess(InputGraph graph) { if (isAllocatableLiveRange(defLiveRange)) { livenessInfo.def = defLiveRange; // Otherwise it is missing or a non-allocatable live range. - liveOut.remove(liveRangeIdentifier(defLiveRange)); + liveOut.remove(defLiveRange); } List uses = usedLiveRanges.get(n.getId()); if (uses != null) { From 1cd7a4e5e493d137e5c1d6e0a4b74751c34a6a20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 10 Feb 2025 11:29:34 +0100 Subject: [PATCH 38/48] Remove comments that are no longer needed --- .../src/main/java/com/sun/hotspot/igv/view/DiagramScene.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 3f37251daf29b..c5a15f3e96953 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -492,7 +492,6 @@ protected Sheet createSheet() { getModel().setSelectedNodes(nodeSelection); getModel().setSelectedLiveRanges(liveRangeSelection); - // TODO: extend with live ranges? boolean b = selectedCoordinatorListener.isEnabled(); selectedCoordinatorListener.setEnabled(false); SelectionCoordinator.getInstance().setSelectedObjects(nodeSelection); @@ -1438,7 +1437,6 @@ public void centerSelectedFigures() { @Override public void centerSelectedLiveRanges() { - // TODO: double check that this works as intended Set selectedLiveRanges = model.getSelectedLiveRangeSegments(); Rectangle overallRect = null; for (LiveRangeSegment segment : selectedLiveRanges) { @@ -1631,8 +1629,6 @@ private void updateVisibleFigureWidgets() { } private void updateVisibleLiveRangeWidgets() { - // TODO: pre-compute visibility for each live range, to avoid - // re-computing it for each segment in each live range. if (getModel().getShowCFG() && getModel().getShowLiveRanges()) { for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { LiveRangeWidget liveRangeWidget = getWidget(segment); From cf2f945e73e471a7a89a1d73cabf4b39c178c1c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 10 Feb 2025 13:46:45 +0100 Subject: [PATCH 39/48] Select all live range sements and not just a representative one --- .../main/java/com/sun/hotspot/igv/view/DiagramScene.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index c5a15f3e96953..b6cf4413dafaa 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -1360,13 +1360,13 @@ public Set liveRangeSegmentSet(Collection live for (InputLiveRange liveRange : liveRanges) { liveRangeIds.add(liveRange.getId()); } - Map representativeSegments = new HashMap<>(); + Set segments = new HashSet<>(); for (LiveRangeSegment segment : model.getDiagram().getLiveRangeSegments()) { if (liveRangeIds.contains(segment.getLiveRange().getId())) { - representativeSegments.put(segment.getLiveRange().getId(), segment); + segments.add(segment); } } - return new HashSet<>(representativeSegments.values()); + return segments; } private Set
figureSet(Collection nodes) { From 0978eee056c1baf9d36e4fd5a1867e88188349b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 10 Feb 2025 14:11:10 +0100 Subject: [PATCH 40/48] Ensure live ranges to go to from pop-up menu become visible --- .../sun/hotspot/igv/view/DiagramScene.java | 31 ++++++++++--------- .../igv/view/widgets/FigureWidget.java | 3 +- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index b6cf4413dafaa..3a06c0a52b0fc 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -623,12 +623,20 @@ public void actionPerformed(ActionEvent e) { return action; } - public Action createGotoLiveRangeAction(String name, Set segments) { - String iconResource = "com/sun/hotspot/igv/view/images/selectLiveRanges.png"; + private Action createGotoLiveRangeAction(String name, String iconResource, Set liveRanges) { Action action = new AbstractAction(name, new ImageIcon(ImageUtilities.loadImage(iconResource))) { @Override public void actionPerformed(ActionEvent e) { + Set segments = liveRangeSegmentSet(liveRanges); setLiveRangeSegmentSelection(segments); + Diagram diagram = getModel().getDiagram(); + Set
figures = new HashSet<>(); + for (InputLiveRange liveRange : liveRanges) { + for (InputNode node : diagram.getInputGraph().getRelatedNodes(liveRange.getId())) { + figures.add((diagram.getFigure(node))); + } + } + model.showFigures(figures); centerSelectedLiveRanges(); } }; @@ -637,19 +645,14 @@ public void actionPerformed(ActionEvent e) { return action; } - public Action createGotoLiveRangeAction(InputLiveRange liveRange) { - String name = "L" + liveRange.getId(); - String iconResource = "com/sun/hotspot/igv/view/images/liveRange.png"; - Action action = new AbstractAction(name, new ImageIcon(ImageUtilities.loadImage(iconResource))) { - @Override - public void actionPerformed(ActionEvent e) { - setLiveRangeSegmentSelection(liveRangeSegmentSet(Collections.singleton(liveRange))); - centerSelectedLiveRanges(); - } - }; + public Action createGotoLiveRangeAction(String name, Set liveRanges) { + return createGotoLiveRangeAction(name, "com/sun/hotspot/igv/view/images/selectLiveRanges.png", liveRanges); + } - action.setEnabled(true); - return action; + public Action createGotoLiveRangeAction(InputLiveRange liveRange) { + return createGotoLiveRangeAction("L" + liveRange.getId(), + "com/sun/hotspot/igv/view/images/liveRange.png", + Collections.singleton(liveRange)); } private void clearObjects() { diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java index 95775d4de5f0e..8d71249479a2c 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/FigureWidget.java @@ -341,9 +341,8 @@ public JPopupMenu getPopupMenu(Widget widget, Point point) { } } if (!liveRanges.isEmpty()) { - Set segments = diagramScene.liveRangeSegmentSet(liveRanges); menu.addSeparator(); - menu.add(diagramScene.createGotoLiveRangeAction("Select live ranges", segments)); + menu.add(diagramScene.createGotoLiveRangeAction("Select live ranges", liveRanges)); menu.addSeparator(); if (l.def != null) { menu.add(diagramScene.createGotoLiveRangeAction(graph.getLiveRange(l.def))); From 153e01a0ba0e2473c820db169df34cdd2fddfab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 10 Feb 2025 14:22:03 +0100 Subject: [PATCH 41/48] Ensure basic blocks with live ranges are always visible --- .../main/java/com/sun/hotspot/igv/view/DiagramScene.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index 3a06c0a52b0fc..dd84645b127f2 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -929,8 +929,8 @@ private void relayout() { updateVisibleFigureWidgets(); updateNodeHull(); - updateVisibleBlockWidgets(); updateVisibleLiveRangeWidgets(); + updateVisibleBlockWidgets(); validateAll(); Set
visibleFigures = getVisibleFigures(); @@ -1708,6 +1708,12 @@ private void updateVisibleBlockWidgets() { visibleBlocks.add(figure.getBlock()); } } + for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { + LiveRangeWidget liveRangeWidget = getWidget(segment); + if (liveRangeWidget.isVisible()) { + visibleBlocks.add(segment.getCluster()); + } + } if (getModel().getShowCFG() && getModel().getShowEmptyBlocks()) { // Add remaining blocks. visibleBlocks.addAll(getModel().getDiagram().getBlocks()); From c5e48e460e7702d8e328aafbbc7db6004cd891ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Tue, 11 Feb 2025 10:29:58 +0100 Subject: [PATCH 42/48] Fix def live range printing in 'Show liveness information' filter --- .../hotspot/igv/servercompiler/filters/showLiveness.filter | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showLiveness.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showLiveness.filter index cc25aef6a4c64..e3b0016a0f2a3 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showLiveness.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showLiveness.filter @@ -2,10 +2,7 @@ // uses, defs, and live-out sets, if available. function formatLiveRange(lrg) { - flrg = "" - if (InputBlock.USE_LIVE_RANGE_IDENTIFIERS) { - flrg += "L"; - } + flrg = "L"; flrg += lrg.trim(); return flrg; } @@ -21,7 +18,7 @@ function addLivenessInfo(lrg, idx, liveout, uses, joins, kills) { } elements = []; if (Number(lrg) > 0) { - elements.push("def: " + (InputBlock.USE_LIVE_RANGE_IDENTIFIERS ? ("L" + lrg) : idx)); + elements.push("def: " + formatLiveRange(lrg)); } if (uses != null) { elements.push("use: " + liveRangeSet(uses)); From 00169223ee4dc6390bbc25ae659108ad594a32ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Mon, 17 Feb 2025 20:21:24 +0100 Subject: [PATCH 43/48] Check if live range widgets actually exist for computing block visibility --- .../src/main/java/com/sun/hotspot/igv/view/DiagramScene.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index dd84645b127f2..2e46970aed55a 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -1710,7 +1710,7 @@ private void updateVisibleBlockWidgets() { } for (LiveRangeSegment segment : getModel().getDiagram().getLiveRangeSegments()) { LiveRangeWidget liveRangeWidget = getWidget(segment); - if (liveRangeWidget.isVisible()) { + if (liveRangeWidget != null && liveRangeWidget.isVisible()) { visibleBlocks.add(segment.getCluster()); } } From 08ee449ed7d17de7ab40772025ffd52337dce01d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Tue, 18 Feb 2025 11:25:32 +0100 Subject: [PATCH 44/48] Remove unnecessary whitespace --- .../com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java index 9beebdd30a037..8910f0c0635f7 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/ShowLiveRangesAction.java @@ -31,7 +31,7 @@ import javax.swing.ImageIcon; import org.openide.util.ImageUtilities; -public class ShowLiveRangesAction extends AbstractAction implements PropertyChangeListener { +public class ShowLiveRangesAction extends AbstractAction implements PropertyChangeListener { private boolean selected; private AbstractAction parentAction; From 87b31e9e4ec08b94e0e9886d6dbd111a618e58c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 20 Feb 2025 10:26:45 +0100 Subject: [PATCH 45/48] Export liveness information when saving a graph from IGV --- .../igv/data/serialization/Printer.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Printer.java b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Printer.java index b098b6ef5da9e..4c82006c0e54a 100644 --- a/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Printer.java +++ b/src/utils/IdealGraphVisualizer/Data/src/main/java/com/sun/hotspot/igv/data/serialization/Printer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -170,11 +170,29 @@ private static void exportInputGraph(XMLWriter writer, InputGraph graph, InputGr writer.endTag(); // Parser.NODES_ELEMENT } + if (!b.getLiveOut().isEmpty()) { + writer.startTag(Parser.LIVEOUT_ELEMENT); + for (Integer lrg : b.getLiveOut()) { + writer.simpleTag(Parser.LIVE_RANGE_ELEMENT, new Properties(Parser.LIVE_RANGE_ID_PROPERTY, String.valueOf(lrg))); + } + writer.endTag(); // Parser.LIVEOUT_ELEMENT + } + writer.endTag(); // Parser.BLOCK_ELEMENT } writer.endTag(); // Parser.CONTROL_FLOW_ELEMENT + if (!graph.getLiveRanges().isEmpty()) { + writer.startTag(Parser.LIVE_RANGES_ELEMENT); + for (InputLiveRange liveRange : graph.getLiveRanges()) { + writer.startTag(Parser.LIVE_RANGE_ELEMENT, new Properties(Parser.LIVE_RANGE_ID_PROPERTY, String.valueOf(liveRange.getId()))); + writer.writeProperties(liveRange.getProperties()); + writer.endTag(); // Parser.LIVE_RANGE_ELEMENT + } + writer.endTag(); // Parser.LIVE_RANGES_ELEMENT + } + exportStates(writer, graph, contexts); writer.endTag(); // Parser.GRAPH_ELEMENT From 31e4510e3f315b01e54dcde29ad56d1ac807449c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 20 Feb 2025 11:59:43 +0100 Subject: [PATCH 46/48] Open and close live ranges joined by phis in their respective blocks --- .../com/sun/hotspot/igv/graph/Diagram.java | 37 ++++++++++++++++++- .../hotspot/igv/graph/LiveRangeSegment.java | 18 +++++++++ .../ServerCompilerPreProcessor.java | 14 +++++-- .../igv/view/widgets/LiveRangeWidget.java | 24 ++++++------ 4 files changed, 76 insertions(+), 17 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java index 268b714659ff2..4fda8f0e575d6 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/Diagram.java @@ -137,17 +137,39 @@ public Diagram(InputGraph graph, String nodeText, String shortNodeText, liveRangeHash.put(lrg.getId(), lrg); } + // Pre-compute live ranges joined by each block. + Map> blockJoined = new HashMap<>(); + for (InputBlock b : graph.getBlocks()) { + blockJoined.put(b, new HashSet<>()); + for (InputNode n : b.getNodes()) { + LivenessInfo l = graph.getLivenessInfoForNode(n); + if (l != null && l.join != null) { + blockJoined.get(b).addAll(l.join); + } + } + } + for (InputBlock b : graph.getBlocks()) { if (b.getNodes().isEmpty()) { continue; } Map active = new HashMap<>(); Set instant = new HashSet<>(); + Set opening = new HashSet<>(); InputNode header = b.getNodes().get(0); if (graph.getLivenessInfoForNode(header) == null) { // No liveness information available, skip. continue; } + Set joined = new HashSet<>(); + if (b.getSuccessors().size() == 1) { + // We assume the live-out ranges in this block might only be + // joined if there is exactly one successor block (i.e. the CFG + // does not contain critical edges). + joined.addAll(b.getLiveOut()); + InputBlock succ = b.getSuccessors().iterator().next(); + joined.retainAll(blockJoined.get(succ)); + } for (int liveRangeId : graph.getLivenessInfoForNode(header).livein) { active.put(liveRangeId, null); } @@ -160,8 +182,12 @@ public Diagram(InputGraph graph, String nodeText, String shortNodeText, Figure start = startNode == null ? null : figureHash.get(startNode.getId()); InputNode endNode = n; Figure end = figureHash.get(endNode.getId()); - liveRangeSegments - .add(new LiveRangeSegment(liveRangeHash.get(liveRangeId), getBlock(b), start, end)); + LiveRangeSegment s = new LiveRangeSegment(liveRangeHash.get(liveRangeId), getBlock(b), start, end); + if (opening.contains(liveRangeId)) { + s.setOpening(true); + } + s.setClosing(true); + liveRangeSegments.add(s); active.remove(liveRangeId); } } @@ -174,6 +200,7 @@ public Diagram(InputGraph graph, String nodeText, String shortNodeText, startNode = null; } active.put(l.def, startNode); + opening.add(l.def); if (!l.liveout.contains(l.def)) { instant.add(l.def); } @@ -187,6 +214,12 @@ public Diagram(InputGraph graph, String nodeText, String shortNodeText, if (instant.contains(liveRangeId)) { s.setInstantaneous(true); } + if (opening.contains(liveRangeId)) { + s.setOpening(true); + } + if (instant.contains(liveRangeId) || joined.contains(liveRangeId)) { + s.setClosing(true); + } liveRangeSegments.add(s); } } diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java index 188bb43863622..79c58948bbe67 100644 --- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java +++ b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/LiveRangeSegment.java @@ -40,6 +40,8 @@ public class LiveRangeSegment extends Properties.Entity implements Segment { private Point endPoint; private boolean lastOfLiveRange; private boolean instantaneous; + private boolean opening; + private boolean closing; private Set segmentSet; private Color color; @@ -105,6 +107,22 @@ public boolean isInstantaneous() { return instantaneous; } + public void setOpening(boolean opening) { + this.opening = opening; + } + + public boolean isOpening() { + return opening; + } + + public void setClosing(boolean closing) { + this.closing = closing; + } + + public boolean isClosing() { + return closing; + } + public Set getSegmentSet() { return segmentSet; } diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java index 9cbc36328f756..e164b8d169e27 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java @@ -33,12 +33,20 @@ @ServiceProvider(service = PreProcessor.class) public class ServerCompilerPreProcessor implements PreProcessor { - private static boolean isPhi(InputNode node) { + private static boolean isPhi(InputNode node, int defLiveRange, List uses) { String nodeName = node.getProperties().get("name"); if (nodeName == null) { return false; } - return nodeName.equals("Phi"); + if (!nodeName.equals("Phi")) { + return false; + } + Set useSet = new HashSet<>(uses); + if (useSet.size() == 1 && useSet.iterator().next() == defLiveRange) { + // The phi operands have been coalesced, treat as a regular instruction. + return false; + } + return true; } private static int getNumericPropertyOrZero(InputNode node, String k) { @@ -103,7 +111,7 @@ public void preProcess(InputGraph graph) { List uses = usedLiveRanges.get(n.getId()); if (uses != null) { String useList = liveRangeList(uses.stream()); - if (isPhi(n)) { + if (isPhi(n, defLiveRange, uses)) { // A phi's uses are not live simultaneously. // Conceptually, they die at the block's incoming egdes. n.getProperties().setProperty("joins", useList); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java index b728b6b16a074..82e496b60ab67 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/widgets/LiveRangeWidget.java @@ -135,20 +135,20 @@ protected void paintWidget() { if (highlighted) { g.setStroke(new BasicStroke(2)); } - if (liveRangeSegment.getStart() != null) { - g.drawLine(-RANGE_WIDTH, 0, RANGE_WIDTH, 0); + int start = 0; + int end = length; + if (length == 0 && !liveRangeSegment.isInstantaneous()) { + // Continuation segment in empty basic block. + assert liveRangeSegment.getStart() == null && liveRangeSegment.getEnd() == null; + start = -2; + end = 3; } - if (length != 0) { - g.drawLine(0, 0, 0, length); - if (liveRangeSegment.getEnd() != null) { - g.drawLine(-RANGE_WIDTH, length, RANGE_WIDTH, length); - } + g.drawLine(0, start, 0, end); + if (liveRangeSegment.isOpening()) { + g.drawLine(-RANGE_WIDTH, 0, RANGE_WIDTH, 0); } - if (liveRangeSegment.getStart() == null && - liveRangeSegment.getEnd() == null && - length == 0) { - // Continuation segment in empty basic block. - g.drawLine(0, -2, 0, 3); + if (liveRangeSegment.isClosing()) { + g.drawLine(-RANGE_WIDTH, end, RANGE_WIDTH, end); } } From 51718b90b26ea54f645bc6addd65b1e5a3237843 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Thu, 20 Feb 2025 14:04:13 +0100 Subject: [PATCH 47/48] Handle single-block CFGs --- .../igv/servercompiler/ServerCompilerPreProcessor.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java index e164b8d169e27..58cc5c242a4bc 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerPreProcessor.java @@ -68,14 +68,8 @@ private String liveRangeList(Stream s) { @Override public void preProcess(InputGraph graph) { - boolean empty = true; - for (InputBlock b : graph.getBlocks()) { - if (!b.getLiveOut().isEmpty()) { - empty = false; - break; - } - } - if (empty) { // No block-level liveness information available, move on. + if (graph.getLiveRanges().isEmpty()) { + // No block-level liveness information available, move on. return; } // Build a map from nodes to live ranges used. From efbde14a08834ee29e57c52ea0de4b2df48ee000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= Date: Fri, 7 Mar 2025 10:41:46 +0100 Subject: [PATCH 48/48] Show liveness info extra line only when liveness information is available --- .../sun/hotspot/igv/servercompiler/filters/showLiveness.filter | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showLiveness.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showLiveness.filter index e3b0016a0f2a3..09d12d6c84710 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showLiveness.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showLiveness.filter @@ -35,7 +35,7 @@ function addLivenessInfo(lrg, idx, liveout, uses, joins, kills) { return elements.join(", "); } -editProperty(matches("name", ".*"), +editProperty(or([hasProperty("liveout"), hasProperty("uses"), hasProperty("joins"), hasProperty("kills")]), ["lrg", "idx", "liveout", "uses", "joins", "kills"], "extra_label", function(propertyValues) {return addLivenessInfo(propertyValues[0], propertyValues[1], propertyValues[2], propertyValues[3], propertyValues[4], propertyValues[5]);});