diff options
author | Ofek <ofekshilon@gmail.com> | 2024-01-16 07:27:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-16 07:27:06 +0200 |
commit | 5b9af2f7b6d6aee6ba4cf82346082fc09e9e492f (patch) | |
tree | fba42b78b01383000a8c80747906594483674c7c | |
parent | 24c4ef7d1cde7706a43108378395d3d23db350eb (diff) | |
download | compiler-explorer-5b9af2f7b6d6aee6ba4cf82346082fc09e9e492f.tar.gz compiler-explorer-5b9af2f7b6d6aee6ba4cf82346082fc09e9e492f.zip |
Fix #5987: make rustc generate *only* IR output in generateIR (#5988)gh-10225
All compilations run asynchronously under `await Promise.all` in
`BaseCompiler.doCompilation`:
https://github.com/compiler-explorer/compiler-explorer/blob/f3277b8aed2ca12ce961d08ef792c4061a3331ac/lib/base-compiler.ts#L2256-L2263
ASM and MIR processing is done from the main `runCompiler` and IR from
the auxiliary `generateIR`. But both compilation calls are passed the
same `options` - which include `--emit asm` for generation of `output.s`
assembly file and `--emit mir=...` for generation of MIR file. So these
2 identically-named file pairs are generated *and cleaned up* in both of
the parallel compilations, sometimes one compilation cleans up its
output before the other one tries to process its own, and mayhem ensues.
This PR makes rust's `generateIR` indeed generate *just* IR by filtering
switches.
From a design perspective: ideally CE would be more opinionated on which
outputs are generated on the main compilation and which on auxiliary
ones. I see no reason for MIR to be generated by an additional switch on
the main compilation and IR require a different compilation (there's
also something called `generateRustHir` - I don't know what it does and
am slightly afraid to ask).
I *think* most (all?) asm/IR outputs could be generated in a single main
compilation, and just post-processed for the different panes in parallel
- which could spell very good news also for servers load. But I don't
dare say anything categorical about *all* languages, compilers and
output (probably no one does). Would be happy to hear opinions.
(Anyway that's just for sake of discussion, this PR does nothing fancy
of that sort)
-rw-r--r-- | lib/compilers/rust.ts | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/compilers/rust.ts b/lib/compilers/rust.ts index 4e588ae77..f88dc0d65 100644 --- a/lib/compilers/rust.ts +++ b/lib/compilers/rust.ts @@ -36,6 +36,7 @@ import {parseRustOutput, changeExtension} from '../utils.js'; import {RustParser} from './argument-parsers.js'; import {CompilerOverrideType} from '../../types/compilation/compiler-overrides.interfaces.js'; +import {LLVMIrBackendOptions} from '../../types/compilation/ir.interfaces.js'; import {ExecutionOptions} from '../../types/compilation/compilation.interfaces.js'; import {SemVer} from 'semver'; @@ -68,6 +69,30 @@ export class RustCompiler extends BaseCompiler { this.linker = this.compilerProps<string>('linker'); } + override async generateIR( + inputFilename: string, + options: string[], + irOptions: LLVMIrBackendOptions, + produceCfg: boolean, + filters: ParseFiltersAndOutputOptions, + ) { + // Filter out the options pairs `--emit mir=*` and `emit asm`, and specify explicit `.ll` extension + const newOptions = options + .filter(option => !option.startsWith('--color=')) + .filter( + (opt, idx, allOpts) => + !(opt === '--emit' && allOpts[idx + 1].startsWith('mir=')) && !opt.startsWith('mir='), + ) + .filter((opt, idx, allOpts) => !(opt === '--emit' && allOpts[idx + 1] === 'asm') && opt !== 'asm') + .map((opt, idx, allOpts) => + opt.endsWith('.s') && idx > 0 && allOpts[idx - 1] === '-o' + ? this.getIrOutputFilename(inputFilename, filters) + : opt, + ); + + return await super.generateIR(inputFilename, newOptions, irOptions, produceCfg, filters); + } + private isNightly() { return ( this.compiler.name === 'nightly' || |