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 {
background-color: #FFFF33 !important;
}
.linenums li > span {
user-select: text;
}
li.selected .line-number {
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 @@
</table>
</div>
</div>
<div id="info-graph-view" class="info-topic">
<div class="info-topic-header">Graph view</div>
<div id="info-common-graph-view" class="info-topic">
<div class="info-topic-header">Sea of Nodes/Turboshaft graph view</div>
<div class="info-topic-content">
<table>
<tr>
......@@ -38,6 +38,13 @@
<td>/</td>
<td>Select search box</td>
</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>
<td>i</td>
<td>Reveal node's input nodes</td>
......@@ -57,8 +64,35 @@
</table>
</div>
</div>
<div id="info-graph-nodes" class="info-topic">
<div class="info-topic-header">TurboFan graph nodes</div>
<div id="info-turboshaft-graph-view" class="info-topic">
<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>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
......@@ -72,6 +106,13 @@
<td>DOWN</td>
<td>Select all output nodes</td>
</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>
<td>1-9</td>
<td>Select input node 1-9</td>
......@@ -96,7 +137,7 @@
</div>
</div>
<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">
<table>
<tr>
......
......@@ -89,3 +89,8 @@ export function storageSetItem(key: string, value: any): void {
export function storageSetIfIsNotExist(key: string, toSet: any): void {
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
return this.width;
}
public compressHeight(): void {
if (this.collapsed) {
this.height = this.getHeight(null);
this.showProperties = null;
}
}
public getRankIndent() {
return this.rank * (C.TURBOSHAFT_BLOCK_ROW_SEPARATION + 2 * C.DEFAULT_NODE_BUBBLE_RADIUS);
}
......
......@@ -6,10 +6,7 @@ import * as C from "./common/constants";
import { TurboshaftGraph } from "./turboshaft-graph";
import { GraphStateType } from "./phases/phase";
import { LayoutOccupation } from "./layout-occupation";
import {
TurboshaftGraphBlock,
TurboshaftGraphBlockType
} from "./phases/turboshaft-graph-phase/turboshaft-graph-block";
import { TurboshaftGraphBlock } from "./phases/turboshaft-graph-phase/turboshaft-graph-block";
export class TurboshaftGraphLayout {
graph: TurboshaftGraph;
......@@ -46,9 +43,7 @@ export class TurboshaftGraphLayout {
const blocks = this.initBlocks();
this.initWorkList(blocks);
let visited = new Array<boolean>();
blocks.forEach((block: TurboshaftGraphBlock) => this.dfsFindRankLate(visited, block));
visited = new Array<boolean>();
const visited = new Array<boolean>();
blocks.forEach((block: TurboshaftGraphBlock) => this.dfsRankOrder(visited, block));
const rankSets = this.getRankSets(showProperties);
......@@ -90,24 +85,21 @@ export class TurboshaftGraphLayout {
}
private initWorkList(blocks: Array<TurboshaftGraphBlock>): void {
const workList: Array<TurboshaftGraphBlock> = blocks.slice();
const workList = blocks.slice();
while (workList.length != 0) {
const block: TurboshaftGraphBlock = workList.pop();
const block = workList.pop();
let changed = false;
if (block.rank == C.MAX_RANK_SENTINEL) {
block.rank = 1;
changed = true;
}
let begin = 0;
let end = block.inputs.length;
if (block.type == TurboshaftGraphBlockType.Merge && block.inputs.length > 0) {
begin = block.inputs.length - 1;
} else if (block.hasBackEdges()) {
if (block.hasBackEdges()) {
end = 1;
}
for (let l = begin; l < end; ++l) {
for (let l = 0; l < end; ++l) {
const input = block.inputs[l].source;
if (input.visible && input.rank >= block.rank) {
if (input.rank >= block.rank) {
block.rank = input.rank + 1;
changed = true;
}
......@@ -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 {
if (visited[block.id]) return;
visited[block.id] = true;
......@@ -163,25 +134,18 @@ export class TurboshaftGraphLayout {
}
private getRankSets(showProperties: boolean): Array<Array<TurboshaftGraphBlock>> {
const rankMaxBlockHeight = new Array<number>();
for (const block of this.graph.blocks()) {
rankMaxBlockHeight[block.rank] = Math.max(rankMaxBlockHeight[block.rank] ?? 0,
block.getHeight(showProperties));
}
const ranksMaxBlockHeight = this.graph.getRanksMaxBlockHeight(showProperties);
const rankSets = new Array<Array<TurboshaftGraphBlock>>();
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;
}, block.rank * (C.TURBOSHAFT_BLOCK_ROW_SEPARATION + 2 * C.DEFAULT_NODE_BUBBLE_RADIUS));
if (block.visible) {
}, block.getRankIndent());
if (!rankSets[block.rank]) {
rankSets[block.rank] = new Array<TurboshaftGraphBlock>(block);
} else {
rankSets[block.rank].push(block);
}
}
}
return rankSets;
}
......@@ -199,16 +163,12 @@ export class TurboshaftGraphLayout {
let placedCount = 0;
rankSet = rankSet.sort((a: TurboshaftGraphBlock, b: TurboshaftGraphBlock) => a.compare(b));
for (const block of rankSet) {
if (block.visible) {
block.x = this.layoutOccupation.occupy(block);
const blockWidth = block.getWidth();
this.trace(`Block ${block.id} is placed between [${block.x}, ${block.x + blockWidth})`);
const staggeredFlooredI = Math.floor(placedCount++ % 3);
const delta = C.MINIMUM_EDGE_SEPARATION * staggeredFlooredI;
block.outputApproach += delta;
} else {
block.x = 0;
}
}
this.traceOccupation("Before clearing blocks");
......
......@@ -61,8 +61,6 @@ export class TurboshaftGraph extends MovableContainer<TurboshaftGraphPhase> {
this.maxGraphY = 1;
for (const block of this.blocks()) {
if (!block.visible) continue;
this.minGraphX = Math.min(this.minGraphX, block.x);
this.maxGraphNodeX = Math.max(this.maxGraphNodeX, block.x + block.getWidth());
......
......@@ -216,8 +216,8 @@ export class CodeView extends View {
}
private getHtmlCodeLines(): NodeListOf<HTMLElement> {
const ordereList = this.divNode.querySelector(`#${this.getCodeHtmlElementName()} ol`);
return ordereList.childNodes as NodeListOf<HTMLElement>;
const orderList = this.divNode.querySelector(`#${this.getCodeHtmlElementName()} ol`);
return orderList.childNodes as NodeListOf<HTMLElement>;
}
private onSelectLine(lineNumber: number, doClear: boolean) {
......
......@@ -304,9 +304,6 @@ export class GraphView extends MovableView<Graph> {
case 80: // 'p'
this.selectOrigins();
break;
default:
eventHandled = false;
break;
case 83: // 's'
if (!d3.event.ctrlKey && !d3.event.shiftKey) {
this.hideSelectedAction(this);
......@@ -321,6 +318,9 @@ export class GraphView extends MovableView<Graph> {
eventHandled = false;
}
break;
default:
eventHandled = false;
break;
}
if (eventHandled) d3.event.preventDefault();
}
......
......@@ -224,7 +224,7 @@ export abstract class MovableView<GraphType extends Graph | TurboshaftGraph> ext
}
}
protected showVisible() {
protected showVisible(): void {
this.updateGraphVisibility();
this.viewWholeGraph();
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