mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 11:44:09 -05:00
Add debug info filter option to LLVM opt pipeline viewer (#3987)
* Add debug info filter option to LLVM opt pipeline viewer * Add MIR debug info pseudo-instructions to filters * Use mixin for LLVM opt pipeline options This fixes a few templating errors from the more verbose version. * Add name to contributors * Generalise dbg call filter
This commit is contained in:
@@ -121,3 +121,4 @@ From oldest to newest contributor, we would like to thank:
|
||||
- [Ofek Shilon](https://github.com/ofekshilon)
|
||||
- [Ross Smyth](https://github.com/RossSmyth)
|
||||
- [Mike Urbach](https://github.com/mikeurbach)
|
||||
- [J. Ryan Stinnett](https://github.com/jryans)
|
||||
|
||||
@@ -82,6 +82,8 @@ type SplitPassDump = {
|
||||
export class LlvmPassDumpParser {
|
||||
filters: RegExp[];
|
||||
lineFilters: RegExp[];
|
||||
debugInfoFilters: RegExp[];
|
||||
debugInfoLineFilters: RegExp[];
|
||||
irDumpHeader: RegExp;
|
||||
machineCodeDumpHeader: RegExp;
|
||||
functionDefine: RegExp;
|
||||
@@ -100,19 +102,25 @@ export class LlvmPassDumpParser {
|
||||
/^; ModuleID = '.+'$/, // module id line
|
||||
/^(source_filename|target datalayout|target triple) = ".+"$/, // module metadata
|
||||
/^; Function Attrs: .+$/, // function attributes
|
||||
/^\s+call void @llvm.dbg.value.+$/, // dbg calls
|
||||
/^\s+call void @llvm.dbg.declare.+$/, // dbg calls
|
||||
/^declare .+$/, // declare directives
|
||||
/^(!\d+) = (?:distinct )?!DI([A-Za-z]+)\(([^)]+?)\)/, // meta
|
||||
/^(!\d+) = (?:distinct )?!{.*}/, // meta
|
||||
/^(![.A-Z_a-z-]+) = (?:distinct )?!{.*}/, // meta
|
||||
/^attributes #\d+ = { .+ }$/, // attributes directive
|
||||
];
|
||||
this.lineFilters = [
|
||||
/,? ![\dA-Za-z]+((?=( {)?$))/, // debug annotation
|
||||
/,? #\d+((?=( {)?$))/, // attribute annotation
|
||||
];
|
||||
|
||||
// Additional filters conditionally enabled by `filterDebugInfo`
|
||||
this.debugInfoFilters = [
|
||||
/^\s+call void @llvm.dbg.+$/, // dbg calls
|
||||
/^\s+DBG_.+$/, // dbg pseudo-instructions
|
||||
/^(!\d+) = (?:distinct )?!DI([A-Za-z]+)\(([^)]+?)\)/, // meta
|
||||
/^(!\d+) = (?:distinct )?!{.*}/, // meta
|
||||
/^(![.A-Z_a-z-]+) = (?:distinct )?!{.*}/, // meta
|
||||
];
|
||||
this.debugInfoLineFilters = [
|
||||
/,? ![\dA-Za-z]+((?=( {)?$))/, // debug annotation
|
||||
];
|
||||
|
||||
// Ir dump headers look like "*** IR Dump After XYZ ***"
|
||||
// Machine dump headers look like "# *** IR Dump After XYZ ***:", possibly with a comment or "(function: xyz)"
|
||||
// or "(loop: %x)" at the end
|
||||
@@ -435,18 +443,26 @@ export class LlvmPassDumpParser {
|
||||
}
|
||||
|
||||
process(ir: ResultLine[], _: ParseFilters, llvmOptPipelineOptions: LLVMOptPipelineBackendOptions) {
|
||||
// Additional filters conditionally enabled by `filterDebugInfo`
|
||||
let filters = this.filters;
|
||||
let lineFilters = this.lineFilters;
|
||||
if (llvmOptPipelineOptions.filterDebugInfo) {
|
||||
filters = filters.concat(this.debugInfoFilters);
|
||||
lineFilters = lineFilters.concat(this.debugInfoLineFilters);
|
||||
}
|
||||
|
||||
// Filter a lot of junk before processing
|
||||
const preprocessed_lines = ir
|
||||
.slice(
|
||||
ir.findIndex(line => line.text.match(this.irDumpHeader) || line.text.match(this.machineCodeDumpHeader)),
|
||||
)
|
||||
.filter(line => this.filters.every(re => line.text.match(re) === null)) // apply filters
|
||||
.filter(line => filters.every(re => line.text.match(re) === null)) // apply filters
|
||||
.map(_line => {
|
||||
let line = _line.text;
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
let newLine = line;
|
||||
for (const re of this.lineFilters) {
|
||||
for (const re of lineFilters) {
|
||||
newLine = newLine.replace(re, '');
|
||||
}
|
||||
if (newLine === line) {
|
||||
|
||||
@@ -61,6 +61,7 @@ export class LLVMOptPipeline extends MonacoPane<monaco.editor.IStandaloneDiffEdi
|
||||
options: Toggles;
|
||||
state: LLVMOptPipelineViewState;
|
||||
lastOptions: LLVMOptPipelineBackendOptions = {
|
||||
filterDebugInfo: true,
|
||||
fullModule: false,
|
||||
noDiscardValueNames: true,
|
||||
demangle: true,
|
||||
@@ -188,6 +189,7 @@ export class LLVMOptPipeline extends MonacoPane<monaco.editor.IStandaloneDiffEdi
|
||||
// the backend? Would be a data transfer optimization.
|
||||
const newOptions: LLVMOptPipelineBackendOptions = {
|
||||
//'filter-inconsequential-passes': options['filter-inconsequential-passes'],
|
||||
filterDebugInfo: options['filter-debug-info'],
|
||||
fullModule: options['dump-full-module'],
|
||||
noDiscardValueNames: options['-fno-discard-value-names'],
|
||||
demangle: options['demangle-symbols'],
|
||||
|
||||
@@ -36,6 +36,7 @@ export type Pass = {
|
||||
export type LLVMOptPipelineOutput = Record<string, Pass[]>;
|
||||
|
||||
export type LLVMOptPipelineBackendOptions = {
|
||||
filterDebugInfo: boolean;
|
||||
fullModule: boolean;
|
||||
noDiscardValueNames: boolean;
|
||||
demangle: boolean;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
mixin optionButton(bind, isActive, text, title)
|
||||
.button-checkbox
|
||||
button(type="button" class="dropdown-item btn btn-sm btn-light" + (isActive ? " active" : "") title=title data-bind=bind aria-pressed=isActive ? "true" : "false")
|
||||
span #{text}
|
||||
input.d-none(type="checkbox" checked=isActive)
|
||||
|
||||
#llvm-opt-pipeline
|
||||
.top-bar.btn-toolbar.bg-light(role="toolbar")
|
||||
include ../../font-size
|
||||
@@ -6,26 +12,12 @@
|
||||
span.fas.fa-anchor
|
||||
span.hideable Options
|
||||
.dropdown-menu
|
||||
.button-checkbox
|
||||
button.dropdown-item.btn.btn-sm.btn-light.filter-inconsequential-passes(type="button" title="Filter passes which do not make changes" data-bind="filter-inconsequential-passes" aria-pressed="false" aria-label="Filter Inconsequential Passes")
|
||||
span Filter Inconsequential Passes
|
||||
input.d-none(type="checkbox" checked=false)
|
||||
.button-checkbox
|
||||
button.dropdown-item.btn.btn-sm.btn-light.dump-full-module(type="button" title="Dump the entire module for each pass" data-bind="dump-full-module" aria-pressed="false" aria-label="Filter Inconsequential Passes")
|
||||
span Dump Full Module
|
||||
input.d-none(type="checkbox" checked=false)
|
||||
.button-checkbox
|
||||
button.dropdown-item.btn.btn-sm.btn-light.dump-full-module(type="button" title="Demangle Symbols" data-bind="demangle-symbols" aria-pressed="false" aria-label="Demangle Symbols")
|
||||
span Demangle Symbols
|
||||
input.d-none(type="checkbox" checked=true)
|
||||
.button-checkbox
|
||||
button.dropdown-item.btn.btn-sm.btn-light.dump-full-module(type="button" title="Keep value names instead of llvm value numbers" data-bind="-fno-discard-value-names" aria-pressed="false" aria-label="-fno-discard-value-names")
|
||||
span -fno-discard-value-names
|
||||
input.d-none(type="checkbox" checked=true)
|
||||
//.button-checkbox
|
||||
// button.dropdown-item.btn.btn-sm.btn-light.dump-full-module(type="button" title="Filter Library Functions" data-bind="library-functions" aria-pressed="false" aria-label="Filter Library Functions")
|
||||
// span Filter Library Functions
|
||||
// input.d-none(type="checkbox" checked=true)
|
||||
+optionButton("filter-inconsequential-passes", false, "Filter Inconsequential Passes", "Filter passes which do not make changes")
|
||||
+optionButton("filter-debug-info", true, "Filter Debug Info", "Filter debug info intrinsics")
|
||||
+optionButton("dump-full-module", false, "Dump Full Module", "Dump the entire module for each pass")
|
||||
+optionButton("demangle-symbols", true, "Demangle Symbols", "Demangle symbols")
|
||||
+optionButton("-fno-discard-value-names", true, "-fno-discard-value-names", "Keep value names instead of LLVM value numbers")
|
||||
//- +optionButton("library-functions", true, "Filter Library Functions", "Filter library functions")
|
||||
.btn-group.btn-group-sm
|
||||
.input-group.input-group-sm.mb-auto
|
||||
.input-group-prepend
|
||||
|
||||
Reference in New Issue
Block a user