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 /lib/compilers/rust.ts | |
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)
Diffstat (limited to 'lib/compilers/rust.ts')
-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' || |