Implement AOT static PGO (#2243)

LLVM PGO (Profile-Guided Optimization) allows the compiler to better optimize code
for how it actually runs. This PR implements the AOT static PGO, and is tested on
Linux x86-64 and x86-32. The basic steps are:

1. Use `wamrc --enable-llvm-pgo -o <aot_file_of_pgo> <wasm_file>`
   to generate an instrumented aot file.
2. Compile iwasm with `cmake -DWAMR_BUILD_STATIC_PGO=1` and run
      `iwasm --gen-prof-file=<raw_profile_file> <aot_file_of_pgo>`
    to generate the raw profile file.
3. Run `llvm-profdata merge -output=<profile_file> <raw_profile_file>`
    to merge the raw profile file into the profile file.
4. Run `wamrc --use-prof-file=<profile_file> -o <aot_file> <wasm_file>`
    to generate the optimized aot file.
5. Run the optimized aot_file: `iwasm <aot_file>`.

The test scripts are also added for each benchmark, run `test_pgo.sh` under
each benchmark's folder to test the AOT static pgo.
This commit is contained in:
Wenyong Huang
2023-06-05 09:17:39 +08:00
committed by GitHub
parent f1e9029ebc
commit 8d88471c46
29 changed files with 2000 additions and 53 deletions

View File

@ -97,6 +97,9 @@ print_help()
#if WASM_ENABLE_DEBUG_INTERP != 0
printf(" -g=ip:port Set the debug sever address, default is debug disabled\n");
printf(" if port is 0, then a random port will be used\n");
#endif
#if WASM_ENABLE_STATIC_PGO != 0
printf(" --gen-prof-file=<path> Generate LLVM PGO (Profile-Guided Optimization) profile file\n");
#endif
printf(" --version Show version information\n");
return 1;
@ -413,6 +416,44 @@ moudle_destroyer(uint8 *buffer, uint32 size)
static char global_heap_buf[WASM_GLOBAL_HEAP_SIZE] = { 0 };
#endif
#if WASM_ENABLE_STATIC_PGO != 0
static void
dump_pgo_prof_data(wasm_module_inst_t module_inst, const char *path)
{
char *buf;
uint32 len;
FILE *file;
if (!(len = wasm_runtime_get_pgo_prof_data_size(module_inst))) {
printf("failed to get LLVM PGO profile data size\n");
return;
}
if (!(buf = wasm_runtime_malloc(len))) {
printf("allocate memory failed\n");
return;
}
if (len != wasm_runtime_dump_pgo_prof_data_to_buf(module_inst, buf, len)) {
printf("failed to dump LLVM PGO profile data\n");
wasm_runtime_free(buf);
return;
}
if (!(file = fopen(path, "wb"))) {
printf("failed to create file %s", path);
wasm_runtime_free(buf);
return;
}
fwrite(buf, len, 1, file);
fclose(file);
wasm_runtime_free(buf);
printf("LLVM raw profile file %s was generated.\n", path);
}
#endif
int
main(int argc, char *argv[])
{
@ -460,6 +501,9 @@ main(int argc, char *argv[])
char *ip_addr = NULL;
int instance_port = 0;
#endif
#if WASM_ENABLE_STATIC_PGO != 0
const char *gen_prof_file = NULL;
#endif
/* Process options. */
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
@ -663,6 +707,13 @@ main(int argc, char *argv[])
return print_help();
ip_addr = argv[0] + 3;
}
#endif
#if WASM_ENABLE_STATIC_PGO != 0
else if (!strncmp(argv[0], "--gen-prof-file=", 16)) {
if (argv[0][16] == '\0')
return print_help();
gen_prof_file = argv[0] + 16;
}
#endif
else if (!strncmp(argv[0], "--version", 9)) {
uint32 major, minor, patch;
@ -826,6 +877,12 @@ main(int argc, char *argv[])
}
#endif
#if WASM_ENABLE_STATIC_PGO != 0 && WASM_ENABLE_AOT != 0
if (get_package_type(wasm_file_buf, wasm_file_size) == Wasm_Module_AoT
&& gen_prof_file)
dump_pgo_prof_data(wasm_module_inst, gen_prof_file);
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
fail4:
#endif