aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOfek <ofekshilon@gmail.com>2024-01-16 07:27:06 +0200
committerGitHub <noreply@github.com>2024-01-16 07:27:06 +0200
commit5b9af2f7b6d6aee6ba4cf82346082fc09e9e492f (patch)
treefba42b78b01383000a8c80747906594483674c7c
parent24c4ef7d1cde7706a43108378395d3d23db350eb (diff)
downloadcompiler-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.ts25
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' ||