Commit 7a0392b6 authored by Danylo Boiko's avatar Danylo Boiko Committed by V8 LUCI CQ

[turbolizer] Turboshaft layout changes and new interaction features

New nenu buttons:
- Uncollapse all blocks
- Compress layout
- Collapse selected blocks
- Uncollapse selected blocks
New hotkeys:
- Layout graph
- Select all nodes
- Select all selected block's nodes
- Collapse selected blocks
- Uncollapse selected blocks
- Select node's input nodes
- Select node's output nodes
- Collapse unused blocks (blocks that don't have direct inputs and outputs of a hovered node)
- Copy hovered node's info

Bug: v8:7327
Change-Id: I942fe595ffea878f10cfbd962c3eff1786f1b954
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3773778Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Danylo Boiko <danielboyko02@gmail.com>
Cr-Commit-Position: refs/heads/main@{#82008}
parent d0a0d1bc
...@@ -91,6 +91,10 @@ ol.linenums { ...@@ -91,6 +91,10 @@ ol.linenums {
background-color: #FFFF33 !important; background-color: #FFFF33 !important;
} }
.linenums li > span {
user-select: text;
}
li.selected .line-number { li.selected .line-number {
background-color: #FFFF33; background-color: #FFFF33;
} }
......
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
</table> </table>
</div> </div>
</div> </div>
<div id="info-graph-view" class="info-topic"> <div id="info-common-graph-view" class="info-topic">
<div class="info-topic-header">Graph view</div> <div class="info-topic-header">Sea of Nodes/Turboshaft graph view</div>
<div class="info-topic-content"> <div class="info-topic-content">
<table> <table>
<tr> <tr>
...@@ -38,6 +38,13 @@ ...@@ -38,6 +38,13 @@
<td>/</td> <td>/</td>
<td>Select search box</td> <td>Select search box</td>
</tr> </tr>
</table>
</div>
</div>
<div id="info-graph-view" class="info-topic">
<div class="info-topic-header">Sea of Nodes graph view</div>
<div class="info-topic-content">
<table>
<tr> <tr>
<td>i</td> <td>i</td>
<td>Reveal node's input nodes</td> <td>Reveal node's input nodes</td>
...@@ -57,8 +64,35 @@ ...@@ -57,8 +64,35 @@
</table> </table>
</div> </div>
</div> </div>
<div id="info-graph-nodes" class="info-topic"> <div id="info-turboshaft-graph-view" class="info-topic">
<div class="info-topic-header">TurboFan graph nodes</div> <div class="info-topic-header">Turboshaft graph view</div>
<div class="info-topic-content">
<table>
<tr>
<td>i</td>
<td>Select all selected block's nodes</td>
</tr>
<tr>
<td>p</td>
<td>Collapse selected blocks</td>
</tr>
<tr>
<td>s</td>
<td>Uncollapse selected blocks</td>
</tr>
<tr>
<td>c</td>
<td>Copy hovered node's info</td>
</tr>
<tr>
<td>u</td>
<td>Collapse unused blocks (blocks that don't have direct inputs and outputs of a hovered node)</td>
</tr>
</table>
</div>
</div>
<div id="info-common-nodes" class="info-topic">
<div class="info-topic-header">Sea of Nodes/Turboshaft graph nodes</div>
<div class="info-topic-content"> <div class="info-topic-content">
<div>The following commands transform node selections, i.e. each operation will be applied <div>The following commands transform node selections, i.e. each operation will be applied
to each node in the current selection and the union of the resulting nodes will become the to each node in the current selection and the union of the resulting nodes will become the
...@@ -72,6 +106,13 @@ ...@@ -72,6 +106,13 @@
<td>DOWN</td> <td>DOWN</td>
<td>Select all output nodes</td> <td>Select all output nodes</td>
</tr> </tr>
</table>
</div>
</div>
<div id="info-graph-nodes" class="info-topic">
<div class="info-topic-header">Sea of Nodes graph nodes</div>
<div class="info-topic-content">
<table>
<tr> <tr>
<td>1-9</td> <td>1-9</td>
<td>Select input node 1-9</td> <td>Select input node 1-9</td>
...@@ -96,7 +137,7 @@ ...@@ -96,7 +137,7 @@
</div> </div>
</div> </div>
<div id="info-graph-search" class="info-topic"> <div id="info-graph-search" class="info-topic">
<div class="info-topic-header">Graph search</div> <div class="info-topic-header">Sea of Nodes/Turboshaft graph search</div>
<div class="info-topic-content"> <div class="info-topic-content">
<table> <table>
<tr> <tr>
......
...@@ -89,3 +89,8 @@ export function storageSetItem(key: string, value: any): void { ...@@ -89,3 +89,8 @@ export function storageSetItem(key: string, value: any): void {
export function storageSetIfIsNotExist(key: string, toSet: any): void { export function storageSetIfIsNotExist(key: string, toSet: any): void {
if (storageGetItem(key, null, false) === null) storageSetItem(key, toSet); if (storageGetItem(key, null, false) === null) storageSetItem(key, toSet);
} }
export function copyToClipboard(text: string): void {
if (!text || text.length == 0) return;
navigator.clipboard.writeText(text);
}
...@@ -55,6 +55,13 @@ export class TurboshaftGraphBlock extends Node<TurboshaftGraphEdge<TurboshaftGra ...@@ -55,6 +55,13 @@ export class TurboshaftGraphBlock extends Node<TurboshaftGraphEdge<TurboshaftGra
return this.width; return this.width;
} }
public compressHeight(): void {
if (this.collapsed) {
this.height = this.getHeight(null);
this.showProperties = null;
}
}
public getRankIndent() { public getRankIndent() {
return this.rank * (C.TURBOSHAFT_BLOCK_ROW_SEPARATION + 2 * C.DEFAULT_NODE_BUBBLE_RADIUS); return this.rank * (C.TURBOSHAFT_BLOCK_ROW_SEPARATION + 2 * C.DEFAULT_NODE_BUBBLE_RADIUS);
} }
......
...@@ -6,10 +6,7 @@ import * as C from "./common/constants"; ...@@ -6,10 +6,7 @@ import * as C from "./common/constants";
import { TurboshaftGraph } from "./turboshaft-graph"; import { TurboshaftGraph } from "./turboshaft-graph";
import { GraphStateType } from "./phases/phase"; import { GraphStateType } from "./phases/phase";
import { LayoutOccupation } from "./layout-occupation"; import { LayoutOccupation } from "./layout-occupation";
import { import { TurboshaftGraphBlock } from "./phases/turboshaft-graph-phase/turboshaft-graph-block";
TurboshaftGraphBlock,
TurboshaftGraphBlockType
} from "./phases/turboshaft-graph-phase/turboshaft-graph-block";
export class TurboshaftGraphLayout { export class TurboshaftGraphLayout {
graph: TurboshaftGraph; graph: TurboshaftGraph;
...@@ -46,9 +43,7 @@ export class TurboshaftGraphLayout { ...@@ -46,9 +43,7 @@ export class TurboshaftGraphLayout {
const blocks = this.initBlocks(); const blocks = this.initBlocks();
this.initWorkList(blocks); this.initWorkList(blocks);
let visited = new Array<boolean>(); const visited = new Array<boolean>();
blocks.forEach((block: TurboshaftGraphBlock) => this.dfsFindRankLate(visited, block));
visited = new Array<boolean>();
blocks.forEach((block: TurboshaftGraphBlock) => this.dfsRankOrder(visited, block)); blocks.forEach((block: TurboshaftGraphBlock) => this.dfsRankOrder(visited, block));
const rankSets = this.getRankSets(showProperties); const rankSets = this.getRankSets(showProperties);
...@@ -90,24 +85,21 @@ export class TurboshaftGraphLayout { ...@@ -90,24 +85,21 @@ export class TurboshaftGraphLayout {
} }
private initWorkList(blocks: Array<TurboshaftGraphBlock>): void { private initWorkList(blocks: Array<TurboshaftGraphBlock>): void {
const workList: Array<TurboshaftGraphBlock> = blocks.slice(); const workList = blocks.slice();
while (workList.length != 0) { while (workList.length != 0) {
const block: TurboshaftGraphBlock = workList.pop(); const block = workList.pop();
let changed = false; let changed = false;
if (block.rank == C.MAX_RANK_SENTINEL) { if (block.rank == C.MAX_RANK_SENTINEL) {
block.rank = 1; block.rank = 1;
changed = true; changed = true;
} }
let begin = 0;
let end = block.inputs.length; let end = block.inputs.length;
if (block.type == TurboshaftGraphBlockType.Merge && block.inputs.length > 0) { if (block.hasBackEdges()) {
begin = block.inputs.length - 1;
} else if (block.hasBackEdges()) {
end = 1; end = 1;
} }
for (let l = begin; l < end; ++l) { for (let l = 0; l < end; ++l) {
const input = block.inputs[l].source; const input = block.inputs[l].source;
if (input.visible && input.rank >= block.rank) { if (input.rank >= block.rank) {
block.rank = input.rank + 1; block.rank = input.rank + 1;
changed = true; changed = true;
} }
...@@ -127,27 +119,6 @@ export class TurboshaftGraphLayout { ...@@ -127,27 +119,6 @@ export class TurboshaftGraphLayout {
} }
} }
private dfsFindRankLate(visited: Array<boolean>, block: TurboshaftGraphBlock): void {
if (visited[block.id]) return;
visited[block.id] = true;
const originalRank = block.rank;
let newRank = block.rank;
let isFirstInput = true;
for (const outputEdge of block.outputs) {
const output = outputEdge.target;
this.dfsFindRankLate(visited, output);
const outputRank = output.rank;
if (output.visible && (isFirstInput || outputRank <= newRank) &&
(outputRank > originalRank)) {
newRank = outputRank - 1;
}
isFirstInput = false;
}
if (block.type != TurboshaftGraphBlockType.Merge) {
block.rank = newRank;
}
}
private dfsRankOrder(visited: Array<boolean>, block: TurboshaftGraphBlock): void { private dfsRankOrder(visited: Array<boolean>, block: TurboshaftGraphBlock): void {
if (visited[block.id]) return; if (visited[block.id]) return;
visited[block.id] = true; visited[block.id] = true;
...@@ -163,25 +134,18 @@ export class TurboshaftGraphLayout { ...@@ -163,25 +134,18 @@ export class TurboshaftGraphLayout {
} }
private getRankSets(showProperties: boolean): Array<Array<TurboshaftGraphBlock>> { private getRankSets(showProperties: boolean): Array<Array<TurboshaftGraphBlock>> {
const rankMaxBlockHeight = new Array<number>(); const ranksMaxBlockHeight = this.graph.getRanksMaxBlockHeight(showProperties);
for (const block of this.graph.blocks()) {
rankMaxBlockHeight[block.rank] = Math.max(rankMaxBlockHeight[block.rank] ?? 0,
block.getHeight(showProperties));
}
const rankSets = new Array<Array<TurboshaftGraphBlock>>(); const rankSets = new Array<Array<TurboshaftGraphBlock>>();
for (const block of this.graph.blocks()) { for (const block of this.graph.blocks()) {
block.y = rankMaxBlockHeight.slice(1, block.rank).reduce<number>((accumulator, current) => { block.y = ranksMaxBlockHeight.slice(1, block.rank).reduce<number>((accumulator, current) => {
return accumulator + current; return accumulator + current;
}, block.rank * (C.TURBOSHAFT_BLOCK_ROW_SEPARATION + 2 * C.DEFAULT_NODE_BUBBLE_RADIUS)); }, block.getRankIndent());
if (block.visible) {
if (!rankSets[block.rank]) { if (!rankSets[block.rank]) {
rankSets[block.rank] = new Array<TurboshaftGraphBlock>(block); rankSets[block.rank] = new Array<TurboshaftGraphBlock>(block);
} else { } else {
rankSets[block.rank].push(block); rankSets[block.rank].push(block);
} }
} }
}
return rankSets; return rankSets;
} }
...@@ -199,16 +163,12 @@ export class TurboshaftGraphLayout { ...@@ -199,16 +163,12 @@ export class TurboshaftGraphLayout {
let placedCount = 0; let placedCount = 0;
rankSet = rankSet.sort((a: TurboshaftGraphBlock, b: TurboshaftGraphBlock) => a.compare(b)); rankSet = rankSet.sort((a: TurboshaftGraphBlock, b: TurboshaftGraphBlock) => a.compare(b));
for (const block of rankSet) { for (const block of rankSet) {
if (block.visible) {
block.x = this.layoutOccupation.occupy(block); block.x = this.layoutOccupation.occupy(block);
const blockWidth = block.getWidth(); const blockWidth = block.getWidth();
this.trace(`Block ${block.id} is placed between [${block.x}, ${block.x + blockWidth})`); this.trace(`Block ${block.id} is placed between [${block.x}, ${block.x + blockWidth})`);
const staggeredFlooredI = Math.floor(placedCount++ % 3); const staggeredFlooredI = Math.floor(placedCount++ % 3);
const delta = C.MINIMUM_EDGE_SEPARATION * staggeredFlooredI; const delta = C.MINIMUM_EDGE_SEPARATION * staggeredFlooredI;
block.outputApproach += delta; block.outputApproach += delta;
} else {
block.x = 0;
}
} }
this.traceOccupation("Before clearing blocks"); this.traceOccupation("Before clearing blocks");
......
...@@ -61,8 +61,6 @@ export class TurboshaftGraph extends MovableContainer<TurboshaftGraphPhase> { ...@@ -61,8 +61,6 @@ export class TurboshaftGraph extends MovableContainer<TurboshaftGraphPhase> {
this.maxGraphY = 1; this.maxGraphY = 1;
for (const block of this.blocks()) { for (const block of this.blocks()) {
if (!block.visible) continue;
this.minGraphX = Math.min(this.minGraphX, block.x); this.minGraphX = Math.min(this.minGraphX, block.x);
this.maxGraphNodeX = Math.max(this.maxGraphNodeX, block.x + block.getWidth()); this.maxGraphNodeX = Math.max(this.maxGraphNodeX, block.x + block.getWidth());
......
...@@ -216,8 +216,8 @@ export class CodeView extends View { ...@@ -216,8 +216,8 @@ export class CodeView extends View {
} }
private getHtmlCodeLines(): NodeListOf<HTMLElement> { private getHtmlCodeLines(): NodeListOf<HTMLElement> {
const ordereList = this.divNode.querySelector(`#${this.getCodeHtmlElementName()} ol`); const orderList = this.divNode.querySelector(`#${this.getCodeHtmlElementName()} ol`);
return ordereList.childNodes as NodeListOf<HTMLElement>; return orderList.childNodes as NodeListOf<HTMLElement>;
} }
private onSelectLine(lineNumber: number, doClear: boolean) { private onSelectLine(lineNumber: number, doClear: boolean) {
......
...@@ -304,9 +304,6 @@ export class GraphView extends MovableView<Graph> { ...@@ -304,9 +304,6 @@ export class GraphView extends MovableView<Graph> {
case 80: // 'p' case 80: // 'p'
this.selectOrigins(); this.selectOrigins();
break; break;
default:
eventHandled = false;
break;
case 83: // 's' case 83: // 's'
if (!d3.event.ctrlKey && !d3.event.shiftKey) { if (!d3.event.ctrlKey && !d3.event.shiftKey) {
this.hideSelectedAction(this); this.hideSelectedAction(this);
...@@ -321,6 +318,9 @@ export class GraphView extends MovableView<Graph> { ...@@ -321,6 +318,9 @@ export class GraphView extends MovableView<Graph> {
eventHandled = false; eventHandled = false;
} }
break; break;
default:
eventHandled = false;
break;
} }
if (eventHandled) d3.event.preventDefault(); if (eventHandled) d3.event.preventDefault();
} }
......
...@@ -224,7 +224,7 @@ export abstract class MovableView<GraphType extends Graph | TurboshaftGraph> ext ...@@ -224,7 +224,7 @@ export abstract class MovableView<GraphType extends Graph | TurboshaftGraph> ext
} }
} }
protected showVisible() { protected showVisible(): void {
this.updateGraphVisibility(); this.updateGraphVisibility();
this.viewWholeGraph(); this.viewWholeGraph();
this.focusOnSvg(); this.focusOnSvg();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment