aboutsummaryrefslogtreecommitdiff
path: root/src/tilde
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-07-28 14:57:04 +0100
committergingerBill <bill@gingerbill.org>2023-07-28 14:57:04 +0100
commitc39a3603720917d6970026e5c0595d468ea9b372 (patch)
tree47f9b81d6a37007aee82834df91bec311742ec9f /src/tilde
parentf6d1724835489120ae4a3805495dafc97c86db80 (diff)
Update Tilde for the new TB_Passes approach
Diffstat (limited to 'src/tilde')
-rw-r--r--src/tilde/tb.h106
-rw-r--r--src/tilde/tb.libbin4162224 -> 4177320 bytes
-rw-r--r--src/tilde/tb_arena.h76
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
index 43e477536..b0886ebfb 100644
--- a/src/tilde/tb.lib
+++ b/src/tilde/tb.lib
Binary files differ
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);