mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
Update gb.h
This commit is contained in:
@@ -44,7 +44,10 @@ del *.ilk > NUL 2> NUL
|
|||||||
|
|
||||||
cl %compiler_settings% "src\main.c" ^
|
cl %compiler_settings% "src\main.c" ^
|
||||||
/link %linker_settings% -OUT:%exe_name% ^
|
/link %linker_settings% -OUT:%exe_name% ^
|
||||||
&& odin run code/demo.odin
|
&& odin build code/metagen.odin ^
|
||||||
|
&& call "code\metagen.exe" "src\ast_nodes.metagen"
|
||||||
|
rem && odin build code/markdown.odin ^
|
||||||
|
rem && call "code\markdown.exe" "misc\example.md"
|
||||||
rem && odin run code/Jaze/src/main.odin
|
rem && odin run code/Jaze/src/main.odin
|
||||||
|
|
||||||
del *.obj > NUL 2> NUL
|
del *.obj > NUL 2> NUL
|
||||||
|
|||||||
+1
-8
@@ -10,14 +10,7 @@
|
|||||||
#import win32 "sys/windows.odin";
|
#import win32 "sys/windows.odin";
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
a := 1;
|
fmt.println("Here");
|
||||||
b := 2;
|
|
||||||
c := a + b;
|
|
||||||
|
|
||||||
if c > 0 {
|
|
||||||
c = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
when false {
|
when false {
|
||||||
/*
|
/*
|
||||||
Version 0.1.1
|
Version 0.1.1
|
||||||
|
|||||||
@@ -247,7 +247,6 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
|
|||||||
|
|
||||||
|
|
||||||
heap_alloc :: proc(size: int) -> rawptr {
|
heap_alloc :: proc(size: int) -> rawptr {
|
||||||
assert(size > 0);
|
|
||||||
return w.HeapAlloc(w.GetProcessHeap(), w.HEAP_ZERO_MEMORY, size);
|
return w.HeapAlloc(w.GetProcessHeap(), w.HEAP_ZERO_MEMORY, size);
|
||||||
}
|
}
|
||||||
heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
|
heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
|
||||||
|
|||||||
+10
-7
@@ -2,6 +2,7 @@
|
|||||||
#foreign_system_library "user32.lib" when ODIN_OS == "windows";
|
#foreign_system_library "user32.lib" when ODIN_OS == "windows";
|
||||||
#foreign_system_library "gdi32.lib" when ODIN_OS == "windows";
|
#foreign_system_library "gdi32.lib" when ODIN_OS == "windows";
|
||||||
#foreign_system_library "winmm.lib" when ODIN_OS == "windows";
|
#foreign_system_library "winmm.lib" when ODIN_OS == "windows";
|
||||||
|
#foreign_system_library "shell32.lib" when ODIN_OS == "windows";
|
||||||
|
|
||||||
Handle :: rawptr;
|
Handle :: rawptr;
|
||||||
Hwnd :: Handle;
|
Hwnd :: Handle;
|
||||||
@@ -181,15 +182,17 @@ GetQueryPerformanceFrequency :: proc() -> i64 {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetCommandLineA :: proc() -> ^u8 #foreign kernel32;
|
GetCommandLineA :: proc() -> ^u8 #foreign kernel32;
|
||||||
GetSystemMetrics :: proc(index: i32) -> i32 #foreign kernel32;
|
GetCommandLineW :: proc() -> ^u16 #foreign kernel32;
|
||||||
GetCurrentThreadId :: proc() -> u32 #foreign kernel32;
|
GetSystemMetrics :: proc(index: i32) -> i32 #foreign kernel32;
|
||||||
|
GetCurrentThreadId :: proc() -> u32 #foreign kernel32;
|
||||||
|
CommandLineToArgvW :: proc(cmd_list: ^u16, num_args: ^i32) -> ^^u16 #foreign shell32;
|
||||||
|
|
||||||
timeGetTime :: proc() -> u32 #foreign winmm;
|
timeGetTime :: proc() -> u32 #foreign winmm;
|
||||||
GetSystemTimeAsFileTime :: proc(system_time_as_file_time: ^Filetime) #foreign kernel32;
|
GetSystemTimeAsFileTime :: proc(system_time_as_file_time: ^Filetime) #foreign kernel32;
|
||||||
FileTimeToLocalFileTime :: proc(file_time: ^Filetime, local_file_time: ^Filetime) -> Bool #foreign kernel32;
|
FileTimeToLocalFileTime :: proc(file_time: ^Filetime, local_file_time: ^Filetime) -> Bool #foreign kernel32;
|
||||||
FileTimeToSystemTime :: proc(file_time: ^Filetime, system_time: ^Systemtime) -> Bool #foreign kernel32;
|
FileTimeToSystemTime :: proc(file_time: ^Filetime, system_time: ^Systemtime) -> Bool #foreign kernel32;
|
||||||
SystemTimeToFileTime :: proc(system_time: ^Systemtime, file_time: ^Filetime) -> Bool #foreign kernel32;
|
SystemTimeToFileTime :: proc(system_time: ^Systemtime, file_time: ^Filetime) -> Bool #foreign kernel32;
|
||||||
|
|
||||||
// File Stuff
|
// File Stuff
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -1112,7 +1112,7 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
|
|||||||
e->flags |= EntityFlag_Used;
|
e->flags |= EntityFlag_Used;
|
||||||
|
|
||||||
Entity *original_e = e;
|
Entity *original_e = e;
|
||||||
while (e->kind == Entity_Alias && e->Alias.original != NULL) {
|
while (e != NULL && e->kind == Entity_Alias && e->Alias.original != NULL) {
|
||||||
e = e->Alias.original;
|
e = e->Alias.original;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1672,7 +1672,7 @@ bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = base_type(base_enum_type(type));
|
type = core_type(type);
|
||||||
|
|
||||||
if (is_type_boolean(type)) {
|
if (is_type_boolean(type)) {
|
||||||
return in_value.kind == ExactValue_Bool;
|
return in_value.kind == ExactValue_Bool;
|
||||||
@@ -2118,8 +2118,8 @@ bool check_is_castable_to(Checker *c, Operand *operand, Type *y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type *x = operand->type;
|
Type *x = operand->type;
|
||||||
Type *src = base_type(base_enum_type(x));
|
Type *src = core_type(x);
|
||||||
Type *dst = base_type(base_enum_type(y));
|
Type *dst = core_type(y);
|
||||||
if (are_types_identical(src, dst)) {
|
if (are_types_identical(src, dst)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2527,7 +2527,7 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type *t = base_type(base_enum_type(target_type));
|
Type *t = core_type(target_type);
|
||||||
switch (t->kind) {
|
switch (t->kind) {
|
||||||
case Type_Basic:
|
case Type_Basic:
|
||||||
if (operand->mode == Addressing_Constant) {
|
if (operand->mode == Addressing_Constant) {
|
||||||
@@ -2689,7 +2689,7 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h
|
|||||||
expr_entity = e;
|
expr_entity = e;
|
||||||
|
|
||||||
Entity *original_e = e;
|
Entity *original_e = e;
|
||||||
while (e->kind == Entity_Alias && e->Alias.original != NULL) {
|
while (e != NULL && e->kind == Entity_Alias && e->Alias.original != NULL) {
|
||||||
e = e->Alias.original;
|
e = e->Alias.original;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+306
-124
File diff suppressed because it is too large
Load Diff
@@ -1328,8 +1328,8 @@ irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String na
|
|||||||
irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) {
|
irValue *ir_emit_store(irProcedure *p, irValue *address, irValue *value) {
|
||||||
#if 1
|
#if 1
|
||||||
// NOTE(bill): Sanity check
|
// NOTE(bill): Sanity check
|
||||||
Type *a = base_type(base_enum_type(type_deref(ir_type(address))));
|
Type *a = core_type(type_deref(ir_type(address)));
|
||||||
Type *b = base_type(base_enum_type(ir_type(value)));
|
Type *b = core_type(ir_type(value));
|
||||||
if (!is_type_untyped(b)) {
|
if (!is_type_untyped(b)) {
|
||||||
GB_ASSERT_MSG(are_types_identical(a, b), "%s %s", type_to_string(a), type_to_string(b));
|
GB_ASSERT_MSG(are_types_identical(a, b), "%s %s", type_to_string(a), type_to_string(b));
|
||||||
}
|
}
|
||||||
@@ -2218,8 +2218,8 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type *src = base_type(base_enum_type(src_type));
|
Type *src = core_type(src_type);
|
||||||
Type *dst = base_type(base_enum_type(t));
|
Type *dst = core_type(t);
|
||||||
|
|
||||||
|
|
||||||
// if (is_type_untyped_nil(src) && type_has_nil(dst)) {
|
// if (is_type_untyped_nil(src) && type_has_nil(dst)) {
|
||||||
|
|||||||
+1
-1
@@ -306,7 +306,7 @@ void ir_print_compound_element(irFileBuffer *f, irModule *m, ExactValue v, Type
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *type) {
|
void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *type) {
|
||||||
type = base_type(base_enum_type(type));
|
type = core_type(type);
|
||||||
if (is_type_float(type)) {
|
if (is_type_float(type)) {
|
||||||
value = exact_value_to_float(value);
|
value = exact_value_to_float(value);
|
||||||
} else if (is_type_integer(type)) {
|
} else if (is_type_integer(type)) {
|
||||||
|
|||||||
+3
-2
@@ -402,7 +402,6 @@ String const ast_node_strings[] = {
|
|||||||
|
|
||||||
typedef struct AstNode {
|
typedef struct AstNode {
|
||||||
AstNodeKind kind;
|
AstNodeKind kind;
|
||||||
// AstNode *prev, *next; // NOTE(bill): allow for Linked list
|
|
||||||
u32 stmt_state_flags;
|
u32 stmt_state_flags;
|
||||||
union {
|
union {
|
||||||
#define AST_NODE_KIND(_kind_name_, name, ...) GB_JOIN2(AstNode, _kind_name_) _kind_name_;
|
#define AST_NODE_KIND(_kind_name_, name, ...) GB_JOIN2(AstNode, _kind_name_) _kind_name_;
|
||||||
@@ -414,7 +413,9 @@ typedef struct AstNode {
|
|||||||
|
|
||||||
#define ast_node(n_, Kind_, node_) GB_JOIN2(AstNode, Kind_) *n_ = &(node_)->Kind_; GB_ASSERT((node_)->kind == GB_JOIN2(AstNode_, Kind_))
|
#define ast_node(n_, Kind_, node_) GB_JOIN2(AstNode, Kind_) *n_ = &(node_)->Kind_; GB_ASSERT((node_)->kind == GB_JOIN2(AstNode_, Kind_))
|
||||||
#define case_ast_node(n_, Kind_, node_) case GB_JOIN2(AstNode_, Kind_): { ast_node(n_, Kind_, node_);
|
#define case_ast_node(n_, Kind_, node_) case GB_JOIN2(AstNode_, Kind_): { ast_node(n_, Kind_, node_);
|
||||||
|
#ifndef case_end
|
||||||
#define case_end } break;
|
#define case_end } break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
gb_inline bool is_ast_node_expr(AstNode *node) {
|
gb_inline bool is_ast_node_expr(AstNode *node) {
|
||||||
@@ -3841,7 +3842,7 @@ ParseFileError parse_files(Parser *p, char *init_filename) {
|
|||||||
gb_printf_err("File permissions problem");
|
gb_printf_err("File permissions problem");
|
||||||
break;
|
break;
|
||||||
case ParseFile_NotFound:
|
case ParseFile_NotFound:
|
||||||
gb_printf_err("File cannot be found");
|
gb_printf_err("File cannot be found (`%.*s`)", LIT(import_path));
|
||||||
break;
|
break;
|
||||||
case ParseFile_InvalidToken:
|
case ParseFile_InvalidToken:
|
||||||
gb_printf_err("Invalid token found in file");
|
gb_printf_err("Invalid token found in file");
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
typedef enum ssaOp ssaOp;
|
typedef enum ssaOp ssaOp;
|
||||||
typedef struct ssaModule ssaModule;
|
typedef struct ssaModule ssaModule;
|
||||||
typedef struct ssaValue ssaValue;
|
typedef struct ssaValue ssaValue;
|
||||||
|
typedef struct ssaValueArgs ssaValueArgs;
|
||||||
typedef struct ssaBlock ssaBlock;
|
typedef struct ssaBlock ssaBlock;
|
||||||
typedef struct ssaProc ssaProc;
|
typedef struct ssaProc ssaProc;
|
||||||
typedef struct ssaEdge ssaEdge;
|
typedef struct ssaEdge ssaEdge;
|
||||||
@@ -294,7 +295,15 @@ String const ssa_op_strings[] = {
|
|||||||
#undef SSA_OP
|
#undef SSA_OP
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SSA_MAX_ARGS 4
|
|
||||||
|
#define SSA_DEFAULT_VALUE_ARG_CAPACITY 8
|
||||||
|
struct ssaValueArgs {
|
||||||
|
ssaValue ** e;
|
||||||
|
isize count;
|
||||||
|
isize capacity;
|
||||||
|
ssaValue * backing[SSA_DEFAULT_VALUE_ARG_CAPACITY];
|
||||||
|
gbAllocator allocator;
|
||||||
|
};
|
||||||
|
|
||||||
struct ssaValue {
|
struct ssaValue {
|
||||||
i32 id; // Unique identifier but the pointer could be used too
|
i32 id; // Unique identifier but the pointer could be used too
|
||||||
@@ -303,13 +312,7 @@ struct ssaValue {
|
|||||||
ssaBlock * block; // Containing basic block
|
ssaBlock * block; // Containing basic block
|
||||||
|
|
||||||
i32 uses;
|
i32 uses;
|
||||||
// Most values will only a few number of arguments
|
ssaValueArgs args;
|
||||||
// Procedure calls may need a lot more so they will use the `var_args` parameter instead
|
|
||||||
ssaValue * args[SSA_MAX_ARGS];
|
|
||||||
isize arg_count;
|
|
||||||
|
|
||||||
ssaValueArray var_args; // Only used in procedure calls as the SSA_MAX_ARGS may be too small
|
|
||||||
|
|
||||||
ExactValue exact_value; // Used for constants
|
ExactValue exact_value; // Used for constants
|
||||||
|
|
||||||
String comment_string;
|
String comment_string;
|
||||||
@@ -501,21 +504,29 @@ void ssa_emit_jump(ssaProc *p, ssaBlock *edge) {
|
|||||||
ssa_add_edge_to(ssa_end_block(p), edge);
|
ssa_add_edge_to(ssa_end_block(p), edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ssa_init_value_args(ssaValueArgs *va, gbAllocator a) {
|
||||||
bool ssa_op_uses_var_args(ssaOp op) {
|
va->e = va->backing;
|
||||||
switch (op) {
|
va->count = 0;
|
||||||
case ssaOp_CallOdin:
|
va->capacity = gb_count_of(va->backing);
|
||||||
case ssaOp_CallC:
|
va->allocator = a;
|
||||||
case ssaOp_CallStd:
|
|
||||||
case ssaOp_CallFast:
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case ssaOp_Phi:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ssa_add_arg(ssaValueArgs *va, ssaValue *arg) {
|
||||||
|
if (va->count >= va->capacity) {
|
||||||
|
isize capacity = 2*va->capacity;
|
||||||
|
if (va->e == va->backing) { // Replace the backing with an allocated version instead
|
||||||
|
ssaValue **new_args = gb_alloc_array(va->allocator, ssaValue *, capacity);
|
||||||
|
gb_memcopy_array(new_args, va->e, va->count);
|
||||||
|
va->e = new_args;
|
||||||
|
} else {
|
||||||
|
isize old_cap_size = va->capacity * gb_size_of(ssaValue *);
|
||||||
|
isize new_cap_size = capacity * gb_size_of(ssaValue *);
|
||||||
|
va->e = gb_resize(va->allocator, va->e, old_cap_size, new_cap_size);
|
||||||
|
}
|
||||||
|
va->capacity = capacity;
|
||||||
|
}
|
||||||
|
va->e[va->count++] = arg; arg->uses++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -525,6 +536,7 @@ ssaValue *ssa_new_value(ssaProc *p, ssaOp op, Type *t, ssaBlock *b) {
|
|||||||
v->op = op;
|
v->op = op;
|
||||||
v->type = t;
|
v->type = t;
|
||||||
v->block = b;
|
v->block = b;
|
||||||
|
ssa_init_value_args(&v->args, p->module->allocator);
|
||||||
array_add(&b->values, v);
|
array_add(&b->values, v);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
@@ -541,7 +553,7 @@ ssaValue *ssa_new_value0v(ssaBlock *b, ssaOp op, Type *t, ExactValue exact_value
|
|||||||
|
|
||||||
ssaValue *ssa_new_value1(ssaBlock *b, ssaOp op, Type *t, ssaValue *arg) {
|
ssaValue *ssa_new_value1(ssaBlock *b, ssaOp op, Type *t, ssaValue *arg) {
|
||||||
ssaValue *v = ssa_new_value(b->proc, op, t, b);
|
ssaValue *v = ssa_new_value(b->proc, op, t, b);
|
||||||
v->args[v->arg_count++] = arg; arg->uses++;
|
ssa_add_arg(&v->args, arg);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
ssaValue *ssa_new_value1v(ssaBlock *b, ssaOp op, Type *t, ExactValue exact_value, ssaValue *arg) {
|
ssaValue *ssa_new_value1v(ssaBlock *b, ssaOp op, Type *t, ExactValue exact_value, ssaValue *arg) {
|
||||||
@@ -552,8 +564,8 @@ ssaValue *ssa_new_value1v(ssaBlock *b, ssaOp op, Type *t, ExactValue exact_value
|
|||||||
|
|
||||||
ssaValue *ssa_new_value2(ssaBlock *b, ssaOp op, Type *t, ssaValue *arg0, ssaValue *arg1) {
|
ssaValue *ssa_new_value2(ssaBlock *b, ssaOp op, Type *t, ssaValue *arg0, ssaValue *arg1) {
|
||||||
ssaValue *v = ssa_new_value(b->proc, op, t, b);
|
ssaValue *v = ssa_new_value(b->proc, op, t, b);
|
||||||
v->args[v->arg_count++] = arg0; arg0->uses++;
|
ssa_add_arg(&v->args, arg0);
|
||||||
v->args[v->arg_count++] = arg1; arg1->uses++;
|
ssa_add_arg(&v->args, arg1);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
ssaValue *ssa_new_value2v(ssaBlock *b, ssaOp op, Type *t, ExactValue exact_value, ssaValue *arg0, ssaValue *arg1) {
|
ssaValue *ssa_new_value2v(ssaBlock *b, ssaOp op, Type *t, ExactValue exact_value, ssaValue *arg0, ssaValue *arg1) {
|
||||||
@@ -564,9 +576,9 @@ ssaValue *ssa_new_value2v(ssaBlock *b, ssaOp op, Type *t, ExactValue exact_value
|
|||||||
|
|
||||||
ssaValue *ssa_new_value3(ssaBlock *b, ssaOp op, Type *t, ssaValue *arg0, ssaValue *arg1, ssaValue *arg2) {
|
ssaValue *ssa_new_value3(ssaBlock *b, ssaOp op, Type *t, ssaValue *arg0, ssaValue *arg1, ssaValue *arg2) {
|
||||||
ssaValue *v = ssa_new_value(b->proc, op, t, b);
|
ssaValue *v = ssa_new_value(b->proc, op, t, b);
|
||||||
v->args[v->arg_count++] = arg0; arg0->uses++;
|
ssa_add_arg(&v->args, arg0);
|
||||||
v->args[v->arg_count++] = arg1; arg1->uses++;
|
ssa_add_arg(&v->args, arg1);
|
||||||
v->args[v->arg_count++] = arg2; arg2->uses++;
|
ssa_add_arg(&v->args, arg2);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
ssaValue *ssa_new_value3v(ssaBlock *b, ssaOp op, Type *t, ExactValue exact_value, ssaValue *arg0, ssaValue *arg1, ssaValue *arg2) {
|
ssaValue *ssa_new_value3v(ssaBlock *b, ssaOp op, Type *t, ExactValue exact_value, ssaValue *arg0, ssaValue *arg1, ssaValue *arg2) {
|
||||||
@@ -577,10 +589,10 @@ ssaValue *ssa_new_value3v(ssaBlock *b, ssaOp op, Type *t, ExactValue exact_value
|
|||||||
|
|
||||||
ssaValue *ssa_new_value4(ssaBlock *b, ssaOp op, Type *t, ssaValue *arg0, ssaValue *arg1, ssaValue *arg2, ssaValue *arg3) {
|
ssaValue *ssa_new_value4(ssaBlock *b, ssaOp op, Type *t, ssaValue *arg0, ssaValue *arg1, ssaValue *arg2, ssaValue *arg3) {
|
||||||
ssaValue *v = ssa_new_value(b->proc, op, t, b);
|
ssaValue *v = ssa_new_value(b->proc, op, t, b);
|
||||||
v->args[v->arg_count++] = arg0; arg0->uses++;
|
ssa_add_arg(&v->args, arg0);
|
||||||
v->args[v->arg_count++] = arg1; arg1->uses++;
|
ssa_add_arg(&v->args, arg1);
|
||||||
v->args[v->arg_count++] = arg2; arg2->uses++;
|
ssa_add_arg(&v->args, arg2);
|
||||||
v->args[v->arg_count++] = arg3; arg3->uses++;
|
ssa_add_arg(&v->args, arg3);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,17 +624,10 @@ ssaValue *ssa_const_int(ssaProc *p, Type *t, i64 c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ssa_reset_value_args(ssaValue *v) {
|
void ssa_reset_value_args(ssaValue *v) {
|
||||||
if (ssa_op_uses_var_args(v->op)) {
|
for_array(i, v->args) {
|
||||||
for_array(i, v->var_args) {
|
v->args.e[i]->uses--;
|
||||||
v->var_args.e[i]->uses--;
|
|
||||||
}
|
|
||||||
v->var_args.count = 0;
|
|
||||||
} else {
|
|
||||||
for (isize i = 0; i < v->arg_count; i++) {
|
|
||||||
v->args[i]->uses--;
|
|
||||||
}
|
|
||||||
v->arg_count = 0;
|
|
||||||
}
|
}
|
||||||
|
v->args.count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -721,6 +726,55 @@ void ssa_emit_comment(ssaProc *p, String s) {
|
|||||||
// ssa_new_value0v(p->curr_block, ssaOp_Comment, NULL, exact_value_string(s));
|
// ssa_new_value0v(p->curr_block, ssaOp_Comment, NULL, exact_value_string(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SSA_MAX_STRUCT_FIELD_COUNT 4
|
||||||
|
|
||||||
|
bool can_ssa_type(Type *t) {
|
||||||
|
i64 s = type_size_of(heap_allocator(), t);
|
||||||
|
if (s > 4*build_context.word_size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
t = core_type(t);
|
||||||
|
|
||||||
|
switch (t->kind) {
|
||||||
|
case Type_Array:
|
||||||
|
return t->Array.count == 0;
|
||||||
|
case Type_Vector:
|
||||||
|
return s < 2*build_context.word_size;
|
||||||
|
|
||||||
|
case Type_DynamicArray:
|
||||||
|
return false;
|
||||||
|
case Type_Map:
|
||||||
|
return false;
|
||||||
|
case Type_Tuple:
|
||||||
|
if (t->Tuple.variable_count > SSA_MAX_STRUCT_FIELD_COUNT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (isize i = 0; i < t->Tuple.variable_count; i++) {
|
||||||
|
if (!can_ssa_type(t->Tuple.variables[i]->type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
case Type_Record:
|
||||||
|
if (t->Record.kind == TypeRecord_Union) {
|
||||||
|
return false;
|
||||||
|
} else if (t->Record.kind == TypeRecord_Struct) {
|
||||||
|
if (t->Record.field_count > SSA_MAX_STRUCT_FIELD_COUNT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (isize i = 0; i < t->Record.field_count; i++) {
|
||||||
|
if (!can_ssa_type(t->Record.fields[i]->type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ssa_build_stmt(ssaProc *p, AstNode *node);
|
void ssa_build_stmt(ssaProc *p, AstNode *node);
|
||||||
void ssa_build_stmt_list(ssaProc *p, AstNodeArray nodes);
|
void ssa_build_stmt_list(ssaProc *p, AstNodeArray nodes);
|
||||||
|
|
||||||
@@ -815,7 +869,7 @@ ssaAddr ssa_build_addr(ssaProc *p, AstNode *expr) {
|
|||||||
|
|
||||||
|
|
||||||
Type *ssa_proper_type(Type *t) {
|
Type *ssa_proper_type(Type *t) {
|
||||||
t = default_type(base_type(base_enum_type(t)));
|
t = default_type(core_type(t));
|
||||||
|
|
||||||
if (t->kind == Type_Basic) {
|
if (t->kind == Type_Basic) {
|
||||||
switch (t->Basic.kind) {
|
switch (t->Basic.kind) {
|
||||||
@@ -1041,7 +1095,7 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) {
|
|||||||
GB_ASSERT_NOT_NULL(tv);
|
GB_ASSERT_NOT_NULL(tv);
|
||||||
|
|
||||||
if (tv->value.kind != ExactValue_Invalid) {
|
if (tv->value.kind != ExactValue_Invalid) {
|
||||||
Type *t = base_type(base_enum_type(tv->type));
|
Type *t = core_type(tv->type);
|
||||||
if (is_type_boolean(t)) {
|
if (is_type_boolean(t)) {
|
||||||
return ssa_const_bool(p, tv->type, tv->value.value_bool);
|
return ssa_const_bool(p, tv->type, tv->value.value_bool);
|
||||||
} else if (is_type_string(t)) {
|
} else if (is_type_string(t)) {
|
||||||
@@ -1675,16 +1729,9 @@ void ssa_print_reg_value(gbFile *f, ssaValue *v) {
|
|||||||
|
|
||||||
ssa_print_exact_value(f, v);
|
ssa_print_exact_value(f, v);
|
||||||
|
|
||||||
if (ssa_op_uses_var_args(v->op)) {
|
for_array(i, v->args) {
|
||||||
for_array(i, v->var_args) {
|
gb_fprintf(f, " ");
|
||||||
gb_fprintf(f, " ");
|
ssa_print_value(f, v->args.e[i]);
|
||||||
ssa_print_value(f, v->var_args.e[i]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (isize i = 0; i < v->arg_count; i++) {
|
|
||||||
gb_fprintf(f, " ");
|
|
||||||
ssa_print_value(f, v->args[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v->comment_string.len > 0) {
|
if (v->comment_string.len > 0) {
|
||||||
@@ -1733,21 +1780,11 @@ void ssa_print_proc(gbFile *f, ssaProc *p) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool skip = false;
|
bool skip = false;
|
||||||
if (ssa_op_uses_var_args(v->op)) {
|
for_array(k, v->args) {
|
||||||
for_array(k, v->var_args) {
|
ssaValue *w = v->args.e[k];
|
||||||
ssaValue *w = v->var_args.e[k];
|
if (w != NULL && w->block == b && !printed[w->id]) {
|
||||||
if (w != NULL && w->block == b && !printed[w->id]) {
|
skip = true;
|
||||||
skip = true;
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (isize k = 0; k < v->arg_count; k++) {
|
|
||||||
ssaValue *w = v->args[k];
|
|
||||||
if (w != NULL && w->block == b && !printed[w->id]) {
|
|
||||||
skip = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-11
@@ -375,6 +375,10 @@ Type *base_enum_type(Type *t) {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type *core_type(Type *t) {
|
||||||
|
return base_type(base_enum_type(t));
|
||||||
|
}
|
||||||
|
|
||||||
void set_base_type(Type *t, Type *base) {
|
void set_base_type(Type *t, Type *base) {
|
||||||
if (t && t->kind == Type_Named) {
|
if (t && t->kind == Type_Named) {
|
||||||
t->Named.base = base;
|
t->Named.base = base;
|
||||||
@@ -530,28 +534,28 @@ bool is_type_named(Type *t) {
|
|||||||
return t->kind == Type_Named;
|
return t->kind == Type_Named;
|
||||||
}
|
}
|
||||||
bool is_type_boolean(Type *t) {
|
bool is_type_boolean(Type *t) {
|
||||||
t = base_type(base_enum_type(t));
|
t = core_type(t);
|
||||||
if (t->kind == Type_Basic) {
|
if (t->kind == Type_Basic) {
|
||||||
return (t->Basic.flags & BasicFlag_Boolean) != 0;
|
return (t->Basic.flags & BasicFlag_Boolean) != 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool is_type_integer(Type *t) {
|
bool is_type_integer(Type *t) {
|
||||||
t = base_type(base_enum_type(t));
|
t = core_type(t);
|
||||||
if (t->kind == Type_Basic) {
|
if (t->kind == Type_Basic) {
|
||||||
return (t->Basic.flags & BasicFlag_Integer) != 0;
|
return (t->Basic.flags & BasicFlag_Integer) != 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool is_type_unsigned(Type *t) {
|
bool is_type_unsigned(Type *t) {
|
||||||
t = base_type(base_enum_type(t));
|
t = core_type(t);
|
||||||
if (t->kind == Type_Basic) {
|
if (t->kind == Type_Basic) {
|
||||||
return (t->Basic.flags & BasicFlag_Unsigned) != 0;
|
return (t->Basic.flags & BasicFlag_Unsigned) != 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool is_type_numeric(Type *t) {
|
bool is_type_numeric(Type *t) {
|
||||||
t = base_type(base_enum_type(t));
|
t = core_type(t);
|
||||||
if (t->kind == Type_Basic) {
|
if (t->kind == Type_Basic) {
|
||||||
return (t->Basic.flags & BasicFlag_Numeric) != 0;
|
return (t->Basic.flags & BasicFlag_Numeric) != 0;
|
||||||
}
|
}
|
||||||
@@ -586,7 +590,7 @@ bool is_type_untyped(Type *t) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool is_type_ordered(Type *t) {
|
bool is_type_ordered(Type *t) {
|
||||||
t = base_type(base_enum_type(t));
|
t = core_type(t);
|
||||||
switch (t->kind) {
|
switch (t->kind) {
|
||||||
case Type_Basic:
|
case Type_Basic:
|
||||||
return (t->Basic.flags & BasicFlag_Ordered) != 0;
|
return (t->Basic.flags & BasicFlag_Ordered) != 0;
|
||||||
@@ -598,28 +602,28 @@ bool is_type_ordered(Type *t) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool is_type_constant_type(Type *t) {
|
bool is_type_constant_type(Type *t) {
|
||||||
t = base_type(base_enum_type(t));
|
t = core_type(t);
|
||||||
if (t->kind == Type_Basic) {
|
if (t->kind == Type_Basic) {
|
||||||
return (t->Basic.flags & BasicFlag_ConstantType) != 0;
|
return (t->Basic.flags & BasicFlag_ConstantType) != 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool is_type_float(Type *t) {
|
bool is_type_float(Type *t) {
|
||||||
t = base_type(base_enum_type(t));
|
t = core_type(t);
|
||||||
if (t->kind == Type_Basic) {
|
if (t->kind == Type_Basic) {
|
||||||
return (t->Basic.flags & BasicFlag_Float) != 0;
|
return (t->Basic.flags & BasicFlag_Float) != 0;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool is_type_f32(Type *t) {
|
bool is_type_f32(Type *t) {
|
||||||
t = base_type(base_enum_type(t));
|
t = core_type(t);
|
||||||
if (t->kind == Type_Basic) {
|
if (t->kind == Type_Basic) {
|
||||||
return t->Basic.kind == Basic_f32;
|
return t->Basic.kind == Basic_f32;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool is_type_f64(Type *t) {
|
bool is_type_f64(Type *t) {
|
||||||
t = base_type(base_enum_type(t));
|
t = core_type(t);
|
||||||
if (t->kind == Type_Basic) {
|
if (t->kind == Type_Basic) {
|
||||||
return t->Basic.kind == Basic_f64;
|
return t->Basic.kind == Basic_f64;
|
||||||
}
|
}
|
||||||
@@ -737,7 +741,7 @@ bool is_type_untyped_nil(Type *t) {
|
|||||||
|
|
||||||
|
|
||||||
bool is_type_valid_for_keys(Type *t) {
|
bool is_type_valid_for_keys(Type *t) {
|
||||||
t = base_type(base_enum_type(t));
|
t = core_type(t);
|
||||||
if (is_type_untyped(t)) {
|
if (is_type_untyped(t)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -798,7 +802,7 @@ bool is_type_comparable(Type *t) {
|
|||||||
return true;
|
return true;
|
||||||
case Type_Record: {
|
case Type_Record: {
|
||||||
if (is_type_enum(t)) {
|
if (is_type_enum(t)) {
|
||||||
return is_type_comparable(base_enum_type(t));
|
return is_type_comparable(core_type(t));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
Reference in New Issue
Block a user