llvm_backend_proc.cpp 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448
  1. void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false) {
  2. dst = lb_emit_conv(p, dst, t_rawptr);
  3. src = lb_emit_conv(p, src, t_rawptr);
  4. len = lb_emit_conv(p, len, t_int);
  5. char const *name = "llvm.memmove";
  6. if (LLVMIsConstant(len.value)) {
  7. i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value);
  8. if (const_len <= 4*build_context.word_size) {
  9. name = "llvm.memmove.inline";
  10. }
  11. }
  12. LLVMTypeRef types[3] = {
  13. lb_type(p->module, t_rawptr),
  14. lb_type(p->module, t_rawptr),
  15. lb_type(p->module, t_int)
  16. };
  17. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  18. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2]));
  19. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  20. LLVMValueRef args[4] = {};
  21. args[0] = dst.value;
  22. args[1] = src.value;
  23. args[2] = len.value;
  24. args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile);
  25. LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  26. }
  27. void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false) {
  28. dst = lb_emit_conv(p, dst, t_rawptr);
  29. src = lb_emit_conv(p, src, t_rawptr);
  30. len = lb_emit_conv(p, len, t_int);
  31. char const *name = "llvm.memcpy";
  32. if (LLVMIsConstant(len.value)) {
  33. i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value);
  34. if (const_len <= 4*build_context.word_size) {
  35. name = "llvm.memcpy.inline";
  36. }
  37. }
  38. LLVMTypeRef types[3] = {
  39. lb_type(p->module, t_rawptr),
  40. lb_type(p->module, t_rawptr),
  41. lb_type(p->module, t_int)
  42. };
  43. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  44. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2]));
  45. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  46. LLVMValueRef args[4] = {};
  47. args[0] = dst.value;
  48. args[1] = src.value;
  49. args[2] = len.value;
  50. args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile);
  51. LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  52. }
  53. lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) {
  54. GB_ASSERT(entity != nullptr);
  55. GB_ASSERT(entity->kind == Entity_Procedure);
  56. if (!entity->Procedure.is_foreign) {
  57. GB_ASSERT(entity->flags & EntityFlag_ProcBodyChecked);
  58. }
  59. String link_name = {};
  60. if (ignore_body) {
  61. lbModule *other_module = lb_pkg_module(m->gen, entity->pkg);
  62. link_name = lb_get_entity_name(other_module, entity);
  63. } else {
  64. link_name = lb_get_entity_name(m, entity);
  65. }
  66. {
  67. StringHashKey key = string_hash_string(link_name);
  68. lbValue *found = string_map_get(&m->members, key);
  69. if (found) {
  70. lb_add_entity(m, entity, *found);
  71. return string_map_must_get(&m->procedures, key);
  72. }
  73. }
  74. lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure);
  75. p->module = m;
  76. entity->code_gen_module = m;
  77. entity->code_gen_procedure = p;
  78. p->entity = entity;
  79. p->name = link_name;
  80. DeclInfo *decl = entity->decl_info;
  81. ast_node(pl, ProcLit, decl->proc_lit);
  82. Type *pt = base_type(entity->type);
  83. GB_ASSERT(pt->kind == Type_Proc);
  84. p->type = entity->type;
  85. p->type_expr = decl->type_expr;
  86. p->body = pl->body;
  87. p->inlining = pl->inlining;
  88. p->is_foreign = entity->Procedure.is_foreign;
  89. p->is_export = entity->Procedure.is_export;
  90. p->is_entry_point = false;
  91. gbAllocator a = heap_allocator();
  92. p->children.allocator = a;
  93. p->params.allocator = a;
  94. p->defer_stmts.allocator = a;
  95. p->blocks.allocator = a;
  96. p->branch_blocks.allocator = a;
  97. p->context_stack.allocator = a;
  98. p->scope_stack.allocator = a;
  99. if (p->is_foreign) {
  100. lb_add_foreign_library_path(p->module, entity->Procedure.foreign_library);
  101. }
  102. char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
  103. LLVMTypeRef func_ptr_type = lb_type(m, p->type);
  104. LLVMTypeRef func_type = LLVMGetElementType(func_ptr_type);
  105. p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
  106. lb_ensure_abi_function_type(m, p);
  107. lb_add_function_type_attributes(p->value, p->abi_function_type, p->abi_function_type->calling_convention);
  108. if (pt->Proc.diverging) {
  109. lb_add_attribute_to_proc(m, p->value, "noreturn");
  110. }
  111. if (pt->Proc.calling_convention == ProcCC_Naked) {
  112. lb_add_attribute_to_proc(m, p->value, "naked");
  113. }
  114. switch (p->inlining) {
  115. case ProcInlining_inline:
  116. lb_add_attribute_to_proc(m, p->value, "alwaysinline");
  117. break;
  118. case ProcInlining_no_inline:
  119. lb_add_attribute_to_proc(m, p->value, "noinline");
  120. break;
  121. }
  122. if (entity->flags & EntityFlag_Cold) {
  123. lb_add_attribute_to_proc(m, p->value, "cold");
  124. }
  125. switch (entity->Procedure.optimization_mode) {
  126. case ProcedureOptimizationMode_None:
  127. lb_add_attribute_to_proc(m, p->value, "optnone");
  128. break;
  129. case ProcedureOptimizationMode_Minimal:
  130. lb_add_attribute_to_proc(m, p->value, "optnone");
  131. break;
  132. case ProcedureOptimizationMode_Size:
  133. lb_add_attribute_to_proc(m, p->value, "optsize");
  134. break;
  135. case ProcedureOptimizationMode_Speed:
  136. // TODO(bill): handle this correctly
  137. lb_add_attribute_to_proc(m, p->value, "optsize");
  138. break;
  139. }
  140. // lbCallingConventionKind cc_kind = lbCallingConvention_C;
  141. // // TODO(bill): Clean up this logic
  142. // if (build_context.metrics.os != TargetOs_js) {
  143. // cc_kind = lb_calling_convention_map[pt->Proc.calling_convention];
  144. // }
  145. // LLVMSetFunctionCallConv(p->value, cc_kind);
  146. lbValue proc_value = {p->value, p->type};
  147. lb_add_entity(m, entity, proc_value);
  148. lb_add_member(m, p->name, proc_value);
  149. lb_add_procedure_value(m, p);
  150. if (p->is_export) {
  151. LLVMSetLinkage(p->value, LLVMDLLExportLinkage);
  152. LLVMSetDLLStorageClass(p->value, LLVMDLLExportStorageClass);
  153. LLVMSetVisibility(p->value, LLVMDefaultVisibility);
  154. if (is_arch_wasm()) {
  155. char const *export_name = alloc_cstring(permanent_allocator(), p->name);
  156. LLVMAddTargetDependentFunctionAttr(p->value, "wasm-export-name", export_name);
  157. }
  158. } else if (!p->is_foreign) {
  159. if (!USE_SEPARATE_MODULES) {
  160. LLVMSetLinkage(p->value, LLVMInternalLinkage);
  161. // NOTE(bill): if a procedure is defined in package runtime and uses a custom link name,
  162. // then it is very likely it is required by LLVM and thus cannot have internal linkage
  163. if (entity->pkg != nullptr && entity->pkg->kind == Package_Runtime && p->body != nullptr) {
  164. GB_ASSERT(entity->kind == Entity_Procedure);
  165. if (entity->Procedure.link_name != "") {
  166. LLVMSetLinkage(p->value, LLVMExternalLinkage);
  167. }
  168. }
  169. }
  170. }
  171. if (p->is_foreign) {
  172. if (is_arch_wasm()) {
  173. char const *import_name = alloc_cstring(permanent_allocator(), p->name);
  174. char const *module_name = "env";
  175. if (entity->Procedure.foreign_library != nullptr) {
  176. Entity *foreign_library = entity->Procedure.foreign_library;
  177. GB_ASSERT(foreign_library->kind == Entity_LibraryName);
  178. if (foreign_library->LibraryName.paths.count > 0) {
  179. module_name = alloc_cstring(permanent_allocator(), foreign_library->LibraryName.paths[0]);
  180. }
  181. }
  182. LLVMAddTargetDependentFunctionAttr(p->value, "wasm-import-name", import_name);
  183. LLVMAddTargetDependentFunctionAttr(p->value, "wasm-import-module", module_name);
  184. }
  185. }
  186. // NOTE(bill): offset==0 is the return value
  187. isize offset = 1;
  188. if (pt->Proc.return_by_pointer) {
  189. offset = 2;
  190. }
  191. isize parameter_index = 0;
  192. if (pt->Proc.param_count) {
  193. TypeTuple *params = &pt->Proc.params->Tuple;
  194. for (isize i = 0; i < pt->Proc.param_count; i++) {
  195. Entity *e = params->variables[i];
  196. if (e->kind != Entity_Variable) {
  197. continue;
  198. }
  199. if (i+1 == params->variables.count && pt->Proc.c_vararg) {
  200. continue;
  201. }
  202. if (e->flags&EntityFlag_NoAlias) {
  203. lb_add_proc_attribute_at_index(p, offset+parameter_index, "noalias");
  204. }
  205. parameter_index += 1;
  206. }
  207. }
  208. if (ignore_body) {
  209. p->body = nullptr;
  210. LLVMSetLinkage(p->value, LLVMExternalLinkage);
  211. }
  212. if (m->debug_builder) { // Debug Information
  213. Type *bt = base_type(p->type);
  214. unsigned line = cast(unsigned)entity->token.pos.line;
  215. LLVMMetadataRef scope = nullptr;
  216. LLVMMetadataRef file = nullptr;
  217. LLVMMetadataRef type = nullptr;
  218. scope = p->module->debug_compile_unit;
  219. type = lb_debug_type_internal_proc(m, bt);
  220. Ast *ident = entity->identifier.load();
  221. if (entity->file != nullptr) {
  222. file = lb_get_llvm_metadata(m, entity->file);
  223. scope = file;
  224. } else if (ident != nullptr && ident->file != nullptr) {
  225. file = lb_get_llvm_metadata(m, ident->file);
  226. scope = file;
  227. } else if (entity->scope != nullptr) {
  228. file = lb_get_llvm_metadata(m, entity->scope->file);
  229. scope = file;
  230. }
  231. GB_ASSERT_MSG(file != nullptr, "%.*s", LIT(entity->token.string));
  232. // LLVMBool is_local_to_unit = !entity->Procedure.is_export;
  233. LLVMBool is_local_to_unit = false;
  234. LLVMBool is_definition = p->body != nullptr;
  235. unsigned scope_line = line;
  236. u32 flags = LLVMDIFlagStaticMember;
  237. LLVMBool is_optimized = false;
  238. if (bt->Proc.diverging) {
  239. flags |= LLVMDIFlagNoReturn;
  240. }
  241. if (p->body == nullptr) {
  242. flags |= LLVMDIFlagPrototyped;
  243. is_optimized = false;
  244. }
  245. if (p->body != nullptr) {
  246. // String debug_name = entity->token.string.text;
  247. String debug_name = p->name;
  248. p->debug_info = LLVMDIBuilderCreateFunction(m->debug_builder, scope,
  249. cast(char const *)debug_name.text, debug_name.len,
  250. cast(char const *)p->name.text, p->name.len,
  251. file, line, type,
  252. is_local_to_unit, is_definition,
  253. scope_line, cast(LLVMDIFlags)flags, is_optimized
  254. );
  255. GB_ASSERT(p->debug_info != nullptr);
  256. LLVMSetSubprogram(p->value, p->debug_info);
  257. lb_set_llvm_metadata(m, p, p->debug_info);
  258. }
  259. }
  260. return p;
  261. }
  262. lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type) {
  263. {
  264. lbValue *found = string_map_get(&m->members, link_name);
  265. GB_ASSERT(found == nullptr);
  266. }
  267. lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure);
  268. p->module = m;
  269. p->name = link_name;
  270. p->type = type;
  271. p->type_expr = nullptr;
  272. p->body = nullptr;
  273. p->tags = 0;
  274. p->inlining = ProcInlining_none;
  275. p->is_foreign = false;
  276. p->is_export = false;
  277. p->is_entry_point = false;
  278. gbAllocator a = permanent_allocator();
  279. p->children.allocator = a;
  280. p->params.allocator = a;
  281. p->defer_stmts.allocator = a;
  282. p->blocks.allocator = a;
  283. p->branch_blocks.allocator = a;
  284. p->context_stack.allocator = a;
  285. char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
  286. LLVMTypeRef func_ptr_type = lb_type(m, p->type);
  287. LLVMTypeRef func_type = LLVMGetElementType(func_ptr_type);
  288. p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
  289. Type *pt = p->type;
  290. lbCallingConventionKind cc_kind = lbCallingConvention_C;
  291. // TODO(bill): Clean up this logic
  292. if (!is_arch_wasm()) {
  293. cc_kind = lb_calling_convention_map[pt->Proc.calling_convention];
  294. }
  295. LLVMSetFunctionCallConv(p->value, cc_kind);
  296. lbValue proc_value = {p->value, p->type};
  297. lb_add_member(m, p->name, proc_value);
  298. lb_add_procedure_value(m, p);
  299. // NOTE(bill): offset==0 is the return value
  300. isize offset = 1;
  301. if (pt->Proc.return_by_pointer) {
  302. lb_add_proc_attribute_at_index(p, 1, "sret");
  303. lb_add_proc_attribute_at_index(p, 1, "noalias");
  304. offset = 2;
  305. }
  306. isize parameter_index = 0;
  307. if (pt->Proc.calling_convention == ProcCC_Odin) {
  308. lb_add_proc_attribute_at_index(p, offset+parameter_index, "noalias");
  309. lb_add_proc_attribute_at_index(p, offset+parameter_index, "nonnull");
  310. lb_add_proc_attribute_at_index(p, offset+parameter_index, "nocapture");
  311. }
  312. return p;
  313. }
  314. lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) {
  315. lbParamPasskind kind = lbParamPass_Value;
  316. if (e != nullptr && !are_types_identical(abi_type, e->type)) {
  317. if (is_type_pointer(abi_type)) {
  318. GB_ASSERT(e->kind == Entity_Variable);
  319. Type *av = core_type(type_deref(abi_type));
  320. if (are_types_identical(av, core_type(e->type))) {
  321. kind = lbParamPass_Pointer;
  322. if (e->flags&EntityFlag_Value) {
  323. kind = lbParamPass_ConstRef;
  324. }
  325. } else {
  326. kind = lbParamPass_BitCast;
  327. }
  328. } else if (is_type_integer(abi_type)) {
  329. kind = lbParamPass_Integer;
  330. } else if (abi_type == t_llvm_bool) {
  331. kind = lbParamPass_Value;
  332. } else if (is_type_boolean(abi_type)) {
  333. kind = lbParamPass_Integer;
  334. } else if (is_type_simd_vector(abi_type)) {
  335. kind = lbParamPass_BitCast;
  336. } else if (is_type_float(abi_type)) {
  337. kind = lbParamPass_BitCast;
  338. } else if (is_type_tuple(abi_type)) {
  339. kind = lbParamPass_Tuple;
  340. } else if (is_type_proc(abi_type)) {
  341. kind = lbParamPass_Value;
  342. } else {
  343. GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type));
  344. }
  345. }
  346. if (kind_) *kind_ = kind;
  347. lbValue res = {};
  348. res.value = LLVMGetParam(p->value, cast(unsigned)index);
  349. res.type = abi_type;
  350. return res;
  351. }
  352. void lb_start_block(lbProcedure *p, lbBlock *b) {
  353. GB_ASSERT(b != nullptr);
  354. if (!b->appended) {
  355. b->appended = true;
  356. LLVMAppendExistingBasicBlock(p->value, b->block);
  357. }
  358. LLVMPositionBuilderAtEnd(p->builder, b->block);
  359. p->curr_block = b;
  360. }
  361. void lb_begin_procedure_body(lbProcedure *p) {
  362. DeclInfo *decl = decl_info_of_entity(p->entity);
  363. if (decl != nullptr) {
  364. for_array(i, decl->labels) {
  365. BlockLabel bl = decl->labels[i];
  366. lbBranchBlocks bb = {bl.label, nullptr, nullptr};
  367. array_add(&p->branch_blocks, bb);
  368. }
  369. }
  370. p->builder = LLVMCreateBuilderInContext(p->module->ctx);
  371. p->decl_block = lb_create_block(p, "decls", true);
  372. p->entry_block = lb_create_block(p, "entry", true);
  373. lb_start_block(p, p->entry_block);
  374. GB_ASSERT(p->type != nullptr);
  375. lb_ensure_abi_function_type(p->module, p);
  376. {
  377. lbFunctionType *ft = p->abi_function_type;
  378. unsigned param_offset = 0;
  379. lbValue return_ptr_value = {};
  380. if (ft->ret.kind == lbArg_Indirect) {
  381. // NOTE(bill): this must be parameter 0
  382. String name = str_lit("agg.result");
  383. Type *ptr_type = alloc_type_pointer(reduce_tuple_to_single_type(p->type->Proc.results));
  384. Entity *e = alloc_entity_param(nullptr, make_token_ident(name), ptr_type, false, false);
  385. e->flags |= EntityFlag_Sret | EntityFlag_NoAlias;
  386. return_ptr_value.value = LLVMGetParam(p->value, 0);
  387. LLVMSetValueName2(return_ptr_value.value, cast(char const *)name.text, name.len);
  388. return_ptr_value.type = ptr_type;
  389. p->return_ptr = lb_addr(return_ptr_value);
  390. lb_add_entity(p->module, e, return_ptr_value);
  391. param_offset += 1;
  392. }
  393. if (p->type->Proc.params != nullptr) {
  394. TypeTuple *params = &p->type->Proc.params->Tuple;
  395. unsigned param_index = 0;
  396. for_array(i, params->variables) {
  397. Entity *e = params->variables[i];
  398. if (e->kind != Entity_Variable) {
  399. continue;
  400. }
  401. lbArgType *arg_type = &ft->args[param_index];
  402. if (arg_type->kind == lbArg_Ignore) {
  403. continue;
  404. } else if (arg_type->kind == lbArg_Direct) {
  405. lbParamPasskind kind = lbParamPass_Value;
  406. LLVMTypeRef param_type = lb_type(p->module, e->type);
  407. if (param_type != arg_type->type) {
  408. kind = lbParamPass_BitCast;
  409. }
  410. LLVMValueRef value = LLVMGetParam(p->value, param_offset+param_index);
  411. value = OdinLLVMBuildTransmute(p, value, param_type);
  412. lbValue param = {};
  413. param.value = value;
  414. param.type = e->type;
  415. array_add(&p->params, param);
  416. if (e->token.string.len != 0) {
  417. lbAddr l = lb_add_local(p, e->type, e, false, param_index);
  418. lb_addr_store(p, l, param);
  419. }
  420. param_index += 1;
  421. } else if (arg_type->kind == lbArg_Indirect) {
  422. LLVMValueRef value_ptr = LLVMGetParam(p->value, param_offset+param_index);
  423. LLVMValueRef value = LLVMBuildLoad(p->builder, value_ptr, "");
  424. lbValue param = {};
  425. param.value = value;
  426. param.type = e->type;
  427. array_add(&p->params, param);
  428. lbValue ptr = {};
  429. ptr.value = value_ptr;
  430. ptr.type = alloc_type_pointer(e->type);
  431. lb_add_entity(p->module, e, ptr);
  432. param_index += 1;
  433. }
  434. }
  435. }
  436. if (p->type->Proc.has_named_results) {
  437. GB_ASSERT(p->type->Proc.result_count > 0);
  438. TypeTuple *results = &p->type->Proc.results->Tuple;
  439. for_array(i, results->variables) {
  440. Entity *e = results->variables[i];
  441. GB_ASSERT(e->kind == Entity_Variable);
  442. if (e->token.string != "") {
  443. GB_ASSERT(!is_blank_ident(e->token));
  444. lbAddr res = {};
  445. if (return_ptr_value.value) {
  446. lbValue ptr = return_ptr_value;
  447. if (results->variables.count != 1) {
  448. ptr = lb_emit_struct_ep(p, ptr, cast(i32)i);
  449. }
  450. res = lb_addr(ptr);
  451. lb_add_entity(p->module, e, ptr);
  452. } else {
  453. res = lb_add_local(p, e->type, e);
  454. }
  455. if (e->Variable.param_value.kind != ParameterValue_Invalid) {
  456. lbValue c = lb_handle_param_value(p, e->type, e->Variable.param_value, e->token.pos);
  457. lb_addr_store(p, res, c);
  458. }
  459. }
  460. }
  461. }
  462. }
  463. if (p->type->Proc.calling_convention == ProcCC_Odin) {
  464. lb_push_context_onto_stack_from_implicit_parameter(p);
  465. }
  466. lb_start_block(p, p->entry_block);
  467. if (p->debug_info != nullptr) {
  468. TokenPos pos = {};
  469. if (p->body != nullptr) {
  470. pos = ast_token(p->body).pos;
  471. } else if (p->type_expr != nullptr) {
  472. pos = ast_token(p->type_expr).pos;
  473. } else if (p->entity != nullptr) {
  474. pos = p->entity->token.pos;
  475. }
  476. if (pos.file_id != 0) {
  477. LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_token_pos(p, pos));
  478. }
  479. if (p->context_stack.count != 0) {
  480. lb_add_debug_context_variable(p, lb_find_or_generate_context_ptr(p));
  481. }
  482. }
  483. }
  484. void lb_end_procedure_body(lbProcedure *p) {
  485. LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
  486. LLVMBuildBr(p->builder, p->entry_block->block);
  487. LLVMPositionBuilderAtEnd(p->builder, p->curr_block->block);
  488. LLVMValueRef instr = nullptr;
  489. // Make sure there is a "ret void" at the end of a procedure with no return type
  490. if (p->type->Proc.result_count == 0) {
  491. instr = LLVMGetLastInstruction(p->curr_block->block);
  492. if (!lb_is_instr_terminating(instr)) {
  493. lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
  494. LLVMBuildRetVoid(p->builder);
  495. }
  496. }
  497. LLVMBasicBlockRef first_block = LLVMGetFirstBasicBlock(p->value);
  498. LLVMBasicBlockRef block = nullptr;
  499. // Make sure every block terminates, and if not, make it unreachable
  500. for (block = first_block; block != nullptr; block = LLVMGetNextBasicBlock(block)) {
  501. instr = LLVMGetLastInstruction(block);
  502. if (instr == nullptr || !lb_is_instr_terminating(instr)) {
  503. LLVMPositionBuilderAtEnd(p->builder, block);
  504. LLVMBuildUnreachable(p->builder);
  505. }
  506. }
  507. p->curr_block = nullptr;
  508. p->state_flags = 0;
  509. }
  510. void lb_end_procedure(lbProcedure *p) {
  511. LLVMDisposeBuilder(p->builder);
  512. }
  513. void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e) {
  514. GB_ASSERT(pd->body != nullptr);
  515. lbModule *m = p->module;
  516. auto *min_dep_set = &m->info->minimum_dependency_set;
  517. if (ptr_set_exists(min_dep_set, e) == false) {
  518. // NOTE(bill): Nothing depends upon it so doesn't need to be built
  519. return;
  520. }
  521. // NOTE(bill): Generate a new name
  522. // parent.name-guid
  523. String original_name = e->token.string;
  524. String pd_name = original_name;
  525. if (e->Procedure.link_name.len > 0) {
  526. pd_name = e->Procedure.link_name;
  527. }
  528. isize name_len = p->name.len + 1 + pd_name.len + 1 + 10 + 1;
  529. char *name_text = gb_alloc_array(permanent_allocator(), char, name_len);
  530. i32 guid = cast(i32)p->children.count;
  531. name_len = gb_snprintf(name_text, name_len, "%.*s.%.*s-%d", LIT(p->name), LIT(pd_name), guid);
  532. String name = make_string(cast(u8 *)name_text, name_len-1);
  533. e->Procedure.link_name = name;
  534. lbProcedure *nested_proc = lb_create_procedure(p->module, e);
  535. e->code_gen_procedure = nested_proc;
  536. lbValue value = {};
  537. value.value = nested_proc->value;
  538. value.type = nested_proc->type;
  539. lb_add_entity(m, e, value);
  540. array_add(&p->children, nested_proc);
  541. array_add(&m->procedures_to_generate, nested_proc);
  542. }
  543. Array<lbValue> lb_value_to_array(lbProcedure *p, lbValue value) {
  544. Array<lbValue> array = {};
  545. Type *t = base_type(value.type);
  546. if (t == nullptr) {
  547. // Do nothing
  548. } else if (is_type_tuple(t)) {
  549. GB_ASSERT(t->kind == Type_Tuple);
  550. auto *rt = &t->Tuple;
  551. if (rt->variables.count > 0) {
  552. array = array_make<lbValue>(permanent_allocator(), rt->variables.count);
  553. for_array(i, rt->variables) {
  554. lbValue elem = lb_emit_struct_ev(p, value, cast(i32)i);
  555. array[i] = elem;
  556. }
  557. }
  558. } else {
  559. array = array_make<lbValue>(permanent_allocator(), 1);
  560. array[0] = value;
  561. }
  562. return array;
  563. }
  564. lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, Array<lbValue> const &processed_args, Type *abi_rt, lbAddr context_ptr, ProcInlining inlining) {
  565. GB_ASSERT(p->module->ctx == LLVMGetTypeContext(LLVMTypeOf(value.value)));
  566. unsigned arg_count = cast(unsigned)processed_args.count;
  567. if (return_ptr.value != nullptr) {
  568. arg_count += 1;
  569. }
  570. if (context_ptr.addr.value != nullptr) {
  571. arg_count += 1;
  572. }
  573. LLVMValueRef *args = gb_alloc_array(permanent_allocator(), LLVMValueRef, arg_count);
  574. isize arg_index = 0;
  575. if (return_ptr.value != nullptr) {
  576. args[arg_index++] = return_ptr.value;
  577. }
  578. for_array(i, processed_args) {
  579. lbValue arg = processed_args[i];
  580. args[arg_index++] = arg.value;
  581. }
  582. if (context_ptr.addr.value != nullptr) {
  583. LLVMValueRef cp = context_ptr.addr.value;
  584. cp = LLVMBuildPointerCast(p->builder, cp, lb_type(p->module, t_rawptr), "");
  585. args[arg_index++] = cp;
  586. }
  587. LLVMBasicBlockRef curr_block = LLVMGetInsertBlock(p->builder);
  588. GB_ASSERT(curr_block != p->decl_block->block);
  589. {
  590. LLVMTypeRef ftp = lb_type(p->module, value.type);
  591. LLVMValueRef fn = value.value;
  592. if (!lb_is_type_kind(LLVMTypeOf(value.value), LLVMFunctionTypeKind)) {
  593. fn = LLVMBuildPointerCast(p->builder, fn, ftp, "");
  594. }
  595. LLVMTypeRef fnp = LLVMGetElementType(LLVMTypeOf(fn));
  596. GB_ASSERT_MSG(lb_is_type_kind(fnp, LLVMFunctionTypeKind), "%s", LLVMPrintTypeToString(fnp));
  597. {
  598. unsigned param_count = LLVMCountParamTypes(fnp);
  599. GB_ASSERT(arg_count >= param_count);
  600. LLVMTypeRef *param_types = gb_alloc_array(temporary_allocator(), LLVMTypeRef, param_count);
  601. LLVMGetParamTypes(fnp, param_types);
  602. for (unsigned i = 0; i < param_count; i++) {
  603. LLVMTypeRef param_type = param_types[i];
  604. LLVMTypeRef arg_type = LLVMTypeOf(args[i]);
  605. // LLVMTypeKind param_kind = LLVMGetTypeKind(param_type);
  606. // LLVMTypeKind arg_kind = LLVMGetTypeKind(arg_type);
  607. GB_ASSERT_MSG(
  608. arg_type == param_type,
  609. "Parameter types do not match: %s != %s, argument: %s",
  610. LLVMPrintTypeToString(arg_type),
  611. LLVMPrintTypeToString(param_type),
  612. LLVMPrintValueToString(args[i])
  613. );
  614. }
  615. }
  616. LLVMValueRef ret = LLVMBuildCall2(p->builder, fnp, fn, args, arg_count, "");
  617. switch (inlining) {
  618. case ProcInlining_none:
  619. break;
  620. case ProcInlining_inline:
  621. LLVMAddCallSiteAttribute(ret, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(p->module->ctx, "alwaysinline"));
  622. break;
  623. case ProcInlining_no_inline:
  624. LLVMAddCallSiteAttribute(ret, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(p->module->ctx, "noinline"));
  625. break;
  626. }
  627. lbValue res = {};
  628. res.value = ret;
  629. res.type = abi_rt;
  630. return res;
  631. }
  632. }
  633. lbValue lb_lookup_runtime_procedure(lbModule *m, String const &name) {
  634. AstPackage *pkg = m->info->runtime_package;
  635. Entity *e = scope_lookup_current(pkg->scope, name);
  636. return lb_find_procedure_value_from_entity(m, e);
  637. }
  638. lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args) {
  639. String name = make_string_c(c_name);
  640. lbValue proc = lb_lookup_runtime_procedure(p->module, name);
  641. return lb_emit_call(p, proc, args);
  642. }
  643. lbValue lb_emit_conjugate(lbProcedure *p, lbValue val, Type *type) {
  644. lbValue res = {};
  645. Type *t = val.type;
  646. if (is_type_complex(t)) {
  647. res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, false));
  648. lbValue real = lb_emit_struct_ev(p, val, 0);
  649. lbValue imag = lb_emit_struct_ev(p, val, 1);
  650. imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type);
  651. lb_emit_store(p, lb_emit_struct_ep(p, res, 0), real);
  652. lb_emit_store(p, lb_emit_struct_ep(p, res, 1), imag);
  653. } else if (is_type_quaternion(t)) {
  654. // @QuaternionLayout
  655. res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, false));
  656. lbValue real = lb_emit_struct_ev(p, val, 3);
  657. lbValue imag = lb_emit_struct_ev(p, val, 0);
  658. lbValue jmag = lb_emit_struct_ev(p, val, 1);
  659. lbValue kmag = lb_emit_struct_ev(p, val, 2);
  660. imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type);
  661. jmag = lb_emit_unary_arith(p, Token_Sub, jmag, jmag.type);
  662. kmag = lb_emit_unary_arith(p, Token_Sub, kmag, kmag.type);
  663. lb_emit_store(p, lb_emit_struct_ep(p, res, 3), real);
  664. lb_emit_store(p, lb_emit_struct_ep(p, res, 0), imag);
  665. lb_emit_store(p, lb_emit_struct_ep(p, res, 1), jmag);
  666. lb_emit_store(p, lb_emit_struct_ep(p, res, 2), kmag);
  667. } else if (is_type_array_like(t)) {
  668. res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, true));
  669. Type *elem_type = base_array_type(t);
  670. i64 count = get_array_type_count(t);
  671. for (i64 i = 0; i < count; i++) {
  672. lbValue dst = lb_emit_array_epi(p, res, i);
  673. lbValue elem = lb_emit_struct_ev(p, val, cast(i32)i);
  674. elem = lb_emit_conjugate(p, elem, elem_type);
  675. lb_emit_store(p, dst, elem);
  676. }
  677. } else if (is_type_matrix(t)) {
  678. Type *mt = base_type(t);
  679. GB_ASSERT(mt->kind == Type_Matrix);
  680. Type *elem_type = mt->Matrix.elem;
  681. res = lb_addr_get_ptr(p, lb_add_local_generated(p, type, true));
  682. for (i64 j = 0; j < mt->Matrix.column_count; j++) {
  683. for (i64 i = 0; i < mt->Matrix.row_count; i++) {
  684. lbValue dst = lb_emit_matrix_epi(p, res, i, j);
  685. lbValue elem = lb_emit_matrix_ev(p, val, i, j);
  686. elem = lb_emit_conjugate(p, elem, elem_type);
  687. lb_emit_store(p, dst, elem);
  688. }
  689. }
  690. }
  691. return lb_emit_load(p, res);
  692. }
  693. lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining, bool use_copy_elision_hint) {
  694. lbModule *m = p->module;
  695. Type *pt = base_type(value.type);
  696. GB_ASSERT(pt->kind == Type_Proc);
  697. Type *results = pt->Proc.results;
  698. if (p->entity != nullptr) {
  699. if (p->entity->flags & EntityFlag_Disabled) {
  700. return {};
  701. }
  702. }
  703. lbAddr context_ptr = {};
  704. if (pt->Proc.calling_convention == ProcCC_Odin) {
  705. context_ptr = lb_find_or_generate_context_ptr(p);
  706. }
  707. defer (if (pt->Proc.diverging) {
  708. LLVMBuildUnreachable(p->builder);
  709. });
  710. bool is_c_vararg = pt->Proc.c_vararg;
  711. isize param_count = pt->Proc.param_count;
  712. if (is_c_vararg) {
  713. GB_ASSERT(param_count-1 <= args.count);
  714. param_count -= 1;
  715. } else {
  716. GB_ASSERT_MSG(param_count == args.count, "%td == %td", param_count, args.count);
  717. }
  718. lbValue result = {};
  719. auto processed_args = array_make<lbValue>(permanent_allocator(), 0, args.count);
  720. {
  721. lbFunctionType *ft = lb_get_function_type(m, p, pt);
  722. bool return_by_pointer = ft->ret.kind == lbArg_Indirect;
  723. unsigned param_index = 0;
  724. for (isize i = 0; i < param_count; i++) {
  725. Entity *e = pt->Proc.params->Tuple.variables[i];
  726. if (e->kind != Entity_Variable) {
  727. continue;
  728. }
  729. GB_ASSERT(e->flags & EntityFlag_Param);
  730. Type *original_type = e->type;
  731. lbArgType *arg = &ft->args[param_index];
  732. if (arg->kind == lbArg_Ignore) {
  733. continue;
  734. }
  735. lbValue x = lb_emit_conv(p, args[i], original_type);
  736. LLVMTypeRef xt = lb_type(p->module, x.type);
  737. if (arg->kind == lbArg_Direct) {
  738. LLVMTypeRef abi_type = arg->cast_type;
  739. if (!abi_type) {
  740. abi_type = arg->type;
  741. }
  742. if (xt == abi_type) {
  743. array_add(&processed_args, x);
  744. } else {
  745. x.value = OdinLLVMBuildTransmute(p, x.value, abi_type);
  746. array_add(&processed_args, x);
  747. }
  748. } else if (arg->kind == lbArg_Indirect) {
  749. lbValue ptr = {};
  750. if (arg->is_byval) {
  751. ptr = lb_copy_value_to_ptr(p, x, original_type, arg->byval_alignment);
  752. } else if (is_calling_convention_odin(pt->Proc.calling_convention)) {
  753. // NOTE(bill): Odin parameters are immutable so the original value can be passed if possible
  754. // i.e. `T const &` in C++
  755. ptr = lb_address_from_load_or_generate_local(p, x);
  756. } else {
  757. ptr = lb_copy_value_to_ptr(p, x, original_type, 16);
  758. }
  759. array_add(&processed_args, ptr);
  760. }
  761. param_index += 1;
  762. }
  763. if (is_c_vararg) {
  764. for (isize i = processed_args.count; i < args.count; i++) {
  765. array_add(&processed_args, args[i]);
  766. }
  767. }
  768. if (inlining == ProcInlining_none) {
  769. inlining = p->inlining;
  770. }
  771. Type *rt = reduce_tuple_to_single_type(results);
  772. if (return_by_pointer) {
  773. lbValue return_ptr = {};
  774. if (use_copy_elision_hint && p->copy_elision_hint.ptr.value != nullptr) {
  775. if (are_types_identical(type_deref(p->copy_elision_hint.ptr.type), rt)) {
  776. return_ptr = lb_consume_copy_elision_hint(p);
  777. }
  778. }
  779. if (return_ptr.value == nullptr) {
  780. lbAddr r = lb_add_local_generated(p, rt, true);
  781. return_ptr = r.addr;
  782. }
  783. GB_ASSERT(is_type_pointer(return_ptr.type));
  784. lb_emit_call_internal(p, value, return_ptr, processed_args, nullptr, context_ptr, inlining);
  785. result = lb_emit_load(p, return_ptr);
  786. } else if (rt != nullptr) {
  787. result = lb_emit_call_internal(p, value, {}, processed_args, rt, context_ptr, inlining);
  788. if (ft->ret.cast_type) {
  789. result.value = OdinLLVMBuildTransmute(p, result.value, ft->ret.cast_type);
  790. }
  791. result.value = OdinLLVMBuildTransmute(p, result.value, ft->ret.type);
  792. result.type = rt;
  793. if (LLVMTypeOf(result.value) == LLVMInt1TypeInContext(p->module->ctx)) {
  794. result.type = t_llvm_bool;
  795. }
  796. if (!is_type_tuple(rt)) {
  797. result = lb_emit_conv(p, result, rt);
  798. }
  799. } else {
  800. lb_emit_call_internal(p, value, {}, processed_args, nullptr, context_ptr, inlining);
  801. }
  802. }
  803. Entity **found = map_get(&p->module->procedure_values, hash_pointer(value.value));
  804. if (found != nullptr) {
  805. Entity *e = *found;
  806. if (e != nullptr && entity_has_deferred_procedure(e)) {
  807. DeferredProcedureKind kind = e->Procedure.deferred_procedure.kind;
  808. Entity *deferred_entity = e->Procedure.deferred_procedure.entity;
  809. lbValue deferred = lb_find_procedure_value_from_entity(p->module, deferred_entity);
  810. auto in_args = args;
  811. Array<lbValue> result_as_args = {};
  812. switch (kind) {
  813. case DeferredProcedure_none:
  814. break;
  815. case DeferredProcedure_in:
  816. result_as_args = in_args;
  817. break;
  818. case DeferredProcedure_out:
  819. result_as_args = lb_value_to_array(p, result);
  820. break;
  821. case DeferredProcedure_in_out:
  822. {
  823. auto out_args = lb_value_to_array(p, result);
  824. array_init(&result_as_args, permanent_allocator(), in_args.count + out_args.count);
  825. array_copy(&result_as_args, in_args, 0);
  826. array_copy(&result_as_args, out_args, in_args.count);
  827. }
  828. break;
  829. }
  830. lb_add_defer_proc(p, p->scope_index, deferred, result_as_args);
  831. }
  832. }
  833. return result;
  834. }
  835. lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, BuiltinProcId id) {
  836. ast_node(ce, CallExpr, expr);
  837. switch (id) {
  838. case BuiltinProc_DIRECTIVE: {
  839. ast_node(bd, BasicDirective, ce->proc);
  840. String name = bd->name.string;
  841. GB_ASSERT(name == "location");
  842. String procedure = p->entity->token.string;
  843. TokenPos pos = ast_token(ce->proc).pos;
  844. if (ce->args.count > 0) {
  845. Ast *ident = unselector_expr(ce->args[0]);
  846. GB_ASSERT(ident->kind == Ast_Ident);
  847. Entity *e = entity_of_node(ident);
  848. GB_ASSERT(e != nullptr);
  849. if (e->parent_proc_decl != nullptr && e->parent_proc_decl->entity != nullptr) {
  850. procedure = e->parent_proc_decl->entity->token.string;
  851. } else {
  852. procedure = str_lit("");
  853. }
  854. pos = e->token.pos;
  855. }
  856. return lb_emit_source_code_location(p, procedure, pos);
  857. }
  858. case BuiltinProc_type_info_of: {
  859. Ast *arg = ce->args[0];
  860. TypeAndValue tav = type_and_value_of_expr(arg);
  861. if (tav.mode == Addressing_Type) {
  862. Type *t = default_type(type_of_expr(arg));
  863. return lb_type_info(p->module, t);
  864. }
  865. GB_ASSERT(is_type_typeid(tav.type));
  866. auto args = array_make<lbValue>(permanent_allocator(), 1);
  867. args[0] = lb_build_expr(p, arg);
  868. return lb_emit_runtime_call(p, "__type_info_of", args);
  869. }
  870. case BuiltinProc_typeid_of: {
  871. Ast *arg = ce->args[0];
  872. TypeAndValue tav = type_and_value_of_expr(arg);
  873. GB_ASSERT(tav.mode == Addressing_Type);
  874. Type *t = default_type(type_of_expr(arg));
  875. return lb_typeid(p->module, t);
  876. }
  877. case BuiltinProc_len: {
  878. lbValue v = lb_build_expr(p, ce->args[0]);
  879. Type *t = base_type(v.type);
  880. if (is_type_pointer(t)) {
  881. // IMPORTANT TODO(bill): Should there be a nil pointer check?
  882. v = lb_emit_load(p, v);
  883. t = type_deref(t);
  884. }
  885. if (is_type_cstring(t)) {
  886. return lb_cstring_len(p, v);
  887. } else if (is_type_string(t)) {
  888. return lb_string_len(p, v);
  889. } else if (is_type_array(t)) {
  890. GB_PANIC("Array lengths are constant");
  891. } else if (is_type_slice(t)) {
  892. return lb_slice_len(p, v);
  893. } else if (is_type_dynamic_array(t)) {
  894. return lb_dynamic_array_len(p, v);
  895. } else if (is_type_map(t)) {
  896. return lb_map_len(p, v);
  897. } else if (is_type_soa_struct(t)) {
  898. return lb_soa_struct_len(p, v);
  899. }
  900. GB_PANIC("Unreachable");
  901. break;
  902. }
  903. case BuiltinProc_cap: {
  904. lbValue v = lb_build_expr(p, ce->args[0]);
  905. Type *t = base_type(v.type);
  906. if (is_type_pointer(t)) {
  907. // IMPORTANT TODO(bill): Should there be a nil pointer check?
  908. v = lb_emit_load(p, v);
  909. t = type_deref(t);
  910. }
  911. if (is_type_string(t)) {
  912. GB_PANIC("Unreachable");
  913. } else if (is_type_array(t)) {
  914. GB_PANIC("Array lengths are constant");
  915. } else if (is_type_slice(t)) {
  916. return lb_slice_len(p, v);
  917. } else if (is_type_dynamic_array(t)) {
  918. return lb_dynamic_array_cap(p, v);
  919. } else if (is_type_map(t)) {
  920. return lb_map_cap(p, v);
  921. } else if (is_type_soa_struct(t)) {
  922. return lb_soa_struct_cap(p, v);
  923. }
  924. GB_PANIC("Unreachable");
  925. break;
  926. }
  927. case BuiltinProc_swizzle: {
  928. isize index_count = ce->args.count-1;
  929. if (is_type_simd_vector(tv.type)) {
  930. lbValue vec = lb_build_expr(p, ce->args[0]);
  931. if (index_count == 0) {
  932. return vec;
  933. }
  934. unsigned mask_len = cast(unsigned)index_count;
  935. LLVMValueRef *mask_elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, index_count);
  936. for (isize i = 1; i < ce->args.count; i++) {
  937. TypeAndValue tv = type_and_value_of_expr(ce->args[i]);
  938. GB_ASSERT(is_type_integer(tv.type));
  939. GB_ASSERT(tv.value.kind == ExactValue_Integer);
  940. u32 index = cast(u32)big_int_to_i64(&tv.value.value_integer);
  941. mask_elems[i-1] = LLVMConstInt(lb_type(p->module, t_u32), index, false);
  942. }
  943. LLVMValueRef mask = LLVMConstVector(mask_elems, mask_len);
  944. LLVMValueRef v1 = vec.value;
  945. LLVMValueRef v2 = vec.value;
  946. lbValue res = {};
  947. res.type = tv.type;
  948. res.value = LLVMBuildShuffleVector(p->builder, v1, v2, mask, "");
  949. return res;
  950. }
  951. lbAddr addr = lb_build_array_swizzle_addr(p, ce, tv);
  952. return lb_addr_load(p, addr);
  953. }
  954. case BuiltinProc_complex: {
  955. lbValue real = lb_build_expr(p, ce->args[0]);
  956. lbValue imag = lb_build_expr(p, ce->args[1]);
  957. lbAddr dst_addr = lb_add_local_generated(p, tv.type, false);
  958. lbValue dst = lb_addr_get_ptr(p, dst_addr);
  959. Type *ft = base_complex_elem_type(tv.type);
  960. real = lb_emit_conv(p, real, ft);
  961. imag = lb_emit_conv(p, imag, ft);
  962. lb_emit_store(p, lb_emit_struct_ep(p, dst, 0), real);
  963. lb_emit_store(p, lb_emit_struct_ep(p, dst, 1), imag);
  964. return lb_emit_load(p, dst);
  965. }
  966. case BuiltinProc_quaternion: {
  967. lbValue real = lb_build_expr(p, ce->args[0]);
  968. lbValue imag = lb_build_expr(p, ce->args[1]);
  969. lbValue jmag = lb_build_expr(p, ce->args[2]);
  970. lbValue kmag = lb_build_expr(p, ce->args[3]);
  971. // @QuaternionLayout
  972. lbAddr dst_addr = lb_add_local_generated(p, tv.type, false);
  973. lbValue dst = lb_addr_get_ptr(p, dst_addr);
  974. Type *ft = base_complex_elem_type(tv.type);
  975. real = lb_emit_conv(p, real, ft);
  976. imag = lb_emit_conv(p, imag, ft);
  977. jmag = lb_emit_conv(p, jmag, ft);
  978. kmag = lb_emit_conv(p, kmag, ft);
  979. lb_emit_store(p, lb_emit_struct_ep(p, dst, 3), real);
  980. lb_emit_store(p, lb_emit_struct_ep(p, dst, 0), imag);
  981. lb_emit_store(p, lb_emit_struct_ep(p, dst, 1), jmag);
  982. lb_emit_store(p, lb_emit_struct_ep(p, dst, 2), kmag);
  983. return lb_emit_load(p, dst);
  984. }
  985. case BuiltinProc_real: {
  986. lbValue val = lb_build_expr(p, ce->args[0]);
  987. if (is_type_complex(val.type)) {
  988. lbValue real = lb_emit_struct_ev(p, val, 0);
  989. return lb_emit_conv(p, real, tv.type);
  990. } else if (is_type_quaternion(val.type)) {
  991. // @QuaternionLayout
  992. lbValue real = lb_emit_struct_ev(p, val, 3);
  993. return lb_emit_conv(p, real, tv.type);
  994. }
  995. GB_PANIC("invalid type for real");
  996. return {};
  997. }
  998. case BuiltinProc_imag: {
  999. lbValue val = lb_build_expr(p, ce->args[0]);
  1000. if (is_type_complex(val.type)) {
  1001. lbValue imag = lb_emit_struct_ev(p, val, 1);
  1002. return lb_emit_conv(p, imag, tv.type);
  1003. } else if (is_type_quaternion(val.type)) {
  1004. // @QuaternionLayout
  1005. lbValue imag = lb_emit_struct_ev(p, val, 0);
  1006. return lb_emit_conv(p, imag, tv.type);
  1007. }
  1008. GB_PANIC("invalid type for imag");
  1009. return {};
  1010. }
  1011. case BuiltinProc_jmag: {
  1012. lbValue val = lb_build_expr(p, ce->args[0]);
  1013. if (is_type_quaternion(val.type)) {
  1014. // @QuaternionLayout
  1015. lbValue imag = lb_emit_struct_ev(p, val, 1);
  1016. return lb_emit_conv(p, imag, tv.type);
  1017. }
  1018. GB_PANIC("invalid type for jmag");
  1019. return {};
  1020. }
  1021. case BuiltinProc_kmag: {
  1022. lbValue val = lb_build_expr(p, ce->args[0]);
  1023. if (is_type_quaternion(val.type)) {
  1024. // @QuaternionLayout
  1025. lbValue imag = lb_emit_struct_ev(p, val, 2);
  1026. return lb_emit_conv(p, imag, tv.type);
  1027. }
  1028. GB_PANIC("invalid type for kmag");
  1029. return {};
  1030. }
  1031. case BuiltinProc_conj: {
  1032. lbValue val = lb_build_expr(p, ce->args[0]);
  1033. return lb_emit_conjugate(p, val, tv.type);
  1034. }
  1035. case BuiltinProc_expand_to_tuple: {
  1036. lbValue val = lb_build_expr(p, ce->args[0]);
  1037. Type *t = base_type(val.type);
  1038. if (!is_type_tuple(tv.type)) {
  1039. if (t->kind == Type_Struct) {
  1040. GB_ASSERT(t->Struct.fields.count == 1);
  1041. return lb_emit_struct_ev(p, val, 0);
  1042. } else if (t->kind == Type_Array) {
  1043. GB_ASSERT(t->Array.count == 1);
  1044. return lb_emit_array_epi(p, val, 0);
  1045. } else {
  1046. GB_PANIC("Unknown type of expand_to_tuple");
  1047. }
  1048. }
  1049. GB_ASSERT(is_type_tuple(tv.type));
  1050. // NOTE(bill): Doesn't need to be zero because it will be initialized in the loops
  1051. lbValue tuple = lb_addr_get_ptr(p, lb_add_local_generated(p, tv.type, false));
  1052. if (t->kind == Type_Struct) {
  1053. for_array(src_index, t->Struct.fields) {
  1054. Entity *field = t->Struct.fields[src_index];
  1055. i32 field_index = field->Variable.field_index;
  1056. lbValue f = lb_emit_struct_ev(p, val, field_index);
  1057. lbValue ep = lb_emit_struct_ep(p, tuple, cast(i32)src_index);
  1058. lb_emit_store(p, ep, f);
  1059. }
  1060. } else if (is_type_array_like(t)) {
  1061. // TODO(bill): Clean-up this code
  1062. lbValue ap = lb_address_from_load_or_generate_local(p, val);
  1063. i32 n = cast(i32)get_array_type_count(t);
  1064. for (i32 i = 0; i < n; i++) {
  1065. lbValue f = lb_emit_load(p, lb_emit_array_epi(p, ap, i));
  1066. lbValue ep = lb_emit_struct_ep(p, tuple, i);
  1067. lb_emit_store(p, ep, f);
  1068. }
  1069. } else {
  1070. GB_PANIC("Unknown type of expand_to_tuple");
  1071. }
  1072. return lb_emit_load(p, tuple);
  1073. }
  1074. case BuiltinProc_min: {
  1075. Type *t = type_of_expr(expr);
  1076. if (ce->args.count == 2) {
  1077. return lb_emit_min(p, t, lb_build_expr(p, ce->args[0]), lb_build_expr(p, ce->args[1]));
  1078. } else {
  1079. lbValue x = lb_build_expr(p, ce->args[0]);
  1080. for (isize i = 1; i < ce->args.count; i++) {
  1081. x = lb_emit_min(p, t, x, lb_build_expr(p, ce->args[i]));
  1082. }
  1083. return x;
  1084. }
  1085. }
  1086. case BuiltinProc_max: {
  1087. Type *t = type_of_expr(expr);
  1088. if (ce->args.count == 2) {
  1089. return lb_emit_max(p, t, lb_build_expr(p, ce->args[0]), lb_build_expr(p, ce->args[1]));
  1090. } else {
  1091. lbValue x = lb_build_expr(p, ce->args[0]);
  1092. for (isize i = 1; i < ce->args.count; i++) {
  1093. x = lb_emit_max(p, t, x, lb_build_expr(p, ce->args[i]));
  1094. }
  1095. return x;
  1096. }
  1097. }
  1098. case BuiltinProc_abs: {
  1099. lbValue x = lb_build_expr(p, ce->args[0]);
  1100. Type *t = x.type;
  1101. if (is_type_unsigned(t)) {
  1102. return x;
  1103. }
  1104. if (is_type_quaternion(t)) {
  1105. i64 sz = 8*type_size_of(t);
  1106. auto args = array_make<lbValue>(permanent_allocator(), 1);
  1107. args[0] = x;
  1108. switch (sz) {
  1109. case 64: return lb_emit_runtime_call(p, "abs_quaternion64", args);
  1110. case 128: return lb_emit_runtime_call(p, "abs_quaternion128", args);
  1111. case 256: return lb_emit_runtime_call(p, "abs_quaternion256", args);
  1112. }
  1113. GB_PANIC("Unknown complex type");
  1114. } else if (is_type_complex(t)) {
  1115. i64 sz = 8*type_size_of(t);
  1116. auto args = array_make<lbValue>(permanent_allocator(), 1);
  1117. args[0] = x;
  1118. switch (sz) {
  1119. case 32: return lb_emit_runtime_call(p, "abs_complex32", args);
  1120. case 64: return lb_emit_runtime_call(p, "abs_complex64", args);
  1121. case 128: return lb_emit_runtime_call(p, "abs_complex128", args);
  1122. }
  1123. GB_PANIC("Unknown complex type");
  1124. }
  1125. lbValue zero = lb_const_nil(p->module, t);
  1126. lbValue cond = lb_emit_comp(p, Token_Lt, x, zero);
  1127. lbValue neg = lb_emit_unary_arith(p, Token_Sub, x, t);
  1128. return lb_emit_select(p, cond, neg, x);
  1129. }
  1130. case BuiltinProc_clamp:
  1131. return lb_emit_clamp(p, type_of_expr(expr),
  1132. lb_build_expr(p, ce->args[0]),
  1133. lb_build_expr(p, ce->args[1]),
  1134. lb_build_expr(p, ce->args[2]));
  1135. case BuiltinProc_soa_zip:
  1136. return lb_soa_zip(p, ce, tv);
  1137. case BuiltinProc_soa_unzip:
  1138. return lb_soa_unzip(p, ce, tv);
  1139. case BuiltinProc_transpose:
  1140. {
  1141. lbValue m = lb_build_expr(p, ce->args[0]);
  1142. return lb_emit_matrix_tranpose(p, m, tv.type);
  1143. }
  1144. case BuiltinProc_outer_product:
  1145. {
  1146. lbValue a = lb_build_expr(p, ce->args[0]);
  1147. lbValue b = lb_build_expr(p, ce->args[1]);
  1148. return lb_emit_outer_product(p, a, b, tv.type);
  1149. }
  1150. case BuiltinProc_hadamard_product:
  1151. {
  1152. lbValue a = lb_build_expr(p, ce->args[0]);
  1153. lbValue b = lb_build_expr(p, ce->args[1]);
  1154. if (is_type_array(tv.type)) {
  1155. return lb_emit_arith(p, Token_Mul, a, b, tv.type);
  1156. }
  1157. GB_ASSERT(is_type_matrix(tv.type));
  1158. return lb_emit_arith_matrix(p, Token_Mul, a, b, tv.type, true);
  1159. }
  1160. case BuiltinProc_matrix_flatten:
  1161. {
  1162. lbValue m = lb_build_expr(p, ce->args[0]);
  1163. return lb_emit_matrix_flatten(p, m, tv.type);
  1164. }
  1165. // "Intrinsics"
  1166. case BuiltinProc_alloca:
  1167. {
  1168. lbValue sz = lb_build_expr(p, ce->args[0]);
  1169. i64 al = exact_value_to_i64(type_and_value_of_expr(ce->args[1]).value);
  1170. lbValue res = {};
  1171. res.type = t_u8_ptr;
  1172. res.value = LLVMBuildArrayAlloca(p->builder, lb_type(p->module, t_u8), sz.value, "");
  1173. LLVMSetAlignment(res.value, cast(unsigned)al);
  1174. return res;
  1175. }
  1176. case BuiltinProc_cpu_relax:
  1177. if (build_context.metrics.arch == TargetArch_386 ||
  1178. build_context.metrics.arch == TargetArch_amd64) {
  1179. LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false);
  1180. LLVMValueRef the_asm = LLVMGetInlineAsm(func_type,
  1181. cast(char *)"pause", 5,
  1182. cast(char *)"", 0,
  1183. /*HasSideEffects*/true, /*IsAlignStack*/false,
  1184. LLVMInlineAsmDialectATT
  1185. );
  1186. GB_ASSERT(the_asm != nullptr);
  1187. LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
  1188. } else if (build_context.metrics.arch == TargetArch_arm64) {
  1189. LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false);
  1190. LLVMValueRef the_asm = LLVMGetInlineAsm(func_type,
  1191. cast(char *)"yield", 5,
  1192. cast(char *)"", 0,
  1193. /*HasSideEffects*/true, /*IsAlignStack*/false,
  1194. LLVMInlineAsmDialectATT
  1195. );
  1196. GB_ASSERT(the_asm != nullptr);
  1197. LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
  1198. }
  1199. return {};
  1200. case BuiltinProc_debug_trap:
  1201. case BuiltinProc_trap:
  1202. {
  1203. char const *name = nullptr;
  1204. switch (id) {
  1205. case BuiltinProc_debug_trap: name = "llvm.debugtrap"; break;
  1206. case BuiltinProc_trap: name = "llvm.trap"; break;
  1207. }
  1208. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1209. GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
  1210. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0);
  1211. LLVMBuildCall(p->builder, ip, nullptr, 0, "");
  1212. if (id == BuiltinProc_trap) {
  1213. LLVMBuildUnreachable(p->builder);
  1214. }
  1215. return {};
  1216. }
  1217. case BuiltinProc_read_cycle_counter:
  1218. {
  1219. char const *name = "llvm.readcyclecounter";
  1220. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1221. GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
  1222. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0);
  1223. lbValue res = {};
  1224. res.value = LLVMBuildCall(p->builder, ip, nullptr, 0, "");
  1225. res.type = tv.type;
  1226. return res;
  1227. }
  1228. case BuiltinProc_count_trailing_zeros:
  1229. return lb_emit_count_trailing_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
  1230. case BuiltinProc_count_leading_zeros:
  1231. return lb_emit_count_leading_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
  1232. case BuiltinProc_count_ones:
  1233. return lb_emit_count_ones(p, lb_build_expr(p, ce->args[0]), tv.type);
  1234. case BuiltinProc_count_zeros:
  1235. return lb_emit_count_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
  1236. case BuiltinProc_reverse_bits:
  1237. return lb_emit_reverse_bits(p, lb_build_expr(p, ce->args[0]), tv.type);
  1238. case BuiltinProc_byte_swap:
  1239. {
  1240. lbValue x = lb_build_expr(p, ce->args[0]);
  1241. x = lb_emit_conv(p, x, tv.type);
  1242. return lb_emit_byte_swap(p, x, tv.type);
  1243. }
  1244. case BuiltinProc_overflow_add:
  1245. case BuiltinProc_overflow_sub:
  1246. case BuiltinProc_overflow_mul:
  1247. {
  1248. Type *main_type = tv.type;
  1249. Type *type = main_type;
  1250. if (is_type_tuple(main_type)) {
  1251. type = main_type->Tuple.variables[0]->type;
  1252. }
  1253. lbValue x = lb_build_expr(p, ce->args[0]);
  1254. lbValue y = lb_build_expr(p, ce->args[1]);
  1255. x = lb_emit_conv(p, x, type);
  1256. y = lb_emit_conv(p, y, type);
  1257. char const *name = nullptr;
  1258. if (is_type_unsigned(type)) {
  1259. switch (id) {
  1260. case BuiltinProc_overflow_add: name = "llvm.uadd.with.overflow"; break;
  1261. case BuiltinProc_overflow_sub: name = "llvm.usub.with.overflow"; break;
  1262. case BuiltinProc_overflow_mul: name = "llvm.umul.with.overflow"; break;
  1263. }
  1264. } else {
  1265. switch (id) {
  1266. case BuiltinProc_overflow_add: name = "llvm.sadd.with.overflow"; break;
  1267. case BuiltinProc_overflow_sub: name = "llvm.ssub.with.overflow"; break;
  1268. case BuiltinProc_overflow_mul: name = "llvm.smul.with.overflow"; break;
  1269. }
  1270. }
  1271. LLVMTypeRef types[1] = {lb_type(p->module, type)};
  1272. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1273. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  1274. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  1275. LLVMValueRef args[2] = {};
  1276. args[0] = x.value;
  1277. args[1] = y.value;
  1278. lbValue res = {};
  1279. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  1280. if (is_type_tuple(main_type)) {
  1281. Type *res_type = nullptr;
  1282. gbAllocator a = permanent_allocator();
  1283. res_type = alloc_type_tuple();
  1284. slice_init(&res_type->Tuple.variables, a, 2);
  1285. res_type->Tuple.variables[0] = alloc_entity_field(nullptr, blank_token, type, false, 0);
  1286. res_type->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1);
  1287. res.type = res_type;
  1288. } else {
  1289. res.value = LLVMBuildExtractValue(p->builder, res.value, 0, "");
  1290. res.type = type;
  1291. }
  1292. return res;
  1293. }
  1294. case BuiltinProc_sqrt:
  1295. {
  1296. Type *type = tv.type;
  1297. lbValue x = lb_build_expr(p, ce->args[0]);
  1298. x = lb_emit_conv(p, x, type);
  1299. char const *name = "llvm.sqrt";
  1300. LLVMTypeRef types[1] = {lb_type(p->module, type)};
  1301. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1302. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  1303. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  1304. LLVMValueRef args[1] = {};
  1305. args[0] = x.value;
  1306. lbValue res = {};
  1307. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  1308. res.type = type;
  1309. return res;
  1310. }
  1311. case BuiltinProc_mem_copy:
  1312. {
  1313. lbValue dst = lb_build_expr(p, ce->args[0]);
  1314. lbValue src = lb_build_expr(p, ce->args[1]);
  1315. lbValue len = lb_build_expr(p, ce->args[2]);
  1316. lb_mem_copy_overlapping(p, dst, src, len, false);
  1317. return {};
  1318. }
  1319. case BuiltinProc_mem_copy_non_overlapping:
  1320. {
  1321. lbValue dst = lb_build_expr(p, ce->args[0]);
  1322. lbValue src = lb_build_expr(p, ce->args[1]);
  1323. lbValue len = lb_build_expr(p, ce->args[2]);
  1324. lb_mem_copy_non_overlapping(p, dst, src, len, false);
  1325. return {};
  1326. }
  1327. case BuiltinProc_mem_zero:
  1328. {
  1329. lbValue ptr = lb_build_expr(p, ce->args[0]);
  1330. lbValue len = lb_build_expr(p, ce->args[1]);
  1331. ptr = lb_emit_conv(p, ptr, t_rawptr);
  1332. len = lb_emit_conv(p, len, t_int);
  1333. unsigned alignment = 1;
  1334. lb_mem_zero_ptr_internal(p, ptr.value, len.value, alignment);
  1335. return {};
  1336. }
  1337. case BuiltinProc_ptr_offset:
  1338. {
  1339. lbValue ptr = lb_build_expr(p, ce->args[0]);
  1340. lbValue len = lb_build_expr(p, ce->args[1]);
  1341. len = lb_emit_conv(p, len, t_int);
  1342. LLVMValueRef indices[1] = {
  1343. len.value,
  1344. };
  1345. lbValue res = {};
  1346. res.type = tv.type;
  1347. res.value = LLVMBuildGEP(p->builder, ptr.value, indices, gb_count_of(indices), "");
  1348. return res;
  1349. }
  1350. case BuiltinProc_ptr_sub:
  1351. {
  1352. lbValue ptr0 = lb_build_expr(p, ce->args[0]);
  1353. lbValue ptr1 = lb_build_expr(p, ce->args[1]);
  1354. LLVMTypeRef type_int = lb_type(p->module, t_int);
  1355. LLVMValueRef diff = LLVMBuildPtrDiff(p->builder, ptr0.value, ptr1.value, "");
  1356. diff = LLVMBuildIntCast2(p->builder, diff, type_int, /*signed*/true, "");
  1357. lbValue res = {};
  1358. res.type = t_int;
  1359. res.value = diff;
  1360. return res;
  1361. }
  1362. case BuiltinProc_atomic_fence:
  1363. LLVMBuildFence(p->builder, LLVMAtomicOrderingSequentiallyConsistent, false, "");
  1364. return {};
  1365. case BuiltinProc_atomic_fence_acq:
  1366. LLVMBuildFence(p->builder, LLVMAtomicOrderingAcquire, false, "");
  1367. return {};
  1368. case BuiltinProc_atomic_fence_rel:
  1369. LLVMBuildFence(p->builder, LLVMAtomicOrderingRelease, false, "");
  1370. return {};
  1371. case BuiltinProc_atomic_fence_acqrel:
  1372. LLVMBuildFence(p->builder, LLVMAtomicOrderingAcquireRelease, false, "");
  1373. return {};
  1374. case BuiltinProc_volatile_store:
  1375. case BuiltinProc_atomic_store:
  1376. case BuiltinProc_atomic_store_rel:
  1377. case BuiltinProc_atomic_store_relaxed:
  1378. case BuiltinProc_atomic_store_unordered: {
  1379. lbValue dst = lb_build_expr(p, ce->args[0]);
  1380. lbValue val = lb_build_expr(p, ce->args[1]);
  1381. val = lb_emit_conv(p, val, type_deref(dst.type));
  1382. LLVMValueRef instr = LLVMBuildStore(p->builder, val.value, dst.value);
  1383. switch (id) {
  1384. case BuiltinProc_volatile_store: LLVMSetVolatile(instr, true); break;
  1385. case BuiltinProc_atomic_store: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
  1386. case BuiltinProc_atomic_store_rel: LLVMSetOrdering(instr, LLVMAtomicOrderingRelease); break;
  1387. case BuiltinProc_atomic_store_relaxed: LLVMSetOrdering(instr, LLVMAtomicOrderingMonotonic); break;
  1388. case BuiltinProc_atomic_store_unordered: LLVMSetOrdering(instr, LLVMAtomicOrderingUnordered); break;
  1389. }
  1390. LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type)));
  1391. return {};
  1392. }
  1393. case BuiltinProc_volatile_load:
  1394. case BuiltinProc_atomic_load:
  1395. case BuiltinProc_atomic_load_acq:
  1396. case BuiltinProc_atomic_load_relaxed:
  1397. case BuiltinProc_atomic_load_unordered: {
  1398. lbValue dst = lb_build_expr(p, ce->args[0]);
  1399. LLVMValueRef instr = LLVMBuildLoad(p->builder, dst.value, "");
  1400. switch (id) {
  1401. case BuiltinProc_volatile_load: LLVMSetVolatile(instr, true); break;
  1402. case BuiltinProc_atomic_load: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
  1403. case BuiltinProc_atomic_load_acq: LLVMSetOrdering(instr, LLVMAtomicOrderingAcquire); break;
  1404. case BuiltinProc_atomic_load_relaxed: LLVMSetOrdering(instr, LLVMAtomicOrderingMonotonic); break;
  1405. case BuiltinProc_atomic_load_unordered: LLVMSetOrdering(instr, LLVMAtomicOrderingUnordered); break;
  1406. }
  1407. LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type)));
  1408. lbValue res = {};
  1409. res.value = instr;
  1410. res.type = type_deref(dst.type);
  1411. return res;
  1412. }
  1413. case BuiltinProc_unaligned_store:
  1414. {
  1415. lbValue dst = lb_build_expr(p, ce->args[0]);
  1416. lbValue src = lb_build_expr(p, ce->args[1]);
  1417. src = lb_address_from_load_or_generate_local(p, src);
  1418. Type *t = type_deref(dst.type);
  1419. lb_mem_copy_non_overlapping(p, dst, src, lb_const_int(p->module, t_int, type_size_of(t)), false);
  1420. return {};
  1421. }
  1422. case BuiltinProc_unaligned_load:
  1423. {
  1424. lbValue src = lb_build_expr(p, ce->args[0]);
  1425. Type *t = type_deref(src.type);
  1426. lbAddr dst = lb_add_local_generated(p, t, false);
  1427. lb_mem_copy_non_overlapping(p, dst.addr, src, lb_const_int(p->module, t_int, type_size_of(t)), false);
  1428. return lb_addr_load(p, dst);
  1429. }
  1430. case BuiltinProc_atomic_add:
  1431. case BuiltinProc_atomic_add_acq:
  1432. case BuiltinProc_atomic_add_rel:
  1433. case BuiltinProc_atomic_add_acqrel:
  1434. case BuiltinProc_atomic_add_relaxed:
  1435. case BuiltinProc_atomic_sub:
  1436. case BuiltinProc_atomic_sub_acq:
  1437. case BuiltinProc_atomic_sub_rel:
  1438. case BuiltinProc_atomic_sub_acqrel:
  1439. case BuiltinProc_atomic_sub_relaxed:
  1440. case BuiltinProc_atomic_and:
  1441. case BuiltinProc_atomic_and_acq:
  1442. case BuiltinProc_atomic_and_rel:
  1443. case BuiltinProc_atomic_and_acqrel:
  1444. case BuiltinProc_atomic_and_relaxed:
  1445. case BuiltinProc_atomic_nand:
  1446. case BuiltinProc_atomic_nand_acq:
  1447. case BuiltinProc_atomic_nand_rel:
  1448. case BuiltinProc_atomic_nand_acqrel:
  1449. case BuiltinProc_atomic_nand_relaxed:
  1450. case BuiltinProc_atomic_or:
  1451. case BuiltinProc_atomic_or_acq:
  1452. case BuiltinProc_atomic_or_rel:
  1453. case BuiltinProc_atomic_or_acqrel:
  1454. case BuiltinProc_atomic_or_relaxed:
  1455. case BuiltinProc_atomic_xor:
  1456. case BuiltinProc_atomic_xor_acq:
  1457. case BuiltinProc_atomic_xor_rel:
  1458. case BuiltinProc_atomic_xor_acqrel:
  1459. case BuiltinProc_atomic_xor_relaxed:
  1460. case BuiltinProc_atomic_xchg:
  1461. case BuiltinProc_atomic_xchg_acq:
  1462. case BuiltinProc_atomic_xchg_rel:
  1463. case BuiltinProc_atomic_xchg_acqrel:
  1464. case BuiltinProc_atomic_xchg_relaxed: {
  1465. lbValue dst = lb_build_expr(p, ce->args[0]);
  1466. lbValue val = lb_build_expr(p, ce->args[1]);
  1467. val = lb_emit_conv(p, val, type_deref(dst.type));
  1468. LLVMAtomicRMWBinOp op = {};
  1469. LLVMAtomicOrdering ordering = {};
  1470. switch (id) {
  1471. case BuiltinProc_atomic_add: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1472. case BuiltinProc_atomic_add_acq: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingAcquire; break;
  1473. case BuiltinProc_atomic_add_rel: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingRelease; break;
  1474. case BuiltinProc_atomic_add_acqrel: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1475. case BuiltinProc_atomic_add_relaxed: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingMonotonic; break;
  1476. case BuiltinProc_atomic_sub: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1477. case BuiltinProc_atomic_sub_acq: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingAcquire; break;
  1478. case BuiltinProc_atomic_sub_rel: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingRelease; break;
  1479. case BuiltinProc_atomic_sub_acqrel: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1480. case BuiltinProc_atomic_sub_relaxed: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingMonotonic; break;
  1481. case BuiltinProc_atomic_and: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1482. case BuiltinProc_atomic_and_acq: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingAcquire; break;
  1483. case BuiltinProc_atomic_and_rel: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingRelease; break;
  1484. case BuiltinProc_atomic_and_acqrel: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1485. case BuiltinProc_atomic_and_relaxed: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingMonotonic; break;
  1486. case BuiltinProc_atomic_nand: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1487. case BuiltinProc_atomic_nand_acq: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingAcquire; break;
  1488. case BuiltinProc_atomic_nand_rel: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingRelease; break;
  1489. case BuiltinProc_atomic_nand_acqrel: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1490. case BuiltinProc_atomic_nand_relaxed: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingMonotonic; break;
  1491. case BuiltinProc_atomic_or: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1492. case BuiltinProc_atomic_or_acq: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingAcquire; break;
  1493. case BuiltinProc_atomic_or_rel: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingRelease; break;
  1494. case BuiltinProc_atomic_or_acqrel: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1495. case BuiltinProc_atomic_or_relaxed: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingMonotonic; break;
  1496. case BuiltinProc_atomic_xor: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1497. case BuiltinProc_atomic_xor_acq: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingAcquire; break;
  1498. case BuiltinProc_atomic_xor_rel: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingRelease; break;
  1499. case BuiltinProc_atomic_xor_acqrel: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1500. case BuiltinProc_atomic_xor_relaxed: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingMonotonic; break;
  1501. case BuiltinProc_atomic_xchg: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  1502. case BuiltinProc_atomic_xchg_acq: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingAcquire; break;
  1503. case BuiltinProc_atomic_xchg_rel: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingRelease; break;
  1504. case BuiltinProc_atomic_xchg_acqrel: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingAcquireRelease; break;
  1505. case BuiltinProc_atomic_xchg_relaxed: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingMonotonic; break;
  1506. }
  1507. lbValue res = {};
  1508. res.value = LLVMBuildAtomicRMW(p->builder, op, dst.value, val.value, ordering, false);
  1509. res.type = tv.type;
  1510. return res;
  1511. }
  1512. case BuiltinProc_atomic_cxchg:
  1513. case BuiltinProc_atomic_cxchg_acq:
  1514. case BuiltinProc_atomic_cxchg_rel:
  1515. case BuiltinProc_atomic_cxchg_acqrel:
  1516. case BuiltinProc_atomic_cxchg_relaxed:
  1517. case BuiltinProc_atomic_cxchg_failrelaxed:
  1518. case BuiltinProc_atomic_cxchg_failacq:
  1519. case BuiltinProc_atomic_cxchg_acq_failrelaxed:
  1520. case BuiltinProc_atomic_cxchg_acqrel_failrelaxed:
  1521. case BuiltinProc_atomic_cxchgweak:
  1522. case BuiltinProc_atomic_cxchgweak_acq:
  1523. case BuiltinProc_atomic_cxchgweak_rel:
  1524. case BuiltinProc_atomic_cxchgweak_acqrel:
  1525. case BuiltinProc_atomic_cxchgweak_relaxed:
  1526. case BuiltinProc_atomic_cxchgweak_failrelaxed:
  1527. case BuiltinProc_atomic_cxchgweak_failacq:
  1528. case BuiltinProc_atomic_cxchgweak_acq_failrelaxed:
  1529. case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: {
  1530. lbValue address = lb_build_expr(p, ce->args[0]);
  1531. Type *elem = type_deref(address.type);
  1532. lbValue old_value = lb_build_expr(p, ce->args[1]);
  1533. lbValue new_value = lb_build_expr(p, ce->args[2]);
  1534. old_value = lb_emit_conv(p, old_value, elem);
  1535. new_value = lb_emit_conv(p, new_value, elem);
  1536. LLVMAtomicOrdering success_ordering = {};
  1537. LLVMAtomicOrdering failure_ordering = {};
  1538. LLVMBool weak = false;
  1539. switch (id) {
  1540. case BuiltinProc_atomic_cxchg: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  1541. case BuiltinProc_atomic_cxchg_acq: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  1542. case BuiltinProc_atomic_cxchg_rel: success_ordering = LLVMAtomicOrderingRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  1543. case BuiltinProc_atomic_cxchg_acqrel: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  1544. case BuiltinProc_atomic_cxchg_relaxed: success_ordering = LLVMAtomicOrderingMonotonic; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
  1545. case BuiltinProc_atomic_cxchg_failrelaxed: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
  1546. case BuiltinProc_atomic_cxchg_failacq: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingAcquire; weak = false; break;
  1547. case BuiltinProc_atomic_cxchg_acq_failrelaxed: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
  1548. case BuiltinProc_atomic_cxchg_acqrel_failrelaxed: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
  1549. case BuiltinProc_atomic_cxchgweak: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  1550. case BuiltinProc_atomic_cxchgweak_acq: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break;
  1551. case BuiltinProc_atomic_cxchgweak_rel: success_ordering = LLVMAtomicOrderingRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break;
  1552. case BuiltinProc_atomic_cxchgweak_acqrel: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break;
  1553. case BuiltinProc_atomic_cxchgweak_relaxed: success_ordering = LLVMAtomicOrderingMonotonic; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
  1554. case BuiltinProc_atomic_cxchgweak_failrelaxed: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
  1555. case BuiltinProc_atomic_cxchgweak_failacq: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingAcquire; weak = true; break;
  1556. case BuiltinProc_atomic_cxchgweak_acq_failrelaxed: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
  1557. case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
  1558. }
  1559. // TODO(bill): Figure out how to make it weak
  1560. LLVMBool single_threaded = weak;
  1561. LLVMValueRef value = LLVMBuildAtomicCmpXchg(
  1562. p->builder, address.value,
  1563. old_value.value, new_value.value,
  1564. success_ordering,
  1565. failure_ordering,
  1566. single_threaded
  1567. );
  1568. if (tv.type->kind == Type_Tuple) {
  1569. Type *fix_typed = alloc_type_tuple();
  1570. slice_init(&fix_typed->Tuple.variables, permanent_allocator(), 2);
  1571. fix_typed->Tuple.variables[0] = tv.type->Tuple.variables[0];
  1572. fix_typed->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1);
  1573. lbValue res = {};
  1574. res.value = value;
  1575. res.type = fix_typed;
  1576. return res;
  1577. } else {
  1578. lbValue res = {};
  1579. res.value = LLVMBuildExtractValue(p->builder, value, 0, "");
  1580. res.type = tv.type;
  1581. return res;
  1582. }
  1583. }
  1584. case BuiltinProc_type_equal_proc:
  1585. return lb_get_equal_proc_for_type(p->module, ce->args[0]->tav.type);
  1586. case BuiltinProc_type_hasher_proc:
  1587. return lb_get_hasher_proc_for_type(p->module, ce->args[0]->tav.type);
  1588. case BuiltinProc_fixed_point_mul:
  1589. case BuiltinProc_fixed_point_div:
  1590. case BuiltinProc_fixed_point_mul_sat:
  1591. case BuiltinProc_fixed_point_div_sat:
  1592. {
  1593. Type *platform_type = integer_endian_type_to_platform_type(tv.type);
  1594. lbValue x = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), platform_type);
  1595. lbValue y = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), platform_type);
  1596. lbValue scale = lb_emit_conv(p, lb_build_expr(p, ce->args[2]), t_i32);
  1597. char const *name = nullptr;
  1598. if (is_type_unsigned(tv.type)) {
  1599. switch (id) {
  1600. case BuiltinProc_fixed_point_mul: name = "llvm.umul.fix"; break;
  1601. case BuiltinProc_fixed_point_div: name = "llvm.udiv.fix"; break;
  1602. case BuiltinProc_fixed_point_mul_sat: name = "llvm.umul.fix.sat"; break;
  1603. case BuiltinProc_fixed_point_div_sat: name = "llvm.udiv.fix.sat"; break;
  1604. }
  1605. } else {
  1606. switch (id) {
  1607. case BuiltinProc_fixed_point_mul: name = "llvm.smul.fix"; break;
  1608. case BuiltinProc_fixed_point_div: name = "llvm.sdiv.fix"; break;
  1609. case BuiltinProc_fixed_point_mul_sat: name = "llvm.smul.fix.sat"; break;
  1610. case BuiltinProc_fixed_point_div_sat: name = "llvm.sdiv.fix.sat"; break;
  1611. }
  1612. }
  1613. GB_ASSERT(name != nullptr);
  1614. LLVMTypeRef types[1] = {lb_type(p->module, platform_type)};
  1615. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1616. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  1617. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  1618. lbValue res = {};
  1619. LLVMValueRef args[3] = {};
  1620. args[0] = x.value;
  1621. args[1] = y.value;
  1622. args[2] = scale.value;
  1623. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  1624. res.type = platform_type;
  1625. return lb_emit_conv(p, res, tv.type);
  1626. }
  1627. case BuiltinProc_expect:
  1628. {
  1629. Type *t = default_type(tv.type);
  1630. lbValue x = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t);
  1631. lbValue y = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t);
  1632. char const *name = "llvm.expect";
  1633. LLVMTypeRef types[1] = {lb_type(p->module, t)};
  1634. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1635. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  1636. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  1637. lbValue res = {};
  1638. LLVMValueRef args[2] = {};
  1639. args[0] = x.value;
  1640. args[1] = y.value;
  1641. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  1642. res.type = t;
  1643. return lb_emit_conv(p, res, t);
  1644. }
  1645. case BuiltinProc_prefetch_read_instruction:
  1646. case BuiltinProc_prefetch_read_data:
  1647. case BuiltinProc_prefetch_write_instruction:
  1648. case BuiltinProc_prefetch_write_data:
  1649. {
  1650. lbValue ptr = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_rawptr);
  1651. unsigned long long locality = cast(unsigned long long)exact_value_to_i64(ce->args[1]->tav.value);
  1652. unsigned long long rw = 0;
  1653. unsigned long long cache = 0;
  1654. switch (id) {
  1655. case BuiltinProc_prefetch_read_instruction:
  1656. rw = 0;
  1657. cache = 0;
  1658. break;
  1659. case BuiltinProc_prefetch_read_data:
  1660. rw = 0;
  1661. cache = 1;
  1662. break;
  1663. case BuiltinProc_prefetch_write_instruction:
  1664. rw = 1;
  1665. cache = 0;
  1666. break;
  1667. case BuiltinProc_prefetch_write_data:
  1668. rw = 1;
  1669. cache = 1;
  1670. break;
  1671. }
  1672. char const *name = "llvm.prefetch";
  1673. LLVMTypeRef types[1] = {lb_type(p->module, t_rawptr)};
  1674. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  1675. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  1676. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  1677. LLVMTypeRef llvm_i32 = lb_type(p->module, t_i32);
  1678. LLVMValueRef args[4] = {};
  1679. args[0] = ptr.value;
  1680. args[1] = LLVMConstInt(llvm_i32, rw, false);
  1681. args[2] = LLVMConstInt(llvm_i32, locality, false);
  1682. args[3] = LLVMConstInt(llvm_i32, cache, false);
  1683. lbValue res = {};
  1684. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  1685. res.type = nullptr;
  1686. return res;
  1687. }
  1688. case BuiltinProc_syscall:
  1689. {
  1690. unsigned arg_count = cast(unsigned)ce->args.count;
  1691. LLVMValueRef *args = gb_alloc_array(permanent_allocator(), LLVMValueRef, arg_count);
  1692. for_array(i, ce->args) {
  1693. lbValue arg = lb_build_expr(p, ce->args[i]);
  1694. arg = lb_emit_conv(p, arg, t_uintptr);
  1695. args[i] = arg.value;
  1696. }
  1697. LLVMTypeRef llvm_uintptr = lb_type(p->module, t_uintptr);
  1698. LLVMTypeRef *llvm_arg_types = gb_alloc_array(permanent_allocator(), LLVMTypeRef, arg_count);
  1699. for (unsigned i = 0; i < arg_count; i++) {
  1700. llvm_arg_types[i] = llvm_uintptr;
  1701. }
  1702. LLVMTypeRef func_type = LLVMFunctionType(llvm_uintptr, llvm_arg_types, arg_count, false);
  1703. LLVMValueRef inline_asm = nullptr;
  1704. switch (build_context.metrics.arch) {
  1705. case TargetArch_amd64:
  1706. {
  1707. GB_ASSERT(arg_count <= 7);
  1708. char asm_string[] = "syscall";
  1709. gbString constraints = gb_string_make(heap_allocator(), "={rax}");
  1710. for (unsigned i = 0; i < arg_count; i++) {
  1711. constraints = gb_string_appendc(constraints, ",{");
  1712. static char const *regs[] = {
  1713. "rax",
  1714. "rdi",
  1715. "rsi",
  1716. "rdx",
  1717. "r10",
  1718. "r8",
  1719. "r9"
  1720. };
  1721. constraints = gb_string_appendc(constraints, regs[i]);
  1722. constraints = gb_string_appendc(constraints, "}");
  1723. }
  1724. size_t asm_string_size = gb_strlen(asm_string);
  1725. size_t constraints_size = gb_string_length(constraints);
  1726. inline_asm = LLVMGetInlineAsm(func_type, asm_string, asm_string_size, constraints, constraints_size, true, false, LLVMInlineAsmDialectATT);
  1727. }
  1728. break;
  1729. case TargetArch_386:
  1730. {
  1731. GB_ASSERT(arg_count <= 7);
  1732. char asm_string_default[] = "int $0x80";
  1733. char *asm_string = asm_string_default;
  1734. gbString constraints = gb_string_make(heap_allocator(), "={eax}");
  1735. for (unsigned i = 0; i < gb_min(arg_count, 6); i++) {
  1736. constraints = gb_string_appendc(constraints, ",{");
  1737. static char const *regs[] = {
  1738. "eax",
  1739. "ebx",
  1740. "ecx",
  1741. "edx",
  1742. "esi",
  1743. "edi",
  1744. };
  1745. constraints = gb_string_appendc(constraints, regs[i]);
  1746. constraints = gb_string_appendc(constraints, "}");
  1747. }
  1748. if (arg_count == 7) {
  1749. char asm_string7[] = "push %[arg6]\npush %%ebp\nmov 4(%%esp), %%ebp\nint $0x80\npop %%ebp\nadd $4, %%esp";
  1750. asm_string = asm_string7;
  1751. constraints = gb_string_appendc(constraints, ",rm");
  1752. }
  1753. size_t asm_string_size = gb_strlen(asm_string);
  1754. size_t constraints_size = gb_string_length(constraints);
  1755. inline_asm = LLVMGetInlineAsm(func_type, asm_string, asm_string_size, constraints, constraints_size, true, false, LLVMInlineAsmDialectATT);
  1756. }
  1757. break;
  1758. case TargetArch_arm64:
  1759. {
  1760. GB_ASSERT(arg_count <= 7);
  1761. char asm_string[] = "svc #0";
  1762. gbString constraints = gb_string_make(heap_allocator(), "={x0}");
  1763. for (unsigned i = 0; i < arg_count; i++) {
  1764. constraints = gb_string_appendc(constraints, ",{");
  1765. static char const *regs[] = {
  1766. "x8",
  1767. "x0",
  1768. "x1",
  1769. "x2",
  1770. "x3",
  1771. "x4",
  1772. "x5",
  1773. };
  1774. constraints = gb_string_appendc(constraints, regs[i]);
  1775. constraints = gb_string_appendc(constraints, "}");
  1776. }
  1777. size_t asm_string_size = gb_strlen(asm_string);
  1778. size_t constraints_size = gb_string_length(constraints);
  1779. inline_asm = LLVMGetInlineAsm(func_type, asm_string, asm_string_size, constraints, constraints_size, true, false, LLVMInlineAsmDialectATT);
  1780. }
  1781. break;
  1782. default:
  1783. GB_PANIC("Unsupported platform");
  1784. }
  1785. lbValue res = {};
  1786. res.value = LLVMBuildCall2(p->builder, func_type, inline_asm, args, arg_count, "");
  1787. res.type = t_uintptr;
  1788. return res;
  1789. }
  1790. }
  1791. GB_PANIC("Unhandled built-in procedure %.*s", LIT(builtin_procs[id].name));
  1792. return {};
  1793. }
  1794. lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos) {
  1795. switch (param_value.kind) {
  1796. case ParameterValue_Constant:
  1797. if (is_type_constant_type(parameter_type)) {
  1798. auto res = lb_const_value(p->module, parameter_type, param_value.value);
  1799. return res;
  1800. } else {
  1801. ExactValue ev = param_value.value;
  1802. lbValue arg = {};
  1803. Type *type = type_of_expr(param_value.original_ast_expr);
  1804. if (type != nullptr) {
  1805. arg = lb_const_value(p->module, type, ev);
  1806. } else {
  1807. arg = lb_const_value(p->module, parameter_type, param_value.value);
  1808. }
  1809. return lb_emit_conv(p, arg, parameter_type);
  1810. }
  1811. case ParameterValue_Nil:
  1812. return lb_const_nil(p->module, parameter_type);
  1813. case ParameterValue_Location:
  1814. {
  1815. String proc_name = {};
  1816. if (p->entity != nullptr) {
  1817. proc_name = p->entity->token.string;
  1818. }
  1819. return lb_emit_source_code_location(p, proc_name, pos);
  1820. }
  1821. case ParameterValue_Value:
  1822. return lb_build_expr(p, param_value.ast_value);
  1823. }
  1824. return lb_const_nil(p->module, parameter_type);
  1825. }
  1826. lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr);
  1827. lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
  1828. expr = unparen_expr(expr);
  1829. ast_node(ce, CallExpr, expr);
  1830. if (ce->sce_temp_data) {
  1831. return *(lbValue *)ce->sce_temp_data;
  1832. }
  1833. lbValue res = lb_build_call_expr_internal(p, expr);
  1834. if (ce->optional_ok_one) { // TODO(bill): Minor hack for #optional_ok procedures
  1835. GB_ASSERT(is_type_tuple(res.type));
  1836. GB_ASSERT(res.type->Tuple.variables.count == 2);
  1837. return lb_emit_struct_ev(p, res, 0);
  1838. }
  1839. return res;
  1840. }
  1841. lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
  1842. lbModule *m = p->module;
  1843. TypeAndValue tv = type_and_value_of_expr(expr);
  1844. ast_node(ce, CallExpr, expr);
  1845. TypeAndValue proc_tv = type_and_value_of_expr(ce->proc);
  1846. AddressingMode proc_mode = proc_tv.mode;
  1847. if (proc_mode == Addressing_Type) {
  1848. GB_ASSERT(ce->args.count == 1);
  1849. lbValue x = lb_build_expr(p, ce->args[0]);
  1850. lbValue y = lb_emit_conv(p, x, tv.type);
  1851. return y;
  1852. }
  1853. Ast *pexpr = unparen_expr(ce->proc);
  1854. if (proc_mode == Addressing_Builtin) {
  1855. Entity *e = entity_of_node(pexpr);
  1856. BuiltinProcId id = BuiltinProc_Invalid;
  1857. if (e != nullptr) {
  1858. id = cast(BuiltinProcId)e->Builtin.id;
  1859. } else {
  1860. id = BuiltinProc_DIRECTIVE;
  1861. }
  1862. return lb_build_builtin_proc(p, expr, tv, id);
  1863. }
  1864. // NOTE(bill): Regular call
  1865. lbValue value = {};
  1866. Ast *proc_expr = unparen_expr(ce->proc);
  1867. if (proc_expr->tav.mode == Addressing_Constant) {
  1868. ExactValue v = proc_expr->tav.value;
  1869. switch (v.kind) {
  1870. case ExactValue_Integer:
  1871. {
  1872. u64 u = big_int_to_u64(&v.value_integer);
  1873. lbValue x = {};
  1874. x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false);
  1875. x.type = t_uintptr;
  1876. x = lb_emit_conv(p, x, t_rawptr);
  1877. value = lb_emit_conv(p, x, proc_expr->tav.type);
  1878. break;
  1879. }
  1880. case ExactValue_Pointer:
  1881. {
  1882. u64 u = cast(u64)v.value_pointer;
  1883. lbValue x = {};
  1884. x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false);
  1885. x.type = t_uintptr;
  1886. x = lb_emit_conv(p, x, t_rawptr);
  1887. value = lb_emit_conv(p, x, proc_expr->tav.type);
  1888. break;
  1889. }
  1890. }
  1891. }
  1892. Entity *proc_entity = entity_of_node(proc_expr);
  1893. if (proc_entity != nullptr) {
  1894. if (proc_entity->flags & EntityFlag_Disabled) {
  1895. return {};
  1896. }
  1897. }
  1898. if (value.value == nullptr) {
  1899. value = lb_build_expr(p, proc_expr);
  1900. }
  1901. GB_ASSERT(value.value != nullptr);
  1902. Type *proc_type_ = base_type(value.type);
  1903. GB_ASSERT(proc_type_->kind == Type_Proc);
  1904. TypeProc *pt = &proc_type_->Proc;
  1905. if (is_call_expr_field_value(ce)) {
  1906. auto args = array_make<lbValue>(permanent_allocator(), pt->param_count);
  1907. for_array(arg_index, ce->args) {
  1908. Ast *arg = ce->args[arg_index];
  1909. ast_node(fv, FieldValue, arg);
  1910. GB_ASSERT(fv->field->kind == Ast_Ident);
  1911. String name = fv->field->Ident.token.string;
  1912. isize index = lookup_procedure_parameter(pt, name);
  1913. GB_ASSERT(index >= 0);
  1914. TypeAndValue tav = type_and_value_of_expr(fv->value);
  1915. if (tav.mode == Addressing_Type) {
  1916. args[index] = lb_const_nil(m, tav.type);
  1917. } else {
  1918. args[index] = lb_build_expr(p, fv->value);
  1919. }
  1920. }
  1921. TypeTuple *params = &pt->params->Tuple;
  1922. for (isize i = 0; i < args.count; i++) {
  1923. Entity *e = params->variables[i];
  1924. if (e->kind == Entity_TypeName) {
  1925. args[i] = lb_const_nil(m, e->type);
  1926. } else if (e->kind == Entity_Constant) {
  1927. continue;
  1928. } else {
  1929. GB_ASSERT(e->kind == Entity_Variable);
  1930. if (args[i].value == nullptr) {
  1931. args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
  1932. } else {
  1933. args[i] = lb_emit_conv(p, args[i], e->type);
  1934. }
  1935. }
  1936. }
  1937. for (isize i = 0; i < args.count; i++) {
  1938. Entity *e = params->variables[i];
  1939. if (args[i].type == nullptr) {
  1940. continue;
  1941. } else if (is_type_untyped_nil(args[i].type)) {
  1942. args[i] = lb_const_nil(m, e->type);
  1943. } else if (is_type_untyped_undef(args[i].type)) {
  1944. args[i] = lb_const_undef(m, e->type);
  1945. }
  1946. }
  1947. return lb_emit_call(p, value, args, ce->inlining, p->copy_elision_hint.ast == expr);
  1948. }
  1949. isize arg_index = 0;
  1950. isize arg_count = 0;
  1951. for_array(i, ce->args) {
  1952. Ast *arg = ce->args[i];
  1953. TypeAndValue tav = type_and_value_of_expr(arg);
  1954. GB_ASSERT_MSG(tav.mode != Addressing_Invalid, "%s %s %d", expr_to_string(arg), expr_to_string(expr), tav.mode);
  1955. GB_ASSERT_MSG(tav.mode != Addressing_ProcGroup, "%s", expr_to_string(arg));
  1956. Type *at = tav.type;
  1957. if (at->kind == Type_Tuple) {
  1958. arg_count += at->Tuple.variables.count;
  1959. } else {
  1960. arg_count++;
  1961. }
  1962. }
  1963. isize param_count = 0;
  1964. if (pt->params) {
  1965. GB_ASSERT(pt->params->kind == Type_Tuple);
  1966. param_count = pt->params->Tuple.variables.count;
  1967. }
  1968. auto args = array_make<lbValue>(permanent_allocator(), cast(isize)gb_max(param_count, arg_count));
  1969. isize variadic_index = pt->variadic_index;
  1970. bool variadic = pt->variadic && variadic_index >= 0;
  1971. bool vari_expand = ce->ellipsis.pos.line != 0;
  1972. bool is_c_vararg = pt->c_vararg;
  1973. String proc_name = {};
  1974. if (p->entity != nullptr) {
  1975. proc_name = p->entity->token.string;
  1976. }
  1977. TokenPos pos = ast_token(ce->proc).pos;
  1978. TypeTuple *param_tuple = nullptr;
  1979. if (pt->params) {
  1980. GB_ASSERT(pt->params->kind == Type_Tuple);
  1981. param_tuple = &pt->params->Tuple;
  1982. }
  1983. for_array(i, ce->args) {
  1984. Ast *arg = ce->args[i];
  1985. TypeAndValue arg_tv = type_and_value_of_expr(arg);
  1986. if (arg_tv.mode == Addressing_Type) {
  1987. args[arg_index++] = lb_const_nil(m, arg_tv.type);
  1988. } else {
  1989. lbValue a = lb_build_expr(p, arg);
  1990. Type *at = a.type;
  1991. if (at->kind == Type_Tuple) {
  1992. for_array(i, at->Tuple.variables) {
  1993. lbValue v = lb_emit_struct_ev(p, a, cast(i32)i);
  1994. args[arg_index++] = v;
  1995. }
  1996. } else {
  1997. args[arg_index++] = a;
  1998. }
  1999. }
  2000. }
  2001. if (param_count > 0) {
  2002. GB_ASSERT_MSG(pt->params != nullptr, "%s %td", expr_to_string(expr), pt->param_count);
  2003. GB_ASSERT(param_count < 1000000);
  2004. if (arg_count < param_count) {
  2005. isize end = cast(isize)param_count;
  2006. if (variadic) {
  2007. end = variadic_index;
  2008. }
  2009. while (arg_index < end) {
  2010. Entity *e = param_tuple->variables[arg_index];
  2011. GB_ASSERT(e->kind == Entity_Variable);
  2012. args[arg_index++] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
  2013. }
  2014. }
  2015. if (is_c_vararg) {
  2016. GB_ASSERT(variadic);
  2017. GB_ASSERT(!vari_expand);
  2018. isize i = 0;
  2019. for (; i < variadic_index; i++) {
  2020. Entity *e = param_tuple->variables[i];
  2021. if (e->kind == Entity_Variable) {
  2022. args[i] = lb_emit_conv(p, args[i], e->type);
  2023. }
  2024. }
  2025. Type *variadic_type = param_tuple->variables[i]->type;
  2026. GB_ASSERT(is_type_slice(variadic_type));
  2027. variadic_type = base_type(variadic_type)->Slice.elem;
  2028. if (!is_type_any(variadic_type)) {
  2029. for (; i < arg_count; i++) {
  2030. args[i] = lb_emit_conv(p, args[i], variadic_type);
  2031. }
  2032. } else {
  2033. for (; i < arg_count; i++) {
  2034. args[i] = lb_emit_conv(p, args[i], default_type(args[i].type));
  2035. }
  2036. }
  2037. } else if (variadic) {
  2038. isize i = 0;
  2039. for (; i < variadic_index; i++) {
  2040. Entity *e = param_tuple->variables[i];
  2041. if (e->kind == Entity_Variable) {
  2042. args[i] = lb_emit_conv(p, args[i], e->type);
  2043. }
  2044. }
  2045. if (!vari_expand) {
  2046. Type *variadic_type = param_tuple->variables[i]->type;
  2047. GB_ASSERT(is_type_slice(variadic_type));
  2048. variadic_type = base_type(variadic_type)->Slice.elem;
  2049. for (; i < arg_count; i++) {
  2050. args[i] = lb_emit_conv(p, args[i], variadic_type);
  2051. }
  2052. }
  2053. } else {
  2054. for (isize i = 0; i < param_count; i++) {
  2055. Entity *e = param_tuple->variables[i];
  2056. if (e->kind == Entity_Variable) {
  2057. if (args[i].value == nullptr) {
  2058. continue;
  2059. }
  2060. GB_ASSERT_MSG(args[i].value != nullptr, "%.*s", LIT(e->token.string));
  2061. args[i] = lb_emit_conv(p, args[i], e->type);
  2062. }
  2063. }
  2064. }
  2065. if (variadic && !vari_expand && !is_c_vararg) {
  2066. // variadic call argument generation
  2067. Type *slice_type = param_tuple->variables[variadic_index]->type;
  2068. Type *elem_type = base_type(slice_type)->Slice.elem;
  2069. lbAddr slice = lb_add_local_generated(p, slice_type, true);
  2070. isize slice_len = arg_count+1 - (variadic_index+1);
  2071. if (slice_len > 0) {
  2072. lbAddr base_array = lb_add_local_generated(p, alloc_type_array(elem_type, slice_len), true);
  2073. for (isize i = variadic_index, j = 0; i < arg_count; i++, j++) {
  2074. lbValue addr = lb_emit_array_epi(p, base_array.addr, cast(i32)j);
  2075. lb_emit_store(p, addr, args[i]);
  2076. }
  2077. lbValue base_elem = lb_emit_array_epi(p, base_array.addr, 0);
  2078. lbValue len = lb_const_int(m, t_int, slice_len);
  2079. lb_fill_slice(p, slice, base_elem, len);
  2080. }
  2081. arg_count = param_count;
  2082. args[variadic_index] = lb_addr_load(p, slice);
  2083. }
  2084. }
  2085. if (variadic && variadic_index+1 < param_count) {
  2086. for (isize i = variadic_index+1; i < param_count; i++) {
  2087. Entity *e = param_tuple->variables[i];
  2088. args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
  2089. }
  2090. }
  2091. isize final_count = param_count;
  2092. if (is_c_vararg) {
  2093. final_count = arg_count;
  2094. }
  2095. if (param_tuple != nullptr) {
  2096. for (isize i = 0; i < gb_min(args.count, param_tuple->variables.count); i++) {
  2097. Entity *e = param_tuple->variables[i];
  2098. if (args[i].type == nullptr) {
  2099. continue;
  2100. } else if (is_type_untyped_nil(args[i].type)) {
  2101. args[i] = lb_const_nil(m, e->type);
  2102. } else if (is_type_untyped_undef(args[i].type)) {
  2103. args[i] = lb_const_undef(m, e->type);
  2104. }
  2105. }
  2106. }
  2107. auto call_args = array_slice(args, 0, final_count);
  2108. return lb_emit_call(p, value, call_args, ce->inlining, p->copy_elision_hint.ast == expr);
  2109. }