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