toolchain: init, refactored from llvm-prefix.ts

This commit is contained in:
2024-06-25 18:39:58 +08:00
parent 0e29cad5ec
commit 910890f685
2 changed files with 115 additions and 28 deletions

View File

@@ -1,28 +0,0 @@
import path from "path";
export interface Toolchain {
/**
* C compiler.
*/
CC: string;
/**
* C++ compiler.
*/
CXX: string;
/**
* Fortran compiler.
*/
FC: string;
};
export function llvmToolchain(prefix: string) {
const bin = path.resolve(prefix, "bin");
return {
CC: path.resolve(bin, "clang"),
CXX: path.resolve(bin, "clang++"),
FC: path.resolve(bin, "flang"),
LLVM_EXTRACT: path.resolve(bin, "llvm-extract"),
};
}

115
src/toolchain/index.ts Normal file
View File

@@ -0,0 +1,115 @@
import { spawn } from 'child_process';
import { promisifySpawn } from 'lyc/cli';
import { generalCommand, extractCommand } from 'lyc/commands/compiler';
import path from 'path';
export interface Toolchain {
/**
* C compiler.
*/
CC: string;
/**
* C++ compiler.
*/
CXX: string;
/**
* Fortran compiler.
*/
FC: string;
};
export interface LLVMToolchain extends Toolchain {
/**
* An llvm tooling that may extract part of LLVM IR.
*/
LLVM_EXTRACT: string;
}
export function llvmToolchain(prefix: string) {
const bin = path.resolve(prefix, "bin");
return {
CC: path.resolve(bin, "clang"),
CXX: path.resolve(bin, "clang++"),
FC: path.resolve(bin, "flang"),
LLVM_EXTRACT: path.resolve(bin, "llvm-extract"),
};
}
/**
* Give an LLVM toolchain, and a desired IR, a list of function names.
* Generate a function that takes vFnPath and sFnPath, used for path calculation.
*/
export function reduceIR(llvmTC: LLVMToolchain, IR: string) {
const objFlags = [
...generalCommand({
outputKind: 'object',
}),
'-x', 'ir',
// Read from stdin.
'-',
];
return {
mkFnObjects: async (fnList: string[], vFnPath: (fn: string) => string, sFnPath: (fn: string) => string) => {
// Parse the IR with all function names
// For each function, extract it.
await Promise.all(fnList.map(fn => {
const proc = spawn(llvmTC.LLVM_EXTRACT, [
...extractCommand({
func: [fn],
asm: true,
input: '-',
output: '-',
}),
]);
// Write IR and close stdin
proc.stdin.write(IR);
proc.stdin.end();
const compileVector = spawn(llvmTC.FC, [
...objFlags,
...generalCommand({ output: vFnPath(fn), }),
'-msimd',
]);
const compileScalar = spawn(llvmTC.FC, [
...objFlags,
...generalCommand({ output: sFnPath(fn) }),
]);
proc.stdout.pipe(compileVector.stdin);
proc.stdout.pipe(compileScalar.stdin);
return Promise.all([proc, compileScalar, compileScalar].map(promisifySpawn));
}));
},
mkGlobalObject: async (globalPath: string) => {
const proc = spawn(llvmTC.LLVM_EXTRACT, [
...extractCommand({
asm: true,
input: "-",
output: "-",
}),
// Extract all global variables.
"-rglob",
".*",
], { stdio: ['pipe', 'pipe', 'inherit'] });
// Write IR and close stdin
proc.stdin.write(IR);
proc.stdin.end();
const compileScalar = spawn(llvmTC.FC, [
...objFlags,
...generalCommand({ output: globalPath }),
], { stdio: ['pipe', 'inherit', 'inherit'] });
proc.stdout.pipe(compileScalar.stdin);
return Promise.all([proc, compileScalar].map(promisifySpawn));
}
};
}