Clang 是否为 WebAssembly 的 memory.fill 和 memory.copy 提供了内在函数?

2023-12-30

我正在用 C 语言开发 WebAssembly 模块,并一直在尝试利用memory.fill and memory.copy中定义的指令WebAssembly 规范 https://webassembly.github.io/spec/core/syntax/instructions.html#memory-instructions.

我已经知道 Clang (v11.1.0)支持其他与内存相关的 wasm 内在函数 https://github.com/llvm/llvm-project/blob/a6628e596e70bf5c31058dec582c8a7907928e98/clang/include/clang/Basic/BuiltinsWebAssembly.def#L25 like __builtin_wasm_memory_size and __builtin_wasm_memory_grow,但我一直很难弄清楚它是否支持内在函数memory.fill and memory.copy.

我不太熟悉 Clang/LLVM 的内部工作原理,但在一些地方似乎暗示了对这些指令的引用[1] https://reviews.llvm.org/D57736#change-nNN3Qfkg9dIt [2] https://reviews.llvm.org/D57791(除非我误解了某些东西)。

我尝试使用__builtin_memcpy and __builtin_memset:

__attribute__((export_name("memcpy")))
void memcpy_test(void* mem_dst, void* mem_src) {
    __builtin_memcpy(mem_dst, mem_src, 128);
}

__attribute__((export_name("memset")))
void memset_test(void* mem_src) {
    __builtin_memset(mem_src, 0, 128);
}

编译,但是调用__builtin_memcpy and __builtin_memset替换为程序集中的导入函数:

...
  (import "env" "memcpy" (func $memcpy (type $t0)))
  (import "env" "memset" (func $memset (type $t0)))
  (func $__wasm_call_ctors (type $t1))
  (func $memcpy_test (type $t2) (param $p0 i32) (param $p1 i32)
    local.get $p0
    local.get $p1
    i32.const 128
    call $memcpy
    drop)
  (func $memset_test (type $t3) (param $p0 i32)
    local.get $p0
    i32.const 0
    i32.const 128
    call $memset
    drop)
...

此时我有点卡住了,似乎这些内在函数尚不可用,但我对此并不肯定。

我真的很感激我能得到的任何帮助!

[快速说明:我目前对使用 emscripten 不感兴趣,因为我试图避免它附带的大量粘合代码。]


但致电__builtin_memcpy and __builtin_memset替换为程序集中的导入函数:

原因是这些指令不是核心 (MVP) WebAssembly 指令集的一部分,而是后来添加到的大容量内存提案 https://github.com/WebAssembly/bulk-memory-operations.

这些后续提案需要明确选择加入,因为存在您可能针对的给定 WebAssembly 引擎尚不支持它们的风险。可以肯定的是,您可以检查我在 web assembly.org 上的支持表 https://webassembly.org/roadmap/.

最后,如果您已经检查过这一点,则可以通过以下方式在 Clang 中选择加入此功能-mbulk-memory旗帜。例如,启用此标志和优化

clang temp.c -mbulk-memory -O -c -o temp.wasm

这是我从上面的示例中得到的:

(module
  (type $t0 (func (param i32 i32)))
  (type $t1 (func (param i32)))
  (import "env" "__linear_memory" (memory $env.__linear_memory 0))
  (import "env" "__indirect_function_table" (table $env.__indirect_function_table 0 funcref))
  (func $memcpy_test (type $t0) (param $p0 i32) (param $p1 i32)
    (memory.copy
      (local.get $p0)
      (local.get $p1)
      (i32.const 128)))
  (func $memset_test (type $t1) (param $p0 i32)
    (memory.fill
      (local.get $p0)
      (i32.const 0)
      (i32.const 128)))
  (export "memcpy" (func $memcpy_test))
  (export "memset" (func $memset_test)))

这似乎是预期的结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Clang 是否为 WebAssembly 的 memory.fill 和 memory.copy 提供了内在函数? 的相关文章

随机推荐