toolchain: init, refactored from llvm-prefix.ts
This commit is contained in:
@@ -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
115
src/toolchain/index.ts
Normal 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));
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user