Skip to content

Commit

Permalink
wasm2c: harmonize bulk mem ops re: i32/i64 (#2506) + parametrize memc…
Browse files Browse the repository at this point in the history
…hecks per-memory (#2507)

The PR updates the bulk memory operations (memory.fill, memory.copy,
table.fill, etc.) to support 64-bit addresses and counts. Previously these functions
only took u32's, even with memory64 enabled. (#2506)

This PR also allows "software-bounds-checked" memories and "guard-page-checked"
memories to coexist in the same module. It creates two versions of every memory
operation: an unrestricted version (that works with any memory) and a _default32
version (for memories with default page size and i32 indexing). (#2507)

#2506 and #2507 have been squashed together to avoid a performance regression.

This is a stepping stone to supporting custom-page-sizes (which will need to be
software-bounds-checked) (#2508).
  • Loading branch information
keithw authored Dec 18, 2024
1 parent 4e7d7ef commit ea193b4
Show file tree
Hide file tree
Showing 17 changed files with 1,142 additions and 631 deletions.
19 changes: 18 additions & 1 deletion src/c-writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1369,7 +1369,24 @@ static std::string GetMemoryTypeString(const Memory& memory) {
}

static std::string GetMemoryAPIString(const Memory& memory, std::string api) {
return memory.page_limits.is_shared ? (api + "_shared") : api;
std::string suffix;
if (memory.page_limits.is_shared) {
suffix += "_shared";
}

// Memory load and store routines can be optimized for default-page-size,
// 32-bit memories (by using hardware to bounds-check memory access).
// Append "_default32" to these function names to choose the (possibly) fast
// path.
//
// We don't need to do this for runtime routines; those can check the
// wasm_rt_memory_t structure.
if (api.substr(0, 8) != "wasm_rt_" &&
memory.page_size == WABT_DEFAULT_PAGE_SIZE &&
memory.page_limits.is_64 == false) {
suffix += "_default32";
}
return api + suffix;
}

void CWriter::WriteInitExpr(const ExprList& expr_list) {
Expand Down
136 changes: 73 additions & 63 deletions src/prebuilt/wasm2c_atomicops_source_declarations.cc

Large diffs are not rendered by default.

46 changes: 26 additions & 20 deletions src/prebuilt/wasm2c_simd_source_declarations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,56 +15,62 @@ R"w2c_template(#endif
R"w2c_template(// TODO: equivalent constraint for ARM and other architectures
)w2c_template"
R"w2c_template(
#define DEFINE_SIMD_LOAD_FUNC(name, func, t) \
#define DEFINE_SIMD_LOAD_FUNC(name, func, t) \
)w2c_template"
R"w2c_template( static inline v128 name(wasm_rt_memory_t* mem, u64 addr) { \
R"w2c_template( static inline v128 name##_unchecked(wasm_rt_memory_t* mem, u64 addr) { \
)w2c_template"
R"w2c_template( MEMCHECK(mem, addr, t); \
R"w2c_template( v128 result = func(MEM_ADDR(mem, addr, sizeof(t))); \
)w2c_template"
R"w2c_template( v128 result = func(MEM_ADDR(mem, addr, sizeof(t))); \
R"w2c_template( SIMD_FORCE_READ(result); \
)w2c_template"
R"w2c_template( SIMD_FORCE_READ(result); \
R"w2c_template( return result; \
)w2c_template"
R"w2c_template( return result; \
R"w2c_template( } \
)w2c_template"
R"w2c_template( }
R"w2c_template( DEF_MEM_CHECKS0(name, _, t, return, v128);
)w2c_template"
R"w2c_template(
#define DEFINE_SIMD_LOAD_LANE(name, func, t, lane) \
)w2c_template"
R"w2c_template( static inline v128 name(wasm_rt_memory_t* mem, u64 addr, v128 vec) { \
R"w2c_template( static inline v128 name##_unchecked(wasm_rt_memory_t* mem, u64 addr, \
)w2c_template"
R"w2c_template( MEMCHECK(mem, addr, t); \
R"w2c_template( v128 vec) { \
)w2c_template"
R"w2c_template( v128 result = func(MEM_ADDR(mem, addr, sizeof(t)), vec, lane); \
)w2c_template"
R"w2c_template( SIMD_FORCE_READ(result); \
)w2c_template"
R"w2c_template( return result; \
)w2c_template"
R"w2c_template( }
R"w2c_template( } \
)w2c_template"
R"w2c_template( DEF_MEM_CHECKS1(name, _, t, return, v128, v128);
)w2c_template"
R"w2c_template(
#define DEFINE_SIMD_STORE(name, t) \
#define DEFINE_SIMD_STORE(name, t) \
)w2c_template"
R"w2c_template( static inline void name##_unchecked(wasm_rt_memory_t* mem, u64 addr, \
)w2c_template"
R"w2c_template( static inline void name(wasm_rt_memory_t* mem, u64 addr, v128 value) { \
R"w2c_template( v128 value) { \
)w2c_template"
R"w2c_template( MEMCHECK(mem, addr, t); \
R"w2c_template( simde_wasm_v128_store(MEM_ADDR(mem, addr, sizeof(t)), value); \
)w2c_template"
R"w2c_template( simde_wasm_v128_store(MEM_ADDR(mem, addr, sizeof(t)), value); \
R"w2c_template( } \
)w2c_template"
R"w2c_template( }
R"w2c_template( DEF_MEM_CHECKS1(name, _, t, , void, v128);
)w2c_template"
R"w2c_template(
#define DEFINE_SIMD_STORE_LANE(name, func, t, lane) \
#define DEFINE_SIMD_STORE_LANE(name, func, t, lane) \
)w2c_template"
R"w2c_template( static inline void name##_unchecked(wasm_rt_memory_t* mem, u64 addr, \
)w2c_template"
R"w2c_template( static inline void name(wasm_rt_memory_t* mem, u64 addr, v128 value) { \
R"w2c_template( v128 value) { \
)w2c_template"
R"w2c_template( MEMCHECK(mem, addr, t); \
R"w2c_template( func(MEM_ADDR(mem, addr, sizeof(t)), value, lane); \
)w2c_template"
R"w2c_template( func(MEM_ADDR(mem, addr, sizeof(t)), value, lane); \
R"w2c_template( } \
)w2c_template"
R"w2c_template( }
R"w2c_template( DEF_MEM_CHECKS1(name, _, t, , void, v128);
)w2c_template"
R"w2c_template(
// clang-format off
Expand Down
Loading

0 comments on commit ea193b4

Please sign in to comment.