From: Brendan Hansen Date: Fri, 16 Apr 2021 16:11:19 +0000 (-0500) Subject: added __zero_value intrinsic to quickly make a zeroed value X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=326161b0a43b2d01354c5fbd9eebe51ce48e7b98;p=onyx.git added __zero_value intrinsic to quickly make a zeroed value --- diff --git a/core/intrinsics/onyx.onyx b/core/intrinsics/onyx.onyx index e77a2ddd..6df73adf 100644 --- a/core/intrinsics/onyx.onyx +++ b/core/intrinsics/onyx.onyx @@ -1,3 +1,4 @@ package core.intrinsics.onyx -__initialize :: (val: ^$T) -> void #intrinsic --- +__initialize :: (val: ^$T) -> void #intrinsic --- +__zero_value :: ($T: type_expr) -> T #intrinsic --- diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index c44353f6..cfd75724 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -290,7 +290,7 @@ typedef enum OnyxIntrinsic { ONYX_INTRINSIC_MEMORY_SIZE, ONYX_INTRINSIC_MEMORY_GROW, ONYX_INTRINSIC_MEMORY_COPY, ONYX_INTRINSIC_MEMORY_FILL, - ONYX_INTRINSIC_INITIALIZE, + ONYX_INTRINSIC_INITIALIZE, ONYX_INTRINSIC_ZERO_VALUE, ONYX_INTRINSIC_I32_CLZ, ONYX_INTRINSIC_I32_CTZ, ONYX_INTRINSIC_I32_POPCNT, ONYX_INTRINSIC_I32_AND, ONYX_INTRINSIC_I32_OR, ONYX_INTRINSIC_I32_XOR, @@ -533,6 +533,7 @@ struct AstRangeLiteral { struct AstCall { AstTyped_base; + Arguments original_args; Arguments args; union { diff --git a/include/onyxtypes.h b/include/onyxtypes.h index b0d22e27..950434e6 100644 --- a/include/onyxtypes.h +++ b/include/onyxtypes.h @@ -97,6 +97,7 @@ struct TypeWithOffset { bh_arr(StructMember *) memarr; \ bh_arr(struct AstPolySolution) poly_sln; \ bh_arr(TypeWithOffset) linear_members; \ + struct AstType *constructed_from; \ }) \ TYPE_KIND(Compound, struct { \ u32 count; \ @@ -202,5 +203,6 @@ b32 type_is_structlike_strict(Type* type); u32 type_structlike_mem_count(Type* type); u32 type_structlike_is_simple(Type* type); b32 type_is_sl_constructable(Type* type); +b32 type_struct_constructed_from_poly_struct(Type* struct_type, struct AstType* from); #endif // #ifndef ONYX_TYPES diff --git a/src/onyxbuiltins.c b/src/onyxbuiltins.c index 37471aef..e9fe9f09 100644 --- a/src/onyxbuiltins.c +++ b/src/onyxbuiltins.c @@ -88,6 +88,7 @@ static IntrinsicMap builtin_intrinsics[] = { { "memory_fill", ONYX_INTRINSIC_MEMORY_FILL }, { "__initialize", ONYX_INTRINSIC_INITIALIZE }, + { "__zero_value", ONYX_INTRINSIC_ZERO_VALUE }, { "clz_i32", ONYX_INTRINSIC_I32_CLZ }, { "ctz_i32", ONYX_INTRINSIC_I32_CTZ }, diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 32e91e7d..b98e0553 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -365,6 +365,10 @@ CheckStatus check_call(AstCall* call) { CHECK(expression, &call->callee); check_arguments(&call->args); + // SPEED CLEANUP: Keeping an original copy for basically no reason except that sometimes you + // need to know the baked argument values in code generation. + arguments_clone(&call->original_args, &call->args); + if (call->callee->kind == Ast_Kind_Overloaded_Function) { call->callee = find_matching_overload_by_arguments(((AstOverloadedFunction *) call->callee)->overloads, &call->args); if (call->callee == NULL) { diff --git a/src/onyxtypes.c b/src/onyxtypes.c index 7310b6f6..22b41072 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -474,7 +474,9 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) { bh_arr_free(slns); if (!concrete) return NULL; - return type_build_from_ast(alloc, (AstType *) concrete); + Type* struct_type = type_build_from_ast(alloc, (AstType *) concrete); + struct_type->Struct.constructed_from = (AstType *) ps_type; + return struct_type; } case Ast_Kind_Type_Compound: { @@ -1024,3 +1026,10 @@ b32 type_is_sl_constructable(Type* type) { default: return 0; } } + +b32 type_struct_constructed_from_poly_struct(Type* struct_type, struct AstType* from) { + DEBUG_HERE; + if (struct_type->kind != Type_Kind_Struct) return 0; + + return struct_type->Struct.constructed_from == from; +} diff --git a/src/onyxwasm.c b/src/onyxwasm.c index 8c2365fd..d427298a 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -240,6 +240,7 @@ EMIT_FUNC(return, AstReturn* ret); EMIT_FUNC(stack_enter, u64 stacksize); EMIT_FUNC(stack_leave, u32 unused); EMIT_FUNC(zero_value, WasmType wt); +EMIT_FUNC(zero_value_for_type, Type* type); EMIT_FUNC(enter_structured_block, StructuredBlockType sbt); EMIT_FUNC_NO_ARGS(leave_structured_block); @@ -1393,6 +1394,13 @@ EMIT_FUNC(intrinsic_call, AstCall* call) { break; } + case ONYX_INTRINSIC_ZERO_VALUE: { + // NOTE: This probably will not have to make an allocation. + Type* zero_type = type_build_from_ast(context.ast_alloc, (AstType *) ((AstArgument *) call->args.values[0])->value); + emit_zero_value_for_type(mod, &code, zero_type); + break; + } + case ONYX_INTRINSIC_I32_CLZ: WI(WI_I32_CLZ); break; case ONYX_INTRINSIC_I32_CTZ: WI(WI_I32_CTZ); break; case ONYX_INTRINSIC_I32_POPCNT: WI(WI_I32_POPCNT); break; @@ -2450,6 +2458,26 @@ EMIT_FUNC(zero_value, WasmType wt) { *pcode = code; } +EMIT_FUNC(zero_value_for_type, Type* type) { + bh_arr(WasmInstruction) code = *pcode; + + if (type_is_structlike_strict(type)) { + i32 mem_count = type_linear_member_count(type); + TypeWithOffset two; + + fori (i, 0, mem_count) { + type_linear_member_lookup(type, i, &two); + emit_zero_value_for_type(mod, &code, two.type); + } + + } else { + WasmType wt = onyx_type_to_wasm_type(type); + emit_zero_value(mod, &code, wt); + } + + *pcode = code; +} + static i32 generate_type_idx(OnyxWasmModule* mod, Type* ft) { if (ft->kind != Type_Kind_Function) return -1;