Эх сурвалжийг харах

Modify AOT static PGO to conform to llvm-18 and add a CI job to test static PGO on the coremark benchmark (#4345)

* static PGO compatible with llvm18 and add CI job to test static PGO on coremark benchmark
* update comments and warning info, bitmaps section in llvm profdata shouldn't be used in PGO
TianlongLiang 7 сар өмнө
parent
commit
0343aaf8c3

+ 1 - 1
core/iwasm/aot/aot_loader.c

@@ -3323,7 +3323,7 @@ do_data_relocation(AOTModule *module, AOTRelocationGroup *group,
     uint8 *data_addr;
     uint32 data_size = 0, i;
     AOTRelocation *relocation = group->relocations;
-    void *symbol_addr;
+    void *symbol_addr = NULL;
     char *symbol, *data_section_name;
 
     if (!strncmp(group->section_name, ".rela.", 6)) {

+ 12 - 3
core/iwasm/aot/aot_runtime.c

@@ -4877,8 +4877,8 @@ aot_dump_pgo_prof_data_to_buf(AOTModuleInstance *module_inst, char *buf,
     }
 
     prof_header.magic = 0xFF6C70726F667281LL;
-    /* Version 8 */
-    prof_header.version = 0x0000000000000008LL;
+    /* Version 9 */
+    prof_header.version = 0x0000000000000009LL;
     /* with VARIANT_MASK_IR_PROF (IR Instrumentation) */
     prof_header.version |= 0x1ULL << 56;
     /* with VARIANT_MASK_MEMPROF (Memory Profile) */
@@ -4887,14 +4887,19 @@ aot_dump_pgo_prof_data_to_buf(AOTModuleInstance *module_inst, char *buf,
     prof_header.num_prof_counters = num_prof_counters;
     prof_header.names_size = prof_names_size;
     prof_header.value_kind_last = 1;
+    /* __llvm_prf_bits won't be used in PGO, set dummy value here */
+    prof_header.num_prof_bitmaps = 0;
+    prof_header.bitmap_delta = 0;
 
     if (!is_little_endian()) {
         aot_exchange_uint64((uint8 *)&prof_header.magic);
         aot_exchange_uint64((uint8 *)&prof_header.version);
         aot_exchange_uint64((uint8 *)&prof_header.num_prof_data);
         aot_exchange_uint64((uint8 *)&prof_header.num_prof_counters);
+        aot_exchange_uint64((uint8 *)&prof_header.num_prof_bitmaps);
         aot_exchange_uint64((uint8 *)&prof_header.names_size);
         aot_exchange_uint64((uint8 *)&prof_header.counters_delta);
+        aot_exchange_uint64((uint8 *)&prof_header.bitmap_delta);
         aot_exchange_uint64((uint8 *)&prof_header.value_kind_last);
     }
 
@@ -4912,19 +4917,23 @@ aot_dump_pgo_prof_data_to_buf(AOTModuleInstance *module_inst, char *buf,
             prof_data_64->func_md5 = prof_data->func_md5;
             prof_data_64->func_hash = prof_data->func_hash;
             prof_data_64->offset_counters = prof_data->offset_counters;
+            prof_data_64->offset_bitmaps = prof_data->offset_bitmaps;
             prof_data_64->func_ptr = prof_data->func_ptr;
             prof_data_64->values = (uint64)(uintptr_t)prof_data->values;
             prof_data_64->num_counters = prof_data->num_counters;
+            /* __llvm_prf_bits won't be used in PGO, set dummy value here */
+            prof_data_64->num_bitmaps = 0;
             prof_data_64->num_value_sites[0] = prof_data->num_value_sites[0];
             prof_data_64->num_value_sites[1] = prof_data->num_value_sites[1];
 
             if (!is_little_endian()) {
                 aot_exchange_uint64((uint8 *)&prof_data_64->func_hash);
                 aot_exchange_uint64((uint8 *)&prof_data_64->offset_counters);
-                aot_exchange_uint64((uint8 *)&prof_data_64->offset_counters);
+                aot_exchange_uint64((uint8 *)&prof_data_64->offset_bitmaps);
                 aot_exchange_uint64((uint8 *)&prof_data_64->func_ptr);
                 aot_exchange_uint64((uint8 *)&prof_data_64->values);
                 aot_exchange_uint32((uint8 *)&prof_data_64->num_counters);
+                aot_exchange_uint32((uint8 *)&prof_data_64->num_bitmaps);
                 aot_exchange_uint16((uint8 *)&prof_data_64->num_value_sites[0]);
                 aot_exchange_uint16((uint8 *)&prof_data_64->num_value_sites[1]);
             }

+ 10 - 0
core/iwasm/aot/aot_runtime.h

@@ -437,6 +437,9 @@ typedef struct AOTFrame {
 } AOTFrame;
 
 #if WASM_ENABLE_STATIC_PGO != 0
+/* The bitmaps fields in LLVMProfileRawHeader, LLVMProfileData,
+ * LLVMProfileData_64 all dummy fields, it's used in MC/DC code coverage
+ * instead of PGO. See https://llvm.org/docs/InstrProfileFormat.html#bitmap */
 typedef struct LLVMProfileRawHeader {
     uint64 magic;
     uint64 version;
@@ -445,8 +448,11 @@ typedef struct LLVMProfileRawHeader {
     uint64 padding_bytes_before_counters;
     uint64 num_prof_counters;
     uint64 padding_bytes_after_counters;
+    uint64 num_prof_bitmaps;
+    uint64 padding_bytes_after_bitmaps;
     uint64 names_size;
     uint64 counters_delta;
+    uint64 bitmap_delta;
     uint64 names_delta;
     uint64 value_kind_last;
 } LLVMProfileRawHeader;
@@ -464,10 +470,12 @@ typedef struct LLVMProfileData {
     uint64 func_md5;
     uint64 func_hash;
     uint64 offset_counters;
+    uint64 offset_bitmaps;
     uintptr_t func_ptr;
     ValueProfNode **values;
     uint32 num_counters;
     uint16 num_value_sites[2];
+    uint32 num_bitmaps;
 } LLVMProfileData;
 
 /* The profiling data for writing to the output file, the width of
@@ -477,10 +485,12 @@ typedef struct LLVMProfileData_64 {
     uint64 func_md5;
     uint64 func_hash;
     uint64 offset_counters;
+    uint64 offset_bitmaps;
     uint64 func_ptr;
     uint64 values;
     uint32 num_counters;
     uint16 num_value_sites[2];
+    uint32 num_bitmaps;
 } LLVMProfileData_64;
 #endif /* end of WASM_ENABLE_STATIC_PGO != 0 */
 

+ 6 - 0
core/iwasm/compilation/aot_emit_aot_file.c

@@ -3378,6 +3378,12 @@ aot_resolve_object_data_sections(AOTObjectData *obj_data)
                     bh_memcpy_s(data_section->name, size, buf, size);
                     data_section->is_name_allocated = true;
                 }
+                else if (obj_data->comp_ctx->enable_llvm_pgo
+                         && !strcmp(name, "__llvm_prf_bits")) {
+                    LOG_WARNING("__llvm_prf_bits section is not supported and "
+                                "shouldn't be used in PGO.");
+                    return false;
+                }
 
                 if (obj_data->comp_ctx->enable_llvm_pgo
                     && !strcmp(name, "__llvm_prf_names")) {

+ 7 - 2
tests/benchmarks/README.md

@@ -8,6 +8,8 @@ Refer to the `README.md` under each folder for how to build and run the benchmar
 
 ## Install `llvm-profdata`
 
+> PS: the `llvm-profdata` vesion needs to be the same major version with llvm libraries used to build wamrc.
+
 The tool `llvm-profdata` is used when running the `test_pgo.sh` script under the benchmark folder. There are two ways to install it:
 
 1. Refer to https://apt.llvm.org/, e.g. in Ubuntu 20.04, add lines below to /etc/apt/source.list
@@ -18,19 +20,22 @@ deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal main
 # 15
 deb http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main
 deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-15 main
+# 18
+deb http://apt.llvm.org/focal/ llvm-toolchain-focal-18 main
+deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-18 main
 ```
 
 Then run `sudo apt update`, `sudo apt install llvm`. And after installing:
 
 ```bash
 cd /usr/bin
-sudo ln -s llvm-profdata-15 llvm-profdata
+sudo ln -s llvm-profdata-18 llvm-profdata
 ```
 
 2. Build manually
 
 ```bash
-git clone --depth 1 --branch release/15.x https://github.com/llvm/llvm-project.git
+git clone --depth 1 --branch release/18.x https://github.com/llvm/llvm-project.git
 cd llvm-project
 mkdir build && cd build
 cmake ../llvm \

+ 1 - 0
tests/benchmarks/coremark/run.sh

@@ -2,6 +2,7 @@
 
 # Copyright (C) 2019 Intel Corporation.  All rights reserved.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+set -e
 
 PLATFORM=$(uname -s | tr A-Z a-z)
 

+ 1 - 0
tests/benchmarks/coremark/test_pgo.sh

@@ -2,6 +2,7 @@
 
 # Copyright (C) 2019 Intel Corporation.  All rights reserved.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+set -e
 
 PLATFORM=$(uname -s | tr A-Z a-z)