From: Axy Date: Wed, 27 May 2026 15:54:05 +0000 (+0200) Subject: Profiling and perf opt X-Git-Url: https://git.uwuaxy.net/?a=commitdiff_plain;h=1cef9c0926bf9c546128e8dc4b105a577bc8f379;p=axy%2Fft%2Fc-cera.git Profiling and perf opt --- diff --git a/.gitignore b/.gitignore index 82bbc62..b929644 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,10 @@ vgcore.* .direnv .norm_fail Makefile.tmp -.deps.tmp +*.tmp +flamegraph.svg +perf.data +out.folded +out.perf +*.old + diff --git a/Makefile b/Makefile index 4dc184e..08a8e86 100644 --- a/Makefile +++ b/Makefile @@ -100,6 +100,7 @@ clean: fclean: clean rm -f ${NAME} rm -fd ${BUILDDIR} + rm -f a.out perf.data out.perf out.folded flamegraph.svg re: fclean all @@ -149,4 +150,18 @@ a.out: test.c ${NAME} test: a.out ./a.out -.PHONY: all clean fclean re remakefile redeps norm watch-step watch test +perf.data: a.out + perf record -F 99 -g ./$< + +out.perf: perf.data + perf script > $@ + +out.folded: out.perf + stackcollapse-perf.pl $< > $@ + +flamegraph.svg: out.folded + flamegraph.pl $< > $@ + +prof: flamegraph.svg + +.PHONY: all clean fclean re remakefile redeps norm watch-step watch test prof diff --git a/conf.mk b/conf.mk index e464f45..35cb9ab 100644 --- a/conf.mk +++ b/conf.mk @@ -1,6 +1,6 @@ -#LTO=1 -OPT=0 -#CC=gcc +LTO=1 +OPT=1 +CC=clang #UBSAN=1 #TSAN=1 #ASAN=1 diff --git a/src/arc.c b/src/arc.c index fa34fd1..bee0b2e 100644 --- a/src/arc.c +++ b/src/arc.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/04/29 16:40:27 by agilliar #+# #+# */ -/* Updated: 2026/05/15 11:22:29 by agilliar ### ########.fr */ +/* Updated: 2026/05/27 17:23:03 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,7 @@ #include "arith.h" #include "atomic.h" +__attribute__((no_instrument_function)) t_arc arc_new(size_t size) { size_t *res; @@ -27,6 +28,7 @@ t_arc arc_new(size_t size) } // Relaxed sub as we own a copy, and as such ultimately sync +__attribute__((no_instrument_function)) void arc_copy(t_arc arc) { if (__atomic_add_fetch(((size_t *)arc) - 1, 1, __ATOMIC_RELAXED) @@ -37,6 +39,7 @@ void arc_copy(t_arc arc) } } +__attribute__((no_instrument_function)) void arc_drop(t_arc arc, t_drop destructor) { if (__atomic_sub_fetch(((size_t *)arc) - 1, 1, __ATOMIC_RELEASE) != 0) @@ -46,11 +49,13 @@ void arc_drop(t_arc arc, t_drop destructor) free(((char *)arc) - 8); } +__attribute__((no_instrument_function)) bool arc_is_unique(t_arc arc) { return (__atomic_load_n(((size_t *)arc) - 1, __ATOMIC_ACQUIRE) == 1); } +__attribute__((no_instrument_function)) void noop(void *ptr) { (void) ptr; diff --git a/src/defer.c b/src/defer.c index c6b02db..fbc03cb 100644 --- a/src/defer.c +++ b/src/defer.c @@ -6,13 +6,14 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/05 17:31:36 by agilliar #+# #+# */ -/* Updated: 2026/05/15 11:02:57 by agilliar ### ########.fr */ +/* Updated: 2026/05/27 17:44:04 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ #include "defer.h" #include "panic.h" +__attribute__((no_instrument_function)) t_defer_frame *defer_store(void) { static __thread t_defer_frame store; @@ -20,6 +21,7 @@ t_defer_frame *defer_store(void) return (&store); } +__attribute__((no_instrument_function)) void defer_pop(void) { t_defer *curr; diff --git a/src/panic.c b/src/panic.c index 857064e..c1b9459 100644 --- a/src/panic.c +++ b/src/panic.c @@ -6,13 +6,14 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/05 15:38:33 by agilliar #+# #+# */ -/* Updated: 2026/05/20 11:14:53 by agilliar ### ########.fr */ +/* Updated: 2026/05/27 17:30:40 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ #include "panic.h" #include "defer.h" +__attribute__((no_instrument_function)) t_panic_info *panic_store(void) { static __thread t_panic_info store; @@ -23,6 +24,7 @@ t_panic_info *panic_store(void) // Scuffed but clang is adament on not doing proper analysis on the semantics // of setjmp/longjmp __attribute__((noinline)) +__attribute__((no_instrument_function)) static t_panic_info *panic_store2(void) { return (panic_store()); @@ -55,6 +57,7 @@ void panic(void *err) __builtin_longjmp((void *)&panic_store()->jmp, 1); } +__attribute__((no_instrument_function)) bool panicking(void) { return (panic_store()->data != NULL); diff --git a/src/value_debug.c b/src/value_debug.c index 2bf18cd..62c4f40 100644 --- a/src/value_debug.c +++ b/src/value_debug.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/20 11:23:55 by agilliar #+# #+# */ -/* Updated: 2026/05/25 18:13:32 by agilliar ### ########.fr */ +/* Updated: 2026/05/27 17:24:53 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -38,7 +38,7 @@ void value_debug(size_t indent, t_value *value) else if (value->tag == VALUE_NIL) printf("%*s%s\n", (int)indent, "", "nil"); else if (value->tag == VALUE_BYTES) - printf("%*s%.*s\n", (int)indent, "", value->val.v_bytes->len, + printf("%*s%.*s\n", (int)indent, "", (int) value->val.v_bytes->len, value->val.v_bytes->buf); else printf("%*s%s\n", (int)indent, "", ""); diff --git a/src/value_get.h b/src/value_get.h index 76ca4aa..82cd4da 100644 --- a/src/value_get.h +++ b/src/value_get.h @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/13 22:01:24 by agilliar #+# #+# */ -/* Updated: 2026/05/20 13:24:13 by agilliar ### ########.fr */ +/* Updated: 2026/05/27 17:27:19 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ # include "value_types.h" # include "panic.h" +__attribute__((no_instrument_function)) __attribute__((always_inline)) static inline intptr_t *value_int(t_value *value) { @@ -24,6 +25,7 @@ static inline intptr_t *value_int(t_value *value) return (&value->val.v_int); } +__attribute__((no_instrument_function)) __attribute__((always_inline)) static inline uintptr_t *value_uint(t_value *value) { @@ -32,6 +34,7 @@ static inline uintptr_t *value_uint(t_value *value) return (&value->val.v_uint); } +__attribute__((no_instrument_function)) __attribute__((always_inline)) static inline t_list *value_list(t_value *value) { @@ -40,6 +43,7 @@ static inline t_list *value_list(t_value *value) return (value->val.v_list); } +__attribute__((no_instrument_function)) __attribute__((always_inline)) static inline t_bytes *value_bytes(t_value *value) { @@ -48,6 +52,7 @@ static inline t_bytes *value_bytes(t_value *value) return (value->val.v_bytes); } +__attribute__((no_instrument_function)) __attribute__((always_inline)) static inline t_builtin *value_builtin(t_value *value) { diff --git a/src/value_lifetime.c b/src/value_lifetime.c index d51ea74..153788c 100644 --- a/src/value_lifetime.c +++ b/src/value_lifetime.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/12 17:42:10 by agilliar #+# #+# */ -/* Updated: 2026/05/25 17:52:28 by agilliar ### ########.fr */ +/* Updated: 2026/05/27 17:35:16 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ #include "value.h" #include "memutils.h" +__attribute__((no_instrument_function)) t_value value_copy(t_value val) { if (val.tag == VALUE_BYTES) @@ -56,6 +57,7 @@ t_value value_clone(t_value val) return (res); } +__attribute__((no_instrument_function)) static void list_drop(t_list *lst) { size_t i; @@ -65,6 +67,7 @@ static void list_drop(t_list *lst) value_drop(&lst->buf[i++]); } +__attribute__((no_instrument_function)) void value_drop(t_value *value) { if (value->tag == VALUE_LIST) @@ -75,6 +78,7 @@ void value_drop(t_value *value) value_builtin(value)->drop(value); } +__attribute__((no_instrument_function)) t_value value_unique(t_value *val) { if ((val->tag == VALUE_BYTES && !arc_is_unique(val->val.v_bytes)) diff --git a/src/value_list.c b/src/value_list.c index 817d793..a217812 100644 --- a/src/value_list.c +++ b/src/value_list.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/13 12:51:13 by agilliar #+# #+# */ -/* Updated: 2026/05/20 10:29:49 by agilliar ### ########.fr */ +/* Updated: 2026/05/27 17:33:36 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,6 +14,7 @@ #include "value.h" #include "panic.h" +__attribute__((no_instrument_function)) size_t value_list_len(t_value lst) { if (lst.tag != VALUE_LIST) @@ -22,6 +23,7 @@ size_t value_list_len(t_value lst) } // Borrows the value +__attribute__((no_instrument_function)) t_value *value_list_get(t_value lst, size_t i) { if (value_list_len(lst) <= i) @@ -29,6 +31,7 @@ t_value *value_list_get(t_value lst, size_t i) return (&lst.val.v_list->buf[i]); } +__attribute__((no_instrument_function)) t_value *value_list_getu(t_value *lst, size_t i) { value_unique(lst); diff --git a/src/value_move.c b/src/value_move.c index 6007feb..d06503d 100644 --- a/src/value_move.c +++ b/src/value_move.c @@ -6,12 +6,15 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/13 21:27:54 by agilliar #+# #+# */ -/* Updated: 2026/05/18 11:55:04 by agilliar ### ########.fr */ +/* Updated: 2026/05/27 17:41:15 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ #include "value.h" +//__attribute__((no_instrument_function)) +// for some reason this segfaults with no instrument, use after frees detected +// hhow i don't know but i'm warry of unnoticed UB void value_swap(t_value *a, t_value *b) { t_value tmp; @@ -21,17 +24,20 @@ void value_swap(t_value *a, t_value *b) *b = tmp; } +__attribute__((no_instrument_function)) t_value value_take(t_value *a, t_value b) { value_swap(a, &b); return (b); } +__attribute__((no_instrument_function)) t_value value_take_nil(t_value *a) { return (value_take(a, value_new_nil())); } +__attribute__((no_instrument_function)) void value_put(t_value *a, t_value b) { value_swap(a, &b); diff --git a/src/value_new.c b/src/value_new.c index b28a7c5..5c4271c 100644 --- a/src/value_new.c +++ b/src/value_new.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/13 08:40:13 by agilliar #+# #+# */ -/* Updated: 2026/05/25 18:14:32 by agilliar ### ########.fr */ +/* Updated: 2026/05/27 17:43:13 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ #include "arc.h" #include "memutils.h" +__attribute__((no_instrument_function)) t_value value_new_bytes(size_t len) { t_value res; @@ -26,6 +27,7 @@ t_value value_new_bytes(size_t len) return (res); } +__attribute__((no_instrument_function)) t_value value_new_str(const char *s) { t_value res; @@ -41,6 +43,7 @@ t_value value_new_str(const char *s) // We could use arc_new_zeroed but clang and gcc cannot tell that the // following zero writes for the nil values are no-ops +__attribute__((no_instrument_function)) t_value value_new_list(size_t len) { t_value res; @@ -56,6 +59,7 @@ t_value value_new_list(size_t len) return (res); } +__attribute__((no_instrument_function)) t_value value_new_builtin(enum e_builtin tag) { t_builtin *builtin; diff --git a/src/value_new.h b/src/value_new.h index 8dc8619..2783dbf 100644 --- a/src/value_new.h +++ b/src/value_new.h @@ -6,13 +6,14 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/13 22:05:40 by agilliar #+# #+# */ -/* Updated: 2026/05/20 13:30:34 by agilliar ### ########.fr */ +/* Updated: 2026/05/27 17:42:54 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef VALUE_NEW_H # define VALUE_NEW_H +__attribute__((no_instrument_function)) __attribute__((always_inline)) static inline t_value value_new_nil(void) { @@ -22,6 +23,7 @@ static inline t_value value_new_nil(void) return (res); } +__attribute__((no_instrument_function)) __attribute__((always_inline)) static inline t_value value_new_int(intptr_t n) { @@ -32,6 +34,7 @@ static inline t_value value_new_int(intptr_t n) return (res); } +__attribute__((no_instrument_function)) __attribute__((always_inline)) static inline t_value value_new_uint(uintptr_t n) { @@ -50,4 +53,5 @@ t_value value_new_builtin(enum e_builtin tag); t_value value_new_va(size_t count, ...); t_value value_new_step(uintptr_t expr_pos, bool expr_mov, uintptr_t arg_pos, bool arg_mov); +t_value value_new_fn(uintptr_t len, uintptr_t pos, ...); #endif diff --git a/src/value_new_utils.c b/src/value_new_utils.c index 5bfbff0..98a4873 100644 --- a/src/value_new_utils.c +++ b/src/value_new_utils.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/05/20 10:29:41 by agilliar #+# #+# */ -/* Updated: 2026/05/20 10:54:22 by agilliar ### ########.fr */ +/* Updated: 2026/05/27 16:32:02 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,19 +16,16 @@ #include "defer.h" #include -t_value value_new_va(size_t count, ...) +static t_value value_new_va_inner(size_t count, va_list ap) { t_value res; t_value *buf; - va_list ap; size_t i; buf = cera_alloca(sizeof(t_value) * count); - va_start(ap, count); i = 0; while (i < count) buf[i++] = va_arg(ap, t_value); - va_end(ap); i = 0; while (i < count) errdefer(value_drop, &buf[i++]); @@ -37,9 +34,31 @@ t_value value_new_va(size_t count, ...) return (res); } +t_value value_new_va(size_t count, ...) +{ + t_value res; + va_list ap; + + va_start(ap, count); + res = value_new_va_inner(count, ap); + va_end(ap); + return (res); +} + t_value value_new_step(uintptr_t expr_pos, bool expr_mov, uintptr_t arg_pos, bool arg_mov) { return (value_new_va(4, value_new_uint(expr_pos), value_new_uint(expr_mov), value_new_uint(arg_pos), value_new_uint(arg_mov))); } + +t_value value_new_fn(uintptr_t len, uintptr_t pos, ...) +{ + va_list ap; + t_value res; + + va_start(ap, pos); + res = value_new_va(2, value_new_va_inner(len, ap), value_new_uint(pos)); + va_end(ap); + return (res); +} diff --git a/test.c b/test.c index 04c4429..3a1217f 100644 --- a/test.c +++ b/test.c @@ -6,7 +6,7 @@ /* By: agilliar +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2026/04/30 17:19:58 by agilliar #+# #+# */ -/* Updated: 2026/05/27 16:12:48 by agilliar ### ########.fr */ +/* Updated: 2026/05/27 17:25:44 by agilliar ### ########.fr */ /* */ /* ************************************************************************** */ @@ -107,8 +107,9 @@ t_value make_rec(void) return (value_new_va(2, comb, value_new_uint(0))); } +/* // f: f' f' -// f': f -> curr: uint -> uint +// f': f' -> curr: uint -> uint // f' = (ite (ulte curr 1) (true 1) (compose (arg_swap f (usub curr 1)) (umul curr))) f t_value fact(void) { @@ -142,6 +143,48 @@ t_value fact(void) ); return (expr_eval(make_rec(), value_new_va(2, res, value_new_uint(9)))); } +*/ + +// f: f' f' 1 +// f': f' -> acc: uint -> curr: uint -> uint +// f' = (ite (ulte curr 1) (true acc) (f' f' (umul acc curr))) (usub curr 1) +t_value fact(void) +{ + t_value f_prime = value_new_fn( + 22, + 6, + ite(), // 0 + value_true(), // 1 + value_new_uint(1), // 2 + value_new_builtin(BUILTIN_UMUL), // 3 + value_new_builtin(BUILTIN_USUB), // 4 + value_new_builtin(BUILTIN_ULTE), // 5 + value_new_nil(), // 6 f' + value_new_nil(), // 7 acc + value_new_nil(), // 8 curr + value_new_step(5, true, 8, false), // 9 ulte curr + value_new_step(9, true, 2, false), // 10 ulte curr 1 + value_new_step(0, true, 10, true), // 11 ite (ulte curr 1) + value_new_step(1, true, 7, false), // 12 true acc + value_new_step(11, true, 12, true), // 13 ite (ulte curr 1) (true acc) + value_new_step(6, false, 6, true), // 14 f' f' + value_new_step(3, true, 7, true), // 15 umul acc + value_new_step(15, true, 8, false), // 16 umul acc curr + value_new_step(14, true, 16, true), // 17 f' f' (umul acc curr) + value_new_step(13, true, 17, true), // 18 ite ... + value_new_step(4, true, 8, true), // 19 usub curr + value_new_step(19, true, 2, true), // 20 umul curr 1 + value_new_step(18, true, 20, true) // res + ); + return (expr_eval(value_new_fn( + 4, + 1, + f_prime, + value_new_nil, + value_new_step(0, false, 0, true), + value_new_step(2, true, 1, true) + ), value_new_uint(1))); +} t_value test_expr(void) { @@ -167,7 +210,7 @@ void main2(void *_orig) defer(free, s2); strcpy(s2, orig); //t_value res = expr_eval(test_expr(), value_new_uint(0)); - t_value res = expr_eval(fact(), value_new_uint(100)); + t_value res = expr_eval(fact(), value_new_uint(1000000)); value_debug(0, &res); defer(value_drop, &res); printf("%s\n", s2);