diff options
| author | gingerBill <bill@gingerbill.org> | 2023-07-28 14:57:04 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-07-28 14:57:04 +0100 |
| commit | c39a3603720917d6970026e5c0595d468ea9b372 (patch) | |
| tree | 47f9b81d6a37007aee82834df91bec311742ec9f /src/tilde | |
| parent | f6d1724835489120ae4a3805495dafc97c86db80 (diff) | |
Update Tilde for the new TB_Passes approach
Diffstat (limited to 'src/tilde')
| -rw-r--r-- | src/tilde/tb.h | 106 | ||||
| -rw-r--r-- | src/tilde/tb.lib | bin | 4162224 -> 4177320 bytes | |||
| -rw-r--r-- | src/tilde/tb_arena.h | 76 |
3 files changed, 126 insertions, 56 deletions
diff --git a/src/tilde/tb.h b/src/tilde/tb.h index a68f06554..b20b98b35 100644 --- a/src/tilde/tb.h +++ b/src/tilde/tb.h @@ -15,20 +15,21 @@ #define TB_VERSION_MINOR 2 #define TB_VERSION_PATCH 0 -#ifdef __cplusplus -#define TB_EXTERN extern "C" -#else -#define TB_EXTERN -#endif - -#ifdef TB_DLL -# ifdef TB_IMPORT_DLL -# define TB_API TB_EXTERN __declspec(dllimport) +#ifndef TB_API +# ifdef __cplusplus +# define TB_EXTERN extern "C" # else -# define TB_API TB_EXTERN __declspec(dllexport) +# define TB_EXTERN +# endif +# ifdef TB_DLL +# ifdef TB_IMPORT_DLL +# define TB_API TB_EXTERN __declspec(dllimport) +# else +# define TB_API TB_EXTERN __declspec(dllexport) +# endif +# else +# define TB_API TB_EXTERN # endif -#else -# define TB_API TB_EXTERN #endif // These are flags @@ -171,7 +172,6 @@ typedef enum TB_FloatFormat { typedef union TB_DataType { struct { uint8_t type; - // 2^N where N is the width value. // Only integers and floats can be wide. uint8_t width; // for integers it's the bitwidth @@ -406,8 +406,6 @@ typedef struct TB_Symbol { typedef int TB_Reg; -#define TB_NULL_REG NULL - typedef struct TB_Node TB_Node; struct TB_Node { TB_NodeType type; @@ -586,29 +584,13 @@ typedef struct { typedef void (*TB_PrintCallback)(void* user_data, const char* fmt, ...); -//////////////////////////////// -// Arena -//////////////////////////////// -// the goal is to move more things to transparent arenas, for now it's just function -// IR which is a big one if you're interested in freeing them in whatever organization -// you please. - -// allocations can make no guarentees about being sequential -// tho it would be greatly appreciated at least to some degree. +// defined in common/arena.h typedef struct TB_Arena TB_Arena; -struct TB_Arena { - // alignment never goes past max_align_t - void* (*alloc)(TB_Arena* arena, size_t size, size_t align); - // clearing but we're not done with it yet, cheap - void (*clear)(TB_Arena* arena); - - // frees everything within the arena, potentially expensive - void (*free)(TB_Arena* arena); -}; - -// allocates in 16MiB chunks and does linear allocation in 'em -TB_API TB_Arena* tb_default_arena(void); +// 0 for default +TB_API void tb_arena_create(TB_Arena* restrict arena, size_t chunk_size); +TB_API void tb_arena_destroy(TB_Arena* restrict arena); +TB_API bool tb_arena_is_empty(TB_Arena* arena); //////////////////////////////// // Module management @@ -651,8 +633,7 @@ struct TB_Assembly { // this is where the machine code and other relevant pieces go. typedef struct TB_FunctionOutput TB_FunctionOutput; -// returns NULL if it fails -TB_API TB_FunctionOutput* tb_module_compile_function(TB_Module* m, TB_Function* f, TB_ISelMode isel_mode, bool emit_asm); +TB_API void tb_output_print_asm(TB_FunctionOutput* out, FILE* fp); TB_API uint8_t* tb_output_get_code(TB_FunctionOutput* out, size_t* out_length); @@ -865,6 +846,9 @@ TB_API TB_DebugType* tb_debug_create_func(TB_Module* m, TB_CallingConv cc, size_ TB_API TB_DebugType* tb_debug_field_type(TB_DebugType* type); +TB_API size_t tb_debug_func_return_count(TB_DebugType* type); +TB_API size_t tb_debug_func_param_count(TB_DebugType* type); + // you'll need to fill these if you make a function TB_API TB_DebugType** tb_debug_func_params(TB_DebugType* type); TB_API TB_DebugType** tb_debug_func_returns(TB_DebugType* type); @@ -895,9 +879,6 @@ TB_API void tb_default_print_callback(void* user_data, const char* fmt, ...); TB_API void tb_inst_set_location(TB_Function* f, TB_FileID file, int line); -// this only allows for power of two vector types -TB_API TB_DataType tb_vector_type(TB_DataTypeEnum type, int width); - // if section is NULL, default to .text TB_API TB_Function* tb_function_create(TB_Module* m, ptrdiff_t len, const char* name, TB_Linkage linkage, TB_ComdatType comdat); @@ -1073,25 +1054,40 @@ TB_API void tb_inst_branch(TB_Function* f, TB_DataType dt, TB_Node* key, TB_Node TB_API void tb_inst_ret(TB_Function* f, size_t count, TB_Node** values); //////////////////////////////// -// Optimizer +// Passes //////////////////////////////// // Function analysis, optimizations, and codegen are all part of this -typedef struct TB_FuncOpt TB_FuncOpt; +typedef struct TB_Passes TB_Passes; -// the arena is used to allocate the nodes -TB_API TB_FuncOpt* tb_funcopt_enter(TB_Function* f, TB_Arena* arena); -TB_API void tb_funcopt_exit(TB_FuncOpt* opt); +// the arena is used to allocate the nodes while passes are being done. +TB_API TB_Passes* tb_pass_enter(TB_Function* f, TB_Arena* arena); +TB_API void tb_pass_exit(TB_Passes* opt); -TB_API bool tb_funcopt_peephole(TB_FuncOpt* opt); -TB_API bool tb_funcopt_mem2reg(TB_FuncOpt* opt); -TB_API bool tb_funcopt_loop(TB_FuncOpt* opt); +// transformation passes: +// peephole: runs most simple reductions on the code, +// should be run after any bigger passes (it's incremental +// so it's not that bad) +// +// mem2reg: lowers TB_LOCALs into SSA values, this makes more +// data flow analysis possible on the code and allows to codegen +// to place variables into registers. +// +// loop: NOT READY +// +TB_API bool tb_pass_peephole(TB_Passes* opt); +TB_API bool tb_pass_mem2reg(TB_Passes* opt); +TB_API bool tb_pass_loop(TB_Passes* opt); -// isn't an optimization, just does the name flat form of IR printing -TB_API bool tb_funcopt_print(TB_FuncOpt* opt); +// analysis +// print: prints IR in a flattened text form. +TB_API bool tb_pass_print(TB_Passes* opt); -TB_API void tb_funcopt_kill(TB_FuncOpt* opt, TB_Node* n); -TB_API bool tb_funcopt_mark(TB_FuncOpt* opt, TB_Node* n); -TB_API void tb_funcopt_mark_users(TB_FuncOpt* opt, TB_Node* n); +// codegen +TB_API TB_FunctionOutput* tb_pass_codegen(TB_Passes* opt, bool emit_asm); + +TB_API void tb_pass_kill_node(TB_Passes* opt, TB_Node* n); +TB_API bool tb_pass_mark(TB_Passes* opt, TB_Node* n); +TB_API void tb_pass_mark_users(TB_Passes* opt, TB_Node* n); //////////////////////////////// // IR access @@ -1099,8 +1095,6 @@ TB_API void tb_funcopt_mark_users(TB_FuncOpt* opt, TB_Node* n); TB_API const char* tb_node_get_name(TB_Node* n); TB_API TB_Node* tb_get_parent_region(TB_Node* n); -TB_API bool tb_has_effects(TB_Node* n); - TB_API bool tb_node_is_constant_non_zero(TB_Node* n); TB_API bool tb_node_is_constant_zero(TB_Node* n); diff --git a/src/tilde/tb.lib b/src/tilde/tb.lib Binary files differindex 43e477536..b0886ebfb 100644 --- a/src/tilde/tb.lib +++ b/src/tilde/tb.lib diff --git a/src/tilde/tb_arena.h b/src/tilde/tb_arena.h new file mode 100644 index 000000000..d50e777da --- /dev/null +++ b/src/tilde/tb_arena.h @@ -0,0 +1,76 @@ +#pragma once +#include <stddef.h> +#include <stdbool.h> + +#ifndef TB_API +# ifdef __cplusplus +# define TB_EXTERN extern "C" +# else +# define TB_EXTERN +# endif +# ifdef TB_DLL +# ifdef TB_IMPORT_DLL +# define TB_API TB_EXTERN __declspec(dllimport) +# else +# define TB_API TB_EXTERN __declspec(dllexport) +# endif +# else +# define TB_API TB_EXTERN +# endif +#endif + +enum { + TB_ARENA_SMALL_CHUNK_SIZE = 4 * 1024, + TB_ARENA_MEDIUM_CHUNK_SIZE = 512 * 1024, + TB_ARENA_LARGE_CHUNK_SIZE = 2 * 1024 * 1024, + + TB_ARENA_ALIGNMENT = 16, +}; + +typedef struct TB_ArenaChunk TB_ArenaChunk; +struct TB_ArenaChunk { + TB_ArenaChunk* next; + size_t pad; + char data[]; +}; + +typedef struct TB_Arena { + size_t chunk_size; + TB_ArenaChunk* base; + TB_ArenaChunk* top; + + // top of the allocation space + char* watermark; + char* high_point; // &top->data[chunk_size] +} TB_Arena; + +typedef struct TB_ArenaSavepoint { + TB_ArenaChunk* top; + char* watermark; +} TB_ArenaSavepoint; + +#define TB_ARENA_FOR(it, arena) for (TB_ArenaChunk* it = (arena)->base; it != NULL; it = it->next) + +#define TB_ARENA_ALLOC(arena, T) tb_arena_alloc(arena, sizeof(T)) +#define TB_ARENA_ARR_ALLOC(arena, count, T) tb_arena_alloc(arena, (count) * sizeof(T)) + +TB_API void tb_arena_create(TB_Arena* restrict arena, size_t chunk_size); +TB_API void tb_arena_destroy(TB_Arena* restrict arena); + +TB_API void* tb_arena_unaligned_alloc(TB_Arena* restrict arena, size_t size); +TB_API void* tb_arena_alloc(TB_Arena* restrict arena, size_t size); + +// asserts if ptr+size != watermark +TB_API void tb_arena_pop(TB_Arena* restrict arena, void* ptr, size_t size); + +// in case you wanna mix unaligned and aligned arenas +TB_API void tb_arena_realign(TB_Arena* restrict arena); + +TB_API bool tb_arena_is_empty(TB_Arena* arena); + +// savepoints +TB_API TB_ArenaSavepoint tb_arena_save(TB_Arena* arena); +TB_API void tb_arena_restore(TB_Arena* arena, TB_ArenaSavepoint sp); + +// resets to only having one chunk +TB_API void tb_arena_clear(TB_Arena* arena); |