From f7a08d4db77eaef1f6685c3fb263bb1cb1376deb Mon Sep 17 00:00:00 2001 From: Moon Flower Date: Fri, 28 Feb 2025 01:50:25 +0330 Subject: Added a (rather useless) profiler (and also linked list speed optimizations) --- Makefile | 12 ++++++- main.c | 27 ++++++++++++---- moonshine.h | 104 ++++++++++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 107 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index b73f7a6..d079677 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ FLAGS = -Wno-incompatible-library-redeclaration -nostartfiles -SIZE_FLAGS = -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -s -fno-unwind-tables -fomit-frame-pointer -fno-asynchronous-unwind-tables -fno-ident -fvisibility=hidden -march=native -Wl,--build-id=none +SIZE_FLAGS = -Wl,--undefined=main -flto -Oz -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--strip-all -finline-hint-functions -fno-builtin -Wl,--print-gc-sections -fno-unwind-tables -fomit-frame-pointer -fno-asynchronous-unwind-tables -fno-ident -fvisibility=hidden -march=native -Wl,--build-id=none all: m4 c test @@ -12,6 +12,16 @@ c: test: ./out.bin +# useless. it don't work. +# profile: +# clang -D__MOONSHINE_PROFILER main.c -o out.bin.profile $(FLAGS) $(SIZE_FLAGS) -fprofile-generate +# echo NOTE: Let the program run completely and provide it with typical inputs. +# ./out.bin.profile +# llvm-profdata merge -output=default.profdata profile.profraw +# rm -rf profile.profraw +# clang main.c -o out.bin.release $(FLAGS) $(SIZE_FLAGS) -fprofile-use +# rm -rf profile.profdata + release: clang main.c -o out.bin.release $(FLAGS) $(SIZE_FLAGS) diff --git a/main.c b/main.c index 58c28dd..c59984f 100644 --- a/main.c +++ b/main.c @@ -2,17 +2,30 @@ #include "moonshine.h" -datatype(binarytree, ((leaf, int), (node, binarytree *, int, binarytree *) )); +const enum { test_datatype, test_linkedlist } current_test = test_linkedlist; int main() { - const auto tree = instance(binarytree, leaf, 3); + if (current_test == test_datatype) { + datatype(binarytree, ((leaf, int), (node, binarytree *, int, binarytree *) )); + const auto tree = instance(binarytree, leaf, 3); - print(&tree); + print(&tree); - match(tree) { - of(leaf, v) print("Leafy ", v); - of(node, _, v, _) print("Nodey ", v); - other() print("Idk man"); + match(tree) { + of(leaf, v) print("Leafy ", v); + of(node, _, v, _) print("Nodey ", v); + other() print("Idk man"); + } + } else if (current_test == test_linkedlist) { + const auto ll = create_linkedlist(); + + for (u8 i = 0; i < 100; i++) push_linkedlist(ll, (var) i); + + print((u8) index_to_ptr(ll, 12)->data); + } + + else { + print("Unknown test."); } return 0; diff --git a/moonshine.h b/moonshine.h index eb47a6c..19c125a 100644 --- a/moonshine.h +++ b/moonshine.h @@ -38,8 +38,9 @@ } #define instance(__type, kind, ...) ((struct __type) { .type = cat(kind, _type), .data.kind = { __VA_ARGS__ } }) #define scope(name, ...) \ - for (auto name unused = __VA_ARGS__, datatype_break = (typeof(name)) 0; datatype_break == (typeof(name)) 0; \ - datatype_break = (typeof(name)) 1) + _Pragma("unroll") for (auto name unused = __VA_ARGS__, datatype_break = (typeof(name)) 0; \ + datatype_break == (typeof(name)) 0; \ + datatype_break = (typeof(name)) 1) #define match(value) scope(parent_value, &value) switch (parent_value->type) #define algebra_field_sum(extra, time, field) +sizeof(cat(extra, field)) #define algebra_of_field(extra, time, field) scope(field, ({ parent_value->data.extra.cat4(object_type_, extra, _, time); })) @@ -1085,17 +1086,16 @@ void unsafe_push(var *array, const var ptr, const u4 ptr_size) [[clang::allocati __attribute__((deprecated(LIBC_WARNINGS_TEXT("strdup")))) #endif -__attribute__((diagnose_as_builtin(__builtin_strdup, 1))) -t(char) strdup(ctring str) { - const u8 len = strlen(str); - const auto obj = new (char, len + 1); +// ctring strdup(ctring str) { +// const u8 len = strlen(str); +// string obj = alloc(len + 1); - for (u8 i = 0; i < len; i++) obj[ 0 ][ i ] = str[ i ]; +// for (u8 i = 0; i < len; i++) obj[ i ] = str[ i ]; - obj[ 0 ][ len ] = 0; +// obj[ len ] = 0; - return obj; -} +// return obj; +// } var *__reverse_array(var *array) { const u4 element_size = element_size(array); @@ -1188,29 +1188,41 @@ linkednode *index_to_ptr(linkedlist *list, u8 index) { else if (index == last - 2) return list->tail->back[ 1 ]; // clang-format on + linkednode *current; + u8 current_index; + // decide whether to start from the head or the tail of the list - if (index < (last / 2)) { // start from the head - byte body = 0; - auto start = list->head->front[ 1 ]->front; - for (u8 i = 3; i <= index; i++) { - if (start[ body ] == NULL) return NULL; - if (i == index) return start[ body ]; - if (body) start = start[ 1 ]->front; - body = 1 - body; + if (index <= (last / 2)) { // start from the head + current = list->head; + current_index = 0; + while (current && current_index < index) { + if (current->front[ 1 ] && current_index + 2 <= index) { + current = current->front[ 1 ]; + current_index += 2; + } else if (current->front[ 0 ]) { + current = current->front[ 0 ]; + current_index += 1; + } else { + break; + } } } else { // start from the tail - byte body = 0; - auto end = list->tail->back[ 1 ]->back; - for (u8 i = last - 3; i >= index; i--) { - if (end[ body ] == NULL) return NULL; - if (i == index) return end[ body ]; - if (i == 0) return NULL; - if (body) end = end[ 1 ]->back; - body = 1 - body; + current = list->tail; + current_index = list->size - 1; + while (current && current_index > index) { + if (current->back[ 1 ] && current_index - 2 >= index) { + current = current->back[ 1 ]; + current_index -= 2; + } else if (current->back[ 0 ]) { + current = current->back[ 0 ]; + current_index -= 1; + } else { + break; + } } } - return NULL; + return (current_index == index) ? current : NULL; } // This function will return a pointer to the linkednode, if free = false, and a pointer to the data contained inside, if free = @@ -1234,6 +1246,8 @@ overload var pop_item(linkedlist *list, bool free, linkednode *item) { item->front[ 0 ] = item->front[ 1 ] = item->back[ 0 ] = item->back[ 1 ] = 0; + list->size--; + auto ptr = item->data; if (free) { release(item); @@ -1263,7 +1277,19 @@ line void front_insert(linkedlist *list, u8 index) { return front_insert(list, i string *environ; -[[noreturn]] void __moonshine_start(int argc, string *argv, string *envp) { +#ifdef __MOONSHINE_PROFILER +extern void __llvm_profile_reset_counters(void); +extern int __llvm_profile_write_file(void); +extern void __llvm_profile_set_filename(const char *name); +#endif + +[[noreturn]] __attribute__((used)) void __moonshine_start(int argc, string *argv, string *envp) { +#ifdef __MOONSHINE_PROFILER + static const char profile_filename[] __attribute__((used)) = "profile.profraw"; + __llvm_profile_reset_counters(); + __llvm_profile_set_filename(profile_filename); +#endif + global_page_table = PageTable(); environ = envp; @@ -1277,7 +1303,13 @@ string *environ; : "r"((long) argc), "r"(argv) : "rdi", "rsi", "rax", "memory"); +#ifdef __MOONSHINE_PROFILER + extern int __llvm_profile_write_file(void); + __llvm_profile_write_file(); +#endif + exit(exit_code); + __builtin_unreachable(); } __attribute__((force_align_arg_pointer)) __attribute__((naked)) void _start(void) { @@ -1357,7 +1389,11 @@ FILE *fopen(const char *pathname, const char *mode) { int fd = syscall5(SYS_openat, AT_FDCWD, pathname, flags, perms); if (fd < 0) return 0; +#ifdef __MOONSHINE_PROFILER + FILE *file = (FILE *) __bare_alloc(sizeof(FILE)); +#else FILE *file = (FILE *) alloc(sizeof(FILE)); +#endif if (!file) { (void) syscall2(SYS_close, fd); return 0; @@ -1381,7 +1417,11 @@ size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream) { int fclose(FILE *stream) { if (!stream) return -1; int ret = syscall2(SYS_close, stream->fd); +#ifdef __MOONSHINE_PROFILER + __bare_munmap((var) stream, sizeof(FILE)); +#else release((var) stream); +#endif return (ret < 0) ? -1 : 0; } @@ -1406,4 +1446,12 @@ size_t fread(void *ptr, size_t size, size_t count, FILE *stream) { long ftell(FILE *stream) { return syscall4(SYS_lseek, stream->fd, 0, SEEK_CUR); } +#ifdef __MOONSHINE_PROFILER +void *__dso_handle = (void *) 0; +int atexit(void (*func)(void)) { + func(); // Call immediately since we don’t buffer exits + return 0; +} +#endif + #endif -- cgit v1.2.3