codegen.cpp 3.3 KB

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