Remove auto

This commit is contained in:
Ginger Bill
2016-11-23 12:03:26 +00:00
parent aa2bcb166f
commit ef8563a818
12 changed files with 612 additions and 671 deletions
+1 -17
View File
@@ -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);
+9 -9
View File
@@ -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);
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
+301
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}