From 537fb3c28d423f8ad68c22aa334550f43d06a810 Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Thu, 25 Dec 2025 16:03:15 -0800 Subject: [PATCH 1/9] faster LD for vec3d --- examples/pathTracer/toy_path_tracer_profile.das | 2 ++ modules/dasLLVM/daslib/llvm_boost.das | 12 +++--------- modules/dasLLVM/daslib/llvm_jit.das | 15 ++++++++++++--- modules/dasLLVM/daslib/llvm_jit_common.das | 5 +++-- modules/dasLLVM/profile/nbodies.das | 2 ++ 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/examples/pathTracer/toy_path_tracer_profile.das b/examples/pathTracer/toy_path_tracer_profile.das index 3ed141a01a..ffdf336bfc 100644 --- a/examples/pathTracer/toy_path_tracer_profile.das +++ b/examples/pathTracer/toy_path_tracer_profile.das @@ -13,6 +13,8 @@ require daslib/jobque_boost require daslib/random require daslib/math_boost +options jit_vec3_ldu // allows unaligned vector3 loads in JIT to not respect boundaries + [export] def main { let width = 256 diff --git a/modules/dasLLVM/daslib/llvm_boost.das b/modules/dasLLVM/daslib/llvm_boost.das index 795bf39c69..077cdf2ec6 100644 --- a/modules/dasLLVM/daslib/llvm_boost.das +++ b/modules/dasLLVM/daslib/llvm_boost.das @@ -177,16 +177,10 @@ def LLVMBuildLoadVector3(builder : LLVMOpaqueBuilder?; var types : PrimitiveType verify(LLVMGetVectorSize(typ) == 3u) let elemT = LLVMGetElementType(typ) var ld = LLVMBuildLoad2(builder, LLVMVectorType(elemT, 4u), ptr, name) - LLVMSetVolatile(ld, 1) + // LLVMSetVolatile(ld, 1) // BBATKIN: verify why this is volatile? LLVMSetAlignment(ld, 4u) - var x = LLVMBuildExtractElement(builder, ld, types.ConstI32(0ul), "") - var y = LLVMBuildExtractElement(builder, ld, types.ConstI32(1ul), "") - var z = LLVMBuildExtractElement(builder, ld, types.ConstI32(2ul), "") - var xyz = LLVMGetUndef(LLVMVectorType(elemT, 3u)) - xyz = LLVMBuildInsertElement(builder, xyz, x, types.ConstI32(0ul), "") - xyz = LLVMBuildInsertElement(builder, xyz, y, types.ConstI32(1ul), "") - xyz = LLVMBuildInsertElement(builder, xyz, z, types.ConstI32(2ul), "") - return xyz + var undef4 = LLVMGetUndef(LLVMVectorType(elemT, 4u)) + return LLVMBuildShuffleVector(builder, types, ld, undef4, [0, 1, 2], name) } def LLVMBuildLoad2Aligned(builder : LLVMOpaqueBuilder?; typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; alignment : uint; name : string) { diff --git a/modules/dasLLVM/daslib/llvm_jit.das b/modules/dasLLVM/daslib/llvm_jit.das index 42d679fb16..238135b6f5 100644 --- a/modules/dasLLVM/daslib/llvm_jit.das +++ b/modules/dasLLVM/daslib/llvm_jit.das @@ -240,7 +240,7 @@ class LlvmJitVisitor : AstVisitor { option_no_alias : bool = false option_no_capture : bool = false own_di : bool = false - ldu_hint : array + ldu_hint : bool attributes : Attributes? def LlvmJitVisitor(ctx : Context?; var types_ : PrimitiveTypes?; uids : UidNodes?; need_di : bool; dib : LLVMOpaqueDIBuilder?; attrs : Attributes?) { @@ -698,7 +698,7 @@ class LlvmJitVisitor : AstVisitor { assert(g_builder != null, "missing builder") thisFunc = get_ptr(fun) uid.reset(get_ptr(fun)) - ldu_hint |> push(LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS) + ldu_hint = LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS let fnmna = uid.get_dll_fn_name(fun) ffunc = LLVMGetNamedFunction(g_mod, fnmna.impl()) wfunc = LLVMGetNamedFunction(g_mod, fnmna.publ()) @@ -731,7 +731,7 @@ class LlvmJitVisitor : AstVisitor { LLVMPositionBuilderAtEnd(g_builder, function_entry) LLVMBuildBr(g_builder, function_body) debug_after_function() - ldu_hint |> pop() + LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS = ldu_hint ffunc = null thisFunc = null uid.reset(null) @@ -6190,6 +6190,9 @@ class JIT_LLVM : AstSimulateMacro { assume path_to_shared_lib = string(prog.policies.jit_path_to_shared_lib) assume path_to_linker = string(prog.policies.jit_path_to_linker) + // Set global options + LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS = prog._options |> find_arg("jit_vec3_ldu") ?as tBool ?? LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS_DEFAULT + prog |> for_each_module <| $(mod) { mod |> for_each_function("") <| $(fun) { var rqj = fun.moreFlags.requestJit @@ -6325,3 +6328,9 @@ class JIT_LLVM : AstSimulateMacro { } +[_macro, macro_function] +def init_llvm_jit_module_options() { + if (is_compiling_macros_in_module("llvm_jit")) { + this_module() |> add_module_option("jit_vec3_ldu", Type.tBool) + } +} diff --git a/modules/dasLLVM/daslib/llvm_jit_common.das b/modules/dasLLVM/daslib/llvm_jit_common.das index 67c96bf514..a1cdf78872 100644 --- a/modules/dasLLVM/daslib/llvm_jit_common.das +++ b/modules/dasLLVM/daslib/llvm_jit_common.das @@ -30,7 +30,8 @@ let public LLVM_DEBUG_LINE_TRACES = false let public LLVM_JIT_LOG = false || LLVM_DEBUG_EVERYTHING -var public LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS = false +let public LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS_DEFAULT = false // NOTE - this should be true, to match interpreter and AOT behavior +var public LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS = LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS_DEFAULT let public LLVM_ENABLE_OPT_PASS = LLVM_DEBUG_EVERYTHING ? false : true let public LLVM_LOG_RESULT = LLVM_DEBUG_EVERYTHING || LLVM_DEBUG_RESULT @@ -869,7 +870,7 @@ def public build_broadcast_vector(builder : LLVMOpaqueBuilder?; opType : TypeDec } } - def public LLVMBuildLoadData2Aligned(builder : LLVMOpaqueBuilder?; var typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; alignment : int; name : string) { +def public LLVMBuildLoadData2Aligned(builder : LLVMOpaqueBuilder?; var typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; alignment : int; name : string) { if (!LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS && alignment != 16 && LLVMIsVector3(typ)) { // slow path return LLVMBuildLoadVector3(builder, g_prim_t, typ, ptr, name) diff --git a/modules/dasLLVM/profile/nbodies.das b/modules/dasLLVM/profile/nbodies.das index f5d820b3a7..c44106ad69 100644 --- a/modules/dasLLVM/profile/nbodies.das +++ b/modules/dasLLVM/profile/nbodies.das @@ -5,6 +5,8 @@ require math require daslib/unroll //ported from https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/nbody-gcc-2.html +options jit_vec3_ldu // allows unaligned vector3 loads in JIT to not respect boundaries + let { SOLAR_MASS = 4. * PI * PI } From 294d6b8591a2287dca9b3454ed2410e13fc06901 Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Thu, 25 Dec 2025 16:16:57 -0800 Subject: [PATCH 2/9] original swizzle? --- modules/dasLLVM/daslib/llvm_boost.das | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/dasLLVM/daslib/llvm_boost.das b/modules/dasLLVM/daslib/llvm_boost.das index 077cdf2ec6..f6583a62a0 100644 --- a/modules/dasLLVM/daslib/llvm_boost.das +++ b/modules/dasLLVM/daslib/llvm_boost.das @@ -179,8 +179,18 @@ def LLVMBuildLoadVector3(builder : LLVMOpaqueBuilder?; var types : PrimitiveType var ld = LLVMBuildLoad2(builder, LLVMVectorType(elemT, 4u), ptr, name) // LLVMSetVolatile(ld, 1) // BBATKIN: verify why this is volatile? LLVMSetAlignment(ld, 4u) + var x = LLVMBuildExtractElement(builder, ld, types.ConstI32(0ul), "") + var y = LLVMBuildExtractElement(builder, ld, types.ConstI32(1ul), "") + var z = LLVMBuildExtractElement(builder, ld, types.ConstI32(2ul), "") + var xyz = LLVMGetUndef(LLVMVectorType(elemT, 3u)) + xyz = LLVMBuildInsertElement(builder, xyz, x, types.ConstI32(0ul), "") + xyz = LLVMBuildInsertElement(builder, xyz, y, types.ConstI32(1ul), "") + xyz = LLVMBuildInsertElement(builder, xyz, z, types.ConstI32(2ul), "") + return xyz +/* var undef4 = LLVMGetUndef(LLVMVectorType(elemT, 4u)) return LLVMBuildShuffleVector(builder, types, ld, undef4, [0, 1, 2], name) +*/ } def LLVMBuildLoad2Aligned(builder : LLVMOpaqueBuilder?; typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; alignment : uint; name : string) { From 401d2682a5196720d7ed0530d87f6e4412f46310 Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Thu, 25 Dec 2025 16:23:21 -0800 Subject: [PATCH 3/9] this permutation? --- modules/dasLLVM/daslib/llvm_boost.das | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/dasLLVM/daslib/llvm_boost.das b/modules/dasLLVM/daslib/llvm_boost.das index f6583a62a0..6ae2e87968 100644 --- a/modules/dasLLVM/daslib/llvm_boost.das +++ b/modules/dasLLVM/daslib/llvm_boost.das @@ -177,8 +177,9 @@ def LLVMBuildLoadVector3(builder : LLVMOpaqueBuilder?; var types : PrimitiveType verify(LLVMGetVectorSize(typ) == 3u) let elemT = LLVMGetElementType(typ) var ld = LLVMBuildLoad2(builder, LLVMVectorType(elemT, 4u), ptr, name) - // LLVMSetVolatile(ld, 1) // BBATKIN: verify why this is volatile? + LLVMSetVolatile(ld, 1) // BBATKIN: verify why this is volatile? LLVMSetAlignment(ld, 4u) +/* var x = LLVMBuildExtractElement(builder, ld, types.ConstI32(0ul), "") var y = LLVMBuildExtractElement(builder, ld, types.ConstI32(1ul), "") var z = LLVMBuildExtractElement(builder, ld, types.ConstI32(2ul), "") @@ -187,10 +188,9 @@ def LLVMBuildLoadVector3(builder : LLVMOpaqueBuilder?; var types : PrimitiveType xyz = LLVMBuildInsertElement(builder, xyz, y, types.ConstI32(1ul), "") xyz = LLVMBuildInsertElement(builder, xyz, z, types.ConstI32(2ul), "") return xyz -/* +*/ var undef4 = LLVMGetUndef(LLVMVectorType(elemT, 4u)) return LLVMBuildShuffleVector(builder, types, ld, undef4, [0, 1, 2], name) -*/ } def LLVMBuildLoad2Aligned(builder : LLVMOpaqueBuilder?; typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; alignment : uint; name : string) { From b5e6b145f5354b85ace224651afe8e68436f2ac2 Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Thu, 25 Dec 2025 17:31:46 -0800 Subject: [PATCH 4/9] trying without? --- modules/dasLLVM/daslib/llvm_boost.das | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/dasLLVM/daslib/llvm_boost.das b/modules/dasLLVM/daslib/llvm_boost.das index 6ae2e87968..4c297ecca6 100644 --- a/modules/dasLLVM/daslib/llvm_boost.das +++ b/modules/dasLLVM/daslib/llvm_boost.das @@ -177,8 +177,8 @@ def LLVMBuildLoadVector3(builder : LLVMOpaqueBuilder?; var types : PrimitiveType verify(LLVMGetVectorSize(typ) == 3u) let elemT = LLVMGetElementType(typ) var ld = LLVMBuildLoad2(builder, LLVMVectorType(elemT, 4u), ptr, name) - LLVMSetVolatile(ld, 1) // BBATKIN: verify why this is volatile? - LLVMSetAlignment(ld, 4u) + //LLVMSetVolatile(ld, 1) // BBATKIN: verify why this is volatile? + LLVMSetAlignment(ld, 16u) /* var x = LLVMBuildExtractElement(builder, ld, types.ConstI32(0ul), "") var y = LLVMBuildExtractElement(builder, ld, types.ConstI32(1ul), "") From c0c0448a0bfee5bd7a3dd64c6de11a87307bf979 Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Thu, 25 Dec 2025 17:49:05 -0800 Subject: [PATCH 5/9] now with volatile v3 load on arm and arm64 only --- include/daScript/simulate/aot_builtin.h | 3 ++ modules/dasLLVM/daslib/llvm_boost.das | 24 +++++++------- modules/dasLLVM/daslib/llvm_jit.das | 9 ++++++ modules/dasLLVM/daslib/llvm_jit_common.das | 8 +++-- src/builtin/module_builtin_runtime.cpp | 37 ++++++++++++++++++++++ 5 files changed, 67 insertions(+), 14 deletions(-) diff --git a/include/daScript/simulate/aot_builtin.h b/include/daScript/simulate/aot_builtin.h index bbfa3a44eb..b5532d5a80 100644 --- a/include/daScript/simulate/aot_builtin.h +++ b/include/daScript/simulate/aot_builtin.h @@ -179,4 +179,7 @@ namespace das { void builtin_main_loop ( const TBlock & block, Context * context, LineInfoArg * at ); vec4f _builtin_hash ( Context & context, SimNode_CallBase * call, vec4f * args ); + + const char * das_get_platform_name(); + const char * das_get_architecture_name(); } diff --git a/modules/dasLLVM/daslib/llvm_boost.das b/modules/dasLLVM/daslib/llvm_boost.das index 4c297ecca6..618800001c 100644 --- a/modules/dasLLVM/daslib/llvm_boost.das +++ b/modules/dasLLVM/daslib/llvm_boost.das @@ -177,22 +177,22 @@ def LLVMBuildLoadVector3(builder : LLVMOpaqueBuilder?; var types : PrimitiveType verify(LLVMGetVectorSize(typ) == 3u) let elemT = LLVMGetElementType(typ) var ld = LLVMBuildLoad2(builder, LLVMVectorType(elemT, 4u), ptr, name) - //LLVMSetVolatile(ld, 1) // BBATKIN: verify why this is volatile? - LLVMSetAlignment(ld, 16u) -/* - var x = LLVMBuildExtractElement(builder, ld, types.ConstI32(0ul), "") - var y = LLVMBuildExtractElement(builder, ld, types.ConstI32(1ul), "") - var z = LLVMBuildExtractElement(builder, ld, types.ConstI32(2ul), "") - var xyz = LLVMGetUndef(LLVMVectorType(elemT, 3u)) - xyz = LLVMBuildInsertElement(builder, xyz, x, types.ConstI32(0ul), "") - xyz = LLVMBuildInsertElement(builder, xyz, y, types.ConstI32(1ul), "") - xyz = LLVMBuildInsertElement(builder, xyz, z, types.ConstI32(2ul), "") - return xyz -*/ + LLVMSetAlignment(ld, 4u) var undef4 = LLVMGetUndef(LLVMVectorType(elemT, 4u)) return LLVMBuildShuffleVector(builder, types, ld, undef4, [0, 1, 2], name) } +def LLVMBuildLoadVector3Volatile(builder : LLVMOpaqueBuilder?; var types : PrimitiveTypes?; var typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; name : string) { + verify(LLVMGetVectorSize(typ) == 3u) + let elemT = LLVMGetElementType(typ) + var ld = LLVMBuildLoad2(builder, LLVMVectorType(elemT, 4u), ptr, name) + LLVMSetVolatile(ld, 1) + LLVMSetAlignment(ld, 4u) + var undef4 = LLVMGetUndef(LLVMVectorType(elemT, 4u)) + return LLVMBuildShuffleVector(builder, types, ld, undef4, [0, 1, 2], name) +} + + def LLVMBuildLoad2Aligned(builder : LLVMOpaqueBuilder?; typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; alignment : uint; name : string) { let ld = LLVMBuildLoad2(builder, typ, ptr, name) LLVMSetAlignment(ld, alignment) diff --git a/modules/dasLLVM/daslib/llvm_jit.das b/modules/dasLLVM/daslib/llvm_jit.das index 238135b6f5..ccf74d146e 100644 --- a/modules/dasLLVM/daslib/llvm_jit.das +++ b/modules/dasLLVM/daslib/llvm_jit.das @@ -6190,6 +6190,15 @@ class JIT_LLVM : AstSimulateMacro { assume path_to_shared_lib = string(prog.policies.jit_path_to_shared_lib) assume path_to_linker = string(prog.policies.jit_path_to_linker) + // determine if we need volatile vector3 loads + let platform = get_platform_name() + let arch = get_architecture_name() + to_log(LOG_INFO, "LLVM JIT: platform={platform}, architecture={arch}\n") + LLVM_JIT_NEED_VOLATILE_VEC3_LOAD = false + if (arch == "arm64" || arch == "arm") { + LLVM_JIT_NEED_VOLATILE_VEC3_LOAD = true + } + // Set global options LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS = prog._options |> find_arg("jit_vec3_ldu") ?as tBool ?? LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS_DEFAULT diff --git a/modules/dasLLVM/daslib/llvm_jit_common.das b/modules/dasLLVM/daslib/llvm_jit_common.das index a1cdf78872..21b119f3c9 100644 --- a/modules/dasLLVM/daslib/llvm_jit_common.das +++ b/modules/dasLLVM/daslib/llvm_jit_common.das @@ -32,6 +32,7 @@ let public LLVM_JIT_LOG = false || LLVM_DEBUG_EVERYTHING let public LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS_DEFAULT = false // NOTE - this should be true, to match interpreter and AOT behavior var public LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS = LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS_DEFAULT +var public LLVM_JIT_NEED_VOLATILE_VEC3_LOAD = false let public LLVM_ENABLE_OPT_PASS = LLVM_DEBUG_EVERYTHING ? false : true let public LLVM_LOG_RESULT = LLVM_DEBUG_EVERYTHING || LLVM_DEBUG_RESULT @@ -872,8 +873,11 @@ def public build_broadcast_vector(builder : LLVMOpaqueBuilder?; opType : TypeDec def public LLVMBuildLoadData2Aligned(builder : LLVMOpaqueBuilder?; var typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; alignment : int; name : string) { if (!LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS && alignment != 16 && LLVMIsVector3(typ)) { - // slow path - return LLVMBuildLoadVector3(builder, g_prim_t, typ, ptr, name) + if ( LLVM_JIT_NEED_VOLATILE_VEC3_LOAD ) { + return LLVMBuildLoadVector3Volatile(builder, g_prim_t, typ, ptr, name) + } else { + return LLVMBuildLoadVector3(builder, g_prim_t, typ, ptr, name) + } } else { return LLVMBuildLoad2Aligned(builder, typ, ptr, alignment |> uint, name) } diff --git a/src/builtin/module_builtin_runtime.cpp b/src/builtin/module_builtin_runtime.cpp index 8cd1ae6000..0511e928b7 100644 --- a/src/builtin/module_builtin_runtime.cpp +++ b/src/builtin/module_builtin_runtime.cpp @@ -1603,6 +1603,38 @@ namespace das idpi->noPointerCast = true; } + // windows, darwin, linux, etc + const char * das_get_platform_name() { + #if defined(_WIN32) || defined(_WIN64) + return "windows"; + #elif defined(__APPLE__) || defined(__MACH__) + return "darwin"; + #elif defined(__linux__) + return "linux"; + #elif defined(__EMSCRIPTEN__) + return "emscripten"; + #else + return "unknown"; + #endif + } + + // x86, arm, etc + const char * das_get_architecture_name() { + #if defined(__x86_64__) || defined(_M_X64) + return "x86_64"; + #elif defined(__i386) || defined(_M_IX86) + return "x86"; + #elif defined(__aarch64__) + return "arm64"; + #elif defined(__arm__) || defined(_M_ARM) + return "arm"; + #elif defined(__EMSCRIPTEN__) + return "wasm32"; + #else + return "unknown"; + #endif + } + void Module_BuiltIn::addRuntime(ModuleLibrary & lib) { // printer flags addAlias(makePrintFlags()); @@ -2133,5 +2165,10 @@ namespace das addExtern(*this, lib, "__bit_set", SideEffects::modifyArgument, "__bit_set64") ->args({"value","mask","on"}); + // platform and architecture + addExtern(*this, lib, "get_platform_name", + SideEffects::none, "das_get_platform_name"); + addExtern(*this, lib, "get_architecture_name", + SideEffects::none, "das_get_architecture_name"); } } From cd9f1e5655253d6dd5891678b0ef3e4f132de1d6 Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Thu, 25 Dec 2025 17:59:05 -0800 Subject: [PATCH 6/9] unformatted --- modules/dasLLVM/daslib/llvm_jit_common.das | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/dasLLVM/daslib/llvm_jit_common.das b/modules/dasLLVM/daslib/llvm_jit_common.das index 21b119f3c9..b552f4c677 100644 --- a/modules/dasLLVM/daslib/llvm_jit_common.das +++ b/modules/dasLLVM/daslib/llvm_jit_common.das @@ -873,7 +873,7 @@ def public build_broadcast_vector(builder : LLVMOpaqueBuilder?; opType : TypeDec def public LLVMBuildLoadData2Aligned(builder : LLVMOpaqueBuilder?; var typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; alignment : int; name : string) { if (!LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS && alignment != 16 && LLVMIsVector3(typ)) { - if ( LLVM_JIT_NEED_VOLATILE_VEC3_LOAD ) { + if (LLVM_JIT_NEED_VOLATILE_VEC3_LOAD) { return LLVMBuildLoadVector3Volatile(builder, g_prim_t, typ, ptr, name) } else { return LLVMBuildLoadVector3(builder, g_prim_t, typ, ptr, name) From a7a085f7221e16b9135574c88c61962bbb0be271 Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Thu, 25 Dec 2025 18:33:22 -0800 Subject: [PATCH 7/9] now with more obvious vec load --- modules/dasLLVM/daslib/llvm_boost.das | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/dasLLVM/daslib/llvm_boost.das b/modules/dasLLVM/daslib/llvm_boost.das index 618800001c..77373d12eb 100644 --- a/modules/dasLLVM/daslib/llvm_boost.das +++ b/modules/dasLLVM/daslib/llvm_boost.das @@ -176,10 +176,14 @@ def LLVMIsVector3(typ : LLVMOpaqueType?) : bool { def LLVMBuildLoadVector3(builder : LLVMOpaqueBuilder?; var types : PrimitiveTypes?; var typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; name : string) { verify(LLVMGetVectorSize(typ) == 3u) let elemT = LLVMGetElementType(typ) - var ld = LLVMBuildLoad2(builder, LLVMVectorType(elemT, 4u), ptr, name) - LLVMSetAlignment(ld, 4u) - var undef4 = LLVMGetUndef(LLVMVectorType(elemT, 4u)) - return LLVMBuildShuffleVector(builder, types, ld, undef4, [0, 1, 2], name) + var x = LLVMBuildLoad2(builder, elemT, ptr, "") + var y = LLVMBuildLoad2(builder, elemT, LLVMBuildGEP2(builder, elemT, ptr, types.ConstI32(1ul), "", true), "") + var z = LLVMBuildLoad2(builder, elemT, LLVMBuildGEP2(builder, elemT, ptr, types.ConstI32(2ul), "", true), "") + var xyz = LLVMGetUndef(LLVMVectorType(elemT, 3u)) + xyz = LLVMBuildInsertElement(builder, xyz, x, types.ConstI32(0ul), "") + xyz = LLVMBuildInsertElement(builder, xyz, y, types.ConstI32(1ul), "") + xyz = LLVMBuildInsertElement(builder, xyz, z, types.ConstI32(2ul), "") + return xyz } def LLVMBuildLoadVector3Volatile(builder : LLVMOpaqueBuilder?; var types : PrimitiveTypes?; var typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; name : string) { From 270f75a0e1d356f1d56364f8412a239e7be7ad77 Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Thu, 25 Dec 2025 18:49:45 -0800 Subject: [PATCH 8/9] bye-bye volatile --- modules/dasLLVM/daslib/llvm_boost.das | 11 ----------- modules/dasLLVM/daslib/llvm_jit.das | 9 --------- modules/dasLLVM/daslib/llvm_jit_common.das | 7 +------ 3 files changed, 1 insertion(+), 26 deletions(-) diff --git a/modules/dasLLVM/daslib/llvm_boost.das b/modules/dasLLVM/daslib/llvm_boost.das index 77373d12eb..30a3d2205a 100644 --- a/modules/dasLLVM/daslib/llvm_boost.das +++ b/modules/dasLLVM/daslib/llvm_boost.das @@ -186,17 +186,6 @@ def LLVMBuildLoadVector3(builder : LLVMOpaqueBuilder?; var types : PrimitiveType return xyz } -def LLVMBuildLoadVector3Volatile(builder : LLVMOpaqueBuilder?; var types : PrimitiveTypes?; var typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; name : string) { - verify(LLVMGetVectorSize(typ) == 3u) - let elemT = LLVMGetElementType(typ) - var ld = LLVMBuildLoad2(builder, LLVMVectorType(elemT, 4u), ptr, name) - LLVMSetVolatile(ld, 1) - LLVMSetAlignment(ld, 4u) - var undef4 = LLVMGetUndef(LLVMVectorType(elemT, 4u)) - return LLVMBuildShuffleVector(builder, types, ld, undef4, [0, 1, 2], name) -} - - def LLVMBuildLoad2Aligned(builder : LLVMOpaqueBuilder?; typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; alignment : uint; name : string) { let ld = LLVMBuildLoad2(builder, typ, ptr, name) LLVMSetAlignment(ld, alignment) diff --git a/modules/dasLLVM/daslib/llvm_jit.das b/modules/dasLLVM/daslib/llvm_jit.das index ccf74d146e..238135b6f5 100644 --- a/modules/dasLLVM/daslib/llvm_jit.das +++ b/modules/dasLLVM/daslib/llvm_jit.das @@ -6190,15 +6190,6 @@ class JIT_LLVM : AstSimulateMacro { assume path_to_shared_lib = string(prog.policies.jit_path_to_shared_lib) assume path_to_linker = string(prog.policies.jit_path_to_linker) - // determine if we need volatile vector3 loads - let platform = get_platform_name() - let arch = get_architecture_name() - to_log(LOG_INFO, "LLVM JIT: platform={platform}, architecture={arch}\n") - LLVM_JIT_NEED_VOLATILE_VEC3_LOAD = false - if (arch == "arm64" || arch == "arm") { - LLVM_JIT_NEED_VOLATILE_VEC3_LOAD = true - } - // Set global options LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS = prog._options |> find_arg("jit_vec3_ldu") ?as tBool ?? LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS_DEFAULT diff --git a/modules/dasLLVM/daslib/llvm_jit_common.das b/modules/dasLLVM/daslib/llvm_jit_common.das index b552f4c677..c3de5b24ec 100644 --- a/modules/dasLLVM/daslib/llvm_jit_common.das +++ b/modules/dasLLVM/daslib/llvm_jit_common.das @@ -32,7 +32,6 @@ let public LLVM_JIT_LOG = false || LLVM_DEBUG_EVERYTHING let public LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS_DEFAULT = false // NOTE - this should be true, to match interpreter and AOT behavior var public LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS = LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS_DEFAULT -var public LLVM_JIT_NEED_VOLATILE_VEC3_LOAD = false let public LLVM_ENABLE_OPT_PASS = LLVM_DEBUG_EVERYTHING ? false : true let public LLVM_LOG_RESULT = LLVM_DEBUG_EVERYTHING || LLVM_DEBUG_RESULT @@ -873,11 +872,7 @@ def public build_broadcast_vector(builder : LLVMOpaqueBuilder?; opType : TypeDec def public LLVMBuildLoadData2Aligned(builder : LLVMOpaqueBuilder?; var typ : LLVMOpaqueType?; ptr : LLVMOpaqueValue?; alignment : int; name : string) { if (!LLVM_JIT_ALLOW_UNALIGNED_VECTOR_READ_OUT_OF_BOUNDS && alignment != 16 && LLVMIsVector3(typ)) { - if (LLVM_JIT_NEED_VOLATILE_VEC3_LOAD) { - return LLVMBuildLoadVector3Volatile(builder, g_prim_t, typ, ptr, name) - } else { - return LLVMBuildLoadVector3(builder, g_prim_t, typ, ptr, name) - } + return LLVMBuildLoadVector3(builder, g_prim_t, typ, ptr, name) } else { return LLVMBuildLoad2Aligned(builder, typ, ptr, alignment |> uint, name) } From 7b453c88d4e98c7eeeb51bb2c280bdfcd3f01d5d Mon Sep 17 00:00:00 2001 From: Boris Batkin Date: Thu, 25 Dec 2025 18:55:10 -0800 Subject: [PATCH 9/9] no longer needed - and only one hint --- examples/pathTracer/toy_path_tracer_profile.das | 2 -- modules/dasLLVM/profile/nbodies.das | 8 +------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/examples/pathTracer/toy_path_tracer_profile.das b/examples/pathTracer/toy_path_tracer_profile.das index ffdf336bfc..3ed141a01a 100644 --- a/examples/pathTracer/toy_path_tracer_profile.das +++ b/examples/pathTracer/toy_path_tracer_profile.das @@ -13,8 +13,6 @@ require daslib/jobque_boost require daslib/random require daslib/math_boost -options jit_vec3_ldu // allows unaligned vector3 loads in JIT to not respect boundaries - [export] def main { let width = 256 diff --git a/modules/dasLLVM/profile/nbodies.das b/modules/dasLLVM/profile/nbodies.das index c44106ad69..013a62274e 100644 --- a/modules/dasLLVM/profile/nbodies.das +++ b/modules/dasLLVM/profile/nbodies.das @@ -5,8 +5,6 @@ require math require daslib/unroll //ported from https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/nbody-gcc-2.html -options jit_vec3_ldu // allows unaligned vector3 loads in JIT to not respect boundaries - let { SOLAR_MASS = 4. * PI * PI } @@ -48,7 +46,6 @@ let { nbodies = 5 } -[jit] def offset_momentum(var bodies : body[5]) { var px : float3 for (b in bodies) { @@ -57,7 +54,7 @@ def offset_momentum(var bodies : body[5]) { bodies[0].v = px / SOLAR_MASS } -[jit, hint(alwaysinline, hot, noalias=bodies, unsafe_range_check)] +[hint(vec3_ldu)] def advance(var bodies : body[5]) { unroll <| $() { for (i in range(nbodies)) { @@ -76,7 +73,6 @@ def advance(var bodies : body[5]) { } } -[jit] def energy(var bodies : body[5]) { var e = 0.0 var i = 0 @@ -91,7 +87,6 @@ def energy(var bodies : body[5]) { return e } -[jit] def scale_bodies(scale; var bodies : body[5]) { for (b in bodies) { b.mass *= scale * scale @@ -99,7 +94,6 @@ def scale_bodies(scale; var bodies : body[5]) { } } -[jit] def nbodies(n : int) { scale_bodies(0.01, g_bodies) for (i in range(n)) {