From b0dc04c33c1037df18ef081ef7a3ef055b8443b8 Mon Sep 17 00:00:00 2001 From: Ofek Shilon Date: Sat, 28 Sep 2024 21:50:28 +0300 Subject: [PATCH] Introduce opt-pipeling for ClangIr --- lib/base-compiler.ts | 11 ++++++++++- lib/compilers/argument-parsers.ts | 14 ++++++++++++++ lib/parsers/llvm-pass-dump-parser.ts | 15 +++++++++++++-- static/panes/opt-pipeline.ts | 9 ++++++++- static/widgets/toggles.ts | 5 ++++- 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/lib/base-compiler.ts b/lib/base-compiler.ts index 9547522ee24..e51c9e4c26c 100644 --- a/lib/base-compiler.ts +++ b/lib/base-compiler.ts @@ -80,7 +80,14 @@ import {BuildEnvSetupBase, getBuildEnvTypeByKey} from './buildenvsetup/index.js' import * as cfg from './cfg/cfg.js'; import {CompilationEnvironment} from './compilation-env.js'; import {CompilerArguments} from './compiler-arguments.js'; -import {ClangCParser, ClangParser, GCCCParser, GCCParser, ICCParser} from './compilers/argument-parsers.js'; +import { + ClangCParser, + ClangirParser, + ClangParser, + GCCCParser, + GCCParser, + ICCParser, +} from './compilers/argument-parsers.js'; import {BaseDemangler, getDemanglerTypeByKey} from './demangler/index.js'; import {LLVMIRDemangler} from './demangler/llvm.js'; import * as exec from './exec.js'; @@ -3221,6 +3228,8 @@ but nothing was dumped. Possible causes are: const exeFilename = path.basename(exe); if (exeFilename.includes('icc')) { return ICCParser; + } else if (exe.includes('clangir')) { + return ClangirParser; } else if (exeFilename.includes('clang++') || exeFilename.includes('icpx')) { // check this first as "clang++" matches "g++" return ClangParser; diff --git a/lib/compilers/argument-parsers.ts b/lib/compilers/argument-parsers.ts index e719e8080e0..36267bb90d9 100644 --- a/lib/compilers/argument-parsers.ts +++ b/lib/compilers/argument-parsers.ts @@ -441,6 +441,20 @@ export class ClangParser extends BaseParser { } } +export class ClangirParser extends ClangParser { + static override setCompilerSettingsFromOptions(compiler, options) { + ClangParser.setCompilerSettingsFromOptions(compiler, options); + + compiler.compiler.optPipeline = { + arg: [], + moduleScopeArg: ['-mmlir', '--mlir-print-ir-before-all', '-mmlir', '--mlir-print-ir-after-all'], + noDiscardValueNamesArg: [], + supportedOptions: ['dump-full-module', 'demangle-symbols'], + supportedFilters: [], + }; + } +} + export class GCCCParser extends GCCParser { static override getLanguageSpecificHelpFlags(): string[] { return ['-fsyntax-only', '--help=c']; diff --git a/lib/parsers/llvm-pass-dump-parser.ts b/lib/parsers/llvm-pass-dump-parser.ts index 7c2d5fb5321..aa4709ae722 100644 --- a/lib/parsers/llvm-pass-dump-parser.ts +++ b/lib/parsers/llvm-pass-dump-parser.ts @@ -73,6 +73,7 @@ export class LlvmPassDumpParser { metadataLineFilters: RegExp[]; irDumpHeader: RegExp; machineCodeDumpHeader: RegExp; + cirDumpHeader: RegExp; functionDefine: RegExp; machineFunctionBegin: RegExp; functionEnd: RegExp; @@ -121,6 +122,10 @@ export class LlvmPassDumpParser { // or "(loop: %x)" at the end this.irDumpHeader = /^;?\s?\*{3} (.+) \*{3}(?:\s+\((?:function: |loop: )(%?[\w$.]+)\))?(?:;.+)?$/; this.machineCodeDumpHeader = /^# \*{3} (.+) \*{3}:$/; + // ClangIr dump headers look like "// -----// IR Dump Before XYZ (cir-xyz) //----- // + // and currently do not refer to functions + this.cirDumpHeader = /^\/\/ -----\/\/ (.+) \/\/----- \/\/$/; + // Ir dumps are "define T @_Z3fooi(...) . .. {" or "# Machine code for function _Z3fooi: " // Some interesting edge cases found when testing: // `define internal %"struct.libassert::detail::assert_static_parameters"* @"_ZZ4mainENK3$_0clEv"( @@ -149,7 +154,8 @@ export class LlvmPassDumpParser { //} const irMatch = line.text.match(this.irDumpHeader); const machineMatch = line.text.match(this.machineCodeDumpHeader); - const header = irMatch || machineMatch; + const cirMatch = line.text.match(this.cirDumpHeader); + const header = irMatch || machineMatch || cirMatch; if (header) { if (pass !== null) { raw_passes.push(pass); @@ -481,7 +487,12 @@ export class LlvmPassDumpParser { process(output: ResultLine[], _: ParseFiltersAndOutputOptions, optPipelineOptions: OptPipelineBackendOptions) { // Crop out any junk before the pass dumps (e.g. warnings) const ir = output.slice( - output.findIndex(line => line.text.match(this.irDumpHeader) || line.text.match(this.machineCodeDumpHeader)), + output.findIndex( + line => + this.irDumpHeader.test(line.text) || + this.machineCodeDumpHeader.test(line.text) || + this.cirDumpHeader.test(line.text), + ), ); const preprocessed_lines = this.applyIrFilters(ir, optPipelineOptions); return this.breakdownOutput(preprocessed_lines, optPipelineOptions); diff --git a/static/panes/opt-pipeline.ts b/static/panes/opt-pipeline.ts index ec661f9cb6c..b66ca02e0ff 100644 --- a/static/panes/opt-pipeline.ts +++ b/static/panes/opt-pipeline.ts @@ -229,12 +229,14 @@ export class OptPipeline extends MonacoPane'); } + + // TODO: un-hackify this + if (this.compilerInfo.compilerName.includes('clangir')) { + this.options.enableToggle('dump-full-module', false, true); + } } updateGroupName() { diff --git a/static/widgets/toggles.ts b/static/widgets/toggles.ts index 5c11cf72e11..6181d22a188 100644 --- a/static/widgets/toggles.ts +++ b/static/widgets/toggles.ts @@ -107,12 +107,15 @@ export class Toggles extends EventEmitter { this.emit('change', before, this.get()); } - enableToggle(key: string, enable: boolean) { + enableToggle(key: string, enable: boolean, lockChecked: boolean = false) { for (const element of this.buttons) { const widget = $(element); const button = widget.find('button'); const bind = button.data('bind'); if (bind === key) { + if (lockChecked) { + this.set(key, true); // Ensure the toggle is checked + } button.prop('disabled', !enable); } }