Skip to content

Commit

Permalink
Fix compiler-explorer#5987: make rustc generate *only* IR output in g…
Browse files Browse the repository at this point in the history
…enerateIR (compiler-explorer#5988)

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)
  • Loading branch information
OfekShilon authored Jan 16, 2024
1 parent 24c4ef7 commit 5b9af2f
Showing 1 changed file with 25 additions and 0 deletions.
25 changes: 25 additions & 0 deletions lib/compilers/rust.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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' ||
Expand Down

0 comments on commit 5b9af2f

Please sign in to comment.