mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-06 06:38:20 +00:00
Use normal i64 arithmetic instead of big-ints for hot path
This commit is contained in:
@@ -57,6 +57,8 @@ gb_internal void big_int_dealloc(BigInt *dst) {
|
||||
mp_clear(dst);
|
||||
}
|
||||
|
||||
gb_internal bool big_int_can_be_represented_in_64_bits(BigInt const *x);
|
||||
|
||||
gb_internal BigInt big_int_make(BigInt const *b, bool abs=false);
|
||||
gb_internal BigInt big_int_make_abs(BigInt const *b);
|
||||
gb_internal BigInt big_int_make_u64(u64 x);
|
||||
@@ -293,6 +295,11 @@ gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success
|
||||
|
||||
|
||||
|
||||
gb_internal bool big_int_can_be_represented_in_64_bits(BigInt const *x) {
|
||||
int bits_used = (x->used-1) * MP_DIGIT_BIT;
|
||||
return bits_used <= 64;
|
||||
}
|
||||
|
||||
gb_internal u64 big_int_to_u64(BigInt const *x) {
|
||||
GB_ASSERT(x->sign == 0);
|
||||
return mp_get_u64(x);
|
||||
|
||||
@@ -2167,9 +2167,13 @@ gb_internal bool check_representable_as_constant(CheckerContext *c, ExactValue i
|
||||
BigInt i = v.value_integer;
|
||||
|
||||
i64 byte_size = type_size_of(type);
|
||||
BigInt umax = {};
|
||||
BigInt imin = {};
|
||||
BigInt imax = {};
|
||||
BigInt umax;
|
||||
BigInt imin;
|
||||
BigInt imax;
|
||||
|
||||
u64 umax_64 = 0;
|
||||
i64 imin_64 = 0;
|
||||
i64 imax_64 = 0;
|
||||
|
||||
if (c->bit_field_bit_size > 0) {
|
||||
i64 bit_size = gb_min(cast(i64)(8*byte_size), cast(i64)c->bit_field_bit_size);
|
||||
@@ -2192,10 +2196,10 @@ gb_internal bool check_representable_as_constant(CheckerContext *c, ExactValue i
|
||||
big_int_shl_eq(&imax, &bi);
|
||||
mp_decr(&imax);
|
||||
} else {
|
||||
if (byte_size < 16) {
|
||||
big_int_from_u64(&umax, unsigned_integer_maxs[byte_size]);
|
||||
big_int_from_i64(&imin, signed_integer_mins[byte_size]);
|
||||
big_int_from_i64(&imax, signed_integer_maxs[byte_size]);
|
||||
if (byte_size <= 8) {
|
||||
umax_64 = unsigned_integer_maxs[byte_size];
|
||||
imin_64 = signed_integer_mins[byte_size];
|
||||
imax_64 = signed_integer_maxs[byte_size];
|
||||
} else {
|
||||
big_int_from_u64(&umax, 1);
|
||||
big_int_from_i64(&imin, 1);
|
||||
@@ -2223,16 +2227,27 @@ gb_internal bool check_representable_as_constant(CheckerContext *c, ExactValue i
|
||||
case Basic_i16:
|
||||
case Basic_i32:
|
||||
case Basic_i64:
|
||||
case Basic_i128:
|
||||
case Basic_int:
|
||||
|
||||
case Basic_i16le:
|
||||
case Basic_i32le:
|
||||
case Basic_i64le:
|
||||
case Basic_i128le:
|
||||
case Basic_i16be:
|
||||
case Basic_i32be:
|
||||
case Basic_i64be:
|
||||
{
|
||||
// return imin <= i && i <= imax;
|
||||
if (!big_int_can_be_represented_in_64_bits(&i)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
i64 val64 = big_int_to_i64(&i);
|
||||
|
||||
return imin_64 <= val64 && val64 <= imax_64;
|
||||
}
|
||||
|
||||
case Basic_i128le:
|
||||
case Basic_i128:
|
||||
case Basic_i128be:
|
||||
{
|
||||
// return imin <= i && i <= imax;
|
||||
@@ -2245,17 +2260,30 @@ gb_internal bool check_representable_as_constant(CheckerContext *c, ExactValue i
|
||||
case Basic_u16:
|
||||
case Basic_u32:
|
||||
case Basic_u64:
|
||||
case Basic_u128:
|
||||
case Basic_uint:
|
||||
case Basic_uintptr:
|
||||
|
||||
case Basic_u16le:
|
||||
case Basic_u32le:
|
||||
case Basic_u64le:
|
||||
case Basic_u128le:
|
||||
case Basic_u16be:
|
||||
case Basic_u32be:
|
||||
case Basic_u64be:
|
||||
{
|
||||
if (big_int_is_neg(&i)) {
|
||||
return false;
|
||||
}
|
||||
if (!big_int_can_be_represented_in_64_bits(&i)) {
|
||||
return false;
|
||||
}
|
||||
u64 val64 = big_int_to_u64(&i);
|
||||
|
||||
return val64 <= umax_64;
|
||||
|
||||
}
|
||||
|
||||
case Basic_u128:
|
||||
case Basic_u128le:
|
||||
case Basic_u128be:
|
||||
{
|
||||
// return 0ull <= i && i <= umax;
|
||||
|
||||
@@ -2442,6 +2442,9 @@ gb_internal Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_res
|
||||
}
|
||||
}
|
||||
|
||||
Entity *entities_to_use = permanent_alloc_array<Entity>(variable_count);
|
||||
isize entities_to_use_index = 0;
|
||||
|
||||
auto variables = array_make<Entity *>(permanent_allocator(), 0, variable_count);
|
||||
i32 field_group_index = -1;
|
||||
for_array(i, results) {
|
||||
@@ -2480,7 +2483,12 @@ gb_internal Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_res
|
||||
if (field->names.count == 0) {
|
||||
Token token = ast_token(field->type);
|
||||
token.string = str_lit("");
|
||||
Entity *param = alloc_entity_param(scope, token, type, false, false);
|
||||
// Entity *param = alloc_entity_param(scope, token, type, false, false);
|
||||
Entity *param = &entities_to_use[entities_to_use_index++];
|
||||
INTERNAL_ENTITY_INIT(param, Entity_Variable, scope, token, type);
|
||||
param->state = EntityState_Resolved;
|
||||
param->flags |= EntityFlag_Used|EntityFlag_Param|EntityFlag_Result;
|
||||
|
||||
param->Variable.param_value = param_value;
|
||||
param->Variable.field_group_index = -1;
|
||||
array_add(&variables, param);
|
||||
@@ -2503,8 +2511,17 @@ gb_internal Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_res
|
||||
error(name, "Result value cannot be a blank identifer `_`");
|
||||
}
|
||||
|
||||
Entity *param = alloc_entity_param(scope, token, type, false, false);
|
||||
param->flags |= EntityFlag_Result;
|
||||
// Entity *param = alloc_entity_param(scope, token, type, false, false);
|
||||
Entity *param = &entities_to_use[entities_to_use_index++];
|
||||
INTERNAL_ENTITY_INIT(param, Entity_Variable, scope, token, type);
|
||||
param->state = EntityState_Resolved;
|
||||
param->flags |= EntityFlag_Used|EntityFlag_Param|EntityFlag_Result;
|
||||
|
||||
if (name->kind == Ast_Ident) {
|
||||
param->interned_name.store(name->Ident.interned);
|
||||
param->interned_name_hash.store(name->Ident.hash);
|
||||
}
|
||||
|
||||
param->Variable.param_value = param_value;
|
||||
param->Variable.field_group_index = field_group_index;
|
||||
array_add(&variables, param);
|
||||
|
||||
Reference in New Issue
Block a user