[turbolizer] Move methods from source resolver to corresponding phases

- source resolver clean up
- started inregration of turboshaft schedule phase

Bug: v8:7327
Change-Id: I4335c275f4cfb2e313ac383a5b9fa12c7b9aa744
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3700078
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Danylo Boiko <danielboyko02@gmail.com>
Cr-Commit-Position: refs/heads/main@{#81164}
This commit is contained in:
Danylo Boiko 2022-06-14 18:04:39 +03:00 committed by V8 LUCI CQ
parent 00fe5f5e65
commit 9f7c28b805
13 changed files with 212 additions and 205 deletions

View File

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
export function anyToString(x: any): string {
return `${x}`;
export function anyToString(obj: any): string {
return `${obj}`;
}
export function snakeToCamel(str: string): string {
@ -18,7 +18,7 @@ export function camelize(obj: any): any {
if (Array.isArray(obj)) {
return obj.map(value => camelize(value));
} else if (obj !== null && obj.constructor === Object) {
return Object.keys(obj).reduce((result, key) => ({
return Object.keys(obj).reduce((result, key: string) => ({
...result,
[snakeToCamel(key)]: camelize(obj[key])
}), {},

View File

@ -0,0 +1,13 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
export class Interval {
start: number;
end: number;
constructor(numbers: [number, number]) {
this.start = numbers[0];
this.end = numbers[1];
}
}

View File

@ -17,6 +17,14 @@ export class DisassemblyPhase extends Phase {
this.blockStartPCtoBlockIds = new Map<number, Array<number>>();
}
public hasBlockStartInfo(): boolean {
return this.blockIdToOffset.length > 0;
}
public getBlockIdsForOffset(offset: number): Array<number> {
return this.blockStartPCtoBlockIds.get(offset);
}
public parseBlockIdToOffsetFromJSON(blockIdToOffsetJson): void {
if (!blockIdToOffsetJson) return;
for (const [blockId, offset] of Object.entries<number>(blockIdToOffsetJson)) {

View File

@ -10,8 +10,8 @@ import { BytecodeOrigin, NodeOrigin } from "../origin";
import { SourcePosition } from "../position";
export class GraphPhase extends Phase {
data: GraphData;
highestNodeId: number;
data: GraphData;
nodeLabelMap: Array<NodeLabel>;
nodeIdToNodeMap: Array<GNode>;

View File

@ -3,12 +3,14 @@
// found in the LICENSE file.
import { Phase, PhaseType } from "./phase";
import { anyToString } from "../common/util";
export class InstructionsPhase extends Phase {
// Maps node ids to instruction ranges.
nodeIdToInstructionRange?: Array<[number, number]>;
// Maps block ids to instruction ranges.
blockIdToInstructionRange?: Array<[number, number]>;
// Maps instruction offsets to PC offset.
instructionOffsetToPCOffset?: Array<[number, number]>;
codeOffsetsInfo?: CodeOffsetsInfo;
@ -31,6 +33,130 @@ export class InstructionsPhase extends Phase {
this.pcOffsets = new Array<number>();
}
public getKeyPcOffset(offset: number): number {
if (this.pcOffsets.length === 0) return -1;
for (const key of this.pcOffsets) {
if (key <= offset) {
return key;
}
}
return -1;
}
public instructionToPcOffsets(instruction: number): TurbolizerInstructionStartInfo {
return this.instructionToPCOffset[instruction];
}
public instructionsToKeyPcOffsets(instructionIds: Iterable<number>): Array<number> {
const keyPcOffsets = new Array<number>();
for (const instructionId of instructionIds) {
const pcOffset = this.instructionToPCOffset[instructionId];
if (pcOffset !== undefined) keyPcOffsets.push(pcOffset.gap);
}
return keyPcOffsets;
}
public nodesForPCOffset(offset: number): Array<string> {
if (this.pcOffsets.length === 0) return new Array<string>();
for (const key of this.pcOffsets) {
if (key <= offset) {
const instructions = this.pcOffsetToInstructions.get(key);
const nodes = new Array<string>();
for (const instruction of instructions) {
for (const [nodeId, range] of this.nodeIdToInstructionRange.entries()) {
if (!range) continue;
const [start, end] = range;
if (start == end && instruction == start) {
nodes.push(anyToString(nodeId));
}
if (start <= instruction && instruction < end) {
nodes.push(anyToString(nodeId));
}
}
}
return nodes;
}
}
return new Array<string>();
}
public nodesToKeyPcOffsets(nodeIds: Set<string>): Array<TurbolizerInstructionStartInfo> {
let offsets = new Array<TurbolizerInstructionStartInfo>();
for (const nodeId of nodeIds) {
const range = this.nodeIdToInstructionRange[nodeId];
if (!range) continue;
offsets = offsets.concat(this.instructionRangeToKeyPcOffsets(range));
}
return offsets;
}
public getInstruction(nodeId: number): [number, number] {
return this.nodeIdToInstructionRange[nodeId] ?? [-1, -1];
}
public getInstructionRangeForBlock(blockId: number): [number, number] {
return this.blockIdToInstructionRange[blockId] ?? [-1, -1];
}
public getInstructionKindForPCOffset(offset: number): InstructionKind {
if (this.codeOffsetsInfo) {
if (offset >= this.codeOffsetsInfo.deoptimizationExits) {
if (offset >= this.codeOffsetsInfo.pools) {
return InstructionKind.Pools;
} else if (offset >= this.codeOffsetsInfo.jumpTables) {
return InstructionKind.JumpTables;
} else {
return InstructionKind.DeoptimizationExits;
}
}
if (offset < this.codeOffsetsInfo.deoptCheck) {
return InstructionKind.CodeStartRegister;
} else if (offset < this.codeOffsetsInfo.initPoison) {
return InstructionKind.DeoptCheck;
} else if (offset < this.codeOffsetsInfo.blocksStart) {
return InstructionKind.InitPoison;
}
}
const keyOffset = this.getKeyPcOffset(offset);
if (keyOffset != -1) {
const infos = this.pcOffsetToInstructions.get(keyOffset)
.map(instrId => this.instructionToPCOffset[instrId])
.filter(info => info.gap !== info.condition);
if (infos.length > 0) {
const info = infos[0];
if (!info || info.gap == info.condition) return InstructionKind.Unknown;
if (offset < info.arch) return InstructionKind.Gap;
if (offset < info.condition) return InstructionKind.Arch;
return InstructionKind.Condition;
}
}
return InstructionKind.Unknown;
}
public instructionKindToReadableName(instructionKind: InstructionKind): string {
switch (instructionKind) {
case InstructionKind.CodeStartRegister:
return "Check code register for right value";
case InstructionKind.DeoptCheck:
return "Check if function was marked for deoptimization";
case InstructionKind.InitPoison:
return "Initialization of poison register";
case InstructionKind.Gap:
return "Instruction implementing a gap move";
case InstructionKind.Arch:
return "Instruction implementing the actual machine operation";
case InstructionKind.Condition:
return "Code implementing conditional after instruction";
case InstructionKind.Pools:
return "Data in a pool (e.g. constant pool)";
case InstructionKind.JumpTables:
return "Part of a jump table";
case InstructionKind.DeoptimizationExits:
return "Jump to deoptimization exit";
}
return null;
}
public parseNodeIdToInstructionRangeFromJSON(nodeIdToInstructionJson): void {
if (!nodeIdToInstructionJson) return;
for (const [nodeId, range] of Object.entries<[number, number]>(nodeIdToInstructionJson)) {
@ -74,6 +200,12 @@ export class InstructionsPhase extends Phase {
codeOffsetsInfoJson.deoptimizationExits, codeOffsetsInfoJson.pools,
codeOffsetsInfoJson.jumpTables);
}
private instructionRangeToKeyPcOffsets([start, end]: [number, number]):
Array<TurbolizerInstructionStartInfo> {
if (start == end) return [this.instructionToPCOffset[start]];
return this.instructionToPCOffset.slice(start, end);
}
}
export class CodeOffsetsInfo {
@ -111,3 +243,16 @@ export class TurbolizerInstructionStartInfo {
this.condition = condition;
}
}
export enum InstructionKind {
Pools = "pools",
JumpTables = "jump-tables",
DeoptimizationExits = "deoptimization-exits",
CodeStartRegister = "code-start-register",
DeoptCheck = "deopt-check",
InitPoison = "init-poison",
Gap = "gap",
Arch = "arch",
Condition = "condition",
Unknown = "unknown"
}

View File

@ -56,9 +56,10 @@ export class SelectionBroker {
}
// Select the lines from the source panel (left panel)
const pcOffsets = this.sourceResolver.instructionsToKeyPcOffsets(instructionOffsets);
const pcOffsets = this.sourceResolver.instructionsPhase
.instructionsToKeyPcOffsets(instructionOffsets);
for (const offset of pcOffsets) {
const nodes = this.sourceResolver.nodesForPCOffset(offset)[0];
const nodes = this.sourceResolver.instructionsPhase.nodesForPCOffset(offset);
const sourcePositions = this.sourceResolver.nodeIdsToSourcePositions(nodes);
for (const b of this.sourcePositionHandlers) {
if (b != from) b.brokeredSourcePositionSelect(sourcePositions, selected);
@ -89,7 +90,8 @@ export class SelectionBroker {
}
for (const node of nodes) {
const instructionOffsets = this.sourceResolver.nodeIdToInstructionRange[node];
const instructionOffsets = this.sourceResolver.instructionsPhase
.nodeIdToInstructionRange[node];
// Skip nodes which do not have an associated instruction range.
if (instructionOffsets == undefined) continue;
@ -118,7 +120,8 @@ export class SelectionBroker {
}
for (const node of nodes) {
const instructionOffsets = this.sourceResolver.nodeIdToInstructionRange[node];
const instructionOffsets = this.sourceResolver.instructionsPhase
.nodeIdToInstructionRange[node];
// Skip nodes which do not have an associated instruction range.
if (instructionOffsets == undefined) continue;
// Select the lines from the disassembly (right panel)

View File

@ -7,13 +7,13 @@ import { PhaseType } from "./phases/phase";
import { GraphPhase } from "./phases/graph-phase";
import { DisassemblyPhase } from "./phases/disassembly-phase";
import { BytecodePosition, InliningPosition, SourcePosition } from "./position";
import { CodeOffsetsInfo, InstructionsPhase,
TurbolizerInstructionStartInfo } from "./phases/instructions-phase";
import { InstructionsPhase } from "./phases/instructions-phase";
import { SchedulePhase } from "./phases/schedule-phase";
import { SequencePhase } from "./phases/sequence-phase";
import { BytecodeOrigin } from "./origin";
import { Source } from "./source";
import { NodeLabel } from "./node-label";
import { TurboshaftGraphPhase } from "./phases/turboshaft-graph-phase";
function sourcePositionLe(a, b) {
if (a.inliningId == b.inliningId) {
@ -44,18 +44,8 @@ export function sourcePositionValid(l) {
}
type GenericPosition = SourcePosition | BytecodePosition;
type GenericPhase = GraphPhase | DisassemblyPhase | InstructionsPhase
| SchedulePhase | SequencePhase;
export class Interval {
start: number;
end: number;
constructor(numbers: [number, number]) {
this.start = numbers[0];
this.end = numbers[1];
}
}
type GenericPhase = GraphPhase | TurboshaftGraphPhase | DisassemblyPhase
| InstructionsPhase | SchedulePhase | SequencePhase;
export class SourceResolver {
nodePositionMap: Array<GenericPosition>;
@ -68,14 +58,6 @@ export class SourceResolver {
disassemblyPhase: DisassemblyPhase;
instructionsPhase: InstructionsPhase;
linePositionMap: Map<string, Array<GenericPosition>>;
nodeIdToInstructionRange: Array<[number, number]>;
blockIdToInstructionRange: Array<[number, number]>;
instructionToPCOffset: Array<TurbolizerInstructionStartInfo>;
pcOffsetToInstructions: Map<number, Array<number>>;
pcOffsets: Array<number>;
blockIdToPCOffset: Array<number>;
blockStartPCtoBlockIds: Map<number, Array<number>>;
codeOffsetsInfo: CodeOffsetsInfo;
constructor() {
// Maps node ids to source positions.
@ -96,26 +78,6 @@ export class SourceResolver {
this.disassemblyPhase = undefined;
// Maps line numbers to source positions
this.linePositionMap = new Map();
// Maps node ids to instruction ranges.
this.nodeIdToInstructionRange = [];
// Maps block ids to instruction ranges.
this.blockIdToInstructionRange = [];
// Maps instruction numbers to PC offsets.
this.instructionToPCOffset = [];
// Maps PC offsets to instructions.
this.pcOffsetToInstructions = new Map();
this.pcOffsets = [];
this.blockIdToPCOffset = [];
this.blockStartPCtoBlockIds = new Map();
this.codeOffsetsInfo = null;
}
getBlockIdsForOffset(offset): Array<number> {
return this.blockStartPCtoBlockIds.get(offset);
}
hasBlockStartInfo() {
return this.blockIdToPCOffset.length > 0;
}
setSources(sources, mainBackup) {
@ -310,133 +272,6 @@ export class SourceResolver {
}
}
getInstruction(nodeId: number): [number, number] {
const X = this.nodeIdToInstructionRange[nodeId];
if (X === undefined) return [-1, -1];
return X;
}
getInstructionRangeForBlock(blockId: number): [number, number] {
const X = this.blockIdToInstructionRange[blockId];
if (X === undefined) return [-1, -1];
return X;
}
hasPCOffsets() {
return this.pcOffsetToInstructions.size > 0;
}
getKeyPcOffset(offset: number): number {
if (this.pcOffsets.length === 0) return -1;
for (const key of this.pcOffsets) {
if (key <= offset) {
return key;
}
}
return -1;
}
getInstructionKindForPCOffset(offset: number) {
if (this.codeOffsetsInfo) {
if (offset >= this.codeOffsetsInfo.deoptimizationExits) {
if (offset >= this.codeOffsetsInfo.pools) {
return "pools";
} else if (offset >= this.codeOffsetsInfo.jumpTables) {
return "jump-tables";
} else {
return "deoptimization-exits";
}
}
if (offset < this.codeOffsetsInfo.deoptCheck) {
return "code-start-register";
} else if (offset < this.codeOffsetsInfo.initPoison) {
return "deopt-check";
} else if (offset < this.codeOffsetsInfo.blocksStart) {
return "init-poison";
}
}
const keyOffset = this.getKeyPcOffset(offset);
if (keyOffset != -1) {
const infos = this.pcOffsetToInstructions.get(keyOffset).map(instrId => this.instructionToPCOffset[instrId]).filter(info => info.gap != info.condition);
if (infos.length > 0) {
const info = infos[0];
if (!info || info.gap == info.condition) return "unknown";
if (offset < info.arch) return "gap";
if (offset < info.condition) return "arch";
return "condition";
}
}
return "unknown";
}
instructionKindToReadableName(instructionKind) {
switch (instructionKind) {
case "code-start-register": return "Check code register for right value";
case "deopt-check": return "Check if function was marked for deoptimization";
case "init-poison": return "Initialization of poison register";
case "gap": return "Instruction implementing a gap move";
case "arch": return "Instruction implementing the actual machine operation";
case "condition": return "Code implementing conditional after instruction";
case "pools": return "Data in a pool (e.g. constant pool)";
case "jump-tables": return "Part of a jump table";
case "deoptimization-exits": return "Jump to deoptimization exit";
}
return null;
}
instructionRangeToKeyPcOffsets([start, end]: [number, number]): Array<TurbolizerInstructionStartInfo> {
if (start == end) return [this.instructionToPCOffset[start]];
return this.instructionToPCOffset.slice(start, end);
}
instructionToPcOffsets(instr: number): TurbolizerInstructionStartInfo {
return this.instructionToPCOffset[instr];
}
instructionsToKeyPcOffsets(instructionIds: Iterable<number>): Array<number> {
const keyPcOffsets = [];
for (const instructionId of instructionIds) {
const pcOffset = this.instructionToPCOffset[instructionId];
if (pcOffset !== undefined) keyPcOffsets.push(pcOffset.gap);
}
return keyPcOffsets;
}
nodesToKeyPcOffsets(nodes) {
let offsets = [];
for (const node of nodes) {
const range = this.nodeIdToInstructionRange[node];
if (!range) continue;
offsets = offsets.concat(this.instructionRangeToKeyPcOffsets(range));
}
return offsets;
}
nodesForPCOffset(offset: number): [Array<string>, Array<string>] {
if (this.pcOffsets.length === 0) return [[], []];
for (const key of this.pcOffsets) {
if (key <= offset) {
const instrs = this.pcOffsetToInstructions.get(key);
const nodes = [];
const blocks = [];
for (const instr of instrs) {
for (const [nodeId, range] of this.nodeIdToInstructionRange.entries()) {
if (!range) continue;
const [start, end] = range;
if (start == end && instr == start) {
nodes.push("" + nodeId);
}
if (start <= instr && instr < end) {
nodes.push("" + nodeId);
}
}
}
return [nodes, blocks];
}
}
return [[], []];
}
public parsePhases(phasesJson): void {
const nodeLabelMap = new Array<NodeLabel>();
for (const [, genericPhase] of Object.entries<GenericPhase>(phasesJson)) {
@ -447,10 +282,6 @@ export class SourceResolver {
castedDisassembly.data);
disassemblyPhase.parseBlockIdToOffsetFromJSON(castedDisassembly?.blockIdToOffset);
this.disassemblyPhase = disassemblyPhase;
// Will be taken from the class
this.blockIdToPCOffset = disassemblyPhase.blockIdToOffset;
this.blockStartPCtoBlockIds = disassemblyPhase.blockStartPCtoBlockIds;
break;
case PhaseType.Schedule:
const castedSchedule = genericPhase as SchedulePhase;
@ -484,14 +315,6 @@ export class SourceResolver {
instructionsPhase.parseCodeOffsetsInfoFromJSON(castedInstructions
?.codeOffsetsInfo);
this.instructionsPhase = instructionsPhase;
// Will be taken from the class
this.nodeIdToInstructionRange = instructionsPhase.nodeIdToInstructionRange;
this.blockIdToInstructionRange = instructionsPhase.blockIdToInstructionRange;
this.codeOffsetsInfo = instructionsPhase.codeOffsetsInfo;
this.instructionToPCOffset = instructionsPhase.instructionToPCOffset;
this.pcOffsetToInstructions = instructionsPhase.pcOffsetToInstructions;
this.pcOffsets = instructionsPhase.pcOffsets;
break;
case PhaseType.Graph:
const castedGraph = genericPhase as GraphPhase;
@ -502,6 +325,9 @@ export class SourceResolver {
this.phaseNames.set(graphPhase.name, this.phases.length);
this.phases.push(graphPhase);
break;
case PhaseType.TurboshaftGraph:
// Allow to avoid exception and view turboshaft schedule phase
break;
default:
throw "Unsupported phase type";
}

View File

@ -8,6 +8,7 @@ import { TextView } from "./text-view";
import { MySelection } from "../selection/selection";
import { anyToString, interpolate } from "../common/util";
import { InstructionSelectionHandler } from "../selection/selection-handler";
import { TurbolizerInstructionStartInfo } from "../phases/instructions-phase";
const toolboxHTML = `<div id="disassembly-toolbox">
<form>
@ -48,10 +49,12 @@ export class DisassemblyView extends TextView {
associateData: (text, fragment: HTMLElement) => {
const matches = text.match(/(?<address>0?x?[0-9a-fA-F]{8,16})(?<addressSpace>\s+)(?<offset>[0-9a-f]+)(?<offsetSpace>\s*)/);
const offset = Number.parseInt(matches.groups["offset"], 16);
const instructionKind = view.sourceResolver.getInstructionKindForPCOffset(offset);
const instructionKind = view.sourceResolver.instructionsPhase
.getInstructionKindForPCOffset(offset);
fragment.dataset.instructionKind = instructionKind;
fragment.title = view.sourceResolver.instructionKindToReadableName(instructionKind);
const blockIds = view.sourceResolver.getBlockIdsForOffset(offset);
fragment.title = view.sourceResolver.instructionsPhase
.instructionKindToReadableName(instructionKind);
const blockIds = view.sourceResolver.disassemblyPhase.getBlockIdsForOffset(offset);
const blockIdElement = document.createElement("SPAN");
blockIdElement.className = "block-id com linkable-text";
blockIdElement.innerText = "";
@ -73,7 +76,7 @@ export class DisassemblyView extends TextView {
fragment.classList.add('tag');
if (!Number.isNaN(offset)) {
let pcOffset = view.sourceResolver.getKeyPcOffset(offset);
let pcOffset = view.sourceResolver.instructionsPhase.getKeyPcOffset(offset);
if (pcOffset == -1) pcOffset = Number(offset);
fragment.dataset.pcOffset = `${pcOffset}`;
addressElement.classList.add('linkable-text');
@ -96,9 +99,9 @@ export class DisassemblyView extends TextView {
fragment.innerHTML = text;
const replacer = (match, hexOffset) => {
const offset = Number.parseInt(hexOffset, 16);
let keyOffset = view.sourceResolver.getKeyPcOffset(offset);
let keyOffset = view.sourceResolver.instructionsPhase.getKeyPcOffset(offset);
if (keyOffset == -1) keyOffset = Number(offset);
const blockIds = view.sourceResolver.getBlockIdsForOffset(offset);
const blockIds = view.sourceResolver.disassemblyPhase.getBlockIdsForOffset(offset);
let block = "";
let blockIdData = "";
if (blockIds && blockIds.length > 0) {
@ -117,7 +120,7 @@ export class DisassemblyView extends TextView {
};
const BLOCK_HEADER_STYLE = {
associateData: function (text, fragment) {
if (view.sourceResolver.hasBlockStartInfo()) return false;
if (view.sourceResolver.disassemblyPhase.hasBlockStartInfo()) return false;
const matches = /\d+/.exec(text);
if (!matches) return true;
const blockId = matches[0];
@ -167,7 +170,7 @@ export class DisassemblyView extends TextView {
const offset = Number.parseInt(offsetAsString, 10);
if ((typeof offsetAsString) != "undefined" && !Number.isNaN(offset)) {
view.offsetSelection.select([offset], true);
const nodes = view.sourceResolver.nodesForPCOffset(offset)[0];
const nodes = view.sourceResolver.instructionsPhase.nodesForPCOffset(offset);
if (nodes.length > 0) {
e.stopPropagation();
if (!e.shiftKey) {
@ -208,7 +211,8 @@ export class DisassemblyView extends TextView {
},
brokeredInstructionSelect: function (instructionIds, selected) {
const firstSelect = view.offsetSelection.isEmpty();
const keyPcOffsets = view.sourceResolver.instructionsToKeyPcOffsets(instructionIds);
const keyPcOffsets = view.sourceResolver.instructionsPhase
.instructionsToKeyPcOffsets(instructionIds);
view.offsetSelection.select(keyPcOffsets, selected);
view.updateSelection(firstSelect);
},
@ -262,7 +266,10 @@ export class DisassemblyView extends TextView {
updateSelection(scrollIntoView: boolean = false) {
super.updateSelection(scrollIntoView);
const keyPcOffsets = this.sourceResolver.nodesToKeyPcOffsets(this.selection.selectedKeys());
const selectedKeys = this.selection.selectedKeys();
const keyPcOffsets: Array<TurbolizerInstructionStartInfo | number> = [
...this.sourceResolver.instructionsPhase.nodesToKeyPcOffsets(selectedKeys)
];
if (this.offsetSelection) {
for (const key of this.offsetSelection.selectedKeys()) {
keyPcOffsets.push(Number(key));

View File

@ -1,7 +1,10 @@
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { View } from "./view";
export class InfoView extends View {
constructor(idOrContainer: HTMLElement | string) {
super(idOrContainer);
fetch("info-view.html")
@ -9,7 +12,7 @@ export class InfoView extends View {
.then(htmlText => this.divNode.innerHTML = htmlText);
}
createViewElement(): HTMLElement {
public createViewElement(): HTMLElement {
const infoContainer = document.createElement("div");
infoContainer.classList.add("info-container");
return infoContainer;

View File

@ -4,8 +4,8 @@
import { createElement } from "../common/util";
import { SequenceView } from "./sequence-view";
import { Interval } from "../source-resolver";
import { ChildRange, Range, RegisterAllocation } from "../phases/sequence-phase";
import { Interval } from "../interval";
class Constants {
// Determines how many rows each div group holds for the purposes of

View File

@ -88,7 +88,7 @@ export class ScheduleView extends TextView {
function createElementForNode(node) {
const nodeEl = createElement("div", "node");
const [start, end] = view.sourceResolver.getInstruction(node.id);
const [start, end] = view.sourceResolver.instructionsPhase.getInstruction(node.id);
const [marker, tooltip] = getMarker(start, end);
const instrMarker = createElement("div", "instr-marker com", marker);
instrMarker.setAttribute("title", tooltip);
@ -128,7 +128,8 @@ export class ScheduleView extends TextView {
const scheduleBlock = createElement("div", "schedule-block");
scheduleBlock.classList.toggle("deferred", block.isDeferred);
const [start, end] = view.sourceResolver.getInstructionRangeForBlock(block.id);
const [start, end] = view.sourceResolver.instructionsPhase
.getInstructionRangeForBlock(block.id);
const instrMarker = createElement("div", "instr-marker com", "&#8857;");
instrMarker.setAttribute("title", `Instructions range for this block is [${start}, ${end})`);
instrMarker.onclick = mkBlockLinkHandler(block.id);

View File

@ -159,7 +159,7 @@ export class SequenceView extends TextView {
const instNodeEl = createElement("div", "instruction-node");
const instId = createElement("div", "instruction-id", instruction.id);
const offsets = view.sourceResolver.instructionToPcOffsets(instruction.id);
const offsets = view.sourceResolver.instructionsPhase.instructionToPcOffsets(instruction.id);
instId.classList.add("clickable");
view.addHtmlElementForInstructionId(instruction.id, instId);
instId.onclick = mkInstructionLinkHandler(instruction.id);

View File

@ -44,6 +44,7 @@
"src/source-resolver.ts",
"src/graph-layout.ts",
"src/graphmultiview.ts",
"src/interval.ts",
"src/turbo-visualizer.ts",
"src/resizer.ts"
]