mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-18 11:52:22 -07:00
Remove auto
This commit is contained in:
+1
-17
@@ -473,22 +473,6 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) {
|
||||
|
||||
void check_scope_usage(Checker *c, Scope *scope) {
|
||||
// TODO(bill): Use this?
|
||||
#if 0
|
||||
for_array(i, scope->elements.entries) {
|
||||
auto *entry = scope->elements.entries + i;
|
||||
Entity *e = entry->value;
|
||||
if (e->kind == Entity_Variable) {
|
||||
auto *v = &e->Variable;
|
||||
if (!v->is_field && !v->used) {
|
||||
warning(e->token, "Unused variable: %.*s", LIT(e->token.string));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Scope *child = scope->first_child; child != NULL; child = child->next) {
|
||||
check_scope_usage(c, child);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -961,7 +945,7 @@ void init_preload_types(Checker *c) {
|
||||
t_type_info = e->type;
|
||||
t_type_info_ptr = make_type_pointer(c->allocator, t_type_info);
|
||||
GB_ASSERT(is_type_union(e->type));
|
||||
auto *record = &base_type(e->type)->Record;
|
||||
TypeRecord *record = &base_type(e->type)->Record;
|
||||
|
||||
t_type_info_member = record->other_fields[0]->type;
|
||||
t_type_info_member_ptr = make_type_pointer(c->allocator, t_type_info_member);
|
||||
|
||||
@@ -74,7 +74,7 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra
|
||||
if (o.type->kind != Type_Tuple) {
|
||||
array_add(&operands, o);
|
||||
} else {
|
||||
auto *tuple = &o.type->Tuple;
|
||||
TypeTuple *tuple = &o.type->Tuple;
|
||||
for (isize j = 0; j < tuple->variable_count; j++) {
|
||||
o.type = tuple->variables[j]->type;
|
||||
array_add(&operands, o);
|
||||
@@ -315,8 +315,8 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, Cycle
|
||||
bool are_signatures_similar_enough(Type *a_, Type *b_) {
|
||||
GB_ASSERT(a_->kind == Type_Proc);
|
||||
GB_ASSERT(b_->kind == Type_Proc);
|
||||
auto *a = &a_->Proc;
|
||||
auto *b = &b_->Proc;
|
||||
TypeProc *a = &a_->Proc;
|
||||
TypeProc *b = &b_->Proc;
|
||||
|
||||
if (a->param_count != b->param_count) {
|
||||
return false;
|
||||
@@ -368,7 +368,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
if ((d->scope->is_file || d->scope->is_global) &&
|
||||
str_eq(e->token.string, str_lit("main"))) {
|
||||
if (proc_type != NULL) {
|
||||
auto *pt = &proc_type->Proc;
|
||||
TypeProc *pt = &proc_type->Proc;
|
||||
if (pt->param_count != 0 ||
|
||||
pt->result_count) {
|
||||
gbString str = type_to_string(proc_type);
|
||||
@@ -402,8 +402,8 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
}
|
||||
|
||||
if (is_foreign) {
|
||||
auto *fp = &c->info.foreign_procs;
|
||||
auto *proc_decl = &d->proc_decl->ProcDecl;
|
||||
MapEntity *fp = &c->info.foreign_procs;
|
||||
AstNodeProcDecl *proc_decl = &d->proc_decl->ProcDecl;
|
||||
String name = proc_decl->name->Ident.string;
|
||||
if (proc_decl->foreign_name.len > 0) {
|
||||
name = proc_decl->foreign_name;
|
||||
@@ -425,8 +425,8 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
map_entity_set(fp, key, e);
|
||||
}
|
||||
} else if (is_link_name) {
|
||||
auto *fp = &c->info.foreign_procs;
|
||||
auto *proc_decl = &d->proc_decl->ProcDecl;
|
||||
MapEntity *fp = &c->info.foreign_procs;
|
||||
AstNodeProcDecl *proc_decl = &d->proc_decl->ProcDecl;
|
||||
String name = proc_decl->link_name;
|
||||
|
||||
HashKey key = hash_string(name);
|
||||
@@ -492,7 +492,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
|
||||
|
||||
GB_ASSERT(type->kind == Type_Proc);
|
||||
if (type->Proc.param_count > 0) {
|
||||
auto *params = &type->Proc.params->Tuple;
|
||||
TypeTuple *params = &type->Proc.params->Tuple;
|
||||
for (isize i = 0; i < params->variable_count; i++) {
|
||||
Entity *e = params->variables[i];
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
|
||||
@@ -3401,7 +3401,7 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
|
||||
if (o.type->kind != Type_Tuple) {
|
||||
array_add(&operands, o);
|
||||
} else {
|
||||
auto *tuple = &o.type->Tuple;
|
||||
TypeTuple *tuple = &o.type->Tuple;
|
||||
if (variadic && i >= param_count) {
|
||||
error(ast_node_token(ce->args.e[i]),
|
||||
"`..` in a variadic procedure cannot be applied to a %td-valued expression", tuple->variable_count);
|
||||
|
||||
@@ -441,7 +441,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
if (o.type->kind != Type_Tuple) {
|
||||
array_add(&operands, o);
|
||||
} else {
|
||||
auto *tuple = &o.type->Tuple;
|
||||
TypeTuple *tuple = &o.type->Tuple;
|
||||
for (isize j = 0; j < tuple->variable_count; j++) {
|
||||
o.type = tuple->variables[j]->type;
|
||||
array_add(&operands, o);
|
||||
@@ -553,7 +553,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
if (result_count > 0) {
|
||||
Entity **variables = NULL;
|
||||
if (proc_type->Proc.results != NULL) {
|
||||
auto *tuple = &proc_type->Proc.results->Tuple;
|
||||
TypeTuple *tuple = &proc_type->Proc.results->Tuple;
|
||||
variables = tuple->variables;
|
||||
}
|
||||
if (rs->results.count == 0) {
|
||||
|
||||
+82
-96
@@ -58,34 +58,6 @@ typedef struct BasicType {
|
||||
String name;
|
||||
} BasicType;
|
||||
|
||||
|
||||
|
||||
#define TYPE_KINDS \
|
||||
TYPE_KIND(Invalid), \
|
||||
TYPE_KIND(Basic), \
|
||||
TYPE_KIND(Pointer), \
|
||||
TYPE_KIND(Array), \
|
||||
TYPE_KIND(Vector), \
|
||||
TYPE_KIND(Slice), \
|
||||
TYPE_KIND(Maybe), \
|
||||
TYPE_KIND(Record), \
|
||||
TYPE_KIND(Named), \
|
||||
TYPE_KIND(Tuple), \
|
||||
TYPE_KIND(Proc), \
|
||||
TYPE_KIND(Count),
|
||||
|
||||
typedef enum TypeKind {
|
||||
#define TYPE_KIND(k, ...) GB_JOIN2(Type_, k)
|
||||
TYPE_KINDS
|
||||
#undef TYPE_KIND
|
||||
} TypeKind;
|
||||
|
||||
String const type_strings[] = {
|
||||
#define TYPE_KIND(k, ...) {cast(u8 *)#k, gb_size_of(#k)-1}
|
||||
TYPE_KINDS
|
||||
#undef TYPE_KIND
|
||||
};
|
||||
|
||||
typedef enum TypeRecordKind {
|
||||
TypeRecord_Invalid,
|
||||
|
||||
@@ -97,75 +69,89 @@ typedef enum TypeRecordKind {
|
||||
TypeRecord_Count,
|
||||
} TypeRecordKind;
|
||||
|
||||
typedef struct TypeRecord {
|
||||
TypeRecordKind kind;
|
||||
|
||||
// All record types
|
||||
// Theses are arrays
|
||||
Entity **fields; // Entity_Variable (otherwise Entity_TypeName if union)
|
||||
i32 field_count; // == offset_count is struct
|
||||
AstNode *node;
|
||||
|
||||
union { // NOTE(bill): Reduce size_of Type
|
||||
struct { // enum only
|
||||
Type * enum_base; // Default is `int`
|
||||
Entity * enum_count;
|
||||
Entity * min_value;
|
||||
Entity * max_value;
|
||||
};
|
||||
struct { // struct only
|
||||
i64 * struct_offsets;
|
||||
bool struct_are_offsets_set;
|
||||
bool struct_is_packed;
|
||||
bool struct_is_ordered;
|
||||
Entity **fields_in_src_order; // Entity_Variable
|
||||
};
|
||||
};
|
||||
|
||||
// Entity_Constant or Entity_TypeName
|
||||
Entity **other_fields;
|
||||
i32 other_field_count;
|
||||
} TypeRecord;
|
||||
|
||||
#define TYPE_KINDS \
|
||||
TYPE_KIND(Basic, BasicType) \
|
||||
TYPE_KIND(Pointer, struct { Type *elem; }) \
|
||||
TYPE_KIND(Array, struct { Type *elem; i64 count; }) \
|
||||
TYPE_KIND(Vector, struct { Type *elem; i64 count; }) \
|
||||
TYPE_KIND(Slice, struct { Type *elem; }) \
|
||||
TYPE_KIND(Maybe, struct { Type *elem; }) \
|
||||
TYPE_KIND(Record, TypeRecord) \
|
||||
TYPE_KIND(Named, struct { \
|
||||
String name; \
|
||||
Type * base; \
|
||||
Entity *type_name; /* Entity_TypeName */ \
|
||||
}) \
|
||||
TYPE_KIND(Tuple, struct { \
|
||||
Entity **variables; /* Entity_Variable */ \
|
||||
i32 variable_count; \
|
||||
bool are_offsets_set; \
|
||||
i64 * offsets; \
|
||||
}) \
|
||||
TYPE_KIND(Proc, struct { \
|
||||
Scope *scope; \
|
||||
Type * params; /* Type_Tuple */ \
|
||||
Type * results; /* Type_Tuple */ \
|
||||
i32 param_count; \
|
||||
i32 result_count; \
|
||||
bool variadic; \
|
||||
})
|
||||
|
||||
typedef enum TypeKind {
|
||||
Type_Invalid,
|
||||
#define TYPE_KIND(k, ...) GB_JOIN2(Type_, k),
|
||||
TYPE_KINDS
|
||||
#undef TYPE_KIND
|
||||
Type_Count,
|
||||
} TypeKind;
|
||||
|
||||
String const type_strings[] = {
|
||||
{cast(u8 *)"Invalid", gb_size_of("Invalid")},
|
||||
#define TYPE_KIND(k, ...) {cast(u8 *)#k, gb_size_of(#k)-1},
|
||||
TYPE_KINDS
|
||||
#undef TYPE_KIND
|
||||
};
|
||||
|
||||
#define TYPE_KIND(k, ...) typedef __VA_ARGS__ GB_JOIN2(Type, k);
|
||||
TYPE_KINDS
|
||||
#undef TYPE_KIND
|
||||
|
||||
typedef struct Type {
|
||||
TypeKind kind;
|
||||
union {
|
||||
BasicType Basic;
|
||||
struct {
|
||||
Type *elem;
|
||||
} Pointer;
|
||||
struct {
|
||||
Type *elem;
|
||||
i64 count;
|
||||
} Array;
|
||||
struct {
|
||||
Type *elem;
|
||||
i64 count;
|
||||
} Vector;
|
||||
struct {
|
||||
Type *elem;
|
||||
} Slice;
|
||||
struct {
|
||||
Type *elem;
|
||||
} Maybe;
|
||||
struct {
|
||||
TypeRecordKind kind;
|
||||
|
||||
// All record types
|
||||
// Theses are arrays
|
||||
Entity **fields; // Entity_Variable (otherwise Entity_TypeName if union)
|
||||
i32 field_count; // == offset_count is struct
|
||||
AstNode *node;
|
||||
|
||||
union { // NOTE(bill): Reduce size_of Type
|
||||
struct { // enum only
|
||||
Type * enum_base; // Default is `int`
|
||||
Entity * enum_count;
|
||||
Entity * min_value;
|
||||
Entity * max_value;
|
||||
};
|
||||
struct { // struct only
|
||||
i64 * struct_offsets;
|
||||
bool struct_are_offsets_set;
|
||||
bool struct_is_packed;
|
||||
bool struct_is_ordered;
|
||||
Entity **fields_in_src_order; // Entity_Variable
|
||||
};
|
||||
};
|
||||
|
||||
// Entity_Constant or Entity_TypeName
|
||||
Entity **other_fields;
|
||||
i32 other_field_count;
|
||||
} Record;
|
||||
struct {
|
||||
String name;
|
||||
Type * base;
|
||||
Entity *type_name; // Entity_TypeName
|
||||
} Named;
|
||||
struct {
|
||||
Entity **variables; // Entity_Variable
|
||||
i32 variable_count;
|
||||
bool are_offsets_set;
|
||||
i64 * offsets;
|
||||
} Tuple;
|
||||
struct {
|
||||
Scope *scope;
|
||||
Type * params; // Type_Tuple
|
||||
Type * results; // Type_Tuple
|
||||
i32 param_count;
|
||||
i32 result_count;
|
||||
bool variadic;
|
||||
} Proc;
|
||||
#define TYPE_KIND(k, ...) GB_JOIN2(Type, k) k;
|
||||
TYPE_KINDS
|
||||
#undef TYPE_KIND
|
||||
};
|
||||
} Type;
|
||||
|
||||
@@ -186,9 +172,9 @@ typedef Array(isize) Array_isize;
|
||||
typedef struct Selection {
|
||||
Entity * entity;
|
||||
Array_isize index;
|
||||
bool indirect; // Set if there was a pointer deref anywhere down the line
|
||||
bool indirect; // Set if there was a pointer deref anywhere down the line
|
||||
} Selection;
|
||||
Selection empty_selection = {};
|
||||
Selection empty_selection = {0};
|
||||
|
||||
Selection make_selection(Entity *entity, Array_isize index, bool indirect) {
|
||||
Selection s = {entity, index, indirect};
|
||||
|
||||
-303
@@ -246,306 +246,3 @@ i16 f32_to_f16(f32 value) {
|
||||
#define MAP_FUNC map_isize_
|
||||
#define MAP_NAME MapIsize
|
||||
#include "map.c"
|
||||
|
||||
|
||||
#if 0
|
||||
#ifndef MAP_FIND_RESULT
|
||||
#define MAP_FIND_RESULT
|
||||
typedef struct MapFindResult {
|
||||
isize hash_index;
|
||||
isize entry_prev;
|
||||
isize entry_index;
|
||||
} MapFindResult;
|
||||
#endif
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct MapEntry {
|
||||
HashKey key;
|
||||
isize next;
|
||||
T value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Map {
|
||||
Array(isize) hashes;
|
||||
Array(MapEntry<T>) entries;
|
||||
};
|
||||
|
||||
template <typename T> void map_init (Map<T> *h, gbAllocator a);
|
||||
template <typename T> void map_init_with_reserve(Map<T> *h, gbAllocator a, isize capacity);
|
||||
template <typename T> void map_destroy (Map<T> *h);
|
||||
template <typename T> T * map_get (Map<T> *h, HashKey key);
|
||||
template <typename T> void map_set (Map<T> *h, HashKey key, T value);
|
||||
template <typename T> void map_remove (Map<T> *h, HashKey key);
|
||||
template <typename T> void map_clear (Map<T> *h);
|
||||
template <typename T> void map_grow (Map<T> *h);
|
||||
template <typename T> void map_rehash (Map<T> *h, isize new_count);
|
||||
|
||||
template <typename T> MapEntry<T> *multi_map_find_first(Map<T> *h, HashKey key);
|
||||
template <typename T> MapEntry<T> *multi_map_find_next (Map<T> *h, MapEntry<T> *e);
|
||||
|
||||
template <typename T> isize multi_map_count (Map<T> *h, HashKey key);
|
||||
template <typename T> void multi_map_get_all (Map<T> *h, HashKey key, T *items);
|
||||
template <typename T> void multi_map_insert (Map<T> *h, HashKey key, T value);
|
||||
template <typename T> void multi_map_remove (Map<T> *h, HashKey key, MapEntry<T> *e);
|
||||
template <typename T> void multi_map_remove_all(Map<T> *h, HashKey key);
|
||||
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
gb_inline void map_init(Map<T> *h, gbAllocator a) {
|
||||
array_init(&h->hashes, a);
|
||||
array_init(&h->entries, a);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline void map_init_with_reserve(Map<T> *h, gbAllocator a, isize capacity) {
|
||||
array_init_reserve(&h->hashes, a, capacity);
|
||||
array_init_reserve(&h->entries, a, capacity);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline void map_destroy(Map<T> *h) {
|
||||
array_free(&h->entries);
|
||||
array_free(&h->hashes);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_internal isize map__add_entry(Map<T> *h, HashKey key) {
|
||||
MapEntry<T> e = {};
|
||||
e.key = key;
|
||||
e.next = -1;
|
||||
array_add(&h->entries, e);
|
||||
return h->entries.count-1;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_internal MapFindResult map__find(Map<T> *h, HashKey key) {
|
||||
MapFindResult fr = {-1, -1, -1};
|
||||
if (h->hashes.count > 0) {
|
||||
fr.hash_index = key.key % h->hashes.count;
|
||||
fr.entry_index = h->hashes.e[fr.hash_index];
|
||||
while (fr.entry_index >= 0) {
|
||||
if (hash_key_equal(h->entries.e[fr.entry_index].key, key)) {
|
||||
return fr;
|
||||
}
|
||||
fr.entry_prev = fr.entry_index;
|
||||
fr.entry_index = h->entries.e[fr.entry_index].next;
|
||||
}
|
||||
}
|
||||
return fr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_internal MapFindResult map__find(Map<T> *h, MapEntry<T> *e) {
|
||||
MapFindResult fr = {-1, -1, -1};
|
||||
if (h->hashes.count > 0) {
|
||||
fr.hash_index = e->key.key % h->hashes.count;
|
||||
fr.entry_index = h->hashes.e[fr.hash_index];
|
||||
while (fr.entry_index >= 0) {
|
||||
if (&h->entries.e[fr.entry_index] == e) {
|
||||
return fr;
|
||||
}
|
||||
fr.entry_prev = fr.entry_index;
|
||||
fr.entry_index = h->entries.e[fr.entry_index].next;
|
||||
}
|
||||
}
|
||||
return fr;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
gb_internal bool map__full(Map<T> *h) {
|
||||
return 0.75f * h->hashes.count <= h->entries.count;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline void map_grow(Map<T> *h) {
|
||||
isize new_count = GB_ARRAY_GROW_FORMULA(h->entries.count);
|
||||
map_rehash(h, new_count);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void map_rehash(Map<T> *h, isize new_count) {
|
||||
isize i, j;
|
||||
Map<T> nh = {0};
|
||||
map_init(&nh, h->hashes.allocator);
|
||||
array_resize(&nh.hashes, new_count);
|
||||
array_reserve(&nh.entries, h->entries.count);
|
||||
for (i = 0; i < new_count; i++) {
|
||||
nh.hashes.e[i] = -1;
|
||||
}
|
||||
for (i = 0; i < h->entries.count; i++) {
|
||||
MapEntry<T> *e = &h->entries.e[i];
|
||||
MapFindResult fr;
|
||||
if (nh.hashes.count == 0) {
|
||||
map_grow(&nh);
|
||||
}
|
||||
fr = map__find(&nh, e->key);
|
||||
j = map__add_entry(&nh, e->key);
|
||||
if (fr.entry_prev < 0) {
|
||||
nh.hashes.e[fr.hash_index] = j;
|
||||
} else {
|
||||
nh.entries.e[fr.entry_prev].next = j;
|
||||
}
|
||||
nh.entries.e[j].next = fr.entry_index;
|
||||
nh.entries.e[j].value = e->value;
|
||||
if (map__full(&nh)) {
|
||||
map_grow(&nh);
|
||||
}
|
||||
}
|
||||
map_destroy(h);
|
||||
*h = nh;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline T *map_get(Map<T> *h, HashKey key) {
|
||||
isize index = map__find(h, key).entry_index;
|
||||
if (index >= 0)
|
||||
return &h->entries.e[index].value;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void map_set(Map<T> *h, HashKey key, T value) {
|
||||
isize index;
|
||||
MapFindResult fr;
|
||||
if (h->hashes.count == 0)
|
||||
map_grow(h);
|
||||
fr = map__find(h, key);
|
||||
if (fr.entry_index >= 0) {
|
||||
index = fr.entry_index;
|
||||
} else {
|
||||
index = map__add_entry(h, key);
|
||||
if (fr.entry_prev >= 0) {
|
||||
h->entries.e[fr.entry_prev].next = index;
|
||||
} else {
|
||||
h->hashes.e[fr.hash_index] = index;
|
||||
}
|
||||
}
|
||||
h->entries.e[index].value = value;
|
||||
|
||||
if (map__full(h))
|
||||
map_grow(h);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
void map__erase(Map<T> *h, MapFindResult fr) {
|
||||
if (fr.entry_prev < 0) {
|
||||
h->hashes.e[fr.hash_index] = h->entries.e[fr.entry_index].next;
|
||||
} else {
|
||||
h->entries.e[fr.entry_prev].next = h->entries.e[fr.entry_index].next;
|
||||
}
|
||||
if (fr.entry_index == h->entries.count-1) {
|
||||
array_pop(&h->entries);
|
||||
return;
|
||||
}
|
||||
h->entries.e[fr.entry_index] = h->entries.e[h->entries.count-1];
|
||||
MapFindResult last = map__find(h, h->entries.e[fr.entry_index].key);
|
||||
if (last.entry_prev >= 0) {
|
||||
h->entries.e[last.entry_prev].next = fr.entry_index;
|
||||
} else {
|
||||
h->hashes.e[last.hash_index] = fr.entry_index;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void map_remove(Map<T> *h, HashKey key) {
|
||||
MapFindResult fr = map__find(h, key);
|
||||
if (fr.entry_index >= 0) {
|
||||
map__erase(h, fr);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gb_inline void map_clear(Map<T> *h) {
|
||||
gb_array_clear(h->hashes);
|
||||
gb_array_clear(h->entries);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
MapEntry<T> *multi_map_find_first(Map<T> *h, HashKey key) {
|
||||
isize i = map__find(h, key).entry_index;
|
||||
if (i < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return &h->entries.e[i];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
MapEntry<T> *multi_map_find_next(Map<T> *h, MapEntry<T> *e) {
|
||||
isize i = e->next;
|
||||
while (i >= 0) {
|
||||
if (hash_key_equal(h->entries.e[i].key, e->key)) {
|
||||
return &h->entries.e[i];
|
||||
}
|
||||
i = h->entries.e[i].next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
isize multi_map_count(Map<T> *h, HashKey key) {
|
||||
isize count = 0;
|
||||
auto *e = multi_map_find_first(h, key);
|
||||
while (e != NULL) {
|
||||
count++;
|
||||
e = multi_map_find_next(h, e);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void multi_map_get_all(Map<T> *h, HashKey key, T *items) {
|
||||
isize i = 0;
|
||||
auto *e = multi_map_find_first(h, key);
|
||||
while (e != NULL) {
|
||||
items[i++] = e->value;
|
||||
e = multi_map_find_next(h, e);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void multi_map_insert(Map<T> *h, HashKey key, T value) {
|
||||
if (h->hashes.count == 0) {
|
||||
map_grow(h);
|
||||
}
|
||||
MapFindResult fr = map__find(h, key);
|
||||
isize i = map__add_entry(h, key);
|
||||
if (fr.entry_prev < 0) {
|
||||
h->hashes.e[fr.hash_index] = i;
|
||||
} else {
|
||||
h->entries.e[fr.entry_prev].next = i;
|
||||
}
|
||||
h->entries.e[i].next = fr.entry_index;
|
||||
h->entries.e[i].value = value;
|
||||
if (map__full(h)) {
|
||||
map_grow(h);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void multi_map_remove(Map<T> *h, HashKey key, MapEntry<T> *e) {
|
||||
MapFindResult fr = map__find(h, e);
|
||||
if (fr.entry_index >= 0) {
|
||||
map__erase(h, fr);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void multi_map_remove_all(Map<T> *h, HashKey key) {
|
||||
while (map_get(h, key) != NULL) {
|
||||
map_remove(h, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
Example of usage:
|
||||
|
||||
#define MAP_TYPE String
|
||||
#define MAP_FUNC map_string_
|
||||
#define MAP_NAME MapString
|
||||
#include "map.c"
|
||||
*/
|
||||
|
||||
#ifndef MAP_FIND_RESULT
|
||||
#define MAP_FIND_RESULT
|
||||
// NOTE(bill): This is the same for every `Map`
|
||||
typedef struct MapFindResult {
|
||||
isize hash_index;
|
||||
isize entry_prev;
|
||||
isize entry_index;
|
||||
} MapFindResult;
|
||||
#endif
|
||||
|
||||
#define _J2(a,b) GB_JOIN2(a,b)
|
||||
|
||||
/*
|
||||
MAP_TYPE - Entry type
|
||||
MAP_FUNC - Function prefix (e.g. entity_map_)
|
||||
MAP_NAME - Name of Map (e.g. EntityMap)
|
||||
*/
|
||||
#define MAP_ENTRY _J2(MAP_NAME,Entry)
|
||||
|
||||
typedef struct MAP_ENTRY {
|
||||
HashKey key;
|
||||
isize next;
|
||||
MAP_TYPE value;
|
||||
} MAP_ENTRY;
|
||||
|
||||
typedef struct MAP_NAME {
|
||||
Array(isize) hashes;
|
||||
Array(MAP_ENTRY) entries;
|
||||
} MAP_NAME;
|
||||
|
||||
void _J2(MAP_FUNC,init) (MAP_NAME *h, gbAllocator a);
|
||||
void _J2(MAP_FUNC,init_with_reserve)(MAP_NAME *h, gbAllocator a, isize capacity);
|
||||
void _J2(MAP_FUNC,destroy) (MAP_NAME *h);
|
||||
MAP_TYPE *_J2(MAP_FUNC,get) (MAP_NAME *h, HashKey key);
|
||||
void _J2(MAP_FUNC,set) (MAP_NAME *h, HashKey key, MAP_TYPE value);
|
||||
void _J2(MAP_FUNC,remove) (MAP_NAME *h, HashKey key);
|
||||
void _J2(MAP_FUNC,clear) (MAP_NAME *h);
|
||||
void _J2(MAP_FUNC,grow) (MAP_NAME *h);
|
||||
void _J2(MAP_FUNC,rehash) (MAP_NAME *h, isize new_count);
|
||||
|
||||
#if 1
|
||||
MAP_ENTRY *_J2(MAP_FUNC,multi_find_first)(MAP_NAME *h, HashKey key);
|
||||
MAP_ENTRY *_J2(MAP_FUNC,multi_find_next) (MAP_NAME *h, MAP_ENTRY *e);
|
||||
|
||||
isize _J2(MAP_FUNC,multi_count) (MAP_NAME *h, HashKey key);
|
||||
void _J2(MAP_FUNC,multi_get_all) (MAP_NAME *h, HashKey key, MAP_TYPE *items);
|
||||
void _J2(MAP_FUNC,multi_insert) (MAP_NAME *h, HashKey key, MAP_TYPE value);
|
||||
void _J2(MAP_FUNC,multi_remove) (MAP_NAME *h, HashKey key, MAP_ENTRY *e);
|
||||
void _J2(MAP_FUNC,multi_remove_all)(MAP_NAME *h, HashKey key);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
gb_inline void _J2(MAP_FUNC,init)(MAP_NAME *h, gbAllocator a) {
|
||||
array_init(&h->hashes, a);
|
||||
array_init(&h->entries, a);
|
||||
}
|
||||
|
||||
gb_inline void _J2(MAP_FUNC,init_with_reserve)(MAP_NAME *h, gbAllocator a, isize capacity) {
|
||||
array_init_reserve(&h->hashes, a, capacity);
|
||||
array_init_reserve(&h->entries, a, capacity);
|
||||
}
|
||||
|
||||
gb_inline void _J2(MAP_FUNC,destroy)(MAP_NAME *h) {
|
||||
array_free(&h->entries);
|
||||
array_free(&h->hashes);
|
||||
}
|
||||
|
||||
gb_internal isize _J2(MAP_FUNC,_add_entry)(MAP_NAME *h, HashKey key) {
|
||||
MAP_ENTRY e = {};
|
||||
e.key = key;
|
||||
e.next = -1;
|
||||
array_add(&h->entries, e);
|
||||
return h->entries.count-1;
|
||||
}
|
||||
|
||||
gb_internal MapFindResult _J2(MAP_FUNC,_find)(MAP_NAME *h, HashKey key) {
|
||||
MapFindResult fr = {-1, -1, -1};
|
||||
if (h->hashes.count > 0) {
|
||||
fr.hash_index = key.key % h->hashes.count;
|
||||
fr.entry_index = h->hashes.e[fr.hash_index];
|
||||
while (fr.entry_index >= 0) {
|
||||
if (hash_key_equal(h->entries.e[fr.entry_index].key, key)) {
|
||||
return fr;
|
||||
}
|
||||
fr.entry_prev = fr.entry_index;
|
||||
fr.entry_index = h->entries.e[fr.entry_index].next;
|
||||
}
|
||||
}
|
||||
return fr;
|
||||
}
|
||||
|
||||
gb_internal MapFindResult _J2(MAP_FUNC,_find)(MAP_NAME *h, MAP_ENTRY *e) {
|
||||
MapFindResult fr = {-1, -1, -1};
|
||||
if (h->hashes.count > 0) {
|
||||
fr.hash_index = e->key.key % h->hashes.count;
|
||||
fr.entry_index = h->hashes.e[fr.hash_index];
|
||||
while (fr.entry_index >= 0) {
|
||||
if (&h->entries.e[fr.entry_index] == e) {
|
||||
return fr;
|
||||
}
|
||||
fr.entry_prev = fr.entry_index;
|
||||
fr.entry_index = h->entries.e[fr.entry_index].next;
|
||||
}
|
||||
}
|
||||
return fr;
|
||||
}
|
||||
|
||||
|
||||
gb_internal b32 _J2(MAP_FUNC,_full)(MAP_NAME *h) {
|
||||
return 0.75f * h->hashes.count <= h->entries.count;
|
||||
}
|
||||
|
||||
gb_inline void _J2(MAP_FUNC,grow)(MAP_NAME *h) {
|
||||
isize new_count = ARRAY_GROW_FORMULA(h->entries.count);
|
||||
_J2(MAP_FUNC,rehash)(h, new_count);
|
||||
}
|
||||
|
||||
void _J2(MAP_FUNC,rehash)(MAP_NAME *h, isize new_count) {
|
||||
isize i, j;
|
||||
MAP_NAME nh = {0};
|
||||
_J2(MAP_FUNC,init)(&nh, h->hashes.allocator);
|
||||
array_resize(&nh.hashes, new_count);
|
||||
array_reserve(&nh.entries, h->entries.count);
|
||||
for (i = 0; i < new_count; i++) {
|
||||
nh.hashes.e[i] = -1;
|
||||
}
|
||||
for (i = 0; i < h->entries.count; i++) {
|
||||
MAP_ENTRY *e = &h->entries.e[i];
|
||||
MapFindResult fr;
|
||||
if (nh.hashes.count == 0) {
|
||||
_J2(MAP_FUNC,grow)(&nh);
|
||||
}
|
||||
fr = _J2(MAP_FUNC,_find)(&nh, e->key);
|
||||
j = _J2(MAP_FUNC,_add_entry)(&nh, e->key);
|
||||
if (fr.entry_prev < 0) {
|
||||
nh.hashes.e[fr.hash_index] = j;
|
||||
} else {
|
||||
nh.entries.e[fr.entry_prev].next = j;
|
||||
}
|
||||
nh.entries.e[j].next = fr.entry_index;
|
||||
nh.entries.e[j].value = e->value;
|
||||
if (_J2(MAP_FUNC,_full)(&nh)) {
|
||||
_J2(MAP_FUNC,grow)(&nh);
|
||||
}
|
||||
}
|
||||
_J2(MAP_FUNC,destroy)(h);
|
||||
*h = nh;
|
||||
}
|
||||
|
||||
gb_inline MAP_TYPE *_J2(MAP_FUNC,get)(MAP_NAME *h, HashKey key) {
|
||||
isize index = _J2(MAP_FUNC,_find)(h, key).entry_index;
|
||||
if (index >= 0) {
|
||||
return &h->entries.e[index].value;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void _J2(MAP_FUNC,set)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
|
||||
isize index;
|
||||
MapFindResult fr;
|
||||
if (h->hashes.count == 0)
|
||||
_J2(MAP_FUNC,grow)(h);
|
||||
fr = _J2(MAP_FUNC,_find)(h, key);
|
||||
if (fr.entry_index >= 0) {
|
||||
index = fr.entry_index;
|
||||
} else {
|
||||
index = _J2(MAP_FUNC,_add_entry)(h, key);
|
||||
if (fr.entry_prev >= 0) {
|
||||
h->entries.e[fr.entry_prev].next = index;
|
||||
} else {
|
||||
h->hashes.e[fr.hash_index] = index;
|
||||
}
|
||||
}
|
||||
h->entries.e[index].value = value;
|
||||
|
||||
if (_J2(MAP_FUNC,_full)(h)) {
|
||||
_J2(MAP_FUNC,grow)(h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _J2(MAP_FUNC,_erase)(MAP_NAME *h, MapFindResult fr) {
|
||||
if (fr.entry_prev < 0) {
|
||||
h->hashes.e[fr.hash_index] = h->entries.e[fr.entry_index].next;
|
||||
} else {
|
||||
h->entries.e[fr.entry_prev].next = h->entries.e[fr.entry_index].next;
|
||||
}
|
||||
if (fr.entry_index == h->entries.count-1) {
|
||||
array_pop(&h->entries);
|
||||
return;
|
||||
}
|
||||
h->entries.e[fr.entry_index] = h->entries.e[h->entries.count-1];
|
||||
MapFindResult last = _J2(MAP_FUNC,_find)(h, h->entries.e[fr.entry_index].key);
|
||||
if (last.entry_prev >= 0) {
|
||||
h->entries.e[last.entry_prev].next = fr.entry_index;
|
||||
} else {
|
||||
h->hashes.e[last.hash_index] = fr.entry_index;
|
||||
}
|
||||
}
|
||||
|
||||
void _J2(MAP_FUNC,remove)(MAP_NAME *h, HashKey key) {
|
||||
MapFindResult fr = _J2(MAP_FUNC,_find)(h, key);
|
||||
if (fr.entry_index >= 0) {
|
||||
_J2(MAP_FUNC,_erase)(h, fr);
|
||||
}
|
||||
}
|
||||
|
||||
gb_inline void _J2(MAP_FUNC,clear)(MAP_NAME *h) {
|
||||
array_clear(&h->hashes);
|
||||
array_clear(&h->entries);
|
||||
}
|
||||
|
||||
|
||||
#if 1
|
||||
MAP_ENTRY *_J2(MAP_FUNC,multi_find_first)(MAP_NAME *h, HashKey key) {
|
||||
isize i = _J2(MAP_FUNC,_find)(h, key).entry_index;
|
||||
if (i < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return &h->entries.e[i];
|
||||
}
|
||||
|
||||
MAP_ENTRY *_J2(MAP_FUNC,multi_find_next)(MAP_NAME *h, MAP_ENTRY *e) {
|
||||
isize i = e->next;
|
||||
while (i >= 0) {
|
||||
if (hash_key_equal(h->entries.e[i].key, e->key)) {
|
||||
return &h->entries.e[i];
|
||||
}
|
||||
i = h->entries.e[i].next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
isize _J2(MAP_FUNC,multi_count)(MAP_NAME *h, HashKey key) {
|
||||
isize count = 0;
|
||||
auto *e = _J2(MAP_FUNC,multi_find_first)(h, key);
|
||||
while (e != NULL) {
|
||||
count++;
|
||||
e = _J2(MAP_FUNC,multi_find_next)(h, e);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void _J2(MAP_FUNC,multi_get_all)(MAP_NAME *h, HashKey key, MAP_TYPE *items) {
|
||||
isize i = 0;
|
||||
auto *e = _J2(MAP_FUNC,multi_find_first)(h, key);
|
||||
while (e != NULL) {
|
||||
items[i++] = e->value;
|
||||
e = _J2(MAP_FUNC,multi_find_next)(h, e);
|
||||
}
|
||||
}
|
||||
|
||||
void _J2(MAP_FUNC,multi_insert)(MAP_NAME *h, HashKey key, MAP_TYPE value) {
|
||||
if (h->hashes.count == 0) {
|
||||
_J2(MAP_FUNC,grow)(h);
|
||||
}
|
||||
MapFindResult fr = _J2(MAP_FUNC,_find)(h, key);
|
||||
isize i = _J2(MAP_FUNC,_add_entry)(h, key);
|
||||
if (fr.entry_prev < 0) {
|
||||
h->hashes.e[fr.hash_index] = i;
|
||||
} else {
|
||||
h->entries.e[fr.entry_prev].next = i;
|
||||
}
|
||||
h->entries.e[i].next = fr.entry_index;
|
||||
h->entries.e[i].value = value;
|
||||
if (_J2(MAP_FUNC,_full)(h)) {
|
||||
_J2(MAP_FUNC,grow)(h);
|
||||
}
|
||||
}
|
||||
|
||||
void _J2(MAP_FUNC,multi_remove)(MAP_NAME *h, HashKey key, MAP_ENTRY *e) {
|
||||
MapFindResult fr = _J2(MAP_FUNC,_find)(h, e);
|
||||
if (fr.entry_index >= 0) {
|
||||
_J2(MAP_FUNC,_erase)(h, fr);
|
||||
}
|
||||
}
|
||||
|
||||
void _J2(MAP_FUNC,multi_remove_all)(MAP_NAME *h, HashKey key) {
|
||||
while (_J2(MAP_FUNC,get)(h, key) != NULL) {
|
||||
_J2(MAP_FUNC,remove)(h, key);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef _J2
|
||||
#undef MAP_TYPE
|
||||
#undef MAP_FUNC
|
||||
#undef MAP_NAME
|
||||
#undef MAP_ENTRY
|
||||
+5
-5
@@ -430,7 +430,7 @@ vmValue vm_operand_value(VirtualMachine *vm, ssaValue *value) {
|
||||
v = vm_exact_value(vm, value, value->Constant.value, value->Constant.type);
|
||||
} break;
|
||||
case ssaValue_ConstantSlice: {
|
||||
auto *cs = &value->ConstantSlice;
|
||||
ssaValueConstant *cs = &value->ConstantSlice;
|
||||
v = vm_make_value_comp(ssa_type(value), vm->stack_allocator, 3);
|
||||
v.val_comp[0] = vm_operand_value(vm, cs->backing_array);
|
||||
v.val_comp[1] = vm_make_value_int(t_int, cs->count);
|
||||
@@ -1120,7 +1120,7 @@ void vm_exec_instr(VirtualMachine *vm, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_BinaryOp: {
|
||||
auto *bo = &instr->BinaryOp;
|
||||
ssaInstrBinaryOp *bo = &instr->BinaryOp;
|
||||
Type *type = ssa_type(bo->left);
|
||||
vmValue lhs = vm_operand_value(vm, bo->left);
|
||||
vmValue rhs = vm_operand_value(vm, bo->right);
|
||||
@@ -1171,7 +1171,7 @@ void vm_exec_instr(VirtualMachine *vm, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_VectorShuffle: {
|
||||
auto *vs = &instr->VectorShuffle;
|
||||
ssaValueVectorShuffle *vs = &instr->VectorShuffle;
|
||||
vmValue old_vector = vm_operand_value(vm, instr->VectorShuffle.vector);
|
||||
vmValue new_vector = vm_make_value_comp(ssa_type(value), vm->stack_allocator, vs->index_count);
|
||||
|
||||
@@ -1183,7 +1183,7 @@ void vm_exec_instr(VirtualMachine *vm, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_BoundsCheck: {
|
||||
auto *bc = &instr->BoundsCheck;
|
||||
ssaInstrBoundsCheck *bc = &instr->BoundsCheck;
|
||||
Array<vmValue> args = {};
|
||||
array_init(&args, vm->stack_allocator, 5);
|
||||
array_add(&args, vm_exact_value(vm, NULL, make_exact_value_string(bc->pos.file), t_string));
|
||||
@@ -1196,7 +1196,7 @@ void vm_exec_instr(VirtualMachine *vm, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_SliceBoundsCheck: {
|
||||
auto *bc = &instr->SliceBoundsCheck;
|
||||
ssaInstrSliceBoundsCheck *bc = &instr->SliceBoundsCheck;
|
||||
Array<vmValue> args = {};
|
||||
|
||||
array_init(&args, vm->stack_allocator, 7);
|
||||
|
||||
+6
-5
@@ -101,7 +101,6 @@ AstNodeArray make_ast_node_array(AstFile *f) {
|
||||
|
||||
|
||||
#define AST_NODE_KINDS \
|
||||
AST_NODE_KIND(Invalid, "invalid node", struct{}) \
|
||||
AST_NODE_KIND(BasicLit, "basic literal", Token) \
|
||||
AST_NODE_KIND(Ident, "identifier", Token) \
|
||||
AST_NODE_KIND(Ellipsis, "ellipsis", struct { \
|
||||
@@ -317,16 +316,18 @@ AST_NODE_KIND(_TypeBegin, "", struct{}) \
|
||||
AstNode *base_type; \
|
||||
AstNodeArray fields; \
|
||||
}) \
|
||||
AST_NODE_KIND(_TypeEnd, "", struct{}) \
|
||||
AST_NODE_KIND(Count, "", struct{})
|
||||
AST_NODE_KIND(_TypeEnd, "", struct{})
|
||||
|
||||
typedef enum AstNodeKind {
|
||||
AstNode_Invalid,
|
||||
#define AST_NODE_KIND(_kind_name_, ...) GB_JOIN2(AstNode_, _kind_name_),
|
||||
AST_NODE_KINDS
|
||||
#undef AST_NODE_KIND
|
||||
AstNode_Count,
|
||||
} AstNodeKind;
|
||||
|
||||
String const ast_node_strings[] = {
|
||||
{cast(u8 *)"invalid node", gb_size_of("invalid node")},
|
||||
#define AST_NODE_KIND(_kind_name_, name, ...) {cast(u8 *)name, gb_size_of(name)-1},
|
||||
AST_NODE_KINDS
|
||||
#undef AST_NODE_KIND
|
||||
@@ -3101,7 +3102,7 @@ void parse_file(Parser *p, AstFile *f) {
|
||||
syntax_error(ast_node_token(node), "Only declarations are allowed at file scope");
|
||||
} else {
|
||||
if (node->kind == AstNode_ImportDecl) {
|
||||
auto *id = &node->ImportDecl;
|
||||
AstNodeImportDecl *id = &node->ImportDecl;
|
||||
String file_str = id->relpath.string;
|
||||
|
||||
if (!is_import_path_valid(file_str)) {
|
||||
@@ -3130,7 +3131,7 @@ void parse_file(Parser *p, AstFile *f) {
|
||||
try_add_import_path(p, import_file, file_str, ast_node_token(node).pos);
|
||||
|
||||
} else if (node->kind == AstNode_ForeignLibrary) {
|
||||
auto *id = &node->ForeignLibrary;
|
||||
AstNodeForeignLibrary *id = &node->ForeignLibrary;
|
||||
String file_str = id->filepath.string;
|
||||
|
||||
if (!is_import_path_valid(file_str)) {
|
||||
|
||||
+182
-211
@@ -131,73 +131,152 @@ struct ssaProcedure {
|
||||
|
||||
|
||||
#define SSA_INSTR_KINDS \
|
||||
SSA_INSTR_KIND(Invalid), \
|
||||
SSA_INSTR_KIND(Comment), \
|
||||
SSA_INSTR_KIND(Local), \
|
||||
SSA_INSTR_KIND(ZeroInit), \
|
||||
SSA_INSTR_KIND(Store), \
|
||||
SSA_INSTR_KIND(Load), \
|
||||
SSA_INSTR_KIND(PtrOffset), \
|
||||
SSA_INSTR_KIND(ArrayElementPtr), \
|
||||
SSA_INSTR_KIND(StructElementPtr), \
|
||||
SSA_INSTR_KIND(ArrayExtractValue), \
|
||||
SSA_INSTR_KIND(StructExtractValue), \
|
||||
SSA_INSTR_KIND(UnionTagPtr), \
|
||||
SSA_INSTR_KIND(UnionTagValue), \
|
||||
SSA_INSTR_KIND(Conv), \
|
||||
SSA_INSTR_KIND(Jump), \
|
||||
SSA_INSTR_KIND(If), \
|
||||
SSA_INSTR_KIND(Return), \
|
||||
SSA_INSTR_KIND(Select), \
|
||||
SSA_INSTR_KIND(Phi), \
|
||||
SSA_INSTR_KIND(Unreachable), \
|
||||
SSA_INSTR_KIND(BinaryOp), \
|
||||
SSA_INSTR_KIND(Call), \
|
||||
SSA_INSTR_KIND(VectorExtractElement), \
|
||||
SSA_INSTR_KIND(VectorInsertElement), \
|
||||
SSA_INSTR_KIND(VectorShuffle), \
|
||||
SSA_INSTR_KIND(StartupRuntime), \
|
||||
SSA_INSTR_KIND(BoundsCheck), \
|
||||
SSA_INSTR_KIND(SliceBoundsCheck), \
|
||||
SSA_INSTR_KIND(Comment, struct { String text; }) \
|
||||
SSA_INSTR_KIND(Local, struct { \
|
||||
Entity * entity; \
|
||||
Type * type; \
|
||||
bool zero_initialized; \
|
||||
ssaValueArray referrers; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(ZeroInit, struct { ssaValue *address; }) \
|
||||
SSA_INSTR_KIND(Store, struct { ssaValue *address, *value; }) \
|
||||
SSA_INSTR_KIND(Load, struct { Type *type; ssaValue *address; }) \
|
||||
SSA_INSTR_KIND(PtrOffset, struct { \
|
||||
ssaValue *address; \
|
||||
ssaValue *offset; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(ArrayElementPtr, struct { \
|
||||
ssaValue *address; \
|
||||
Type * result_type; \
|
||||
ssaValue *elem_index; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(StructElementPtr, struct { \
|
||||
ssaValue *address; \
|
||||
Type * result_type; \
|
||||
i32 elem_index; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(ArrayExtractValue, struct { \
|
||||
ssaValue *address; \
|
||||
Type * result_type; \
|
||||
i32 index; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(StructExtractValue, struct { \
|
||||
ssaValue *address; \
|
||||
Type * result_type; \
|
||||
i32 index; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(UnionTagPtr, struct { \
|
||||
ssaValue *address; \
|
||||
Type *type; /* ^int */ \
|
||||
}) \
|
||||
SSA_INSTR_KIND(UnionTagValue, struct { \
|
||||
ssaValue *address; \
|
||||
Type *type; /* int */ \
|
||||
}) \
|
||||
SSA_INSTR_KIND(Conv, struct { \
|
||||
ssaConvKind kind; \
|
||||
ssaValue *value; \
|
||||
Type *from, *to; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(Jump, struct { ssaBlock *block; }) \
|
||||
SSA_INSTR_KIND(If, struct { \
|
||||
ssaValue *cond; \
|
||||
ssaBlock *true_block; \
|
||||
ssaBlock *false_block; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(Return, struct { ssaValue *value; }) \
|
||||
SSA_INSTR_KIND(Select, struct { \
|
||||
ssaValue *cond; \
|
||||
ssaValue *true_value; \
|
||||
ssaValue *false_value; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(Phi, struct { ssaValueArray edges; Type *type; }) \
|
||||
SSA_INSTR_KIND(Unreachable, struct {}) \
|
||||
SSA_INSTR_KIND(BinaryOp, struct { \
|
||||
Type * type; \
|
||||
TokenKind op; \
|
||||
ssaValue *left, *right; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(Call, struct { \
|
||||
Type * type; /* return type */ \
|
||||
ssaValue *value; \
|
||||
ssaValue **args; \
|
||||
isize arg_count; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(VectorExtractElement, struct { \
|
||||
ssaValue *vector; \
|
||||
ssaValue *index; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(VectorInsertElement, struct { \
|
||||
ssaValue *vector; \
|
||||
ssaValue *elem; \
|
||||
ssaValue *index; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(VectorShuffle, struct { \
|
||||
ssaValue *vector; \
|
||||
i32 * indices; \
|
||||
i32 index_count; \
|
||||
Type * type; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(StartupRuntime, struct {}) \
|
||||
SSA_INSTR_KIND(BoundsCheck, struct { \
|
||||
TokenPos pos; \
|
||||
ssaValue *index; \
|
||||
ssaValue *len; \
|
||||
}) \
|
||||
SSA_INSTR_KIND(SliceBoundsCheck, struct { \
|
||||
TokenPos pos; \
|
||||
ssaValue *low; \
|
||||
ssaValue *high; \
|
||||
ssaValue *max; \
|
||||
bool is_substring; \
|
||||
})
|
||||
|
||||
#define SSA_CONV_KINDS \
|
||||
SSA_CONV_KIND(Invalid), \
|
||||
SSA_CONV_KIND(trunc), \
|
||||
SSA_CONV_KIND(zext), \
|
||||
SSA_CONV_KIND(fptrunc), \
|
||||
SSA_CONV_KIND(fpext), \
|
||||
SSA_CONV_KIND(fptoui), \
|
||||
SSA_CONV_KIND(fptosi), \
|
||||
SSA_CONV_KIND(uitofp), \
|
||||
SSA_CONV_KIND(sitofp), \
|
||||
SSA_CONV_KIND(ptrtoint), \
|
||||
SSA_CONV_KIND(inttoptr), \
|
||||
SSA_CONV_KIND(bitcast),
|
||||
SSA_CONV_KIND(trunc) \
|
||||
SSA_CONV_KIND(zext) \
|
||||
SSA_CONV_KIND(fptrunc) \
|
||||
SSA_CONV_KIND(fpext) \
|
||||
SSA_CONV_KIND(fptoui) \
|
||||
SSA_CONV_KIND(fptosi) \
|
||||
SSA_CONV_KIND(uitofp) \
|
||||
SSA_CONV_KIND(sitofp) \
|
||||
SSA_CONV_KIND(ptrtoint) \
|
||||
SSA_CONV_KIND(inttoptr) \
|
||||
SSA_CONV_KIND(bitcast)
|
||||
|
||||
typedef enum ssaInstrKind {
|
||||
#define SSA_INSTR_KIND(x) GB_JOIN2(ssaInstr_, x)
|
||||
ssaInstr_Invalid,
|
||||
#define SSA_INSTR_KIND(x, ...) GB_JOIN2(ssaInstr_, x),
|
||||
SSA_INSTR_KINDS
|
||||
#undef SSA_INSTR_KIND
|
||||
} ssaInstrKind;
|
||||
|
||||
String const ssa_instr_strings[] = {
|
||||
#define SSA_INSTR_KIND(x) {cast(u8 *)#x, gb_size_of(#x)-1}
|
||||
{cast(u8 *)"Invalid", gb_size_of("Invalid")-1},
|
||||
#define SSA_INSTR_KIND(x, ...) {cast(u8 *)#x, gb_size_of(#x)-1},
|
||||
SSA_INSTR_KINDS
|
||||
#undef SSA_INSTR_KIND
|
||||
};
|
||||
|
||||
typedef enum ssaConvKind {
|
||||
#define SSA_CONV_KIND(x) GB_JOIN2(ssaConv_, x)
|
||||
ssaConv_Invalid,
|
||||
#define SSA_CONV_KIND(x) GB_JOIN2(ssaConv_, x),
|
||||
SSA_CONV_KINDS
|
||||
#undef SSA_CONV_KIND
|
||||
} ssaConvKind;
|
||||
|
||||
String const ssa_conv_strings[] = {
|
||||
#define SSA_CONV_KIND(x) {cast(u8 *)#x, gb_size_of(#x)-1}
|
||||
{cast(u8 *)"Invalid", gb_size_of("Invalid")-1},
|
||||
#define SSA_CONV_KIND(x) {cast(u8 *)#x, gb_size_of(#x)-1},
|
||||
SSA_CONV_KINDS
|
||||
#undef SSA_CONV_KIND
|
||||
};
|
||||
|
||||
#define SSA_INSTR_KIND(k, ...) typedef __VA_ARGS__ GB_JOIN2(ssaInstr, k);
|
||||
SSA_INSTR_KINDS
|
||||
#undef SSA_INSTR_KIND
|
||||
|
||||
typedef struct ssaInstr ssaInstr;
|
||||
struct ssaInstr {
|
||||
ssaInstrKind kind;
|
||||
@@ -206,129 +285,9 @@ struct ssaInstr {
|
||||
Type *type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
String text;
|
||||
} Comment;
|
||||
struct {
|
||||
Entity * entity;
|
||||
Type * type;
|
||||
bool zero_initialized;
|
||||
ssaValueArray referrers;
|
||||
} Local;
|
||||
struct {
|
||||
ssaValue *address;
|
||||
} ZeroInit;
|
||||
struct {
|
||||
ssaValue *address;
|
||||
ssaValue *value;
|
||||
} Store;
|
||||
struct {
|
||||
Type *type;
|
||||
ssaValue *address;
|
||||
} Load;
|
||||
struct {
|
||||
ssaValue *address;
|
||||
Type * result_type;
|
||||
ssaValue *elem_index;
|
||||
} ArrayElementPtr;
|
||||
struct {
|
||||
ssaValue *address;
|
||||
Type * result_type;
|
||||
i32 elem_index;
|
||||
} StructElementPtr;
|
||||
struct {
|
||||
ssaValue *address;
|
||||
ssaValue *offset;
|
||||
} PtrOffset;
|
||||
struct {
|
||||
ssaValue *address;
|
||||
Type * result_type;
|
||||
i32 index;
|
||||
} ArrayExtractValue;
|
||||
struct {
|
||||
ssaValue *address;
|
||||
Type * result_type;
|
||||
i32 index;
|
||||
} StructExtractValue;
|
||||
struct {
|
||||
ssaValue *address;
|
||||
Type *type; // ^int
|
||||
} UnionTagPtr;
|
||||
struct {
|
||||
ssaValue *address;
|
||||
Type *type; // int
|
||||
} UnionTagValue;
|
||||
struct {
|
||||
ssaValue *value;
|
||||
ssaValue *elem;
|
||||
i32 index;
|
||||
} InsertValue;
|
||||
struct {
|
||||
ssaConvKind kind;
|
||||
ssaValue *value;
|
||||
Type *from, *to;
|
||||
} Conv;
|
||||
struct {
|
||||
ssaBlock *block;
|
||||
} Jump;
|
||||
struct {
|
||||
ssaValue *cond;
|
||||
ssaBlock *true_block;
|
||||
ssaBlock *false_block;
|
||||
} If;
|
||||
struct {
|
||||
ssaValue *value;
|
||||
} Return;
|
||||
struct {} Unreachable;
|
||||
struct {
|
||||
ssaValue *cond;
|
||||
ssaValue *true_value;
|
||||
ssaValue *false_value;
|
||||
} Select;
|
||||
struct {
|
||||
ssaValueArray edges;
|
||||
Type *type;
|
||||
} Phi;
|
||||
struct {
|
||||
Type *type;
|
||||
TokenKind op;
|
||||
ssaValue *left, *right;
|
||||
} BinaryOp;
|
||||
struct {
|
||||
Type *type; // return type
|
||||
ssaValue *value;
|
||||
ssaValue **args;
|
||||
isize arg_count;
|
||||
} Call;
|
||||
struct {
|
||||
ssaValue *vector;
|
||||
ssaValue *index;
|
||||
} VectorExtractElement;
|
||||
struct {
|
||||
ssaValue *vector;
|
||||
ssaValue *elem;
|
||||
ssaValue *index;
|
||||
} VectorInsertElement;
|
||||
struct {
|
||||
ssaValue *vector;
|
||||
i32 *indices;
|
||||
i32 index_count;
|
||||
Type *type;
|
||||
} VectorShuffle;
|
||||
|
||||
struct {} StartupRuntime;
|
||||
struct {
|
||||
TokenPos pos;
|
||||
ssaValue *index;
|
||||
ssaValue *len;
|
||||
} BoundsCheck;
|
||||
struct {
|
||||
TokenPos pos;
|
||||
ssaValue *low;
|
||||
ssaValue *high;
|
||||
ssaValue *max;
|
||||
bool is_substring;
|
||||
} SliceBoundsCheck;
|
||||
#define SSA_INSTR_KIND(k, ...) GB_JOIN2(ssaInstr, k) k;
|
||||
SSA_INSTR_KINDS
|
||||
#undef SSA_INSTR_KIND
|
||||
};
|
||||
};
|
||||
|
||||
@@ -350,45 +309,57 @@ typedef enum ssaValueKind {
|
||||
ssaValue_Count,
|
||||
} ssaValueKind;
|
||||
|
||||
typedef struct ssaValueConstant {
|
||||
Type * type;
|
||||
ExactValue value;
|
||||
} ssaValueConstant;
|
||||
|
||||
typedef struct ssaValueConstantSlice {
|
||||
Type * type;
|
||||
ssaValue *backing_array;
|
||||
i64 count;
|
||||
} ssaValueConstantSlice;
|
||||
|
||||
typedef struct ssaValueNil {
|
||||
Type *type;
|
||||
} ssaValueNil;
|
||||
|
||||
typedef struct ssaValueTypeName {
|
||||
Type * type;
|
||||
String name;
|
||||
} ssaValueTypeName;
|
||||
|
||||
typedef struct ssaValueGlobal {
|
||||
Entity * entity;
|
||||
Type * type;
|
||||
ssaValue * value;
|
||||
ssaValueArray referrers;
|
||||
bool is_constant;
|
||||
bool is_private;
|
||||
bool is_thread_local;
|
||||
bool is_unnamed_addr;
|
||||
} ssaValueGlobal;
|
||||
|
||||
typedef struct ssaValueParam {
|
||||
ssaProcedure *parent;
|
||||
Entity * entity;
|
||||
Type * type;
|
||||
ssaValueArray referrers;
|
||||
} ssaValueParam;
|
||||
|
||||
typedef struct ssaValue {
|
||||
ssaValueKind kind;
|
||||
i32 index;
|
||||
union {
|
||||
struct {
|
||||
Type * type;
|
||||
ExactValue value;
|
||||
} Constant;
|
||||
struct {
|
||||
Type * type;
|
||||
ssaValue *backing_array;
|
||||
i64 count;
|
||||
} ConstantSlice;
|
||||
struct {
|
||||
Type *type;
|
||||
} Nil;
|
||||
struct {
|
||||
Type * type;
|
||||
String name;
|
||||
} TypeName;
|
||||
struct {
|
||||
Entity * entity;
|
||||
Type * type;
|
||||
ssaValue * value;
|
||||
ssaValueArray referrers;
|
||||
bool is_constant;
|
||||
bool is_private;
|
||||
bool is_thread_local;
|
||||
bool is_unnamed_addr;
|
||||
} Global;
|
||||
struct {
|
||||
ssaProcedure * parent;
|
||||
Entity * entity;
|
||||
Type * type;
|
||||
ssaValueArray referrers;
|
||||
} Param;
|
||||
ssaProcedure Proc;
|
||||
ssaBlock Block;
|
||||
ssaInstr Instr;
|
||||
ssaValueConstant Constant;
|
||||
ssaValueConstantSlice ConstantSlice;
|
||||
ssaValueNil Nil;
|
||||
ssaValueTypeName TypeName;
|
||||
ssaValueGlobal Global;
|
||||
ssaValueParam Param;
|
||||
ssaProcedure Proc;
|
||||
ssaBlock Block;
|
||||
ssaInstr Instr;
|
||||
};
|
||||
} ssaValue;
|
||||
|
||||
@@ -2547,14 +2518,14 @@ void ssa_gen_global_type_name(ssaModule *m, Entity *e, String name) {
|
||||
|
||||
Type *bt = base_type(e->type);
|
||||
if (bt->kind == Type_Record) {
|
||||
auto *s = &bt->Record;
|
||||
TypeRecord *s = &bt->Record;
|
||||
for (isize j = 0; j < s->other_field_count; j++) {
|
||||
ssa_mangle_sub_type_name(m, s->other_fields[j], name);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_type_union(bt)) {
|
||||
auto *s = &bt->Record;
|
||||
TypeRecord *s = &bt->Record;
|
||||
// NOTE(bill): Zeroth entry is null (for `match type` stmts)
|
||||
for (isize j = 1; j < s->field_count; j++) {
|
||||
ssa_mangle_sub_type_name(m, s->fields[j], name);
|
||||
@@ -3135,7 +3106,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
ssaValue *value = ssa_build_expr(proc, ce->proc);
|
||||
Type *proc_type_ = base_type(ssa_type(value));
|
||||
GB_ASSERT(proc_type_->kind == Type_Proc);
|
||||
auto *type = &proc_type_->Proc;
|
||||
TypeProc *type = &proc_type_->Proc;
|
||||
|
||||
isize arg_index = 0;
|
||||
|
||||
@@ -3167,7 +3138,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
}
|
||||
}
|
||||
|
||||
auto *pt = &type->params->Tuple;
|
||||
TypeTuple *pt = &type->params->Tuple;
|
||||
|
||||
if (variadic) {
|
||||
isize i = 0;
|
||||
@@ -3213,7 +3184,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
}
|
||||
|
||||
if (args[0]->kind == ssaValue_Constant) {
|
||||
auto *c = &args[0]->Constant;
|
||||
ssaValueConstant *c = &args[0]->Constant;
|
||||
gb_printf_err("%s %d\n", type_to_string(c->type), c->value.kind);
|
||||
}
|
||||
|
||||
@@ -3657,7 +3628,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
|
||||
|
||||
case Type_Record: {
|
||||
GB_ASSERT(is_type_struct(bt));
|
||||
auto *st = &bt->Record;
|
||||
TypeRecord *st = &bt->Record;
|
||||
if (cl->elems.count > 0) {
|
||||
ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)));
|
||||
for_array(field_index, cl->elems) {
|
||||
@@ -4121,7 +4092,7 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
|
||||
case_ast_node(rs, ReturnStmt, node);
|
||||
ssa_emit_comment(proc, str_lit("ReturnStmt"));
|
||||
ssaValue *v = NULL;
|
||||
auto *return_type_tuple = &proc->type->Proc.results->Tuple;
|
||||
TypeTuple *return_type_tuple = &proc->type->Proc.results->Tuple;
|
||||
isize return_count = proc->type->Proc.result_count;
|
||||
if (return_count == 0) {
|
||||
// No return values
|
||||
@@ -4569,7 +4540,7 @@ void ssa_begin_procedure_body(ssaProcedure *proc) {
|
||||
proc->curr_block = proc->entry_block;
|
||||
|
||||
if (proc->type->Proc.params != NULL) {
|
||||
auto *params = &proc->type->Proc.params->Tuple;
|
||||
TypeTuple *params = &proc->type->Proc.params->Tuple;
|
||||
for (isize i = 0; i < params->variable_count; i++) {
|
||||
Entity *e = params->variables[i];
|
||||
ssaValue *param = ssa_add_param(proc, e);
|
||||
@@ -4938,7 +4909,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
} break;
|
||||
|
||||
case Entity_Procedure: {
|
||||
auto *pd = &decl->proc_decl->ProcDecl;
|
||||
AstNodeProcDecl *pd = &decl->proc_decl->ProcDecl;
|
||||
String original_name = name;
|
||||
AstNode *body = pd->body;
|
||||
if (pd->tags & ProcTag_foreign) {
|
||||
|
||||
+2
-2
@@ -149,7 +149,7 @@ void ssa_remove_pred(ssaBlock *b, ssaBlock *p) {
|
||||
if (pred != p) {
|
||||
b->preds.e[i] = b->preds.e[j];
|
||||
for_array(k, phis) {
|
||||
auto *phi = &phis.e[k]->Instr.Phi;
|
||||
ssaInstrPhi *phi = &phis.e[k]->Instr.Phi;
|
||||
phi->edges.e[i] = phi->edges.e[j];
|
||||
}
|
||||
i++;
|
||||
@@ -157,7 +157,7 @@ void ssa_remove_pred(ssaBlock *b, ssaBlock *p) {
|
||||
}
|
||||
b->preds.count = i;
|
||||
for_array(k, phis) {
|
||||
auto *phi = &phis.e[k]->Instr.Phi;
|
||||
ssaInstrPhi *phi = &phis.e[k]->Instr.Phi;
|
||||
phi->edges.count = i;
|
||||
}
|
||||
|
||||
|
||||
+21
-20
@@ -268,7 +268,7 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) {
|
||||
ssa_print_type(f, m, t->Proc.results);
|
||||
}
|
||||
ssa_fprintf(f, " (");
|
||||
auto *params = &t->Proc.params->Tuple;
|
||||
TypeTuple *params = &t->Proc.params->Tuple;
|
||||
for (isize i = 0; i < t->Proc.param_count; i++) {
|
||||
if (i > 0) {
|
||||
ssa_fprintf(f, ", ");
|
||||
@@ -580,7 +580,7 @@ void ssa_print_value(ssaFileBuffer *f, ssaModule *m, ssaValue *value, Type *type
|
||||
break;
|
||||
|
||||
case ssaValue_ConstantSlice: {
|
||||
auto *cs = &value->ConstantSlice;
|
||||
ssaValueConstantSlice *cs = &value->ConstantSlice;
|
||||
if (cs->backing_array == NULL || cs->count == 0) {
|
||||
ssa_fprintf(f, "zeroinitializer");
|
||||
} else {
|
||||
@@ -835,7 +835,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_Return: {
|
||||
auto *ret = &instr->Return;
|
||||
ssaInstrReturn *ret = &instr->Return;
|
||||
ssa_fprintf(f, "ret ");
|
||||
if (ret->value == NULL) {
|
||||
ssa_fprintf(f, "void");
|
||||
@@ -851,7 +851,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_Conv: {
|
||||
auto *c = &instr->Conv;
|
||||
ssaInstrConv *c = &instr->Conv;
|
||||
ssa_fprintf(f, "%%%d = %.*s ", value->index, LIT(ssa_conv_strings[c->kind]));
|
||||
ssa_print_type(f, m, c->from);
|
||||
ssa_fprintf(f, " ");
|
||||
@@ -867,7 +867,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_BinaryOp: {
|
||||
auto *bo = &value->Instr.BinaryOp;
|
||||
ssaInstrBinaryOp *bo = &value->Instr.BinaryOp;
|
||||
Type *type = base_type(ssa_type(bo->left));
|
||||
Type *elem_type = type;
|
||||
while (elem_type->kind == Type_Vector) {
|
||||
@@ -975,7 +975,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_Call: {
|
||||
auto *call = &instr->Call;
|
||||
ssaInstrCall *call = &instr->Call;
|
||||
Type *result_type = call->type;
|
||||
if (result_type) {
|
||||
ssa_fprintf(f, "%%%d = ", value->index);
|
||||
@@ -994,7 +994,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
||||
if (call->arg_count > 0) {
|
||||
Type *proc_type = base_type(ssa_type(call->value));
|
||||
GB_ASSERT(proc_type->kind == Type_Proc);
|
||||
auto *params = &proc_type->Proc.params->Tuple;
|
||||
TypeTuple *params = &proc_type->Proc.params->Tuple;
|
||||
for (isize i = 0; i < call->arg_count; i++) {
|
||||
Entity *e = params->variables[i];
|
||||
GB_ASSERT(e != NULL);
|
||||
@@ -1042,7 +1042,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_VectorInsertElement: {
|
||||
auto *ie = &instr->VectorInsertElement;
|
||||
ssaInstrVectorInsertElement *ie = &instr->VectorInsertElement;
|
||||
Type *vt = ssa_type(ie->vector);
|
||||
ssa_fprintf(f, "%%%d = insertelement ", value->index);
|
||||
|
||||
@@ -1064,7 +1064,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_VectorShuffle: {
|
||||
auto *sv = &instr->VectorShuffle;
|
||||
ssaInstrVectorShuffle *sv = &instr->VectorShuffle;
|
||||
Type *vt = ssa_type(sv->vector);
|
||||
ssa_fprintf(f, "%%%d = shufflevector ", value->index);
|
||||
|
||||
@@ -1090,7 +1090,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_BoundsCheck: {
|
||||
auto *bc = &instr->BoundsCheck;
|
||||
ssaInstrBoundsCheck *bc = &instr->BoundsCheck;
|
||||
ssa_fprintf(f, "call void ");
|
||||
ssa_print_encoded_global(f, str_lit("__bounds_check_error"), false);
|
||||
ssa_fprintf(f, "(");
|
||||
@@ -1120,7 +1120,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
|
||||
} break;
|
||||
|
||||
case ssaInstr_SliceBoundsCheck: {
|
||||
auto *bc = &instr->SliceBoundsCheck;
|
||||
ssaInstrSliceBoundsCheck *bc = &instr->SliceBoundsCheck;
|
||||
ssa_fprintf(f, "call void ");
|
||||
if (bc->is_substring) {
|
||||
ssa_print_encoded_global(f, str_lit("__substring_expr_error"), false);
|
||||
@@ -1188,7 +1188,7 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
||||
ssa_fprintf(f, "cc 65 ");
|
||||
}
|
||||
|
||||
auto *proc_type = &proc->type->Proc;
|
||||
TypeProc *proc_type = &proc->type->Proc;
|
||||
|
||||
if (proc_type->result_count == 0) {
|
||||
ssa_fprintf(f, "void");
|
||||
@@ -1201,7 +1201,7 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
||||
ssa_fprintf(f, "(");
|
||||
|
||||
if (proc_type->param_count > 0) {
|
||||
auto *params = &proc_type->params->Tuple;
|
||||
TypeTuple *params = &proc_type->params->Tuple;
|
||||
for (isize i = 0; i < params->variable_count; i++) {
|
||||
Entity *e = params->variables[i];
|
||||
if (i > 0) {
|
||||
@@ -1296,7 +1296,7 @@ void ssa_print_llvm_ir(ssaGen *ssa) {
|
||||
|
||||
|
||||
for_array(member_index, m->members.entries) {
|
||||
auto *entry = &m->members.entries.e[member_index];
|
||||
MapSsaValueEntry *entry = &m->members.entries.e[member_index];
|
||||
ssaValue *v = entry->value;
|
||||
if (v->kind != ssaValue_TypeName) {
|
||||
continue;
|
||||
@@ -1307,7 +1307,7 @@ void ssa_print_llvm_ir(ssaGen *ssa) {
|
||||
ssa_fprintf(f, "\n");
|
||||
|
||||
for_array(member_index, m->members.entries) {
|
||||
auto *entry = &m->members.entries.e[member_index];
|
||||
MapSsaValueEntry *entry = &m->members.entries.e[member_index];
|
||||
ssaValue *v = entry->value;
|
||||
if (v->kind != ssaValue_Proc) {
|
||||
continue;
|
||||
@@ -1318,7 +1318,7 @@ void ssa_print_llvm_ir(ssaGen *ssa) {
|
||||
}
|
||||
|
||||
for_array(member_index, m->members.entries) {
|
||||
auto *entry = &m->members.entries.e[member_index];
|
||||
MapSsaValueEntry *entry = &m->members.entries.e[member_index];
|
||||
ssaValue *v = entry->value;
|
||||
if (v->kind != ssaValue_Proc) {
|
||||
continue;
|
||||
@@ -1330,12 +1330,12 @@ void ssa_print_llvm_ir(ssaGen *ssa) {
|
||||
|
||||
|
||||
for_array(member_index, m->members.entries) {
|
||||
auto *entry = &m->members.entries.e[member_index];
|
||||
MapSsaValueEntry *entry = &m->members.entries.e[member_index];
|
||||
ssaValue *v = entry->value;
|
||||
if (v->kind != ssaValue_Global) {
|
||||
continue;
|
||||
}
|
||||
auto *g = &v->Global;
|
||||
ssaValueGlobal *g = &v->Global;
|
||||
Scope *scope = g->entity->scope;
|
||||
bool in_global_scope = false;
|
||||
if (scope != NULL) {
|
||||
@@ -1371,12 +1371,13 @@ void ssa_print_llvm_ir(ssaGen *ssa) {
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
if (m->generate_debug_info) {
|
||||
ssa_fprintf(f, "\n");
|
||||
ssa_fprintf(f, "!llvm.dbg.cu = !{!0}\n");
|
||||
|
||||
for_array(di_index, m->debug_info.entries) {
|
||||
auto *entry = &m->debug_info.entries.e[di_index];
|
||||
MapSsaDebugInfoEntry *entry = &m->debug_info.entries.e[di_index];
|
||||
ssaDebugInfo *di = entry->value;
|
||||
ssa_fprintf(f, "!%d = ", di->id);
|
||||
|
||||
@@ -1433,6 +1434,6 @@ void ssa_print_llvm_ir(ssaGen *ssa) {
|
||||
ssa_fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
ssa_file_buffer_destroy(f);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user