]> Untitled Git - axy/ft/c-cera.git/commitdiff
Profiling and perf opt
authorAxy <gilliardmarthey.axel@gmail.com>
Wed, 27 May 2026 15:54:05 +0000 (17:54 +0200)
committerAxy <gilliardmarthey.axel@gmail.com>
Wed, 27 May 2026 15:54:05 +0000 (17:54 +0200)
15 files changed:
.gitignore
Makefile
conf.mk
src/arc.c
src/defer.c
src/panic.c
src/value_debug.c
src/value_get.h
src/value_lifetime.c
src/value_list.c
src/value_move.c
src/value_new.c
src/value_new.h
src/value_new_utils.c
test.c

index 82bbc6280d3501dbbec4f607ab47111df4778c5a..b9296446b9fb69ecf413563d7c169faf8e790625 100644 (file)
@@ -6,4 +6,10 @@ vgcore.*
 .direnv
 .norm_fail
 Makefile.tmp
-.deps.tmp
+*.tmp
+flamegraph.svg
+perf.data
+out.folded
+out.perf
+*.old
+
index 4dc184e848d4adb096df8aa9e8ee31b569baf833..08a8e86f9502aba7831b13515e3dd590fa642965 100644 (file)
--- 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 e464f4554a43b07b28fded866ebe9ede168a72df..35cb9ab5241ecc4e4350fab2b0debcdc8d80595b 100644 (file)
--- 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
index fa34fd18feeaaee95a84df7b36765c274cb62f0c..bee0b2e88ace2b8b821de3ea2596133ed4ca6713 100644 (file)
--- a/src/arc.c
+++ b/src/arc.c
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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;
index c6b02db8cd556b2fb049b28c624bc0ec81b179cb..fbc03cbf79ebb0489cd4d43eb17f1117990e4cb6 100644 (file)
@@ -6,13 +6,14 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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;
index 857064e3b9fe2de7130154d7ef48950f468b6f9e..c1b945978f6972abf8f2b8536fdc7d93fe46d178 100644 (file)
@@ -6,13 +6,14 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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);
index 2bf18cdb8b3f938d1e22bf84fbeaa2daf8f08251..62c4f40985a400267fee7bf751eeb6fce69160c0 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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, "", "<unknown>");
index 76ca4aab34851acc51e978e7118d2cd5740b86cb..82cd4da5626f72cb767c9abfb438fa18a6dc3130 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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)
 {
index d51ea742910defcaee8312d23a2f93af0553e95e..153788c601c065a6da6f132b384d307ae8c54ff0 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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))
index 817d793184fe9a488f5adc34ae8d65153c69c825..a2178123bde250acbd50a72249c405384f61bf12 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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);
index 6007febb0ff9f16d2570809d19635916cf8c517d..d06503d551e99aaa923762e4f3bf31bda7fa5fe8 100644 (file)
@@ -6,12 +6,15 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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);
index b28a7c5beecbec69c180e845059d08e6481dbc96..5c4271c03da11149358796a9786c18fe4861a2a7 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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;
index 8dc8619afede44ad4b646a512a008e9ee1378d58..2783dbf58d7552ef838ec9a9ac8ee7b13e02a8b0 100644 (file)
@@ -6,13 +6,14 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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
index 5bfbff0f0ce9c2833f33b7914aa4e28b6d718120..98a48736ba8925dc5aeba79dc70722b058015c82 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "defer.h"
 #include <stdarg.h>
 
-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 04c4429a20c78632e6010afc5c7783aa912ea15f..3a1217f28d28c4549eea78280e8b3bb3dbf1646b 100644 (file)
--- a/test.c
+++ b/test.c
@@ -6,7 +6,7 @@
 /*   By: agilliar <agilliar@student.42mulhouse.fr>  +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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);