1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
#include "ssa.cpp"
#include "print_llvm.cpp"
struct ssaGen {
ssaModule module;
gbFile output_file;
};
b32 ssa_gen_init(ssaGen *s, Checker *c) {
if (c->error_collector.count != 0)
return false;
gb_for_array(i, c->parser->files) {
AstFile *f = &c->parser->files[i];
if (f->error_collector.count != 0)
return false;
if (f->tokenizer.error_count != 0)
return false;
}
ssa_module_init(&s->module, c);
// TODO(bill): generate appropriate output name
isize pos = string_extension_position(c->parser->init_fullpath);
gbFileError err = gb_file_create(&s->output_file, gb_bprintf("%.*s.ll", pos, c->parser->init_fullpath.text));
if (err != gbFileError_None)
return false;
return true;
}
void ssa_gen_destroy(ssaGen *s) {
ssa_module_destroy(&s->module);
gb_file_close(&s->output_file);
}
void ssa_gen_code(ssaGen *s) {
if (v_zero == NULL) {
v_zero = ssa_make_value_constant(gb_heap_allocator(), t_int, make_exact_value_integer(0));
v_one = ssa_make_value_constant(gb_heap_allocator(), t_int, make_exact_value_integer(1));
v_zero32 = ssa_make_value_constant(gb_heap_allocator(), t_i32, make_exact_value_integer(0));
v_one32 = ssa_make_value_constant(gb_heap_allocator(), t_i32, make_exact_value_integer(1));
v_two32 = ssa_make_value_constant(gb_heap_allocator(), t_i32, make_exact_value_integer(2));
}
ssaModule *m = &s->module;
CheckerInfo *info = m->info;
gbAllocator a = m->allocator;
gb_for_array(i, info->entities.entries) {
auto *entry = &info->entities.entries[i];
Entity *e = cast(Entity *)cast(uintptr)entry->key;
DeclInfo *decl = entry->value;
String name = e->token.string;
switch (e->kind) {
case Entity_TypeName: {
ssaValue *t = ssa_make_value_type_name(a, e);
map_set(&m->members, hash_string(name), t);
} break;
case Entity_Variable: {
ssaValue *g = ssa_make_value_global(a, e, NULL);
map_set(&m->values, hash_pointer(e), g);
map_set(&m->members, hash_string(name), g);
} break;
case Entity_Procedure: {
ssaValue *p = ssa_make_value_procedure(a, e, decl, m);
map_set(&m->values, hash_pointer(e), p);
map_set(&m->members, hash_string(name), p);
} break;
}
}
gb_for_array(i, m->members.entries) {
auto *entry = &m->members.entries[i];
ssaValue *v = entry->value;
if (v->kind == ssaValue_Proc)
ssa_build_proc(v);
}
ssa_print_llvm_ir(&s->output_file, &s->module);
}
|