Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions examples/test/test_handles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,31 @@ void testPoint3Array(const TBlock<void,const Point3Array> & blk, Context * conte
context->invoke(blk, args, nullptr, at);
}


float2 test_abi_mad2 ( float2 a, float2 b, float2 c ) {
return v_add(v_mul(a,b),c);
}

float3 test_abi_mad3 ( float3 a, float3 b, float3 c ) {
return v_add(v_mul(a,b),c);
}

float4 test_abi_mad4 ( float4 a, float4 b, float4 c ) {
return v_add(v_mul(a,b),c);
}

Func test_abi_func ( Func a, Context * ctx ) {
bool found = false;
for ( int i=0; i!=ctx->getTotalFunctions(); ++i ) {
if ( ctx->getFunction(i)==a.PTR ) {
found = true;
break;
}
}
if ( !found ) ctx->throw_error("function not found");
return a;
}

TDim<int32_t,10> testCMRES ( Context * __context__ )
{
TDim<int32_t,10> __a_rename_at_7; das_zero(__a_rename_at_7);
Expand Down Expand Up @@ -514,6 +539,16 @@ Module_UnitTest::Module_UnitTest() : Module("UnitTest") {
SideEffects::modifyExternal, "testPoint3Array");
addExtern<DAS_BIND_FUN(testCMRES),SimNode_ExtFuncCallAndCopyOrMove>(*this, lib, "testCMRES",
SideEffects::modifyExternal, "testCMRES");

// abi tests. We use it in JIT.
addExtern<DAS_BIND_FUN(test_abi_mad2) >(*this,lib,"test_abi_mad",SideEffects::worstDefault,"test_abi_mad2")
->args({"a","b","c"});
addExtern<DAS_BIND_FUN(test_abi_mad3) >(*this,lib,"test_abi_mad",SideEffects::worstDefault,"test_abi_mad3")
->args({"a","b","c"});
addExtern<DAS_BIND_FUN(test_abi_mad4) >(*this,lib,"test_abi_mad",SideEffects::worstDefault,"test_abi_mad4")
->args({"a","b","c"});
addExtern<DAS_BIND_FUN(test_abi_func) >(*this,lib,"test_abi_func",SideEffects::worstDefault,"test_abi_func")
->args({"fn","context"});
// foo array
addExtern<DAS_BIND_FUN(testFooArray)>(*this, lib, "testFooArray",
SideEffects::modifyExternal, "testFooArray");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,41 @@
options gen2
require dastest/testing_boost
options no_aot // `test_abi_func` etc is not declared in headers.

require llvm
require jit
require UnitTest

[jit]
def jit_test_abi_mad(a, b, c) {
return test_abi_mad(a, b, c)
}

[test]
def test_vec_abi(t : T?) {
t |> run("test_abi_mad float2") <| @(t : T?) {
t |> success(is_jit_function(@@ < (a, b, c : float2) : float2 > jit_test_abi_mad))
def test_vec_abi() {
if (true) {
verify(!jit_enabled() || is_jit_function(@@ < (a, b, c : float2) : float2 > jit_test_abi_mad))
let a = float2(1, 2)
let b = float2(3, 4)
let c = float2(5, 6)
let tt = test_abi_mad(a, b, c)
let jt = jit_test_abi_mad(a, b, c)
t |> equal(tt, jt)
assert(tt == jt)
}
t |> run("test_abi_mad float3") <| @(t : T?) {
t |> success(is_jit_function(@@ < (a, b, c : float3) : float3 > jit_test_abi_mad))

if (true) {
verify(!jit_enabled() || is_jit_function(@@ < (a, b, c : float3) : float3 > jit_test_abi_mad))
let a = float3(1, 2, 3)
let b = float3(4, 5, 6)
let c = float3(7, 8, 9)
let tt = test_abi_mad(a, b, c)
let jt = jit_test_abi_mad(a, b, c)
t |> equal(tt, jt)
assert(tt == jt)
}
t |> run("test_abi_mad float4") <| @(t : T?) {
t |> success(is_jit_function(@@ < (a, b, c : float4) : float4 > jit_test_abi_mad))

if (true) {
verify(!jit_enabled() || is_jit_function(@@ < (a, b, c : float4) : float4 > jit_test_abi_mad))
let a = float4(1, 2, 3, 4)
let b = float4(5, 6, 7, 8)
let c = float4(9, 10, 11, 12)
let tt = test_abi_mad(a, b, c)
let jt = jit_test_abi_mad(a, b, c)
t |> equal(tt, jt)
assert(tt == jt)
}
}

Expand All @@ -45,9 +44,15 @@ def dummy {
assert(false)
}

[test]
def test_func_abi(t : T?) {
def test_func_abi() {
let fnA = @@dummy
let fnB = test_abi_func(fnA)
t |> equal(fnA, fnB)
assert(fnA == fnB)
}

[export]
def test {
test_vec_abi()
test_func_abi()
return true
}
17 changes: 3 additions & 14 deletions modules/dasLLVM/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ IF ((NOT DAS_LLVM_INCLUDED) AND ((NOT ${DAS_LLVM_DISABLED}) OR (NOT DEFINED DAS_

LIST(APPEND CMAKE_MODULE_PATH ${DAS_LLVM_DIR})

SET(DAS_LLVM_MODULE_SRC
${DAS_LLVM_DIR}/src/dasLLVM.cpp
)

ADD_MODULE_CPP(dasLLVM)

ADD_MODULE_DAS(llvm bindings llvm_const)
ADD_MODULE_DAS(llvm bindings llvm_enum)
ADD_MODULE_DAS(llvm bindings llvm_func)
Expand All @@ -24,9 +18,6 @@ IF ((NOT DAS_LLVM_INCLUDED) AND ((NOT ${DAS_LLVM_DISABLED}) OR (NOT DEFINED DAS_
ADD_MODULE_DAS(llvm daslib llvm_jit_intrin)
ADD_MODULE_DAS(llvm daslib llvm_jit_common)
ADD_MODULE_DAS(llvm daslib llvm_dll_utils)
ADD_MODULE_LIB(libDasModuleLlvm ${DAS_LLVM_MODULE_SRC})

TARGET_INCLUDE_DIRECTORIES(libDasModuleLlvm PUBLIC ${LLVM_INCLUDE_DIRS})

set(DAS_LLVM_LIB_OUTPUT "${PROJECT_SOURCE_DIR}/lib")
set(DAS_CLANG_OUTPUT "${PROJECT_SOURCE_DIR}/bin")
Expand All @@ -38,9 +29,8 @@ IF ((NOT DAS_LLVM_INCLUDED) AND ((NOT ${DAS_LLVM_DISABLED}) OR (NOT DEFINED DAS_
MESSAGE(STATUS "LLVM found at: ${LLVM_INSTALL_PREFIX}")
IF(WIN32)
# Copy clang-cl to use it as a linker
add_custom_command(TARGET libDasModuleLlvm POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${LLVM_INSTALL_PREFIX}/bin/clang-cl.exe"
FILE(COPY
"${LLVM_INSTALL_PREFIX}/bin/clang-cl.exe" DESTINATION
"${DAS_CLANG_OUTPUT}/clang-cl.exe"
)
set(DAS_LLVM_DLL_PATH ${LLVM_INSTALL_PREFIX}/bin/LLVM-C.dll)
Expand All @@ -50,7 +40,7 @@ IF ((NOT DAS_LLVM_INCLUDED) AND ((NOT ${DAS_LLVM_DISABLED}) OR (NOT DEFINED DAS_
set(DAS_LLVM_DLL_PATH ${LLVM_INSTALL_PREFIX}/lib/libLLVM.so )
ENDIF()
get_filename_component(dll_name "${dll}" NAME)
add_custom_command(TARGET libDasModuleLlvm POST_BUILD
add_custom_target(copy_llvm_dll ALL
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${DAS_LLVM_DLL_PATH}"
"${DAS_LLVM_LIB_OUTPUT}/${DAS_LLVM_DLL_NAME}"
Expand Down Expand Up @@ -121,5 +111,4 @@ IF ((NOT DAS_LLVM_INCLUDED) AND ((NOT ${DAS_LLVM_DISABLED}) OR (NOT DEFINED DAS_
file(GLOB DASLLVM_BINDINGS ${DAS_LLVM_DIR}/das_llvm/*.das)
install(FILES ${DASLLVM_BINDINGS} DESTINATION ${DAS_INSTALL_MODULESDIR}/dasLLVM/das_llvm)

SETUP_CPP11(libDasModuleLlvm)
ENDIF()
58 changes: 52 additions & 6 deletions modules/dasLLVM/daslib/llvm_jit.das
Original file line number Diff line number Diff line change
Expand Up @@ -905,20 +905,22 @@ class LlvmJitVisitor : AstVisitor {
vptrtype = get_type_pointer(arg._type)
}
var v_ptr : LLVMOpaqueValue?
var vsize = arg._type.flags.ref ? typeinfo sizeof(type<void?>) : arg._type.sizeOf
var valign = arg._type.flags.ref ? typeinfo alignof(type<void?>) : arg._type.alignOf

if (arg.flags.aliasCMRES) {
v_ptr = get_cmres_param()
v_ptr = LLVMBuildPointerCast(g_builder, v_ptr, vptrtype, "variable_cmres_{arg.name}")
} else {
at_function_entry <| $() {
v_ptr = LLVMBuildAlloca(g_builder, vtype, "variable_{arg.name}")
LLVMBuildMemSet(g_builder, v_ptr, 0ul, uint64(vsize), uint(valign))
LLVMSetAlignment(v_ptr, 16u)
v_ptr = LLVMBuildPointerCast(g_builder, v_ptr, vptrtype, "variable_{arg.name}")
}
}
setV(arg, v_ptr)
if (arg.init == null) {
var vsize = arg._type.flags.ref ? typeinfo sizeof(type<void?>) : arg._type.sizeOf
var valign = arg._type.flags.ref ? typeinfo alignof(type<void?>) : arg._type.alignOf
LLVMBuildMemSet(g_builder, v_ptr, 0ul, uint64(vsize), uint(valign))
} elif (make_call_to_cmres(arg.init, v_ptr)) {
pass // do nothing
Expand Down Expand Up @@ -2770,6 +2772,33 @@ class LlvmJitVisitor : AstVisitor {
LLVMBuildBr(g_builder, okay)
LLVMPositionBuilderAtEnd(g_builder, okay)
}
} elif (ssrc._type.isString) {
at_function_entry <| $() {
// Let's reuse range for string iterator.
range2[get_ptr(ssrc)] = LLVMBuildAlloca(g_builder, LLVMPointerType(types.t_int8, 0u), "loop_iter")
}
var s_ptr = getE(ssrc)
// Check if it's das-optimized empty string (just nullptr).
var is_empty_str = LLVMBuildIsNull(g_builder, s_ptr, "null_check")
var not_empty_str = append_basic_block("not_empty_str")
LLVMBuildCondBr(g_builder, is_empty_str, lblk.loop_end, not_empty_str)

LLVMPositionBuilderAtEnd(g_builder, not_empty_str)

LLVMBuildStore(g_builder, s_ptr, range2[get_ptr(ssrc)])
var cur_chr = LLVMBuildLoad2(g_builder, types.t_int8, s_ptr, "cur_chr")
let zero_i8 = types.ConstI8(0 |> int8)
let is_null = LLVMBuildICmp(g_builder,
LLVMIntPredicate.LLVMIntNE, cur_chr, zero_i8, "is_null")
// Just in case check whether string is equal to '\0', e.g. this
// is native string.
LLVMBuildStore(g_builder, is_null, lblk.need_loop)

assume svar_t = svar._type
assert(svar_t.baseType == Type.tInt)
// Cast to i32, since char is i32 in das.
var res = LLVMBuildSExt(g_builder, cur_chr, type_to_llvm_type(svar_t), "sext_cast")
LLVMBuildStore(g_builder, res, getV(svar))
} else {
failed_E(ssrc, "unsupported loop source {describe(ssrc._type)}")
}
Expand Down Expand Up @@ -2839,6 +2868,20 @@ class LlvmJitVisitor : AstVisitor {
LLVMBuildCondBr(g_builder, rcond, nextOk, lblk.loop_end)
LLVMPositionBuilderAtEnd(g_builder, nextOk)
}
} elif (ssrc._type.isString) {
var svar_val = LLVMBuildLoad2(g_builder, LLVMPointerType(types.t_int8, 0u), range2[get_ptr(ssrc)], "")
var svar_i = LLVMBuildGEP2(g_builder, types.t_int8, svar_val, types.ConstI32(1ul), "next_element")
var val = LLVMBuildLoad2(g_builder, types.t_int8, svar_i, "")
let zero_i8 = types.ConstI8(0 |> int8)
var is_empty_str = LLVMBuildICmp(g_builder, LLVMIntPredicate.LLVMIntEQ, val, zero_i8, "is_zero")
var nextOk = append_basic_block("for_{svar.name}_next_ok")
LLVMBuildCondBr(g_builder, is_empty_str, lblk.loop_end, nextOk)
LLVMPositionBuilderAtEnd(g_builder, nextOk)

LLVMBuildStore(g_builder, svar_i, range2[get_ptr(ssrc)])
assert(svar._type.baseType == Type.tInt)
var res = LLVMBuildSExt(g_builder, val, type_to_llvm_type(svar._type), "sext_cast")
LLVMBuildStore(g_builder, res, getV(svar))
} else {
failed_E(ssrc, "unsupported loop source {describe(ssrc._type)}")
}
Expand Down Expand Up @@ -6044,11 +6087,14 @@ class DisableJitVisitor : AstVisitor {

def override preVisitExprForBody(expr : smart_ptr<ExprFor>) : void {
for (svar, ssrc in expr.iteratorVariables, expr.sources) {
if (ssrc._type.isRange || ssrc._type.dim |> length != 0 || ssrc._type.isGoodArrayType || ssrc._type.isIterator) {
assume ssrc_t = ssrc._type
if (ssrc_t.isRange || ssrc_t.dim |> length != 0 ||
ssrc_t.isGoodArrayType || ssrc_t.isIterator ||
ssrc_t.isString) {
} else {
// At least string is not supported yet as the source of loop.
disable = true
return
assert(false,
"We shouldn't be here, all loop sources expected to be supported"
)
}
}
}
Expand Down
53 changes: 0 additions & 53 deletions modules/dasLLVM/moretests/launch.das

This file was deleted.

Loading