Commit 0c09e615 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[turbolizer] Add more types to graph layout

This is a step towards removing all instances of implicit any types
from turbolizer.

This CL also replaces var with const/let. This improves readability
and warnings.

Change-Id: I67c2974df209f857e67dfdbb743ce695ce861982
Notry: true
Bug: v8:7327
Reviewed-on: https://chromium-review.googlesource.com/c/1396419
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58572}
parent c0f62209
...@@ -10,16 +10,15 @@ import { Graph } from "./graph"; ...@@ -10,16 +10,15 @@ import { Graph } from "./graph";
const DEFAULT_NODE_ROW_SEPARATION = 130 const DEFAULT_NODE_ROW_SEPARATION = 130
const traceLayout = false;
var traceLayout = false;
function newGraphOccupation(graph: Graph) { function newGraphOccupation(graph: Graph) {
var isSlotFilled = []; const isSlotFilled = [];
var maxSlot = 0; let maxSlot = 0;
var minSlot = 0; let minSlot = 0;
var nodeOccupation = []; let nodeOccupation: Array<[number, number]> = [];
function slotToIndex(slot) { function slotToIndex(slot: number) {
if (slot >= 0) { if (slot >= 0) {
return slot * 2; return slot * 2;
} else { } else {
...@@ -27,24 +26,24 @@ function newGraphOccupation(graph: Graph) { ...@@ -27,24 +26,24 @@ function newGraphOccupation(graph: Graph) {
} }
} }
function positionToSlot(pos) { function positionToSlot(pos: number) {
return Math.floor(pos / NODE_INPUT_WIDTH); return Math.floor(pos / NODE_INPUT_WIDTH);
} }
function slotToLeftPosition(slot) { function slotToLeftPosition(slot: number) {
return slot * NODE_INPUT_WIDTH return slot * NODE_INPUT_WIDTH
} }
function findSpace(pos, width, direction) { function findSpace(pos: number, width: number, direction: number) {
var widthSlots = Math.floor((width + NODE_INPUT_WIDTH - 1) / const widthSlots = Math.floor((width + NODE_INPUT_WIDTH - 1) /
NODE_INPUT_WIDTH); NODE_INPUT_WIDTH);
var currentSlot = positionToSlot(pos + width / 2); const currentSlot = positionToSlot(pos + width / 2);
var currentScanSlot = currentSlot; let currentScanSlot = currentSlot;
var widthSlotsRemainingLeft = widthSlots; let widthSlotsRemainingLeft = widthSlots;
var widthSlotsRemainingRight = widthSlots; let widthSlotsRemainingRight = widthSlots;
var slotsChecked = 0; let slotsChecked = 0;
while (true) { while (true) {
var mod = slotsChecked++ % 2; const mod = slotsChecked++ % 2;
currentScanSlot = currentSlot + (mod ? -1 : 1) * (slotsChecked >> 1); currentScanSlot = currentSlot + (mod ? -1 : 1) * (slotsChecked >> 1);
if (!isSlotFilled[slotToIndex(currentScanSlot)]) { if (!isSlotFilled[slotToIndex(currentScanSlot)]) {
if (mod) { if (mod) {
...@@ -72,7 +71,7 @@ function newGraphOccupation(graph: Graph) { ...@@ -72,7 +71,7 @@ function newGraphOccupation(graph: Graph) {
} }
} }
function setIndexRange(from, to, value) { function setIndexRange(from: number, to: number, value: boolean) {
if (to < from) { if (to < from) {
throw ("illegal slot range"); throw ("illegal slot range");
} }
...@@ -87,47 +86,47 @@ function newGraphOccupation(graph: Graph) { ...@@ -87,47 +86,47 @@ function newGraphOccupation(graph: Graph) {
} }
} }
function occupySlotRange(from, to) { function occupySlotRange(from: number, to: number) {
if (traceLayout) { if (traceLayout) {
console.log("Occupied [" + slotToLeftPosition(from) + " " + slotToLeftPosition(to + 1) + ")"); console.log("Occupied [" + slotToLeftPosition(from) + " " + slotToLeftPosition(to + 1) + ")");
} }
setIndexRange(from, to, true); setIndexRange(from, to, true);
} }
function clearSlotRange(from, to) { function clearSlotRange(from: number, to: number) {
if (traceLayout) { if (traceLayout) {
console.log("Cleared [" + slotToLeftPosition(from) + " " + slotToLeftPosition(to + 1) + ")"); console.log("Cleared [" + slotToLeftPosition(from) + " " + slotToLeftPosition(to + 1) + ")");
} }
setIndexRange(from, to, false); setIndexRange(from, to, false);
} }
function occupyPositionRange(from, to) { function occupyPositionRange(from: number, to: number) {
occupySlotRange(positionToSlot(from), positionToSlot(to - 1)); occupySlotRange(positionToSlot(from), positionToSlot(to - 1));
} }
function clearPositionRange(from, to) { function clearPositionRange(from: number, to: number) {
clearSlotRange(positionToSlot(from), positionToSlot(to - 1)); clearSlotRange(positionToSlot(from), positionToSlot(to - 1));
} }
function occupyPositionRangeWithMargin(from, to, margin) { function occupyPositionRangeWithMargin(from: number, to: number, margin: number) {
var fromMargin = from - Math.floor(margin); const fromMargin = from - Math.floor(margin);
var toMargin = to + Math.floor(margin); const toMargin = to + Math.floor(margin);
occupyPositionRange(fromMargin, toMargin); occupyPositionRange(fromMargin, toMargin);
} }
function clearPositionRangeWithMargin(from, to, margin) { function clearPositionRangeWithMargin(from: number, to: number, margin: number) {
var fromMargin = from - Math.floor(margin); const fromMargin = from - Math.floor(margin);
var toMargin = to + Math.floor(margin); const toMargin = to + Math.floor(margin);
clearPositionRange(fromMargin, toMargin); clearPositionRange(fromMargin, toMargin);
} }
var occupation = { const occupation = {
occupyNodeInputs: function (node: GNode, showTypes: boolean) { occupyNodeInputs: function (node: GNode, showTypes: boolean) {
for (var i = 0; i < node.inputs.length; ++i) { for (let i = 0; i < node.inputs.length; ++i) {
if (node.inputs[i].isVisible()) { if (node.inputs[i].isVisible()) {
var edge = node.inputs[i]; const edge = node.inputs[i];
if (!edge.isBackEdge()) { if (!edge.isBackEdge()) {
var horizontalPos = edge.getInputHorizontalPosition(graph, showTypes); const horizontalPos = edge.getInputHorizontalPosition(graph, showTypes);
if (traceLayout) { if (traceLayout) {
console.log("Occupying input " + i + " of " + node.id + " at " + horizontalPos); console.log("Occupying input " + i + " of " + node.id + " at " + horizontalPos);
} }
...@@ -138,19 +137,19 @@ function newGraphOccupation(graph: Graph) { ...@@ -138,19 +137,19 @@ function newGraphOccupation(graph: Graph) {
} }
} }
}, },
occupyNode: function (node) { occupyNode: function (node: GNode) {
var getPlacementHint = function (n) { const getPlacementHint = function (n: GNode) {
var pos = 0; let pos = 0;
var direction = -1; let direction = -1;
var outputEdges = 0; let outputEdges = 0;
var inputEdges = 0; let inputEdges = 0;
for (var k = 0; k < n.outputs.length; ++k) { for (let k = 0; k < n.outputs.length; ++k) {
var outputEdge = n.outputs[k]; const outputEdge = n.outputs[k];
if (outputEdge.isVisible()) { if (outputEdge.isVisible()) {
var output = n.outputs[k].target; const output = n.outputs[k].target;
for (var l = 0; l < output.inputs.length; ++l) { for (let l = 0; l < output.inputs.length; ++l) {
if (output.rank > n.rank) { if (output.rank > n.rank) {
var inputEdge = output.inputs[l]; const inputEdge = output.inputs[l];
if (inputEdge.isVisible()) { if (inputEdge.isVisible()) {
++inputEdges; ++inputEdges;
} }
...@@ -173,18 +172,18 @@ function newGraphOccupation(graph: Graph) { ...@@ -173,18 +172,18 @@ function newGraphOccupation(graph: Graph) {
} }
return [direction, pos]; return [direction, pos];
} }
var width = node.getTotalNodeWidth(); const width = node.getTotalNodeWidth();
var margin = MINIMUM_EDGE_SEPARATION; const margin = MINIMUM_EDGE_SEPARATION;
var paddedWidth = width + 2 * margin; const paddedWidth = width + 2 * margin;
var placementHint = getPlacementHint(node); const placementHint = getPlacementHint(node);
var x = placementHint[1] - paddedWidth + margin; const x = placementHint[1] - paddedWidth + margin;
if (traceLayout) { if (traceLayout) {
console.log("Node " + node.id + " placement hint [" + x + ", " + (x + paddedWidth) + ")"); console.log("Node " + node.id + " placement hint [" + x + ", " + (x + paddedWidth) + ")");
} }
var placement = findSpace(x, paddedWidth, placementHint[0]); const placement = findSpace(x, paddedWidth, placementHint[0]);
var firstSlot = placement[0]; const firstSlot = placement[0];
var slotWidth = placement[1]; const slotWidth = placement[1];
var endSlotExclusive = firstSlot + slotWidth - 1; const endSlotExclusive = firstSlot + slotWidth - 1;
occupySlotRange(firstSlot, endSlotExclusive); occupySlotRange(firstSlot, endSlotExclusive);
nodeOccupation.push([firstSlot, endSlotExclusive]); nodeOccupation.push([firstSlot, endSlotExclusive]);
if (placementHint[0] < 0) { if (placementHint[0] < 0) {
...@@ -196,18 +195,18 @@ function newGraphOccupation(graph: Graph) { ...@@ -196,18 +195,18 @@ function newGraphOccupation(graph: Graph) {
} }
}, },
clearOccupiedNodes: function () { clearOccupiedNodes: function () {
nodeOccupation.forEach(function (o) { nodeOccupation.forEach(([firstSlot, endSlotExclusive]) => {
clearSlotRange(o[0], o[1]); clearSlotRange(firstSlot, endSlotExclusive);
}); });
nodeOccupation = []; nodeOccupation = [];
}, },
clearNodeOutputs: function (source: GNode, showTypes: boolean) { clearNodeOutputs: function (source: GNode, showTypes: boolean) {
source.outputs.forEach(function (edge) { source.outputs.forEach(function (edge) {
if (edge.isVisible()) { if (edge.isVisible()) {
var target = edge.target; const target = edge.target;
for (var i = 0; i < target.inputs.length; ++i) { for (let i = 0; i < target.inputs.length; ++i) {
if (target.inputs[i].source === source) { if (target.inputs[i].source === source) {
var horizontalPos = edge.getInputHorizontalPosition(graph, showTypes); const horizontalPos = edge.getInputHorizontalPosition(graph, showTypes);
clearPositionRangeWithMargin(horizontalPos, clearPositionRangeWithMargin(horizontalPos,
horizontalPos, horizontalPos,
NODE_INPUT_WIDTH / 2); NODE_INPUT_WIDTH / 2);
...@@ -217,8 +216,8 @@ function newGraphOccupation(graph: Graph) { ...@@ -217,8 +216,8 @@ function newGraphOccupation(graph: Graph) {
}); });
}, },
print: function () { print: function () {
var s = ""; let s = "";
for (var currentSlot = -40; currentSlot < 40; ++currentSlot) { for (let currentSlot = -40; currentSlot < 40; ++currentSlot) {
if (currentSlot != 0) { if (currentSlot != 0) {
s += " "; s += " ";
} else { } else {
...@@ -227,7 +226,7 @@ function newGraphOccupation(graph: Graph) { ...@@ -227,7 +226,7 @@ function newGraphOccupation(graph: Graph) {
} }
console.log(s); console.log(s);
s = ""; s = "";
for (var currentSlot2 = -40; currentSlot2 < 40; ++currentSlot2) { for (let currentSlot2 = -40; currentSlot2 < 40; ++currentSlot2) {
if (isSlotFilled[slotToIndex(currentSlot2)]) { if (isSlotFilled[slotToIndex(currentSlot2)]) {
s += "*"; s += "*";
} else { } else {
...@@ -258,10 +257,10 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void { ...@@ -258,10 +257,10 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void {
}); });
// Finialize the list of start and end nodes. // Finialize the list of start and end nodes.
var endNodes = []; const endNodes: Array<GNode> = [];
var startNodes = []; const startNodes: Array<GNode> = [];
var visited = []; let visited: Array<boolean> = [];
var rank = []; const rank: Array<number> = [];
for (const n of graph.nodes()) { for (const n of graph.nodes()) {
if (endNodesHasNoOutputs[n.id]) { if (endNodesHasNoOutputs[n.id]) {
endNodes.push(n); endNodes.push(n);
...@@ -280,36 +279,38 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void { ...@@ -280,36 +279,38 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void {
console.log(`layoutGraph init ${performance.now() - start}`); console.log(`layoutGraph init ${performance.now() - start}`);
} }
var maxRank = 0; let maxRank = 0;
var visited = []; visited = [];
var visitOrderWithinRank = 0; let visitOrderWithinRank = 0;
var worklist = startNodes.slice(); const worklist: Array<GNode> = startNodes.slice();
while (worklist.length != 0) { while (worklist.length != 0) {
var n = worklist.pop(); const n: GNode = worklist.pop();
var changed = false; let changed = false;
if (n.rank == MAX_RANK_SENTINEL) { if (n.rank == MAX_RANK_SENTINEL) {
n.rank = 1; n.rank = 1;
changed = true; changed = true;
} }
var begin = 0; let begin = 0;
var end = n.inputs.length; let end = n.inputs.length;
if (n.opcode == 'Phi' || n.opcode == 'EffectPhi') { if (n.nodeLabel.opcode == 'Phi' ||
n.nodeLabel.opcode == 'EffectPhi' ||
n.nodeLabel.opcode == 'InductionVariablePhi') {
// Keep with merge or loop node // Keep with merge or loop node
begin = n.inputs.length - 1; begin = n.inputs.length - 1;
} else if (n.hasBackEdges()) { } else if (n.hasBackEdges()) {
end = 1; end = 1;
} }
for (var l = begin; l < end; ++l) { for (let l = begin; l < end; ++l) {
var input = n.inputs[l].source; const input = n.inputs[l].source;
if (input.visible && input.rank >= n.rank) { if (input.visible && input.rank >= n.rank) {
n.rank = input.rank + 1; n.rank = input.rank + 1;
changed = true; changed = true;
} }
} }
if (changed) { if (changed) {
var hasBackEdges = n.hasBackEdges(); const hasBackEdges = n.hasBackEdges();
for (var l = n.outputs.length - 1; l >= 0; --l) { for (let l = n.outputs.length - 1; l >= 0; --l) {
if (hasBackEdges && (l != 0)) { if (hasBackEdges && (l != 0)) {
worklist.unshift(n.outputs[l].target); worklist.unshift(n.outputs[l].target);
} else { } else {
...@@ -330,18 +331,18 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void { ...@@ -330,18 +331,18 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void {
function dfsFindRankLate(n: GNode) { function dfsFindRankLate(n: GNode) {
if (visited[n.id]) return; if (visited[n.id]) return;
visited[n.id] = true; visited[n.id] = true;
var originalRank = n.rank; const originalRank = n.rank;
var newRank = n.rank; let newRank = n.rank;
var firstInput = true; let isFirstInput = true;
for (var l = 0; l < n.outputs.length; ++l) { for (let l = 0; l < n.outputs.length; ++l) {
var output = n.outputs[l].target; const output = n.outputs[l].target;
dfsFindRankLate(output); dfsFindRankLate(output);
var outputRank = output.rank; const outputRank = output.rank;
if (output.visible && (firstInput || outputRank <= newRank) && if (output.visible && (isFirstInput || outputRank <= newRank) &&
(outputRank > originalRank)) { (outputRank > originalRank)) {
newRank = outputRank - 1; newRank = outputRank - 1;
} }
firstInput = false; isFirstInput = false;
} }
if (n.nodeLabel.opcode != "Start" && n.nodeLabel.opcode != "Phi" && n.nodeLabel.opcode != "EffectPhi" && n.nodeLabel.opcode != "InductionVariablePhi") { if (n.nodeLabel.opcode != "Start" && n.nodeLabel.opcode != "Phi" && n.nodeLabel.opcode != "EffectPhi" && n.nodeLabel.opcode != "InductionVariablePhi") {
n.rank = newRank; n.rank = newRank;
...@@ -354,10 +355,10 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void { ...@@ -354,10 +355,10 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void {
function dfsRankOrder(n: GNode) { function dfsRankOrder(n: GNode) {
if (visited[n.id]) return; if (visited[n.id]) return;
visited[n.id] = true; visited[n.id] = true;
for (var l = 0; l < n.outputs.length; ++l) { for (let l = 0; l < n.outputs.length; ++l) {
var edge = n.outputs[l]; const edge = n.outputs[l];
if (edge.isVisible()) { if (edge.isVisible()) {
var output = edge.target; const output = edge.target;
dfsRankOrder(output); dfsRankOrder(output);
} }
} }
...@@ -388,11 +389,11 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void { ...@@ -388,11 +389,11 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void {
// Iterate backwards from highest to lowest rank, placing nodes so that they // Iterate backwards from highest to lowest rank, placing nodes so that they
// spread out from the "center" as much as possible while still being // spread out from the "center" as much as possible while still being
// compact and not overlapping live input lines. // compact and not overlapping live input lines.
var occupation = newGraphOccupation(graph); const occupation = newGraphOccupation(graph);
rankSets.reverse().forEach(function (rankSet: Array<GNode>) { rankSets.reverse().forEach(function (rankSet: Array<GNode>) {
for (var i = 0; i < rankSet.length; ++i) { for (let i = 0; i < rankSet.length; ++i) {
occupation.clearNodeOutputs(rankSet[i], showTypes); occupation.clearNodeOutputs(rankSet[i], showTypes);
} }
...@@ -401,7 +402,7 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void { ...@@ -401,7 +402,7 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void {
occupation.print(); occupation.print();
} }
var placedCount = 0; let placedCount = 0;
rankSet = rankSet.sort((a: GNode, b: GNode) => { rankSet = rankSet.sort((a: GNode, b: GNode) => {
if (a.visitOrderWithinRank < b.visitOrderWithinRank) { if (a.visitOrderWithinRank < b.visitOrderWithinRank) {
return -1 return -1
...@@ -411,15 +412,16 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void { ...@@ -411,15 +412,16 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void {
return 1; return 1;
} }
}); });
for (var i = 0; i < rankSet.length; ++i) {
var nodeToPlace = rankSet[i]; for (let i = 0; i < rankSet.length; ++i) {
const nodeToPlace = rankSet[i];
if (nodeToPlace.visible) { if (nodeToPlace.visible) {
nodeToPlace.x = occupation.occupyNode(nodeToPlace); nodeToPlace.x = occupation.occupyNode(nodeToPlace);
if (traceLayout) { if (traceLayout) {
console.log("Node " + nodeToPlace.id + " is placed between [" + nodeToPlace.x + ", " + (nodeToPlace.x + nodeToPlace.getTotalNodeWidth()) + ")"); console.log("Node " + nodeToPlace.id + " is placed between [" + nodeToPlace.x + ", " + (nodeToPlace.x + nodeToPlace.getTotalNodeWidth()) + ")");
} }
var staggeredFlooredI = Math.floor(placedCount++ % 3); const staggeredFlooredI = Math.floor(placedCount++ % 3);
var delta = MINIMUM_EDGE_SEPARATION * staggeredFlooredI const delta = MINIMUM_EDGE_SEPARATION * staggeredFlooredI
nodeToPlace.outputApproach += delta; nodeToPlace.outputApproach += delta;
} else { } else {
nodeToPlace.x = 0; nodeToPlace.x = 0;
...@@ -438,8 +440,8 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void { ...@@ -438,8 +440,8 @@ export function layoutNodeGraph(graph: Graph, showTypes: boolean): void {
occupation.print(); occupation.print();
} }
for (var i = 0; i < rankSet.length; ++i) { for (let i = 0; i < rankSet.length; ++i) {
var node = rankSet[i]; const node = rankSet[i];
occupation.occupyNodeInputs(node, showTypes); occupation.occupyNodeInputs(node, showTypes);
} }
......
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