tilde.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. #include "tilde.hpp"
  2. gb_global Slice<TB_Arena *> global_tb_arenas;
  3. gb_internal TB_Arena *cg_arena(void) {
  4. return global_tb_arenas[current_thread_index()];
  5. }
  6. gb_internal void cg_global_arena_init(void) {
  7. global_tb_arenas = slice_make<TB_Arena *>(permanent_allocator(), global_thread_pool.threads.count);
  8. for_array(i, global_tb_arenas) {
  9. global_tb_arenas[i] = tb_default_arena();
  10. }
  11. }
  12. // returns TB_TYPE_VOID if not trivially possible
  13. gb_internal TB_DataType cg_data_type(Type *t) {
  14. GB_ASSERT(t != nullptr);
  15. t = core_type(t);
  16. i64 sz = type_size_of(t);
  17. switch (t->kind) {
  18. case Type_Basic:
  19. switch (t->Basic.kind) {
  20. case Basic_bool:
  21. case Basic_b8:
  22. case Basic_b16:
  23. case Basic_b32:
  24. case Basic_b64:
  25. case Basic_i8:
  26. case Basic_u8:
  27. case Basic_i16:
  28. case Basic_u16:
  29. case Basic_i32:
  30. case Basic_u32:
  31. case Basic_i64:
  32. case Basic_u64:
  33. case Basic_i128:
  34. case Basic_u128:
  35. case Basic_rune:
  36. case Basic_int:
  37. case Basic_uint:
  38. case Basic_uintptr:
  39. case Basic_typeid:
  40. return TB_TYPE_INTN(cast(u16)gb_min(8*sz, 64));
  41. case Basic_f16: return TB_TYPE_F16;
  42. case Basic_f32: return TB_TYPE_F32;
  43. case Basic_f64: return TB_TYPE_F64;
  44. case Basic_rawptr: return TB_TYPE_PTR;
  45. case Basic_cstring: return TB_TYPE_PTR;
  46. // Endian Specific Types
  47. case Basic_i16le:
  48. case Basic_u16le:
  49. case Basic_i32le:
  50. case Basic_u32le:
  51. case Basic_i64le:
  52. case Basic_u64le:
  53. case Basic_i128le:
  54. case Basic_u128le:
  55. case Basic_i16be:
  56. case Basic_u16be:
  57. case Basic_i32be:
  58. case Basic_u32be:
  59. case Basic_i64be:
  60. case Basic_u64be:
  61. case Basic_i128be:
  62. case Basic_u128be:
  63. return TB_TYPE_INTN(cast(u16)gb_min(8*sz, 64));
  64. case Basic_f16le: return TB_TYPE_F16;
  65. case Basic_f32le: return TB_TYPE_F32;
  66. case Basic_f64le: return TB_TYPE_F64;
  67. case Basic_f16be: return TB_TYPE_F16;
  68. case Basic_f32be: return TB_TYPE_F32;
  69. case Basic_f64be: return TB_TYPE_F64;
  70. }
  71. break;
  72. case Type_Pointer:
  73. case Type_MultiPointer:
  74. case Type_Proc:
  75. return TB_TYPE_PTR;
  76. case Type_BitSet:
  77. return cg_data_type(bit_set_to_int(t));
  78. case Type_RelativePointer:
  79. return cg_data_type(t->RelativePointer.base_integer);
  80. }
  81. // unknown
  82. return {};
  83. }
  84. gb_internal cgValue cg_value(TB_Global *g, Type *type) {
  85. return cg_value((TB_Symbol *)g, type);
  86. }
  87. gb_internal cgValue cg_value(TB_External *e, Type *type) {
  88. return cg_value((TB_Symbol *)e, type);
  89. }
  90. gb_internal cgValue cg_value(TB_Function *f, Type *type) {
  91. return cg_value((TB_Symbol *)f, type);
  92. }
  93. gb_internal cgValue cg_value(TB_Symbol *s, Type *type) {
  94. cgValue v = {};
  95. v.kind = cgValue_Symbol;
  96. v.type = type;
  97. v.symbol = s;
  98. return v;
  99. }
  100. gb_internal cgValue cg_value(TB_Node *node, Type *type) {
  101. cgValue v = {};
  102. v.kind = cgValue_Value;
  103. v.type = type;
  104. v.node = node;
  105. return v;
  106. }
  107. gb_internal cgValue cg_lvalue_addr(TB_Node *node, Type *type) {
  108. GB_ASSERT(node->dt.type == TB_PTR);
  109. cgValue v = {};
  110. v.kind = cgValue_Addr;
  111. v.type = type;
  112. v.node = node;
  113. return v;
  114. }
  115. gb_internal cgValue cg_lvalue_addr_to_value(cgValue v) {
  116. if (v.kind == cgValue_Value) {
  117. GB_ASSERT(is_type_pointer(v.type));
  118. GB_ASSERT(v.node->dt.type == TB_PTR);
  119. } else {
  120. GB_ASSERT(v.kind == cgValue_Addr);
  121. GB_ASSERT(v.node->dt.type == TB_PTR);
  122. v.kind = cgValue_Value;
  123. v.type = alloc_type_pointer(v.type);
  124. }
  125. return v;
  126. }
  127. gb_internal cgValue cg_value_multi(cgValueMulti *multi, Type *type) {
  128. GB_ASSERT(type->kind == Type_Tuple);
  129. GB_ASSERT(multi != nullptr);
  130. GB_ASSERT(type->Tuple.variables.count > 1);
  131. GB_ASSERT(multi->values.count == type->Tuple.variables.count);
  132. cgValue v = {};
  133. v.kind = cgValue_Multi;
  134. v.type = type;
  135. v.multi = multi;
  136. return v;
  137. }
  138. gb_internal cgValue cg_value_multi(Slice<cgValue> const &values, Type *type) {
  139. cgValueMulti *multi = gb_alloc_item(permanent_allocator(), cgValueMulti);
  140. multi->values = values;
  141. return cg_value_multi(multi, type);
  142. }
  143. gb_internal cgValue cg_value_multi2(cgValue const &x, cgValue const &y, Type *type) {
  144. GB_ASSERT(type->kind == Type_Tuple);
  145. GB_ASSERT(type->Tuple.variables.count == 2);
  146. cgValueMulti *multi = gb_alloc_item(permanent_allocator(), cgValueMulti);
  147. multi->values = slice_make<cgValue>(permanent_allocator(), 2);
  148. multi->values[0] = x;
  149. multi->values[1] = y;
  150. return cg_value_multi(multi, type);
  151. }
  152. gb_internal cgAddr cg_addr(cgValue const &value) {
  153. GB_ASSERT(value.kind != cgValue_Multi);
  154. cgAddr addr = {};
  155. addr.kind = cgAddr_Default;
  156. addr.addr = value;
  157. if (addr.addr.kind == cgValue_Addr) {
  158. GB_ASSERT(addr.addr.node != nullptr);
  159. addr.addr.kind = cgValue_Value;
  160. addr.addr.type = alloc_type_pointer(addr.addr.type);
  161. }
  162. return addr;
  163. }
  164. gb_internal void cg_set_debug_pos_from_node(cgProcedure *p, Ast *node) {
  165. if (node) {
  166. TokenPos pos = ast_token(node).pos;
  167. TB_FileID *file_id = map_get(&p->module->file_id_map, cast(uintptr)pos.file_id);
  168. if (file_id) {
  169. tb_inst_set_location(p->func, *file_id, pos.line);
  170. }
  171. }
  172. }
  173. gb_internal void cg_add_symbol(cgModule *m, Entity *e, TB_Symbol *symbol) {
  174. if (e) {
  175. rw_mutex_lock(&m->values_mutex);
  176. map_set(&m->symbols, e, symbol);
  177. rw_mutex_unlock(&m->values_mutex);
  178. }
  179. }
  180. gb_internal void cg_add_entity(cgModule *m, Entity *e, cgValue const &val) {
  181. if (e) {
  182. rw_mutex_lock(&m->values_mutex);
  183. GB_ASSERT(val.node != nullptr);
  184. map_set(&m->values, e, val);
  185. rw_mutex_unlock(&m->values_mutex);
  186. }
  187. }
  188. gb_internal void cg_add_member(cgModule *m, String const &name, cgValue const &val) {
  189. if (name.len > 0) {
  190. rw_mutex_lock(&m->values_mutex);
  191. string_map_set(&m->members, name, val);
  192. rw_mutex_unlock(&m->values_mutex);
  193. }
  194. }
  195. gb_internal void cg_add_procedure_value(cgModule *m, cgProcedure *p) {
  196. rw_mutex_lock(&m->values_mutex);
  197. if (p->entity != nullptr) {
  198. map_set(&m->procedure_values, p->func, p->entity);
  199. if (p->symbol != nullptr) {
  200. map_set(&m->symbols, p->entity, p->symbol);
  201. }
  202. }
  203. string_map_set(&m->procedures, p->name, p);
  204. rw_mutex_unlock(&m->values_mutex);
  205. }
  206. gb_internal TB_Symbol *cg_find_symbol_from_entity(cgModule *m, Entity *e) {
  207. GB_ASSERT(e != nullptr);
  208. rw_mutex_lock(&m->values_mutex);
  209. defer (rw_mutex_unlock(&m->values_mutex));
  210. TB_Symbol **found = map_get(&m->symbols, e);
  211. if (found) {
  212. return *found;
  213. }
  214. String link_name = cg_get_entity_name(m, e);
  215. cgProcedure **proc_found = string_map_get(&m->procedures, link_name);
  216. if (proc_found) {
  217. return (*proc_found)->symbol;
  218. }
  219. GB_PANIC("could not find entity's symbol %.*s", LIT(e->token.string));
  220. return nullptr;
  221. }
  222. struct cgGlobalVariable {
  223. cgValue var;
  224. cgValue init;
  225. DeclInfo *decl;
  226. bool is_initialized;
  227. };
  228. // Returns already_has_entry_point
  229. gb_internal bool cg_global_variables_create(cgModule *m) {
  230. isize global_variable_max_count = 0;
  231. bool already_has_entry_point = false;
  232. for (Entity *e : m->info->entities) {
  233. String name = e->token.string;
  234. if (e->kind == Entity_Variable) {
  235. global_variable_max_count++;
  236. } else if (e->kind == Entity_Procedure) {
  237. if ((e->scope->flags&ScopeFlag_Init) && name == "main") {
  238. GB_ASSERT(e == m->info->entry_point);
  239. }
  240. if (build_context.command_kind == Command_test &&
  241. (e->Procedure.is_export || e->Procedure.link_name.len > 0)) {
  242. String link_name = e->Procedure.link_name;
  243. if (e->pkg->kind == Package_Runtime) {
  244. if (link_name == "main" ||
  245. link_name == "DllMain" ||
  246. link_name == "WinMain" ||
  247. link_name == "wWinMain" ||
  248. link_name == "mainCRTStartup" ||
  249. link_name == "_start") {
  250. already_has_entry_point = true;
  251. }
  252. }
  253. }
  254. }
  255. }
  256. auto global_variables = array_make<cgGlobalVariable>(permanent_allocator(), 0, global_variable_max_count);
  257. auto *min_dep_set = &m->info->minimum_dependency_set;
  258. for (DeclInfo *d : m->info->variable_init_order) {
  259. Entity *e = d->entity;
  260. if ((e->scope->flags & ScopeFlag_File) == 0) {
  261. continue;
  262. }
  263. if (!ptr_set_exists(min_dep_set, e)) {
  264. continue;
  265. }
  266. DeclInfo *decl = decl_info_of_entity(e);
  267. if (decl == nullptr) {
  268. continue;
  269. }
  270. GB_ASSERT(e->kind == Entity_Variable);
  271. bool is_foreign = e->Variable.is_foreign;
  272. bool is_export = e->Variable.is_export;
  273. String name = cg_get_entity_name(m, e);
  274. TB_Linkage linkage = TB_LINKAGE_PRIVATE;
  275. if (is_foreign) {
  276. linkage = TB_LINKAGE_PUBLIC;
  277. // lb_add_foreign_library_path(m, e->Variable.foreign_library);
  278. // lb_set_wasm_import_attributes(g.value, e, name);
  279. } else if (is_export) {
  280. linkage = TB_LINKAGE_PUBLIC;
  281. }
  282. // lb_set_linkage_from_entity_flags(m, g.value, e->flags);
  283. TB_DebugType *debug_type = cg_debug_type(m, e->type);
  284. TB_Global *global = tb_global_create(m->mod, name.len, cast(char const *)name.text, debug_type, linkage);
  285. cgValue g = cg_value(global, alloc_type_pointer(e->type));
  286. TB_ModuleSection *section = tb_module_get_data(m->mod);
  287. if (e->Variable.thread_local_model != "") {
  288. section = tb_module_get_tls(m->mod);
  289. }
  290. if (e->Variable.link_section.len > 0) {
  291. // TODO(bill): custom module sections
  292. // LLVMSetSection(g.value, alloc_cstring(permanent_allocator(), e->Variable.link_section));
  293. }
  294. cgGlobalVariable var = {};
  295. var.var = g;
  296. var.decl = decl;
  297. if (decl->init_expr != nullptr) {
  298. TypeAndValue tav = type_and_value_of_expr(decl->init_expr);
  299. isize max_regions = cg_global_const_calculate_region_count(tav.value, e->type);
  300. tb_global_set_storage(m->mod, section, global, type_size_of(e->type), type_align_of(e->type), max_regions);
  301. if (tav.mode != Addressing_Invalid &&
  302. tav.value.kind != ExactValue_Invalid) {
  303. cg_global_const_add_region(m, tav.value, e->type, global, 0);
  304. var.is_initialized = true;
  305. }
  306. if (!var.is_initialized && is_type_untyped_nil(tav.type)) {
  307. var.is_initialized = true;
  308. }
  309. } else {
  310. i64 max_regions = cg_global_const_calculate_region_count_from_basic_type(e->type);
  311. tb_global_set_storage(m->mod, section, global, type_size_of(e->type), type_align_of(e->type), max_regions);
  312. }
  313. array_add(&global_variables, var);
  314. cg_add_symbol(m, e, cast(TB_Symbol *)global);
  315. cg_add_entity(m, e, g);
  316. cg_add_member(m, name, g);
  317. }
  318. cg_setup_type_info_data(m);
  319. return already_has_entry_point;
  320. }
  321. gb_internal cgModule *cg_module_create(Checker *c) {
  322. cgModule *m = gb_alloc_item(permanent_allocator(), cgModule);
  323. m->checker = c;
  324. m->info = &c->info;
  325. TB_FeatureSet feature_set = {};
  326. bool is_jit = false;
  327. m->mod = tb_module_create(TB_ARCH_X86_64, TB_SYSTEM_WINDOWS, &feature_set, is_jit);
  328. tb_module_set_tls_index(m->mod, 10, "_tls_index");
  329. map_init(&m->values);
  330. map_init(&m->symbols);
  331. map_init(&m->file_id_map);
  332. map_init(&m->debug_type_map);
  333. map_init(&m->proc_debug_type_map);
  334. map_init(&m->proc_proto_map);
  335. map_init(&m->anonymous_proc_lits_map);
  336. array_init(&m->single_threaded_procedure_queue, heap_allocator());
  337. for_array(id, global_files) {
  338. if (AstFile *f = global_files[id]) {
  339. char const *path = alloc_cstring(permanent_allocator(), f->fullpath);
  340. map_set(&m->file_id_map, cast(uintptr)id, tb_file_create(m->mod, path));
  341. }
  342. }
  343. return m;
  344. }
  345. gb_internal void cg_module_destroy(cgModule *m) {
  346. map_destroy(&m->values);
  347. map_destroy(&m->symbols);
  348. map_destroy(&m->file_id_map);
  349. map_destroy(&m->debug_type_map);
  350. map_destroy(&m->proc_debug_type_map);
  351. map_destroy(&m->proc_proto_map);
  352. map_destroy(&m->anonymous_proc_lits_map);
  353. array_free(&m->single_threaded_procedure_queue);
  354. tb_module_destroy(m->mod);
  355. }
  356. gb_internal String cg_set_nested_type_name_ir_mangled_name(Entity *e, cgProcedure *p) {
  357. // NOTE(bill, 2020-03-08): A polymorphic procedure may take a nested type declaration
  358. // and as a result, the declaration does not have time to determine what it should be
  359. GB_ASSERT(e != nullptr && e->kind == Entity_TypeName);
  360. if (e->TypeName.ir_mangled_name.len != 0) {
  361. return e->TypeName.ir_mangled_name;
  362. }
  363. GB_ASSERT((e->scope->flags & ScopeFlag_File) == 0);
  364. if (p == nullptr) {
  365. Entity *proc = nullptr;
  366. if (e->parent_proc_decl != nullptr) {
  367. proc = e->parent_proc_decl->entity;
  368. } else {
  369. Scope *scope = e->scope;
  370. while (scope != nullptr && (scope->flags & ScopeFlag_Proc) == 0) {
  371. scope = scope->parent;
  372. }
  373. GB_ASSERT(scope != nullptr);
  374. GB_ASSERT(scope->flags & ScopeFlag_Proc);
  375. proc = scope->procedure_entity;
  376. }
  377. GB_ASSERT(proc->kind == Entity_Procedure);
  378. if (proc->cg_procedure != nullptr) {
  379. p = proc->cg_procedure;
  380. }
  381. }
  382. // NOTE(bill): Generate a new name
  383. // parent_proc.name-guid
  384. String ts_name = e->token.string;
  385. if (p != nullptr) {
  386. isize name_len = p->name.len + 1 + ts_name.len + 1 + 10 + 1;
  387. char *name_text = gb_alloc_array(permanent_allocator(), char, name_len);
  388. u32 guid = 1+p->module->nested_type_name_guid.fetch_add(1);
  389. name_len = gb_snprintf(name_text, name_len, "%.*s" ABI_PKG_NAME_SEPARATOR "%.*s-%u", LIT(p->name), LIT(ts_name), guid);
  390. String name = make_string(cast(u8 *)name_text, name_len-1);
  391. e->TypeName.ir_mangled_name = name;
  392. return name;
  393. } else {
  394. // NOTE(bill): a nested type be required before its parameter procedure exists. Just give it a temp name for now
  395. isize name_len = 9 + 1 + ts_name.len + 1 + 10 + 1;
  396. char *name_text = gb_alloc_array(permanent_allocator(), char, name_len);
  397. static std::atomic<u32> guid;
  398. name_len = gb_snprintf(name_text, name_len, "_internal" ABI_PKG_NAME_SEPARATOR "%.*s-%u", LIT(ts_name), 1+guid.fetch_add(1));
  399. String name = make_string(cast(u8 *)name_text, name_len-1);
  400. e->TypeName.ir_mangled_name = name;
  401. return name;
  402. }
  403. }
  404. gb_internal String cg_mangle_name(cgModule *m, Entity *e) {
  405. String name = e->token.string;
  406. AstPackage *pkg = e->pkg;
  407. GB_ASSERT_MSG(pkg != nullptr, "Missing package for '%.*s'", LIT(name));
  408. String pkgn = pkg->name;
  409. GB_ASSERT(!rune_is_digit(pkgn[0]));
  410. if (pkgn == "llvm") {
  411. GB_PANIC("llvm. entities are not allowed with the tilde backend");
  412. }
  413. isize max_len = pkgn.len + 1 + name.len + 1;
  414. bool require_suffix_id = is_type_polymorphic(e->type, true);
  415. if ((e->scope->flags & (ScopeFlag_File | ScopeFlag_Pkg)) == 0) {
  416. require_suffix_id = true;
  417. } else if (is_blank_ident(e->token)) {
  418. require_suffix_id = true;
  419. }if (e->flags & EntityFlag_NotExported) {
  420. require_suffix_id = true;
  421. }
  422. if (require_suffix_id) {
  423. max_len += 21;
  424. }
  425. char *new_name = gb_alloc_array(permanent_allocator(), char, max_len);
  426. isize new_name_len = gb_snprintf(
  427. new_name, max_len,
  428. "%.*s" ABI_PKG_NAME_SEPARATOR "%.*s", LIT(pkgn), LIT(name)
  429. );
  430. if (require_suffix_id) {
  431. char *str = new_name + new_name_len-1;
  432. isize len = max_len-new_name_len;
  433. isize extra = gb_snprintf(str, len, "-%llu", cast(unsigned long long)e->id);
  434. new_name_len += extra-1;
  435. }
  436. String mangled_name = make_string((u8 const *)new_name, new_name_len-1);
  437. return mangled_name;
  438. }
  439. gb_internal String cg_get_entity_name(cgModule *m, Entity *e) {
  440. if (e != nullptr && e->kind == Entity_TypeName && e->TypeName.ir_mangled_name.len != 0) {
  441. return e->TypeName.ir_mangled_name;
  442. }
  443. GB_ASSERT(e != nullptr);
  444. if (e->pkg == nullptr) {
  445. return e->token.string;
  446. }
  447. if (e->kind == Entity_TypeName && (e->scope->flags & ScopeFlag_File) == 0) {
  448. return cg_set_nested_type_name_ir_mangled_name(e, nullptr);
  449. }
  450. String name = {};
  451. bool no_name_mangle = false;
  452. if (e->kind == Entity_Variable) {
  453. bool is_foreign = e->Variable.is_foreign;
  454. bool is_export = e->Variable.is_export;
  455. no_name_mangle = e->Variable.link_name.len > 0 || is_foreign || is_export;
  456. if (e->Variable.link_name.len > 0) {
  457. return e->Variable.link_name;
  458. }
  459. } else if (e->kind == Entity_Procedure && e->Procedure.link_name.len > 0) {
  460. return e->Procedure.link_name;
  461. } else if (e->kind == Entity_Procedure && e->Procedure.is_export) {
  462. no_name_mangle = true;
  463. }
  464. if (!no_name_mangle) {
  465. name = cg_mangle_name(m, e);
  466. }
  467. if (name.len == 0) {
  468. name = e->token.string;
  469. }
  470. if (e->kind == Entity_TypeName) {
  471. e->TypeName.ir_mangled_name = name;
  472. } else if (e->kind == Entity_Procedure) {
  473. e->Procedure.link_name = name;
  474. }
  475. return name;
  476. }
  477. #include "tilde_const.cpp"
  478. #include "tilde_debug.cpp"
  479. #include "tilde_expr.cpp"
  480. #include "tilde_builtin.cpp"
  481. #include "tilde_type_info.cpp"
  482. #include "tilde_proc.cpp"
  483. #include "tilde_stmt.cpp"
  484. gb_internal String cg_filepath_obj_for_module(cgModule *m) {
  485. String path = concatenate3_strings(permanent_allocator(),
  486. build_context.build_paths[BuildPath_Output].basename,
  487. STR_LIT("/"),
  488. build_context.build_paths[BuildPath_Output].name
  489. );
  490. // if (m->file) {
  491. // char buf[32] = {};
  492. // isize n = gb_snprintf(buf, gb_size_of(buf), "-%u", m->file->id);
  493. // String suffix = make_string((u8 *)buf, n-1);
  494. // path = concatenate_strings(permanent_allocator(), path, suffix);
  495. // } else if (m->pkg) {
  496. // path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name);
  497. // }
  498. String ext = {};
  499. if (build_context.build_mode == BuildMode_Assembly) {
  500. ext = STR_LIT(".S");
  501. } else {
  502. if (is_arch_wasm()) {
  503. ext = STR_LIT(".wasm.o");
  504. } else {
  505. switch (build_context.metrics.os) {
  506. case TargetOs_windows:
  507. ext = STR_LIT(".obj");
  508. break;
  509. default:
  510. case TargetOs_darwin:
  511. case TargetOs_linux:
  512. case TargetOs_essence:
  513. ext = STR_LIT(".o");
  514. break;
  515. case TargetOs_freestanding:
  516. switch (build_context.metrics.abi) {
  517. default:
  518. case TargetABI_Default:
  519. case TargetABI_SysV:
  520. ext = STR_LIT(".o");
  521. break;
  522. case TargetABI_Win64:
  523. ext = STR_LIT(".obj");
  524. break;
  525. }
  526. break;
  527. }
  528. }
  529. }
  530. return concatenate_strings(permanent_allocator(), path, ext);
  531. }
  532. gb_internal WORKER_TASK_PROC(cg_procedure_generate_worker_proc) {
  533. cgProcedure *p = cast(cgProcedure *)data;
  534. cg_procedure_generate(p);
  535. return 0;
  536. }
  537. gb_internal void cg_add_procedure_to_queue(cgProcedure *p) {
  538. cgModule *m = p->module;
  539. if (m->do_threading) {
  540. thread_pool_add_task(cg_procedure_generate_worker_proc, p);
  541. } else {
  542. array_add(&m->single_threaded_procedure_queue, p);
  543. }
  544. }
  545. gb_internal bool cg_generate_code(Checker *c, LinkerData *linker_data) {
  546. TIME_SECTION("Tilde Module Initializtion");
  547. CheckerInfo *info = &c->info;
  548. linker_data_init(linker_data, info, c->parser->init_fullpath);
  549. cg_global_arena_init();
  550. cgModule *m = cg_module_create(c);
  551. defer (cg_module_destroy(m));
  552. m->do_threading = false;
  553. TIME_SECTION("Tilde Global Variables");
  554. bool already_has_entry_point = cg_global_variables_create(m);
  555. gb_unused(already_has_entry_point);
  556. if (true) {
  557. Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin);
  558. cgProcedure *p = cg_procedure_create_dummy(m, str_lit(CG_STARTUP_RUNTIME_PROC_NAME), proc_type);
  559. p->is_startup = true;
  560. cg_procedure_begin(p);
  561. tb_inst_ret(p->func, 0, nullptr);
  562. cg_procedure_end(p);
  563. }
  564. if (true) {
  565. Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin);
  566. cgProcedure *p = cg_procedure_create_dummy(m, str_lit(CG_CLEANUP_RUNTIME_PROC_NAME), proc_type);
  567. p->is_startup = true;
  568. cg_procedure_begin(p);
  569. tb_inst_ret(p->func, 0, nullptr);
  570. cg_procedure_end(p);
  571. }
  572. auto *min_dep_set = &info->minimum_dependency_set;
  573. Array<cgProcedure *> procedures_to_generate = {};
  574. array_init(&procedures_to_generate, heap_allocator());
  575. defer (array_free(&procedures_to_generate));
  576. for (Entity *e : info->entities) {
  577. String name = e->token.string;
  578. Scope *scope = e->scope;
  579. if ((scope->flags & ScopeFlag_File) == 0) {
  580. continue;
  581. }
  582. Scope *package_scope = scope->parent;
  583. GB_ASSERT(package_scope->flags & ScopeFlag_Pkg);
  584. if (e->kind != Entity_Procedure) {
  585. continue;
  586. }
  587. if (!ptr_set_exists(min_dep_set, e)) {
  588. // NOTE(bill): Nothing depends upon it so doesn't need to be built
  589. continue;
  590. }
  591. if (cgProcedure *p = cg_procedure_create(m, e)) {
  592. array_add(&procedures_to_generate, p);
  593. }
  594. }
  595. for (cgProcedure *p : procedures_to_generate) {
  596. cg_add_procedure_to_queue(p);
  597. }
  598. if (!m->do_threading) {
  599. for (isize i = 0; i < m->single_threaded_procedure_queue.count; i++) {
  600. cgProcedure *p = m->single_threaded_procedure_queue[i];
  601. cg_procedure_generate(p);
  602. }
  603. }
  604. thread_pool_wait();
  605. TB_DebugFormat debug_format = TB_DEBUGFMT_NONE;
  606. if (build_context.ODIN_DEBUG) {
  607. switch (build_context.metrics.os) {
  608. case TargetOs_windows:
  609. debug_format = TB_DEBUGFMT_CODEVIEW;
  610. break;
  611. case TargetOs_darwin:
  612. case TargetOs_linux:
  613. case TargetOs_essence:
  614. case TargetOs_freebsd:
  615. case TargetOs_openbsd:
  616. debug_format = TB_DEBUGFMT_DWARF;
  617. break;
  618. }
  619. }
  620. TB_ExportBuffer export_buffer = tb_module_object_export(m->mod, debug_format);
  621. defer (tb_export_buffer_free(export_buffer));
  622. String filepath_obj = cg_filepath_obj_for_module(m);
  623. array_add(&linker_data->output_object_paths, filepath_obj);
  624. GB_ASSERT(tb_export_buffer_to_file(export_buffer, cast(char const *)filepath_obj.text));
  625. return true;
  626. }
  627. #undef ABI_PKG_NAME_SEPARATOR