mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 07:04:04 -05:00
Add option for how parents are placed in control flow layout (#7850)
This PR implements this part of the cutter graph layout algorithm:   
This commit is contained in:
@@ -160,7 +160,10 @@ export class GraphLayoutCore {
|
||||
edgeRows: (RowDescriptor & EdgeRowMetadata)[];
|
||||
readonly layoutTime: number;
|
||||
|
||||
constructor(cfg: AnnotatedCfgDescriptor) {
|
||||
constructor(
|
||||
cfg: AnnotatedCfgDescriptor,
|
||||
readonly centerParents: boolean,
|
||||
) {
|
||||
this.populate_graph(cfg);
|
||||
|
||||
const start = performance.now();
|
||||
@@ -358,9 +361,14 @@ export class GraphLayoutCore {
|
||||
boundingBox.rows++;
|
||||
block.boundingBox = boundingBox;
|
||||
block.row = 0;
|
||||
// between immediate children
|
||||
const [left, right] = [this.blocks[block.treeEdges[0]], this.blocks[block.treeEdges[1]]];
|
||||
block.col = Math.floor((left.col + right.col) / 2); // TODO
|
||||
if (this.centerParents) {
|
||||
// center of bounding box
|
||||
block.col = Math.floor(Math.max(boundingBox.cols - 2, 0) / 2);
|
||||
} else {
|
||||
// center between immediate children
|
||||
const [left, right] = [this.blocks[block.treeEdges[0]], this.blocks[block.treeEdges[1]]];
|
||||
block.col = Math.floor((left.col + right.col) / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
export interface CfgState {
|
||||
selectedFunction: string | null;
|
||||
isircfg?: boolean;
|
||||
centerparents?: boolean;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -48,6 +48,7 @@ import {CompilerInfo} from '../../types/compiler.interfaces.js';
|
||||
import {assert, unwrap} from '../assert.js';
|
||||
import {GraphLayoutCore} from '../graph-layout-core.js';
|
||||
import * as MonacoConfig from '../monaco-config.js';
|
||||
import {Toggles} from '../widgets/toggles.js';
|
||||
|
||||
const ColorTable = {
|
||||
red: '#FE5D5D',
|
||||
@@ -107,6 +108,7 @@ export class Cfg extends Pane<CfgState> {
|
||||
graphContainer: HTMLElement;
|
||||
graphElement: HTMLElement;
|
||||
infoElement: HTMLElement;
|
||||
centerParentsButton: JQuery<HTMLElement>;
|
||||
exportPNGButton: JQuery;
|
||||
estimatedPNGSize: Element;
|
||||
exportSVGButton: JQuery;
|
||||
@@ -118,6 +120,8 @@ export class Cfg extends Pane<CfgState> {
|
||||
functionSelector: TomSelect;
|
||||
resetViewButton: JQuery;
|
||||
zoomOutButton: JQuery;
|
||||
toggles: Toggles;
|
||||
|
||||
results: CFGResult;
|
||||
state: CfgState & PaneState;
|
||||
layout: GraphLayoutCore;
|
||||
@@ -201,10 +205,13 @@ export class Cfg extends Pane<CfgState> {
|
||||
this.graphContainer = this.domRoot.find('.graph-container')[0];
|
||||
this.graphElement = this.domRoot.find('.graph')[0];
|
||||
this.infoElement = this.domRoot.find('.cfg-info')[0];
|
||||
this.centerParentsButton = this.domRoot.find('.center-parents');
|
||||
this.exportPNGButton = this.domRoot.find('.export-png').first();
|
||||
this.estimatedPNGSize = unwrap(this.exportPNGButton[0].querySelector('.estimated-export-size'));
|
||||
this.exportSVGButton = this.domRoot.find('.export-svg').first();
|
||||
this.setupFictitiousGraphContainer();
|
||||
|
||||
this.toggles = new Toggles(this.domRoot.find('.options'), state as unknown as Record<string, boolean>);
|
||||
}
|
||||
|
||||
setupFictitiousGraphContainer() {
|
||||
@@ -271,6 +278,7 @@ export class Cfg extends Pane<CfgState> {
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
this.toggles.on('change', this.onToggleChange.bind(this));
|
||||
this.exportPNGButton.on('click', () => {
|
||||
this.exportPNG();
|
||||
});
|
||||
@@ -290,6 +298,12 @@ export class Cfg extends Pane<CfgState> {
|
||||
});
|
||||
}
|
||||
|
||||
onToggleChange() {
|
||||
this.state = this.getCurrentState();
|
||||
this.updateState();
|
||||
this.selectFunction(this.state.selectedFunction);
|
||||
}
|
||||
|
||||
async exportPNG() {
|
||||
fileSaver.saveAs(await this.createPNG(), 'cfg.png');
|
||||
}
|
||||
@@ -519,7 +533,7 @@ export class Cfg extends Pane<CfgState> {
|
||||
const fn = this.results[name];
|
||||
this.bbMap = {};
|
||||
await this.createBasicBlocks(fn);
|
||||
this.layout = new GraphLayoutCore(fn as AnnotatedCfgDescriptor);
|
||||
this.layout = new GraphLayoutCore(fn as AnnotatedCfgDescriptor, !!this.state.centerparents);
|
||||
this.applyLayout();
|
||||
this.drawEdges();
|
||||
this.infoElement.innerHTML = `Layout time: ${Math.round(this.layout.layoutTime)}ms<br/>Basic blocks: ${
|
||||
@@ -695,6 +709,7 @@ export class Cfg extends Pane<CfgState> {
|
||||
treeid: this.compilerInfo.treeId,
|
||||
selectedFunction: this.state.selectedFunction,
|
||||
isircfg: this.state.isircfg,
|
||||
centerparents: this.toggles.get().centerparents,
|
||||
};
|
||||
this.paneRenaming.addState(state);
|
||||
return state;
|
||||
|
||||
@@ -504,6 +504,10 @@ pre.content.wrap * {
|
||||
font-size: x-small;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.options button {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.change-language {
|
||||
|
||||
@@ -2,6 +2,15 @@
|
||||
.top-bar.btn-toolbar.bg-light.cfg-toolbar(role="toolbar")
|
||||
.btn-group.btn-group-sm(role="group")
|
||||
select.function-selector
|
||||
.btn-group.btn-group-sm.filters(role="group")
|
||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="Control flow graph options" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Change how the control flow graph is rendered")
|
||||
span.fas.fa-cog
|
||||
span.hideable Layout Options
|
||||
.dropdown-menu.options
|
||||
.button-checkbox
|
||||
button.dropdown-item.btn.btn-sm.btn-light.center-parents(type="button" title="Center Parents" data-bind="centerparents" aria-pressed="false" aria-label="Center Parents")
|
||||
span Center Parents
|
||||
input.d-none(type="checkbox" checked=false)
|
||||
.btn-group.btn-group-sm(role="group" aria-label="CFG Export")
|
||||
button.btn.btn-sm.btn-light.dropdown-toggle(type="button" title="LLVM Opt Pass Options" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Set output options")
|
||||
span.fas.fa-arrow-down
|
||||
|
||||
Reference in New Issue
Block a user