Support integrate 3rd-party toolchains into wamrc (#1237)

Support integrating 3rd-party toolchain llc compiler or asm compiler
into wamrc by setting environment variable WAMRC_LLC_COMPILER
or WAMRC_ASM_COMPILER, wamrc will use these tools to generate
object file from LLVM IR firstly, and then refactor the object file into
aot file.
This commit is contained in:
Xu Jun
2022-06-20 13:13:41 +08:00
committed by GitHub
parent bc6eda2803
commit 53b775aa4b
8 changed files with 241 additions and 1 deletions

View File

@ -2886,6 +2886,36 @@ aot_compile_wasm(AOTCompContext *comp_ctx)
return true;
}
#if !(defined(_WIN32) || defined(_WIN32_))
char *
aot_generate_tempfile_name(const char *prefix, const char *extension,
char *buffer, uint32 len)
{
int fd, name_len;
name_len = snprintf(buffer, len, "%s-XXXXXX", prefix);
if ((fd = mkstemp(buffer)) <= 0) {
aot_set_last_error("make temp file failed.");
return NULL;
}
/* close and remove temp file */
close(fd);
unlink(buffer);
/* Check if buffer length is enough */
/* name_len + '.' + extension + '\0' */
if (name_len + 1 + strlen(extension) + 1 > len) {
aot_set_last_error("temp file name too long.");
return NULL;
}
snprintf(buffer + name_len, len - name_len, ".%s", extension);
return buffer;
}
#endif /* end of !(defined(_WIN32) || defined(_WIN32_)) */
#if WASM_ENABLE_LAZY_JIT == 0
bool
aot_emit_llvm_file(AOTCompContext *comp_ctx, const char *file_name)
@ -2915,6 +2945,83 @@ aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
bh_print_time("Begin to emit object file");
#if !(defined(_WIN32) || defined(_WIN32_))
if (comp_ctx->external_llc_compiler || comp_ctx->external_asm_compiler) {
char cmd[1024];
int ret;
if (comp_ctx->external_llc_compiler) {
char bc_file_name[64];
if (!aot_generate_tempfile_name("wamrc-bc", "bc", bc_file_name,
sizeof(bc_file_name))) {
return false;
}
if (LLVMWriteBitcodeToFile(comp_ctx->module, bc_file_name) != 0) {
aot_set_last_error("emit llvm bitcode file failed.");
return false;
}
snprintf(cmd, sizeof(cmd), "%s %s -o %s %s",
comp_ctx->external_llc_compiler,
comp_ctx->llc_compiler_flags ? comp_ctx->llc_compiler_flags
: "-O3 -c",
file_name, bc_file_name);
LOG_VERBOSE("invoking external LLC compiler:\n\t%s", cmd);
ret = system(cmd);
/* remove temp bitcode file */
unlink(bc_file_name);
if (ret != 0) {
aot_set_last_error("failed to compile LLVM bitcode to obj file "
"with external LLC compiler.");
return false;
}
}
else if (comp_ctx->external_asm_compiler) {
char asm_file_name[64];
if (!aot_generate_tempfile_name("wamrc-asm", "s", asm_file_name,
sizeof(asm_file_name))) {
return false;
}
if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine,
comp_ctx->module, asm_file_name,
LLVMAssemblyFile, &err)
!= 0) {
if (err) {
LLVMDisposeMessage(err);
err = NULL;
}
aot_set_last_error("emit elf to assembly file failed.");
return false;
}
snprintf(cmd, sizeof(cmd), "%s %s -o %s %s",
comp_ctx->external_asm_compiler,
comp_ctx->asm_compiler_flags ? comp_ctx->asm_compiler_flags
: "-O3 -c",
file_name, asm_file_name);
LOG_VERBOSE("invoking external ASM compiler:\n\t%s", cmd);
ret = system(cmd);
/* remove temp assembly file */
unlink(asm_file_name);
if (ret != 0) {
aot_set_last_error("failed to compile Assembly file to obj "
"file with external ASM compiler.");
return false;
}
}
return true;
}
#endif /* end of !(defined(_WIN32) || defined(_WIN32_)) */
if (!strncmp(LLVMGetTargetName(target), "arc", 3))
/* Emit to assmelby file instead for arc target
as it cannot emit to object file */