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