From d7cf8fa9ab68cfbdbf06a9815dc26b217fd357ea Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sun, 15 Feb 2026 00:43:29 +0100 Subject: [PATCH] Reduce macro inlining size. Remove non-const atomic ordering. --- lib/std/atomic.c3 | 132 ++++++++++++------------------------------- lib/std/math/math.c3 | 20 ++++--- 2 files changed, 49 insertions(+), 103 deletions(-) diff --git a/lib/std/atomic.c3 b/lib/std/atomic.c3 index 3a881adf4..0caa35275 100644 --- a/lib/std/atomic.c3 +++ b/lib/std/atomic.c3 @@ -1,9 +1,9 @@ // Copyright (c) 2023-2025 Eduardo José Gómez Hernández. All rights reserved. // Use of this source code is governed by the MIT license // a copy of which can be found in the LICENSE_STDLIB file. -module std::atomic::types ; +module std::atomic::types; -struct Atomic +struct Atomic { Type data; } @@ -11,147 +11,87 @@ struct Atomic <* Loads data atomically, by default this uses SEQ_CONSISTENT ordering. - @param ordering : "The ordering, cannot be release or acquire-release." - @require ordering != RELEASE && ordering != ACQUIRE_RELEASE : "Release and acquire-release are not valid for load" + @param $ordering : "The ordering, cannot be release or acquire-release." + @require $ordering != RELEASE && $ordering != ACQUIRE_RELEASE : "Release and acquire-release are not valid for load" *> -macro Type Atomic.load(&self, AtomicOrdering ordering = SEQ_CONSISTENT) +macro Type Atomic.load(&self, AtomicOrdering $ordering = SEQ_CONSISTENT) { - Type* data = &self.data; - switch(ordering) - { - case NOT_ATOMIC: return $$atomic_load(data, false, AtomicOrdering.NOT_ATOMIC.ordinal); - case UNORDERED: return $$atomic_load(data, false, AtomicOrdering.UNORDERED.ordinal); - case RELAXED: return $$atomic_load(data, false, AtomicOrdering.RELAXED.ordinal); - case ACQUIRE: return $$atomic_load(data, false, AtomicOrdering.ACQUIRE.ordinal); - case SEQ_CONSISTENT: return $$atomic_load(data, false, AtomicOrdering.SEQ_CONSISTENT.ordinal); - case ACQUIRE_RELEASE: - case RELEASE: unreachable("Invalid ordering."); - } + return $$atomic_load(&self.data, false, $ordering.ordinal); } <* Stores data atomically, by default this uses SEQ_CONSISTENT ordering. - @param ordering : "The ordering, cannot be acquire or acquire-release." - @require ordering != ACQUIRE && ordering != ACQUIRE_RELEASE : "Acquire and acquire-release are not valid for store" + @param $ordering : "The ordering, cannot be acquire or acquire-release." + @require $ordering != ACQUIRE && $ordering != ACQUIRE_RELEASE : "Acquire and acquire-release are not valid for store" *> -macro void Atomic.store(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) +macro void Atomic.store(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) { - Type* data = &self.data; - switch(ordering) - { - case NOT_ATOMIC: $$atomic_store(data, value, false, AtomicOrdering.NOT_ATOMIC.ordinal); - case UNORDERED: $$atomic_store(data, value, false, AtomicOrdering.UNORDERED.ordinal); - case RELAXED: $$atomic_store(data, value, false, AtomicOrdering.RELAXED.ordinal); - case RELEASE: $$atomic_store(data, value, false, AtomicOrdering.RELEASE.ordinal); - case SEQ_CONSISTENT: $$atomic_store(data, value, false, AtomicOrdering.SEQ_CONSISTENT.ordinal); - case ACQUIRE_RELEASE: - case ACQUIRE: unreachable("Invalid ordering."); - } + $$atomic_store(&self.data, value, false, $ordering.ordinal); } -macro Type Atomic.add(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) +macro Type Atomic.add(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) { - Type* data = &self.data; - return @atomic_exec(atomic::fetch_add, data, value, ordering); + return atomic::fetch_add(&self.data, value, $ordering); } -macro Type Atomic.sub(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) +macro Type Atomic.sub(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) { - Type* data = &self.data; - return @atomic_exec(atomic::fetch_sub, data, value, ordering); + return atomic::fetch_sub(&self.data, value, $ordering); } -macro Type Atomic.mul(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) +macro Type Atomic.mul(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) { - Type* data = &self.data; - return @atomic_exec(atomic::fetch_mul, data, value, ordering); + return atomic::fetch_mul(&self.data, value, $ordering); } -macro Type Atomic.div(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) +macro Type Atomic.div(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) { - Type* data = &self.data; - return @atomic_exec(atomic::fetch_div, data, value, ordering); + return atomic::fetch_div(&self.data, value, $ordering); } -macro Type Atomic.max(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) +macro Type Atomic.max(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) { - Type* data = &self.data; - return @atomic_exec(atomic::fetch_max, data, value, ordering); + return atomic::fetch_max(&self.data, value, $ordering); } -macro Type Atomic.min(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) +macro Type Atomic.min(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) { - Type* data = &self.data; - return @atomic_exec(atomic::fetch_min, data, value, ordering); + return atomic::fetch_min(&self.data, value, $ordering); } -macro Type Atomic.or(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT) +macro Type Atomic.or(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT) { - Type* data = &self.data; - return @atomic_exec(atomic::fetch_or, data, value, ordering); + return atomic::fetch_or(&self.data, value, $ordering); } -macro Type Atomic.xor(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT) +macro Type Atomic.xor(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT) { - Type* data = &self.data; - return @atomic_exec(atomic::fetch_xor, data, value, ordering); + return atomic::fetch_xor(&self.data, value, $ordering); } -macro Type Atomic.and(&self, Type value, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT) +macro Type Atomic.and(&self, Type value, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT) { - Type* data = &self.data; - return @atomic_exec(atomic::fetch_and, data, value, ordering); + return atomic::fetch_and(&self.data, value, $ordering); } -macro Type Atomic.shr(&self, Type amount, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT) +macro Type Atomic.shr(&self, Type amount, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT) { - Type* data = &self.data; - return @atomic_exec(atomic::fetch_shift_right, data, amount, ordering); + return atomic::fetch_shift_right(&self.data, amount, $ordering); } -macro Type Atomic.shl(&self, Type amount, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT) +macro Type Atomic.shl(&self, Type amount, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) != FLOAT) { - Type* data = &self.data; - return @atomic_exec(atomic::fetch_shift_left, data, amount, ordering); + return atomic::fetch_shift_left(&self.data, amount, $ordering); } -macro Type Atomic.set(&self, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) == BOOL) +macro Type Atomic.set(&self, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) == BOOL) { - Type* data = &self.data; - return @atomic_exec_no_arg(atomic::flag_set, data, ordering); + return atomic::flag_set(&self.data, $ordering); } -macro Type Atomic.clear(&self, AtomicOrdering ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) == BOOL) +macro Type Atomic.clear(&self, AtomicOrdering $ordering = SEQ_CONSISTENT) @if(types::flat_kind(Type) == BOOL) { - Type* data = &self.data; - - return @atomic_exec_no_arg(atomic::flag_clear, data, ordering); -} - -macro @atomic_exec(#func, data, value, ordering) @local -{ - switch(ordering) - { - case RELAXED: return #func(data, value, RELAXED); - case ACQUIRE: return #func(data, value, ACQUIRE); - case RELEASE: return #func(data, value, RELEASE); - case ACQUIRE_RELEASE: return #func(data, value, ACQUIRE_RELEASE); - case SEQ_CONSISTENT: return #func(data, value, SEQ_CONSISTENT); - default: unreachable("Ordering may not be non-atomic or unordered."); - } -} - -macro @atomic_exec_no_arg(#func, data, ordering) @local -{ - switch(ordering) - { - case RELAXED: return #func(data, RELAXED); - case ACQUIRE: return #func(data, ACQUIRE); - case RELEASE: return #func(data, RELEASE); - case ACQUIRE_RELEASE: return #func(data, ACQUIRE_RELEASE); - case SEQ_CONSISTENT: return #func(data, SEQ_CONSISTENT); - default: unreachable("Ordering may not be non-atomic or unordered."); - } + return atomic::flag_clear(&self.data, $ordering); } module std::atomic; diff --git a/lib/std/math/math.c3 b/lib/std/math/math.c3 index f39628262..36d4768b6 100644 --- a/lib/std/math/math.c3 +++ b/lib/std/math/math.c3 @@ -89,9 +89,12 @@ macro abs(x) => $$abs(x); *> macro bool is_approx(x, y, eps) { - if (x == y) return true; - if (is_nan(x) || is_nan(y)) return false; - return abs(x - y) <= eps; + return fn bool($typeof(x) a, $typeof(y) b, $typeof(eps) eps) + { + if (a == b) return true; + if (is_nan(a) || is_nan(b)) return false; + return abs(a - b) <= eps; + }(x, y, eps); } <* @@ -100,9 +103,12 @@ macro bool is_approx(x, y, eps) *> macro bool is_approx_rel(x, y, eps) { - if (x == y) return true; - if (is_nan(x) || is_nan(y)) return false; - return abs(x - y) <= eps * max(abs(x), abs(y)); + return fn bool($typeof(x) a, $typeof(y) b, $typeof(eps) eps) + { + if (a == b) return true; + if (is_nan(a) || is_nan(b)) return false; + return abs(a - b) <= eps * max(abs(a), abs(b)); + }(x, y, eps); } <* @@ -474,7 +480,7 @@ macro round(x) => $$round(x); macro round_to_decimals(x, int decimal_places) { var div = $$pow_int(($typeof(x))10, decimal_places); - return round(div * x) / div; + return $$round(div * x) / div; } <*