8368753: IGV: improve CFG view of difference graphs

Reviewed-by: chagedorn, mhaessig, dfenacci
This commit is contained in:
Roberto Castañeda Lozano 2025-10-06 08:14:24 +00:00
parent e6781fd949
commit 59e87437b4
4 changed files with 54 additions and 21 deletions

View File

@ -135,7 +135,7 @@ public class InputBlock {
successors.add(b);
}
void setArtificial() {
public void setArtificial() {
this.artificial = true;
}

View File

@ -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
@ -24,9 +24,7 @@
*/
package com.sun.hotspot.igv.data.services;
import com.sun.hotspot.igv.data.InputBlock;
import com.sun.hotspot.igv.data.InputGraph;
import java.util.Collection;
/**
*
@ -34,5 +32,9 @@ import java.util.Collection;
*/
public interface Scheduler {
public Collection<InputBlock> schedule(InputGraph graph);
// Compute a set of scheduled blocks for the given graph, creating new
// blocks if these are not found in the graph.
public void schedule(InputGraph graph);
// Schedule locally the set of blocks in the given graph.
public void scheduleLocally(InputGraph graph);
}

View File

@ -114,6 +114,9 @@ public class Difference {
Map<InputBlock, InputBlock> blocksMap = new HashMap<>();
for (InputBlock blk : a.getBlocks()) {
InputBlock diffblk = graph.addBlock(blk.getName());
if (blk.isArtificial()) {
diffblk.setArtificial();
}
blocksMap.put(blk, diffblk);
}
for (InputBlock blk : b.getBlocks()) {
@ -121,6 +124,9 @@ public class Difference {
if (diffblk == null) {
diffblk = graph.addBlock(blk.getName());
}
if (blk.isArtificial()) {
diffblk.setArtificial();
}
blocksMap.put(blk, diffblk);
}
@ -249,6 +255,9 @@ public class Difference {
}
}
Scheduler s = Lookup.getDefault().lookup(Scheduler.class);
s.scheduleLocally(graph);
return graph;
}

View File

@ -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
@ -296,10 +296,25 @@ public class ServerCompilerScheduler implements Scheduler {
return n.getProperties().get("block");
}
private boolean initialize(InputGraph graph) {
nodes = new ArrayList<>();
inputNodeToNode = new HashMap<>(graph.getNodes().size());
this.graph = graph;
if (!hasCategoryInformation()) {
ErrorManager.getDefault().log(ErrorManager.WARNING,
"Cannot find node category information in the input graph. " +
"The control-flow graph will not be approximated.");
return false;
}
buildUpGraph();
markCFGNodes();
return true;
}
@Override
public Collection<InputBlock> schedule(InputGraph graph) {
public void schedule(InputGraph graph) {
if (graph.getNodes().isEmpty()) {
return Collections.emptyList();
return;
}
if (graph.getBlocks().size() > 0) {
@ -311,20 +326,11 @@ public class ServerCompilerScheduler implements Scheduler {
assert graph.getBlock(n) != null;
}
}
return graph.getBlocks();
return;
} else {
nodes = new ArrayList<>();
inputNodeToNode = new HashMap<>(graph.getNodes().size());
this.graph = graph;
if (!hasCategoryInformation()) {
ErrorManager.getDefault().log(ErrorManager.WARNING,
"Cannot find node category information in the input graph. " +
"The control-flow graph will not be approximated.");
return null;
if (!initialize(graph)) {
return;
}
buildUpGraph();
markCFGNodes();
buildBlocks();
schedulePinned();
buildDominators();
@ -333,10 +339,26 @@ public class ServerCompilerScheduler implements Scheduler {
check();
reportWarnings();
return blocks;
return;
}
}
@Override
public void scheduleLocally(InputGraph graph) {
if (!initialize(graph)) {
return;
}
// Import global schedule from the given graph.
blocks = new Vector<>();
for (InputBlock block : graph.getBlocks()) {
blocks.add(block);
for (InputNode in : block.getNodes()) {
inputNodeToNode.get(in).block = block;
}
}
scheduleLocal();
}
private void scheduleLocal() {
// Leave only local predecessors and successors.
for (InputBlock b : blocks) {