llvm_backend.cpp 108 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447
  1. #define MULTITHREAD_OBJECT_GENERATION 1
  2. #ifndef USE_SEPARATE_MODULES
  3. #define USE_SEPARATE_MODULES build_context.use_separate_modules
  4. #endif
  5. #ifndef MULTITHREAD_OBJECT_GENERATION
  6. #define MULTITHREAD_OBJECT_GENERATION 0
  7. #endif
  8. #ifndef LLVM_IGNORE_VERIFICATION
  9. #define LLVM_IGNORE_VERIFICATION 0
  10. #endif
  11. #include "llvm_backend.hpp"
  12. #include "llvm_abi.cpp"
  13. #include "llvm_backend_opt.cpp"
  14. #include "llvm_backend_general.cpp"
  15. #include "llvm_backend_debug.cpp"
  16. #include "llvm_backend_const.cpp"
  17. #include "llvm_backend_type.cpp"
  18. #include "llvm_backend_utility.cpp"
  19. #include "llvm_backend_expr.cpp"
  20. #include "llvm_backend_stmt.cpp"
  21. #include "llvm_backend_proc.cpp"
  22. String get_default_microarchitecture() {
  23. String default_march = str_lit("generic");
  24. if (build_context.metrics.arch == TargetArch_amd64) {
  25. // NOTE(bill): x86-64-v2 is more than enough for everyone
  26. //
  27. // x86-64: CMOV, CMPXCHG8B, FPU, FXSR, MMX, FXSR, SCE, SSE, SSE2
  28. // x86-64-v2: (close to Nehalem) CMPXCHG16B, LAHF-SAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3
  29. // x86-64-v3: (close to Haswell) AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE
  30. // x86-64-v4: AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL
  31. if (ODIN_LLVM_MINIMUM_VERSION_12) {
  32. if (build_context.metrics.os == TargetOs_freestanding) {
  33. default_march = str_lit("x86-64");
  34. } else {
  35. default_march = str_lit("x86-64-v2");
  36. }
  37. }
  38. }
  39. return default_march;
  40. }
  41. String get_final_microarchitecture() {
  42. BuildContext *bc = &build_context;
  43. String microarch = bc->microarch;
  44. if (microarch.len == 0) {
  45. microarch = get_default_microarchitecture();
  46. } else if (microarch == str_lit("native")) {
  47. microarch = make_string_c(LLVMGetHostCPUName());
  48. }
  49. return microarch;
  50. }
  51. gb_internal String get_default_features() {
  52. BuildContext *bc = &build_context;
  53. int off = 0;
  54. for (int i = 0; i < bc->metrics.arch; i += 1) {
  55. off += target_microarch_counts[i];
  56. }
  57. String microarch = get_final_microarchitecture();
  58. for (int i = off; i < off+target_microarch_counts[bc->metrics.arch]; i += 1) {
  59. if (microarch_features_list[i].microarch == microarch) {
  60. return microarch_features_list[i].features;
  61. }
  62. }
  63. GB_PANIC("unknown microarch");
  64. return {};
  65. }
  66. gb_internal void lb_add_foreign_library_path(lbModule *m, Entity *e) {
  67. if (e == nullptr) {
  68. return;
  69. }
  70. GB_ASSERT(e->kind == Entity_LibraryName);
  71. GB_ASSERT(e->flags & EntityFlag_Used);
  72. mutex_lock(&m->gen->foreign_mutex);
  73. if (!ptr_set_update(&m->gen->foreign_libraries_set, e)) {
  74. array_add(&m->gen->foreign_libraries, e);
  75. }
  76. mutex_unlock(&m->gen->foreign_mutex);
  77. }
  78. gb_internal GB_COMPARE_PROC(foreign_library_cmp) {
  79. int cmp = 0;
  80. Entity *x = *(Entity **)a;
  81. Entity *y = *(Entity **)b;
  82. if (x == y) {
  83. return 0;
  84. }
  85. GB_ASSERT(x->kind == Entity_LibraryName);
  86. GB_ASSERT(y->kind == Entity_LibraryName);
  87. cmp = i64_cmp(x->LibraryName.priority_index, y->LibraryName.priority_index);
  88. if (cmp) {
  89. return cmp;
  90. }
  91. if (x->pkg != y->pkg) {
  92. isize order_x = x->pkg ? x->pkg->order : 0;
  93. isize order_y = y->pkg ? y->pkg->order : 0;
  94. cmp = isize_cmp(order_x, order_y);
  95. if (cmp) {
  96. return cmp;
  97. }
  98. }
  99. if (x->file != y->file) {
  100. String fullpath_x = x->file ? x->file->fullpath : (String{});
  101. String fullpath_y = y->file ? y->file->fullpath : (String{});
  102. String file_x = filename_from_path(fullpath_x);
  103. String file_y = filename_from_path(fullpath_y);
  104. cmp = string_compare(file_x, file_y);
  105. if (cmp) {
  106. return cmp;
  107. }
  108. }
  109. cmp = u64_cmp(x->order_in_src, y->order_in_src);
  110. if (cmp) {
  111. return cmp;
  112. }
  113. return i32_cmp(x->token.pos.offset, y->token.pos.offset);
  114. }
  115. gb_internal void lb_set_entity_from_other_modules_linkage_correctly(lbModule *other_module, Entity *e, String const &name) {
  116. if (other_module == nullptr) {
  117. return;
  118. }
  119. char const *cname = alloc_cstring(temporary_allocator(), name);
  120. LLVMValueRef other_global = nullptr;
  121. if (e->kind == Entity_Variable) {
  122. other_global = LLVMGetNamedGlobal(other_module->mod, cname);
  123. } else if (e->kind == Entity_Procedure) {
  124. other_global = LLVMGetNamedFunction(other_module->mod, cname);
  125. }
  126. if (other_global) {
  127. LLVMSetLinkage(other_global, LLVMExternalLinkage);
  128. }
  129. }
  130. gb_internal void lb_emit_init_context(lbProcedure *p, lbAddr addr) {
  131. TEMPORARY_ALLOCATOR_GUARD();
  132. GB_ASSERT(addr.kind == lbAddr_Context);
  133. GB_ASSERT(addr.ctx.sel.index.count == 0);
  134. auto args = array_make<lbValue>(temporary_allocator(), 1);
  135. args[0] = addr.addr;
  136. lb_emit_runtime_call(p, "__init_context", args);
  137. }
  138. gb_internal lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p) {
  139. Type *pt = base_type(p->type);
  140. GB_ASSERT(pt->kind == Type_Proc);
  141. GB_ASSERT(pt->Proc.calling_convention == ProcCC_Odin);
  142. String name = str_lit("__.context_ptr");
  143. Entity *e = alloc_entity_param(nullptr, make_token_ident(name), t_context_ptr, false, false);
  144. e->flags |= EntityFlag_NoAlias;
  145. LLVMValueRef context_ptr = LLVMGetParam(p->value, LLVMCountParams(p->value)-1);
  146. LLVMSetValueName2(context_ptr, cast(char const *)name.text, name.len);
  147. context_ptr = LLVMBuildPointerCast(p->builder, context_ptr, lb_type(p->module, e->type), "");
  148. lbValue param = {context_ptr, e->type};
  149. lb_add_entity(p->module, e, param);
  150. lbAddr ctx_addr = {};
  151. ctx_addr.kind = lbAddr_Context;
  152. ctx_addr.addr = param;
  153. lbContextData *cd = array_add_and_get(&p->context_stack);
  154. cd->ctx = ctx_addr;
  155. cd->scope_index = -1;
  156. cd->uses = +1; // make sure it has been used already
  157. return cd;
  158. }
  159. gb_internal lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx) {
  160. ctx.kind = lbAddr_Context;
  161. lbContextData *cd = array_add_and_get(&p->context_stack);
  162. cd->ctx = ctx;
  163. cd->scope_index = p->scope_index;
  164. return cd;
  165. }
  166. gb_internal lbValue lb_equal_proc_for_type(lbModule *m, Type *type) {
  167. type = base_type(type);
  168. GB_ASSERT(is_type_comparable(type));
  169. Type *pt = alloc_type_pointer(type);
  170. LLVMTypeRef ptr_type = lb_type(m, pt);
  171. lbProcedure **found = map_get(&m->equal_procs, type);
  172. lbProcedure *compare_proc = nullptr;
  173. if (found) {
  174. compare_proc = *found;
  175. GB_ASSERT(compare_proc != nullptr);
  176. return {compare_proc->value, compare_proc->type};
  177. }
  178. static std::atomic<u32> proc_index;
  179. char buf[32] = {};
  180. isize n = gb_snprintf(buf, 32, "__$equal%u", 1+proc_index.fetch_add(1));
  181. char *str = gb_alloc_str_len(permanent_allocator(), buf, n-1);
  182. String proc_name = make_string_c(str);
  183. lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_equal_proc);
  184. map_set(&m->equal_procs, type, p);
  185. lb_begin_procedure_body(p);
  186. // lb_add_attribute_to_proc(m, p->value, "readonly");
  187. lb_add_attribute_to_proc(m, p->value, "nounwind");
  188. LLVMValueRef x = LLVMGetParam(p->value, 0);
  189. LLVMValueRef y = LLVMGetParam(p->value, 1);
  190. x = LLVMBuildPointerCast(p->builder, x, ptr_type, "");
  191. y = LLVMBuildPointerCast(p->builder, y, ptr_type, "");
  192. lbValue lhs = {x, pt};
  193. lbValue rhs = {y, pt};
  194. lb_add_proc_attribute_at_index(p, 1+0, "nonnull");
  195. lb_add_proc_attribute_at_index(p, 1+1, "nonnull");
  196. lbBlock *block_same_ptr = lb_create_block(p, "same_ptr");
  197. lbBlock *block_diff_ptr = lb_create_block(p, "diff_ptr");
  198. lbValue same_ptr = lb_emit_comp(p, Token_CmpEq, lhs, rhs);
  199. lb_emit_if(p, same_ptr, block_same_ptr, block_diff_ptr);
  200. lb_start_block(p, block_same_ptr);
  201. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_bool), 1, false));
  202. lb_start_block(p, block_diff_ptr);
  203. if (type->kind == Type_Struct) {
  204. type_set_offsets(type);
  205. lbBlock *block_false = lb_create_block(p, "bfalse");
  206. lbValue res = lb_const_bool(m, t_bool, true);
  207. for_array(i, type->Struct.fields) {
  208. lbBlock *next_block = lb_create_block(p, "btrue");
  209. lbValue pleft = lb_emit_struct_ep(p, lhs, cast(i32)i);
  210. lbValue pright = lb_emit_struct_ep(p, rhs, cast(i32)i);
  211. lbValue left = lb_emit_load(p, pleft);
  212. lbValue right = lb_emit_load(p, pright);
  213. lbValue ok = lb_emit_comp(p, Token_CmpEq, left, right);
  214. lb_emit_if(p, ok, next_block, block_false);
  215. lb_emit_jump(p, next_block);
  216. lb_start_block(p, next_block);
  217. }
  218. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_bool), 1, false));
  219. lb_start_block(p, block_false);
  220. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_bool), 0, false));
  221. } else if (type->kind == Type_Union) {
  222. if (type_size_of(type) == 0) {
  223. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_bool), 1, false));
  224. } else if (is_type_union_maybe_pointer(type)) {
  225. Type *v = type->Union.variants[0];
  226. Type *pv = alloc_type_pointer(v);
  227. lbValue left = lb_emit_load(p, lb_emit_conv(p, lhs, pv));
  228. lbValue right = lb_emit_load(p, lb_emit_conv(p, rhs, pv));
  229. lbValue ok = lb_emit_comp(p, Token_CmpEq, left, right);
  230. ok = lb_emit_conv(p, ok, t_bool);
  231. LLVMBuildRet(p->builder, ok.value);
  232. } else {
  233. lbBlock *block_false = lb_create_block(p, "bfalse");
  234. lbBlock *block_switch = lb_create_block(p, "bswitch");
  235. lbValue left_tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, lhs));
  236. lbValue right_tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, rhs));
  237. lbValue tag_eq = lb_emit_comp(p, Token_CmpEq, left_tag, right_tag);
  238. lb_emit_if(p, tag_eq, block_switch, block_false);
  239. lb_start_block(p, block_switch);
  240. unsigned variant_count = cast(unsigned)type->Union.variants.count;
  241. if (type->Union.kind != UnionType_no_nil) {
  242. variant_count += 1;
  243. }
  244. LLVMValueRef v_switch = LLVMBuildSwitch(p->builder, left_tag.value, block_false->block, variant_count);
  245. if (type->Union.kind != UnionType_no_nil) {
  246. lbBlock *case_block = lb_create_block(p, "bcase");
  247. lb_start_block(p, case_block);
  248. lbValue case_tag = lb_const_int(p->module, union_tag_type(type), 0);
  249. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_bool), 1, false));
  250. LLVMAddCase(v_switch, case_tag.value, case_block->block);
  251. }
  252. for (Type *v : type->Union.variants) {
  253. lbBlock *case_block = lb_create_block(p, "bcase");
  254. lb_start_block(p, case_block);
  255. lbValue case_tag = lb_const_union_tag(p->module, type, v);
  256. Type *vp = alloc_type_pointer(v);
  257. lbValue left = lb_emit_load(p, lb_emit_conv(p, lhs, vp));
  258. lbValue right = lb_emit_load(p, lb_emit_conv(p, rhs, vp));
  259. lbValue ok = lb_emit_comp(p, Token_CmpEq, left, right);
  260. ok = lb_emit_conv(p, ok, t_bool);
  261. LLVMBuildRet(p->builder, ok.value);
  262. LLVMAddCase(v_switch, case_tag.value, case_block->block);
  263. }
  264. lb_start_block(p, block_false);
  265. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_bool), 0, false));
  266. }
  267. } else {
  268. lbValue left = lb_emit_load(p, lhs);
  269. lbValue right = lb_emit_load(p, rhs);
  270. lbValue ok = lb_emit_comp(p, Token_CmpEq, left, right);
  271. ok = lb_emit_conv(p, ok, t_bool);
  272. LLVMBuildRet(p->builder, ok.value);
  273. }
  274. lb_end_procedure_body(p);
  275. compare_proc = p;
  276. return {compare_proc->value, compare_proc->type};
  277. }
  278. gb_internal lbValue lb_simple_compare_hash(lbProcedure *p, Type *type, lbValue data, lbValue seed) {
  279. TEMPORARY_ALLOCATOR_GUARD();
  280. GB_ASSERT_MSG(is_type_simple_compare(type), "%s", type_to_string(type));
  281. auto args = array_make<lbValue>(temporary_allocator(), 3);
  282. args[0] = data;
  283. args[1] = seed;
  284. args[2] = lb_const_int(p->module, t_int, type_size_of(type));
  285. return lb_emit_runtime_call(p, "default_hasher", args);
  286. }
  287. gb_internal void lb_add_callsite_force_inline(lbProcedure *p, lbValue ret_value) {
  288. LLVMAddCallSiteAttribute(ret_value.value, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(p->module->ctx, "alwaysinline"));
  289. }
  290. gb_internal lbValue lb_hasher_proc_for_type(lbModule *m, Type *type) {
  291. type = core_type(type);
  292. GB_ASSERT_MSG(is_type_comparable(type), "%s", type_to_string(type));
  293. Type *pt = alloc_type_pointer(type);
  294. lbProcedure **found = map_get(&m->hasher_procs, type);
  295. if (found) {
  296. GB_ASSERT(*found != nullptr);
  297. return {(*found)->value, (*found)->type};
  298. }
  299. static std::atomic<u32> proc_index;
  300. char buf[32] = {};
  301. isize n = gb_snprintf(buf, 32, "__$hasher%u", 1+proc_index.fetch_add(1));
  302. char *str = gb_alloc_str_len(permanent_allocator(), buf, n-1);
  303. String proc_name = make_string_c(str);
  304. lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_hasher_proc);
  305. map_set(&m->hasher_procs, type, p);
  306. lb_begin_procedure_body(p);
  307. defer (lb_end_procedure_body(p));
  308. // lb_add_attribute_to_proc(m, p->value, "readonly");
  309. lb_add_attribute_to_proc(m, p->value, "nounwind");
  310. LLVMValueRef x = LLVMGetParam(p->value, 0);
  311. LLVMValueRef y = LLVMGetParam(p->value, 1);
  312. lbValue data = {x, t_rawptr};
  313. lbValue seed = {y, t_uintptr};
  314. lb_add_proc_attribute_at_index(p, 1+0, "nonnull");
  315. // lb_add_proc_attribute_at_index(p, 1+0, "readonly");
  316. if (is_type_simple_compare(type)) {
  317. lbValue res = lb_simple_compare_hash(p, type, data, seed);
  318. lb_add_callsite_force_inline(p, res);
  319. LLVMBuildRet(p->builder, res.value);
  320. return {p->value, p->type};
  321. }
  322. TEMPORARY_ALLOCATOR_GUARD();
  323. if (type->kind == Type_Struct) {
  324. type_set_offsets(type);
  325. data = lb_emit_conv(p, data, t_u8_ptr);
  326. auto args = array_make<lbValue>(temporary_allocator(), 2);
  327. for_array(i, type->Struct.fields) {
  328. GB_ASSERT(type->Struct.offsets != nullptr);
  329. i64 offset = type->Struct.offsets[i];
  330. Entity *field = type->Struct.fields[i];
  331. lbValue field_hasher = lb_hasher_proc_for_type(m, field->type);
  332. lbValue ptr = lb_emit_ptr_offset(p, data, lb_const_int(m, t_uintptr, offset));
  333. args[0] = ptr;
  334. args[1] = seed;
  335. seed = lb_emit_call(p, field_hasher, args);
  336. }
  337. LLVMBuildRet(p->builder, seed.value);
  338. } else if (type->kind == Type_Union) {
  339. auto args = array_make<lbValue>(temporary_allocator(), 2);
  340. if (is_type_union_maybe_pointer(type)) {
  341. Type *v = type->Union.variants[0];
  342. lbValue variant_hasher = lb_hasher_proc_for_type(m, v);
  343. args[0] = data;
  344. args[1] = seed;
  345. lbValue res = lb_emit_call(p, variant_hasher, args);
  346. lb_add_callsite_force_inline(p, res);
  347. LLVMBuildRet(p->builder, res.value);
  348. }
  349. lbBlock *end_block = lb_create_block(p, "bend");
  350. data = lb_emit_conv(p, data, pt);
  351. lbValue tag_ptr = lb_emit_union_tag_ptr(p, data);
  352. lbValue tag = lb_emit_load(p, tag_ptr);
  353. LLVMValueRef v_switch = LLVMBuildSwitch(p->builder, tag.value, end_block->block, cast(unsigned)type->Union.variants.count);
  354. for (Type *v : type->Union.variants) {
  355. lbBlock *case_block = lb_create_block(p, "bcase");
  356. lb_start_block(p, case_block);
  357. lbValue case_tag = lb_const_union_tag(p->module, type, v);
  358. lbValue variant_hasher = lb_hasher_proc_for_type(m, v);
  359. args[0] = data;
  360. args[1] = seed;
  361. lbValue res = lb_emit_call(p, variant_hasher, args);
  362. LLVMBuildRet(p->builder, res.value);
  363. LLVMAddCase(v_switch, case_tag.value, case_block->block);
  364. }
  365. lb_start_block(p, end_block);
  366. LLVMBuildRet(p->builder, seed.value);
  367. } else if (type->kind == Type_Array) {
  368. lbAddr pres = lb_add_local_generated(p, t_uintptr, false);
  369. lb_addr_store(p, pres, seed);
  370. auto args = array_make<lbValue>(temporary_allocator(), 2);
  371. lbValue elem_hasher = lb_hasher_proc_for_type(m, type->Array.elem);
  372. auto loop_data = lb_loop_start(p, cast(isize)type->Array.count, t_i32);
  373. data = lb_emit_conv(p, data, pt);
  374. lbValue ptr = lb_emit_array_ep(p, data, loop_data.idx);
  375. args[0] = ptr;
  376. args[1] = lb_addr_load(p, pres);
  377. lbValue new_seed = lb_emit_call(p, elem_hasher, args);
  378. lb_addr_store(p, pres, new_seed);
  379. lb_loop_end(p, loop_data);
  380. lbValue res = lb_addr_load(p, pres);
  381. LLVMBuildRet(p->builder, res.value);
  382. } else if (type->kind == Type_EnumeratedArray) {
  383. lbAddr res = lb_add_local_generated(p, t_uintptr, false);
  384. lb_addr_store(p, res, seed);
  385. auto args = array_make<lbValue>(temporary_allocator(), 2);
  386. lbValue elem_hasher = lb_hasher_proc_for_type(m, type->EnumeratedArray.elem);
  387. auto loop_data = lb_loop_start(p, cast(isize)type->EnumeratedArray.count, t_i32);
  388. data = lb_emit_conv(p, data, pt);
  389. lbValue ptr = lb_emit_array_ep(p, data, loop_data.idx);
  390. args[0] = ptr;
  391. args[1] = lb_addr_load(p, res);
  392. lbValue new_seed = lb_emit_call(p, elem_hasher, args);
  393. lb_addr_store(p, res, new_seed);
  394. lb_loop_end(p, loop_data);
  395. lbValue vres = lb_addr_load(p, res);
  396. LLVMBuildRet(p->builder, vres.value);
  397. } else if (is_type_cstring(type)) {
  398. auto args = array_make<lbValue>(temporary_allocator(), 2);
  399. args[0] = data;
  400. args[1] = seed;
  401. lbValue res = lb_emit_runtime_call(p, "default_hasher_cstring", args);
  402. lb_add_callsite_force_inline(p, res);
  403. LLVMBuildRet(p->builder, res.value);
  404. } else if (is_type_string(type)) {
  405. auto args = array_make<lbValue>(temporary_allocator(), 2);
  406. args[0] = data;
  407. args[1] = seed;
  408. lbValue res = lb_emit_runtime_call(p, "default_hasher_string", args);
  409. lb_add_callsite_force_inline(p, res);
  410. LLVMBuildRet(p->builder, res.value);
  411. } else {
  412. GB_PANIC("Unhandled type for hasher: %s", type_to_string(type));
  413. }
  414. return {p->value, p->type};
  415. }
  416. #define LLVM_SET_VALUE_NAME(value, name) LLVMSetValueName2((value), (name), gb_count_of((name))-1);
  417. gb_internal lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) {
  418. GB_ASSERT(!build_context.dynamic_map_calls);
  419. type = base_type(type);
  420. GB_ASSERT(type->kind == Type_Map);
  421. lbProcedure **found = map_get(&m->map_get_procs, type);
  422. if (found) {
  423. GB_ASSERT(*found != nullptr);
  424. return {(*found)->value, (*found)->type};
  425. }
  426. static std::atomic<u32> proc_index;
  427. char buf[32] = {};
  428. isize n = gb_snprintf(buf, 32, "__$map_get-%u", 1+proc_index.fetch_add(1));
  429. char *str = gb_alloc_str_len(permanent_allocator(), buf, n-1);
  430. String proc_name = make_string_c(str);
  431. lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_map_get_proc);
  432. map_set(&m->map_get_procs, type, p);
  433. lb_begin_procedure_body(p);
  434. defer (lb_end_procedure_body(p));
  435. LLVMSetLinkage(p->value, LLVMInternalLinkage);
  436. lb_add_attribute_to_proc(m, p->value, "nounwind");
  437. if (build_context.ODIN_DEBUG) {
  438. lb_add_attribute_to_proc(m, p->value, "noinline");
  439. }
  440. LLVMValueRef x = LLVMGetParam(p->value, 0);
  441. LLVMValueRef y = LLVMGetParam(p->value, 1);
  442. LLVMValueRef z = LLVMGetParam(p->value, 2);
  443. lbValue map_ptr = {x, t_rawptr};
  444. lbValue h = {y, t_uintptr};
  445. lbValue key_ptr = {z, t_rawptr};
  446. LLVM_SET_VALUE_NAME(h.value, "hash");
  447. lb_add_proc_attribute_at_index(p, 1+0, "nonnull");
  448. lb_add_proc_attribute_at_index(p, 1+0, "readonly");
  449. lb_add_proc_attribute_at_index(p, 1+2, "nonnull");
  450. lb_add_proc_attribute_at_index(p, 1+2, "readonly");
  451. lbBlock *loop_block = lb_create_block(p, "loop");
  452. lbBlock *hash_block = lb_create_block(p, "hash");
  453. lbBlock *probe_block = lb_create_block(p, "probe");
  454. lbBlock *increment_block = lb_create_block(p, "increment");
  455. lbBlock *hash_compare_block = lb_create_block(p, "hash_compare");
  456. lbBlock *key_compare_block = lb_create_block(p, "key_compare");
  457. lbBlock *value_block = lb_create_block(p, "value");
  458. lbBlock *nil_block = lb_create_block(p, "nil");
  459. map_ptr = lb_emit_conv(p, map_ptr, t_raw_map_ptr);
  460. LLVM_SET_VALUE_NAME(map_ptr.value, "map_ptr");
  461. lbValue map = lb_emit_load(p, map_ptr);
  462. LLVM_SET_VALUE_NAME(map.value, "map");
  463. lbValue length = lb_map_len(p, map);
  464. LLVM_SET_VALUE_NAME(length.value, "length");
  465. lb_emit_if(p, lb_emit_comp(p, Token_CmpEq, length, lb_const_nil(m, t_int)), nil_block, hash_block);
  466. lb_start_block(p, hash_block);
  467. key_ptr = lb_emit_conv(p, key_ptr, alloc_type_pointer(type->Map.key));
  468. LLVM_SET_VALUE_NAME(key_ptr.value, "key_ptr");
  469. lbValue key = lb_emit_load(p, key_ptr);
  470. LLVM_SET_VALUE_NAME(key.value, "key");
  471. lbAddr pos = lb_add_local_generated(p, t_uintptr, false);
  472. lbAddr distance = lb_add_local_generated(p, t_uintptr, true);
  473. LLVM_SET_VALUE_NAME(pos.addr.value, "pos");
  474. LLVM_SET_VALUE_NAME(distance.addr.value, "distance");
  475. lbValue capacity = lb_map_cap(p, map);
  476. LLVM_SET_VALUE_NAME(capacity.value, "capacity");
  477. lbValue cap_minus_1 = lb_emit_arith(p, Token_Sub, capacity, lb_const_int(m, t_int, 1), t_int);
  478. lbValue mask = lb_emit_conv(p, cap_minus_1, t_uintptr);
  479. LLVM_SET_VALUE_NAME(mask.value, "mask");
  480. {
  481. // map_desired_position inlined
  482. lbValue the_pos = lb_emit_arith(p, Token_And, h, mask, t_uintptr);
  483. the_pos = lb_emit_conv(p, the_pos, t_uintptr);
  484. lb_addr_store(p, pos, the_pos);
  485. }
  486. lbValue zero_uintptr = lb_const_int(m, t_uintptr, 0);
  487. lbValue one_uintptr = lb_const_int(m, t_uintptr, 1);
  488. lbValue ks = lb_map_data_uintptr(p, map);
  489. lbValue vs = lb_map_cell_index_static(p, type->Map.key, ks, capacity);
  490. lbValue hs = lb_map_cell_index_static(p, type->Map.value, vs, capacity);
  491. ks = lb_emit_conv(p, ks, alloc_type_pointer(type->Map.key));
  492. vs = lb_emit_conv(p, vs, alloc_type_pointer(type->Map.value));
  493. hs = lb_emit_conv(p, hs, alloc_type_pointer(t_uintptr));
  494. LLVM_SET_VALUE_NAME(ks.value, "ks");
  495. LLVM_SET_VALUE_NAME(vs.value, "vs");
  496. LLVM_SET_VALUE_NAME(hs.value, "hs");
  497. lb_emit_jump(p, loop_block);
  498. lb_start_block(p, loop_block);
  499. lbValue element_hash = lb_emit_load(p, lb_emit_ptr_offset(p, hs, lb_addr_load(p, pos)));
  500. LLVM_SET_VALUE_NAME(element_hash.value, "element_hash");
  501. {
  502. // if element_hash == 0 { return nil }
  503. lb_emit_if(p, lb_emit_comp(p, Token_CmpEq, element_hash, zero_uintptr), nil_block, probe_block);
  504. }
  505. lb_start_block(p, probe_block);
  506. {
  507. // map_probe_distance inlined
  508. lbValue probe_distance = lb_emit_arith(p, Token_And, h, mask, t_uintptr);
  509. probe_distance = lb_emit_conv(p, probe_distance, t_uintptr);
  510. lbValue cap = lb_emit_conv(p, capacity, t_uintptr);
  511. lbValue base = lb_emit_arith(p, Token_Add, lb_addr_load(p, pos), cap, t_uintptr);
  512. probe_distance = lb_emit_arith(p, Token_Sub, base, probe_distance, t_uintptr);
  513. probe_distance = lb_emit_arith(p, Token_And, probe_distance, mask, t_uintptr);
  514. LLVM_SET_VALUE_NAME(probe_distance.value, "probe_distance");
  515. lbValue cond = lb_emit_comp(p, Token_Gt, lb_addr_load(p, distance), probe_distance);
  516. lb_emit_if(p, cond, nil_block, hash_compare_block);
  517. }
  518. lb_start_block(p, hash_compare_block);
  519. {
  520. lb_emit_if(p, lb_emit_comp(p, Token_CmpEq, element_hash, h), key_compare_block, increment_block);
  521. }
  522. lb_start_block(p, key_compare_block);
  523. {
  524. lbValue element_key = lb_map_cell_index_static(p, type->Map.key, ks, lb_addr_load(p, pos));
  525. element_key = lb_emit_conv(p, element_key, ks.type);
  526. LLVM_SET_VALUE_NAME(element_key.value, "element_key_ptr");
  527. lbValue cond = lb_emit_comp(p, Token_CmpEq, lb_emit_load(p, element_key), key);
  528. lb_emit_if(p, cond, value_block, increment_block);
  529. }
  530. lb_start_block(p, value_block);
  531. {
  532. lbValue element_value = lb_map_cell_index_static(p, type->Map.value, vs, lb_addr_load(p, pos));
  533. LLVM_SET_VALUE_NAME(element_value.value, "element_value_ptr");
  534. element_value = lb_emit_conv(p, element_value, t_rawptr);
  535. LLVMBuildRet(p->builder, element_value.value);
  536. }
  537. lb_start_block(p, increment_block);
  538. {
  539. lbValue pp = lb_addr_load(p, pos);
  540. pp = lb_emit_arith(p, Token_Add, pp, one_uintptr, t_uintptr);
  541. pp = lb_emit_arith(p, Token_And, pp, mask, t_uintptr);
  542. lb_addr_store(p, pos, pp);
  543. lb_emit_increment(p, distance.addr);
  544. }
  545. lb_emit_jump(p, loop_block);
  546. lb_start_block(p, nil_block);
  547. {
  548. lbValue res = lb_const_nil(m, t_rawptr);
  549. LLVMBuildRet(p->builder, res.value);
  550. }
  551. // gb_printf_err("%s\n", LLVMPrintValueToString(p->value));
  552. return {p->value, p->type};
  553. }
  554. // gb_internal void lb_debug_print(lbProcedure *p, String const &str) {
  555. // auto args = array_make<lbValue>(heap_allocator(), 1);
  556. // args[0] = lb_const_string(p->module, str);
  557. // lb_emit_runtime_call(p, "print_string", args);
  558. // }
  559. gb_internal lbValue lb_map_set_proc_for_type(lbModule *m, Type *type) {
  560. TEMPORARY_ALLOCATOR_GUARD();
  561. GB_ASSERT(!build_context.dynamic_map_calls);
  562. type = base_type(type);
  563. GB_ASSERT(type->kind == Type_Map);
  564. lbProcedure **found = map_get(&m->map_set_procs, type);
  565. if (found) {
  566. GB_ASSERT(*found != nullptr);
  567. return {(*found)->value, (*found)->type};
  568. }
  569. static std::atomic<u32> proc_index;
  570. char buf[32] = {};
  571. isize n = gb_snprintf(buf, 32, "__$map_set-%u", 1+proc_index.fetch_add(1));
  572. char *str = gb_alloc_str_len(permanent_allocator(), buf, n-1);
  573. String proc_name = make_string_c(str);
  574. lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_map_set_proc);
  575. map_set(&m->map_set_procs, type, p);
  576. lb_begin_procedure_body(p);
  577. defer (lb_end_procedure_body(p));
  578. LLVMSetLinkage(p->value, LLVMInternalLinkage);
  579. lb_add_attribute_to_proc(m, p->value, "nounwind");
  580. if (build_context.ODIN_DEBUG) {
  581. lb_add_attribute_to_proc(m, p->value, "noinline");
  582. }
  583. lbValue map_ptr = {LLVMGetParam(p->value, 0), t_rawptr};
  584. lbValue hash_param = {LLVMGetParam(p->value, 1), t_uintptr};
  585. lbValue key_ptr = {LLVMGetParam(p->value, 2), t_rawptr};
  586. lbValue value_ptr = {LLVMGetParam(p->value, 3), t_rawptr};
  587. lbValue location_ptr = {LLVMGetParam(p->value, 4), t_source_code_location_ptr};
  588. map_ptr = lb_emit_conv(p, map_ptr, alloc_type_pointer(type));
  589. key_ptr = lb_emit_conv(p, key_ptr, alloc_type_pointer(type->Map.key));
  590. LLVM_SET_VALUE_NAME(map_ptr.value, "map_ptr");
  591. LLVM_SET_VALUE_NAME(hash_param.value, "hash_param");
  592. LLVM_SET_VALUE_NAME(key_ptr.value, "key_ptr");
  593. LLVM_SET_VALUE_NAME(value_ptr.value, "value_ptr");
  594. LLVM_SET_VALUE_NAME(location_ptr.value, "location");
  595. lb_add_proc_attribute_at_index(p, 1+0, "nonnull");
  596. lb_add_proc_attribute_at_index(p, 1+0, "noalias");
  597. lb_add_proc_attribute_at_index(p, 1+2, "nonnull");
  598. if (!are_types_identical(type->Map.key, type->Map.value)) {
  599. lb_add_proc_attribute_at_index(p, 1+2, "noalias");
  600. }
  601. lb_add_proc_attribute_at_index(p, 1+2, "readonly");
  602. lb_add_proc_attribute_at_index(p, 1+3, "nonnull");
  603. if (!are_types_identical(type->Map.key, type->Map.value)) {
  604. lb_add_proc_attribute_at_index(p, 1+3, "noalias");
  605. }
  606. lb_add_proc_attribute_at_index(p, 1+3, "readonly");
  607. lb_add_proc_attribute_at_index(p, 1+4, "nonnull");
  608. lb_add_proc_attribute_at_index(p, 1+4, "noalias");
  609. lb_add_proc_attribute_at_index(p, 1+4, "readonly");
  610. lbAddr hash_addr = lb_add_local_generated(p, t_uintptr, false);
  611. lb_addr_store(p, hash_addr, hash_param);
  612. LLVM_SET_VALUE_NAME(hash_addr.addr.value, "hash");
  613. ////
  614. lbValue found_ptr = {};
  615. {
  616. lbValue map_get_proc = lb_map_get_proc_for_type(m, type);
  617. auto args = array_make<lbValue>(temporary_allocator(), 3);
  618. args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
  619. args[1] = lb_addr_load(p, hash_addr);
  620. args[2] = key_ptr;
  621. found_ptr = lb_emit_call(p, map_get_proc, args);
  622. }
  623. LLVM_SET_VALUE_NAME(found_ptr.value, "found_ptr");
  624. lbBlock *found_block = lb_create_block(p, "found");
  625. lbBlock *check_grow_block = lb_create_block(p, "check-grow");
  626. lbBlock *grow_fail_block = lb_create_block(p, "grow-fail");
  627. lbBlock *insert_block = lb_create_block(p, "insert");
  628. lbBlock *check_has_grown_block = lb_create_block(p, "check-has-grown");
  629. lbBlock *rehash_block = lb_create_block(p, "rehash");
  630. lb_emit_if(p, lb_emit_comp_against_nil(p, Token_NotEq, found_ptr), found_block, check_grow_block);
  631. lb_start_block(p, found_block);
  632. {
  633. lb_mem_copy_non_overlapping(p, found_ptr, value_ptr, lb_const_int(m, t_int, type_size_of(type->Map.value)));
  634. LLVMBuildRet(p->builder, lb_emit_conv(p, found_ptr, t_rawptr).value);
  635. }
  636. lb_start_block(p, check_grow_block);
  637. lbValue map_info = lb_gen_map_info_ptr(p->module, type);
  638. LLVM_SET_VALUE_NAME(map_info.value, "map_info");
  639. {
  640. auto args = array_make<lbValue>(temporary_allocator(), 3);
  641. args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
  642. args[1] = map_info;
  643. args[2] = lb_emit_load(p, location_ptr);
  644. lbValue grow_err_and_has_grown = lb_emit_runtime_call(p, "__dynamic_map_check_grow", args);
  645. lbValue grow_err = lb_emit_struct_ev(p, grow_err_and_has_grown, 0);
  646. lbValue has_grown = lb_emit_struct_ev(p, grow_err_and_has_grown, 1);
  647. LLVM_SET_VALUE_NAME(grow_err.value, "grow_err");
  648. LLVM_SET_VALUE_NAME(has_grown.value, "has_grown");
  649. lb_emit_if(p, lb_emit_comp_against_nil(p, Token_NotEq, grow_err), grow_fail_block, check_has_grown_block);
  650. lb_start_block(p, grow_fail_block);
  651. LLVMBuildRet(p->builder, LLVMConstNull(lb_type(m, t_rawptr)));
  652. lb_start_block(p, check_has_grown_block);
  653. lb_emit_if(p, has_grown, rehash_block, insert_block);
  654. lb_start_block(p, rehash_block);
  655. lbValue key = lb_emit_load(p, key_ptr);
  656. lbValue new_hash = lb_gen_map_key_hash(p, map_ptr, key, nullptr);
  657. LLVM_SET_VALUE_NAME(new_hash.value, "new_hash");
  658. lb_addr_store(p, hash_addr, new_hash);
  659. lb_emit_jump(p, insert_block);
  660. }
  661. lb_start_block(p, insert_block);
  662. {
  663. auto args = array_make<lbValue>(temporary_allocator(), 5);
  664. args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
  665. args[1] = map_info;
  666. args[2] = lb_addr_load(p, hash_addr);
  667. args[3] = lb_emit_conv(p, key_ptr, t_uintptr);
  668. args[4] = lb_emit_conv(p, value_ptr, t_uintptr);
  669. lbValue result = lb_emit_runtime_call(p, "map_insert_hash_dynamic", args);
  670. lb_emit_increment(p, lb_map_len_ptr(p, map_ptr));
  671. LLVMBuildRet(p->builder, lb_emit_conv(p, result, t_rawptr).value);
  672. }
  673. return {p->value, p->type};
  674. }
  675. gb_internal lbValue lb_gen_map_cell_info_ptr(lbModule *m, Type *type) {
  676. lbAddr *found = map_get(&m->map_cell_info_map, type);
  677. if (found) {
  678. return found->addr;
  679. }
  680. i64 size = 0, len = 0;
  681. map_cell_size_and_len(type, &size, &len);
  682. LLVMValueRef const_values[4] = {};
  683. const_values[0] = lb_const_int(m, t_uintptr, type_size_of(type)).value;
  684. const_values[1] = lb_const_int(m, t_uintptr, type_align_of(type)).value;
  685. const_values[2] = lb_const_int(m, t_uintptr, size).value;
  686. const_values[3] = lb_const_int(m, t_uintptr, len).value;
  687. LLVMValueRef llvm_res = llvm_const_named_struct(m, t_map_cell_info, const_values, gb_count_of(const_values));
  688. lbValue res = {llvm_res, t_map_cell_info};
  689. lbAddr addr = lb_add_global_generated(m, t_map_cell_info, res, nullptr);
  690. lb_make_global_private_const(addr);
  691. map_set(&m->map_cell_info_map, type, addr);
  692. return addr.addr;
  693. }
  694. gb_internal lbValue lb_gen_map_info_ptr(lbModule *m, Type *map_type) {
  695. map_type = base_type(map_type);
  696. GB_ASSERT(map_type->kind == Type_Map);
  697. lbAddr *found = map_get(&m->map_info_map, map_type);
  698. if (found) {
  699. return found->addr;
  700. }
  701. GB_ASSERT(t_map_info != nullptr);
  702. GB_ASSERT(t_map_cell_info != nullptr);
  703. LLVMValueRef key_cell_info = lb_gen_map_cell_info_ptr(m, map_type->Map.key).value;
  704. LLVMValueRef value_cell_info = lb_gen_map_cell_info_ptr(m, map_type->Map.value).value;
  705. LLVMValueRef const_values[4] = {};
  706. const_values[0] = key_cell_info;
  707. const_values[1] = value_cell_info;
  708. const_values[2] = lb_hasher_proc_for_type(m, map_type->Map.key).value;
  709. const_values[3] = lb_equal_proc_for_type(m, map_type->Map.key).value;
  710. LLVMValueRef llvm_res = llvm_const_named_struct(m, t_map_info, const_values, gb_count_of(const_values));
  711. lbValue res = {llvm_res, t_map_info};
  712. lbAddr addr = lb_add_global_generated(m, t_map_info, res, nullptr);
  713. lb_make_global_private_const(addr);
  714. map_set(&m->map_info_map, map_type, addr);
  715. return addr.addr;
  716. }
  717. gb_internal lbValue lb_const_hash(lbModule *m, lbValue key, Type *key_type) {
  718. if (true) {
  719. return {};
  720. }
  721. lbValue hashed_key = {};
  722. #if 0
  723. if (lb_is_const(key)) {
  724. u64 hash = 0xcbf29ce484222325;
  725. if (is_type_cstring(key_type)) {
  726. size_t length = 0;
  727. char const *text = LLVMGetAsString(key.value, &length);
  728. hash = fnv64a(text, cast(isize)length);
  729. } else if (is_type_string(key_type)) {
  730. unsigned data_indices[] = {0};
  731. unsigned len_indices[] = {1};
  732. LLVMValueRef data = LLVMConstExtractValue(key.value, data_indices, gb_count_of(data_indices));
  733. LLVMValueRef len = LLVMConstExtractValue(key.value, len_indices, gb_count_of(len_indices));
  734. i64 length = LLVMConstIntGetSExtValue(len);
  735. char const *text = nullptr;
  736. if (false && length != 0) {
  737. if (LLVMGetConstOpcode(data) != LLVMGetElementPtr) {
  738. return {};
  739. }
  740. // TODO(bill): THIS IS BROKEN! THIS NEEDS FIXING :P
  741. size_t ulength = 0;
  742. text = LLVMGetAsString(data, &ulength);
  743. gb_printf_err("%lld %llu %s\n", length, ulength, text);
  744. length = gb_min(length, cast(i64)ulength);
  745. }
  746. hash = fnv64a(text, cast(isize)length);
  747. } else {
  748. return {};
  749. }
  750. // TODO(bill): other const hash types
  751. if (build_context.word_size == 4) {
  752. hash &= 0xffffffffull;
  753. }
  754. hashed_key = lb_const_int(m, t_uintptr, hash);
  755. }
  756. #endif
  757. return hashed_key;
  758. }
  759. gb_internal lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue const &map_ptr, lbValue key, lbValue *key_ptr_) {
  760. TEMPORARY_ALLOCATOR_GUARD();
  761. lbValue key_ptr = lb_address_from_load_or_generate_local(p, key);
  762. key_ptr = lb_emit_conv(p, key_ptr, t_rawptr);
  763. if (key_ptr_) *key_ptr_ = key_ptr;
  764. Type* key_type = base_type(type_deref(map_ptr.type))->Map.key;
  765. lbValue hashed_key = lb_const_hash(p->module, key, key_type);
  766. if (hashed_key.value == nullptr) {
  767. lbValue hasher = lb_hasher_proc_for_type(p->module, key_type);
  768. lbValue seed = {};
  769. {
  770. auto args = array_make<lbValue>(temporary_allocator(), 1);
  771. args[0] = lb_map_data_uintptr(p, lb_emit_load(p, map_ptr));
  772. seed = lb_emit_runtime_call(p, "map_seed_from_map_data", args);
  773. }
  774. auto args = array_make<lbValue>(temporary_allocator(), 2);
  775. args[0] = key_ptr;
  776. args[1] = seed;
  777. hashed_key = lb_emit_call(p, hasher, args);
  778. }
  779. return hashed_key;
  780. }
  781. gb_internal lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr, lbValue const &key) {
  782. TEMPORARY_ALLOCATOR_GUARD();
  783. Type *map_type = base_type(type_deref(map_ptr.type));
  784. GB_ASSERT(map_type->kind == Type_Map);
  785. lbValue ptr = {};
  786. lbValue key_ptr = {};
  787. lbValue hash = lb_gen_map_key_hash(p, map_ptr, key, &key_ptr);
  788. if (build_context.dynamic_map_calls) {
  789. auto args = array_make<lbValue>(temporary_allocator(), 4);
  790. args[0] = lb_emit_transmute(p, map_ptr, t_raw_map_ptr);
  791. args[1] = lb_gen_map_info_ptr(p->module, map_type);
  792. args[2] = hash;
  793. args[3] = key_ptr;
  794. ptr = lb_emit_runtime_call(p, "__dynamic_map_get", args);
  795. } else {
  796. lbValue map_get_proc = lb_map_get_proc_for_type(p->module, map_type);
  797. auto args = array_make<lbValue>(temporary_allocator(), 3);
  798. args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
  799. args[1] = hash;
  800. args[2] = key_ptr;
  801. ptr = lb_emit_call(p, map_get_proc, args);
  802. }
  803. return lb_emit_conv(p, ptr, alloc_type_pointer(map_type->Map.value));
  804. }
  805. gb_internal void lb_internal_dynamic_map_set(lbProcedure *p, lbValue const &map_ptr, Type *map_type,
  806. lbValue const &map_key, lbValue const &map_value, Ast *node) {
  807. TEMPORARY_ALLOCATOR_GUARD();
  808. map_type = base_type(map_type);
  809. GB_ASSERT(map_type->kind == Type_Map);
  810. lbValue key_ptr = {};
  811. lbValue hash = lb_gen_map_key_hash(p, map_ptr, map_key, &key_ptr);
  812. lbValue v = lb_emit_conv(p, map_value, map_type->Map.value);
  813. lbValue value_ptr = lb_address_from_load_or_generate_local(p, v);
  814. if (build_context.dynamic_map_calls) {
  815. auto args = array_make<lbValue>(temporary_allocator(), 6);
  816. args[0] = lb_emit_conv(p, map_ptr, t_raw_map_ptr);
  817. args[1] = lb_gen_map_info_ptr(p->module, map_type);
  818. args[2] = hash;
  819. args[3] = lb_emit_conv(p, key_ptr, t_rawptr);
  820. args[4] = lb_emit_conv(p, value_ptr, t_rawptr);
  821. args[5] = lb_emit_source_code_location_as_global(p, node);
  822. lb_emit_runtime_call(p, "__dynamic_map_set", args);
  823. } else {
  824. lbValue map_set_proc = lb_map_set_proc_for_type(p->module, map_type);
  825. auto args = array_make<lbValue>(temporary_allocator(), 5);
  826. args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
  827. args[1] = hash;
  828. args[2] = lb_emit_conv(p, key_ptr, t_rawptr);
  829. args[3] = lb_emit_conv(p, value_ptr, t_rawptr);
  830. args[4] = lb_emit_source_code_location_as_global(p, node);
  831. lb_emit_call(p, map_set_proc, args);
  832. }
  833. }
  834. gb_internal lbValue lb_dynamic_map_reserve(lbProcedure *p, lbValue const &map_ptr, isize const capacity, TokenPos const &pos) {
  835. GB_ASSERT(!build_context.no_dynamic_literals);
  836. TEMPORARY_ALLOCATOR_GUARD();
  837. String proc_name = {};
  838. if (p->entity) {
  839. proc_name = p->entity->token.string;
  840. }
  841. auto args = array_make<lbValue>(temporary_allocator(), 4);
  842. args[0] = lb_emit_conv(p, map_ptr, t_rawptr);
  843. args[1] = lb_gen_map_info_ptr(p->module, type_deref(map_ptr.type));
  844. args[2] = lb_const_int(p->module, t_uint, capacity);
  845. args[3] = lb_emit_source_code_location_as_global(p, proc_name, pos);
  846. return lb_emit_runtime_call(p, "__dynamic_map_reserve", args);
  847. }
  848. struct lbGlobalVariable {
  849. lbValue var;
  850. lbValue init;
  851. DeclInfo *decl;
  852. bool is_initialized;
  853. };
  854. gb_internal lbProcedure *lb_create_objc_names(lbModule *main_module) {
  855. if (build_context.metrics.os != TargetOs_darwin) {
  856. return nullptr;
  857. }
  858. Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_CDecl);
  859. lbProcedure *p = lb_create_dummy_procedure(main_module, str_lit("__$init_objc_names"), proc_type);
  860. lb_add_attribute_to_proc(p->module, p->value, "nounwind");
  861. p->is_startup = true;
  862. return p;
  863. }
  864. gb_internal void lb_finalize_objc_names(lbProcedure *p) {
  865. if (p == nullptr) {
  866. return;
  867. }
  868. lbModule *m = p->module;
  869. TEMPORARY_ALLOCATOR_GUARD();
  870. auto args = array_make<lbValue>(temporary_allocator(), 1);
  871. LLVMSetLinkage(p->value, LLVMInternalLinkage);
  872. lb_begin_procedure_body(p);
  873. for (auto const &entry : m->objc_classes) {
  874. String name = entry.key;
  875. args[0] = lb_const_value(m, t_cstring, exact_value_string(name));
  876. lbValue ptr = lb_emit_runtime_call(p, "objc_lookUpClass", args);
  877. lb_addr_store(p, entry.value, ptr);
  878. }
  879. for (auto const &entry : m->objc_selectors) {
  880. String name = entry.key;
  881. args[0] = lb_const_value(m, t_cstring, exact_value_string(name));
  882. lbValue ptr = lb_emit_runtime_call(p, "sel_registerName", args);
  883. lb_addr_store(p, entry.value, ptr);
  884. }
  885. lb_end_procedure_body(p);
  886. }
  887. gb_internal void lb_verify_function(lbModule *m, lbProcedure *p, bool dump_ll=false) {
  888. if (LLVM_IGNORE_VERIFICATION) {
  889. return;
  890. }
  891. if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
  892. char *llvm_error = nullptr;
  893. gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %.*s\n", LIT(p->name));
  894. LLVMDumpValue(p->value);
  895. gb_printf_err("\n");
  896. if (dump_ll) {
  897. gb_printf_err("\n\n\n");
  898. String filepath_ll = lb_filepath_ll_for_module(m);
  899. if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
  900. gb_printf_err("LLVM Error: %s\n", llvm_error);
  901. }
  902. }
  903. LLVMVerifyFunction(p->value, LLVMPrintMessageAction);
  904. exit_with_errors();
  905. }
  906. }
  907. gb_internal WORKER_TASK_PROC(lb_llvm_module_verification_worker_proc) {
  908. char *llvm_error = nullptr;
  909. defer (LLVMDisposeMessage(llvm_error));
  910. lbModule *m = cast(lbModule *)data;
  911. if (LLVMVerifyModule(m->mod, LLVMReturnStatusAction, &llvm_error)) {
  912. gb_printf_err("LLVM Error:\n%s\n", llvm_error);
  913. if (build_context.keep_temp_files) {
  914. TIME_SECTION("LLVM Print Module to File");
  915. String filepath_ll = lb_filepath_ll_for_module(m);
  916. if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
  917. gb_printf_err("LLVM Error: %s\n", llvm_error);
  918. exit_with_errors();
  919. return false;
  920. }
  921. }
  922. exit_with_errors();
  923. return 1;
  924. }
  925. return 0;
  926. }
  927. gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *objc_names, Array<lbGlobalVariable> &global_variables) { // Startup Runtime
  928. Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin);
  929. lbProcedure *p = lb_create_dummy_procedure(main_module, str_lit(LB_STARTUP_RUNTIME_PROC_NAME), proc_type);
  930. p->is_startup = true;
  931. lb_add_attribute_to_proc(p->module, p->value, "optnone");
  932. lb_add_attribute_to_proc(p->module, p->value, "noinline");
  933. lb_begin_procedure_body(p);
  934. lb_setup_type_info_data(main_module);
  935. if (objc_names) {
  936. LLVMBuildCall2(p->builder, lb_type_internal_for_procedures_raw(main_module, objc_names->type), objc_names->value, nullptr, 0, "");
  937. }
  938. for (auto &var : global_variables) {
  939. if (var.is_initialized) {
  940. continue;
  941. }
  942. lbModule *entity_module = main_module;
  943. Entity *e = var.decl->entity;
  944. GB_ASSERT(e->kind == Entity_Variable);
  945. e->code_gen_module = entity_module;
  946. Ast *init_expr = var.decl->init_expr;
  947. if (init_expr != nullptr) {
  948. lbValue init = lb_build_expr(p, init_expr);
  949. if (init.value == nullptr) {
  950. LLVMTypeRef global_type = llvm_addr_type(p->module, var.var);
  951. if (is_type_untyped_nil(init.type)) {
  952. LLVMSetInitializer(var.var.value, LLVMConstNull(global_type));
  953. var.is_initialized = true;
  954. if (e->Variable.is_rodata) {
  955. LLVMSetGlobalConstant(var.var.value, true);
  956. }
  957. continue;
  958. }
  959. GB_PANIC("Invalid init value, got %s", expr_to_string(init_expr));
  960. }
  961. if (is_type_any(e->type) || is_type_union(e->type)) {
  962. var.init = init;
  963. } else if (lb_is_const_or_global(init)) {
  964. if (!var.is_initialized) {
  965. if (is_type_proc(init.type)) {
  966. init.value = LLVMConstPointerCast(init.value, lb_type(p->module, init.type));
  967. }
  968. LLVMSetInitializer(var.var.value, init.value);
  969. var.is_initialized = true;
  970. if (e->Variable.is_rodata) {
  971. LLVMSetGlobalConstant(var.var.value, true);
  972. }
  973. continue;
  974. }
  975. } else {
  976. var.init = init;
  977. }
  978. }
  979. if (var.init.value != nullptr) {
  980. GB_ASSERT(!var.is_initialized);
  981. Type *t = type_deref(var.var.type);
  982. if (is_type_any(t)) {
  983. // NOTE(bill): Edge case for 'any' type
  984. Type *var_type = default_type(var.init.type);
  985. lbAddr g = lb_add_global_generated(main_module, var_type, var.init);
  986. lb_addr_store(p, g, var.init);
  987. lbValue gp = lb_addr_get_ptr(p, g);
  988. lbValue data = lb_emit_struct_ep(p, var.var, 0);
  989. lbValue ti = lb_emit_struct_ep(p, var.var, 1);
  990. lb_emit_store(p, data, lb_emit_conv(p, gp, t_rawptr));
  991. lb_emit_store(p, ti, lb_type_info(p, var_type));
  992. } else {
  993. LLVMTypeRef vt = llvm_addr_type(p->module, var.var);
  994. lbValue src0 = lb_emit_conv(p, var.init, t);
  995. LLVMValueRef src = OdinLLVMBuildTransmute(p, src0.value, vt);
  996. LLVMValueRef dst = var.var.value;
  997. LLVMBuildStore(p->builder, src, dst);
  998. }
  999. var.is_initialized = true;
  1000. }
  1001. }
  1002. CheckerInfo *info = main_module->gen->info;
  1003. for (Entity *e : info->init_procedures) {
  1004. lbValue value = lb_find_procedure_value_from_entity(main_module, e);
  1005. lb_emit_call(p, value, {}, ProcInlining_none);
  1006. }
  1007. lb_end_procedure_body(p);
  1008. lb_verify_function(main_module, p);
  1009. return p;
  1010. }
  1011. gb_internal lbProcedure *lb_create_cleanup_runtime(lbModule *main_module) { // Cleanup Runtime
  1012. Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_Odin);
  1013. lbProcedure *p = lb_create_dummy_procedure(main_module, str_lit(LB_CLEANUP_RUNTIME_PROC_NAME), proc_type);
  1014. p->is_startup = true;
  1015. lb_add_attribute_to_proc(p->module, p->value, "optnone");
  1016. lb_add_attribute_to_proc(p->module, p->value, "noinline");
  1017. lb_begin_procedure_body(p);
  1018. CheckerInfo *info = main_module->gen->info;
  1019. for (Entity *e : info->fini_procedures) {
  1020. lbValue value = lb_find_procedure_value_from_entity(main_module, e);
  1021. lb_emit_call(p, value, {}, ProcInlining_none);
  1022. }
  1023. lb_end_procedure_body(p);
  1024. lb_verify_function(main_module, p);
  1025. return p;
  1026. }
  1027. gb_internal WORKER_TASK_PROC(lb_generate_procedures_and_types_per_module) {
  1028. lbModule *m = cast(lbModule *)data;
  1029. for (Entity *e : m->global_types_to_create) {
  1030. (void)lb_get_entity_name(m, e);
  1031. (void)lb_type(m, e->type);
  1032. }
  1033. for (Entity *e : m->global_procedures_to_create) {
  1034. (void)lb_get_entity_name(m, e);
  1035. array_add(&m->procedures_to_generate, lb_create_procedure(m, e));
  1036. }
  1037. return 0;
  1038. }
  1039. gb_internal void lb_create_global_procedures_and_types(lbGenerator *gen, CheckerInfo *info, bool do_threading) {
  1040. auto *min_dep_set = &info->minimum_dependency_set;
  1041. for (Entity *e : info->entities) {
  1042. String name = e->token.string;
  1043. Scope * scope = e->scope;
  1044. if ((scope->flags & ScopeFlag_File) == 0) {
  1045. continue;
  1046. }
  1047. Scope *package_scope = scope->parent;
  1048. GB_ASSERT(package_scope->flags & ScopeFlag_Pkg);
  1049. switch (e->kind) {
  1050. case Entity_Variable:
  1051. // NOTE(bill): Handled above as it requires a specific load order
  1052. continue;
  1053. case Entity_ProcGroup:
  1054. continue;
  1055. case Entity_TypeName:
  1056. case Entity_Procedure:
  1057. break;
  1058. case Entity_Constant:
  1059. if (build_context.ODIN_DEBUG) {
  1060. add_debug_info_for_global_constant_from_entity(gen, e);
  1061. }
  1062. break;
  1063. }
  1064. bool polymorphic_struct = false;
  1065. if (e->type != nullptr && e->kind == Entity_TypeName) {
  1066. Type *bt = base_type(e->type);
  1067. if (bt->kind == Type_Struct) {
  1068. polymorphic_struct = is_type_polymorphic(bt);
  1069. }
  1070. }
  1071. if (!polymorphic_struct && !ptr_set_exists(min_dep_set, e)) {
  1072. // NOTE(bill): Nothing depends upon it so doesn't need to be built
  1073. continue;
  1074. }
  1075. lbModule *m = &gen->default_module;
  1076. if (USE_SEPARATE_MODULES) {
  1077. m = lb_module_of_entity(gen, e);
  1078. }
  1079. if (e->kind == Entity_Procedure) {
  1080. array_add(&m->global_procedures_to_create, e);
  1081. } else if (e->kind == Entity_TypeName) {
  1082. array_add(&m->global_types_to_create, e);
  1083. }
  1084. }
  1085. if (do_threading) {
  1086. for (auto const &entry : gen->modules) {
  1087. lbModule *m = entry.value;
  1088. thread_pool_add_task(lb_generate_procedures_and_types_per_module, m);
  1089. }
  1090. } else {
  1091. for (auto const &entry : gen->modules) {
  1092. lbModule *m = entry.value;
  1093. lb_generate_procedures_and_types_per_module(m);
  1094. }
  1095. }
  1096. thread_pool_wait();
  1097. }
  1098. gb_internal void lb_generate_procedure(lbModule *m, lbProcedure *p);
  1099. gb_internal bool lb_is_module_empty(lbModule *m) {
  1100. if (LLVMGetFirstFunction(m->mod) == nullptr &&
  1101. LLVMGetFirstGlobal(m->mod) == nullptr) {
  1102. return true;
  1103. }
  1104. for (auto fn = LLVMGetFirstFunction(m->mod); fn != nullptr; fn = LLVMGetNextFunction(fn)) {
  1105. if (LLVMGetFirstBasicBlock(fn) != nullptr) {
  1106. return false;
  1107. }
  1108. }
  1109. for (auto g = LLVMGetFirstGlobal(m->mod); g != nullptr; g = LLVMGetNextGlobal(g)) {
  1110. if (LLVMGetLinkage(g) == LLVMExternalLinkage) {
  1111. continue;
  1112. }
  1113. if (!LLVMIsExternallyInitialized(g)) {
  1114. return false;
  1115. }
  1116. }
  1117. return true;
  1118. }
  1119. struct lbLLVMEmitWorker {
  1120. LLVMTargetMachineRef target_machine;
  1121. LLVMCodeGenFileType code_gen_file_type;
  1122. String filepath_obj;
  1123. lbModule *m;
  1124. };
  1125. gb_internal WORKER_TASK_PROC(lb_llvm_emit_worker_proc) {
  1126. GB_ASSERT(MULTITHREAD_OBJECT_GENERATION);
  1127. char *llvm_error = nullptr;
  1128. auto wd = cast(lbLLVMEmitWorker *)data;
  1129. if (LLVMTargetMachineEmitToFile(wd->target_machine, wd->m->mod, cast(char *)wd->filepath_obj.text, wd->code_gen_file_type, &llvm_error)) {
  1130. gb_printf_err("LLVM Error: %s\n", llvm_error);
  1131. exit_with_errors();
  1132. }
  1133. debugf("Generated File: %.*s\n", LIT(wd->filepath_obj));
  1134. return 0;
  1135. }
  1136. gb_internal void lb_llvm_function_pass_per_function_internal(lbModule *module, lbProcedure *p, lbFunctionPassManagerKind pass_manager_kind = lbFunctionPassManager_default) {
  1137. LLVMPassManagerRef pass_manager = module->function_pass_managers[pass_manager_kind];
  1138. lb_run_function_pass_manager(pass_manager, p, pass_manager_kind);
  1139. }
  1140. gb_internal WORKER_TASK_PROC(lb_llvm_function_pass_per_module) {
  1141. lbModule *m = cast(lbModule *)data;
  1142. {
  1143. GB_ASSERT(m->function_pass_managers[lbFunctionPassManager_default] == nullptr);
  1144. for (i32 i = 0; i < lbFunctionPassManager_COUNT; i++) {
  1145. m->function_pass_managers[i] = LLVMCreateFunctionPassManagerForModule(m->mod);
  1146. }
  1147. for (i32 i = 0; i < lbFunctionPassManager_COUNT; i++) {
  1148. LLVMInitializeFunctionPassManager(m->function_pass_managers[i]);
  1149. }
  1150. lb_populate_function_pass_manager(m, m->function_pass_managers[lbFunctionPassManager_default], false, build_context.optimization_level);
  1151. lb_populate_function_pass_manager(m, m->function_pass_managers[lbFunctionPassManager_default_without_memcpy], true, build_context.optimization_level);
  1152. lb_populate_function_pass_manager_specific(m, m->function_pass_managers[lbFunctionPassManager_none], -1);
  1153. lb_populate_function_pass_manager_specific(m, m->function_pass_managers[lbFunctionPassManager_minimal], 0);
  1154. lb_populate_function_pass_manager_specific(m, m->function_pass_managers[lbFunctionPassManager_size], 1);
  1155. lb_populate_function_pass_manager_specific(m, m->function_pass_managers[lbFunctionPassManager_speed], 2);
  1156. lb_populate_function_pass_manager_specific(m, m->function_pass_managers[lbFunctionPassManager_aggressive], 3);
  1157. for (i32 i = 0; i < lbFunctionPassManager_COUNT; i++) {
  1158. LLVMFinalizeFunctionPassManager(m->function_pass_managers[i]);
  1159. }
  1160. }
  1161. if (m == &m->gen->default_module) {
  1162. lb_llvm_function_pass_per_function_internal(m, m->gen->startup_runtime);
  1163. lb_llvm_function_pass_per_function_internal(m, m->gen->cleanup_runtime);
  1164. lb_llvm_function_pass_per_function_internal(m, m->gen->objc_names);
  1165. }
  1166. for (lbProcedure *p : m->procedures_to_generate) {
  1167. if (p->body != nullptr) { // Build Procedure
  1168. lbFunctionPassManagerKind pass_manager_kind = lbFunctionPassManager_default;
  1169. if (p->flags & lbProcedureFlag_WithoutMemcpyPass) {
  1170. pass_manager_kind = lbFunctionPassManager_default_without_memcpy;
  1171. lb_add_attribute_to_proc(p->module, p->value, "optnone");
  1172. lb_add_attribute_to_proc(p->module, p->value, "noinline");
  1173. } else {
  1174. if (p->entity && p->entity->kind == Entity_Procedure) {
  1175. switch (p->entity->Procedure.optimization_mode) {
  1176. case ProcedureOptimizationMode_None:
  1177. case ProcedureOptimizationMode_Minimal:
  1178. pass_manager_kind = lbFunctionPassManager_minimal;
  1179. break;
  1180. case ProcedureOptimizationMode_Size:
  1181. pass_manager_kind = lbFunctionPassManager_size;
  1182. lb_add_attribute_to_proc(p->module, p->value, "optsize");
  1183. break;
  1184. case ProcedureOptimizationMode_Speed:
  1185. pass_manager_kind = lbFunctionPassManager_speed;
  1186. break;
  1187. }
  1188. }
  1189. }
  1190. lb_llvm_function_pass_per_function_internal(m, p, pass_manager_kind);
  1191. }
  1192. }
  1193. for (auto const &entry : m->equal_procs) {
  1194. lbProcedure *p = entry.value;
  1195. lb_llvm_function_pass_per_function_internal(m, p);
  1196. }
  1197. for (auto const &entry : m->hasher_procs) {
  1198. lbProcedure *p = entry.value;
  1199. lb_llvm_function_pass_per_function_internal(m, p);
  1200. }
  1201. for (auto const &entry : m->map_get_procs) {
  1202. lbProcedure *p = entry.value;
  1203. lb_llvm_function_pass_per_function_internal(m, p, lbFunctionPassManager_none);
  1204. }
  1205. for (auto const &entry : m->map_set_procs) {
  1206. lbProcedure *p = entry.value;
  1207. lb_llvm_function_pass_per_function_internal(m, p, lbFunctionPassManager_none);
  1208. }
  1209. return 0;
  1210. }
  1211. struct lbLLVMModulePassWorkerData {
  1212. lbModule *m;
  1213. LLVMTargetMachineRef target_machine;
  1214. };
  1215. gb_internal WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) {
  1216. auto wd = cast(lbLLVMModulePassWorkerData *)data;
  1217. lb_run_remove_unused_function_pass(wd->m);
  1218. lb_run_remove_unused_globals_pass(wd->m);
  1219. LLVMPassManagerRef module_pass_manager = LLVMCreatePassManager();
  1220. lb_populate_module_pass_manager(wd->target_machine, module_pass_manager, build_context.optimization_level);
  1221. LLVMRunPassManager(module_pass_manager, wd->m->mod);
  1222. #if LB_USE_NEW_PASS_SYSTEM
  1223. auto passes = array_make<char const *>(heap_allocator(), 0, 64);
  1224. defer (array_free(&passes));
  1225. LLVMPassBuilderOptionsRef pb_options = LLVMCreatePassBuilderOptions();
  1226. defer (LLVMDisposePassBuilderOptions(pb_options));
  1227. switch (build_context.optimization_level) {
  1228. case -1:
  1229. break;
  1230. case 0:
  1231. array_add(&passes, "always-inline");
  1232. array_add(&passes, "function(annotation-remarks)");
  1233. break;
  1234. case 1:
  1235. // default<Os>
  1236. // Passes removed: coro, openmp, sroa
  1237. #if LLVM_VERSION_MAJOR == 17
  1238. array_add(&passes, u8R"(
  1239. annotation2metadata,
  1240. forceattrs,
  1241. inferattrs,
  1242. function<eager-inv>(
  1243. lower-expect,
  1244. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1245. early-cse<>
  1246. ),
  1247. ipsccp,
  1248. called-value-propagation,
  1249. globalopt,
  1250. function<eager-inv>(
  1251. mem2reg,
  1252. instcombine<max-iterations=1000;no-use-loop-info>,
  1253. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>
  1254. ),
  1255. require<globals-aa>,
  1256. function(
  1257. invalidate<aa>
  1258. ),
  1259. require<profile-summary>,
  1260. cgscc(
  1261. devirt<4>(
  1262. inline<only-mandatory>,
  1263. inline,
  1264. function-attrs<skip-non-recursive>,
  1265. function<eager-inv;no-rerun>(
  1266. early-cse<memssa>,
  1267. speculative-execution,
  1268. jump-threading,
  1269. correlated-propagation,
  1270. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1271. instcombine<max-iterations=1000;no-use-loop-info>,
  1272. aggressive-instcombine,
  1273. constraint-elimination,
  1274. tailcallelim,
  1275. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1276. reassociate,
  1277. loop-mssa(
  1278. loop-instsimplify,
  1279. loop-simplifycfg,
  1280. licm<no-allowspeculation>,
  1281. loop-rotate<header-duplication;no-prepare-for-lto>,
  1282. licm<allowspeculation>,
  1283. simple-loop-unswitch<no-nontrivial;trivial>
  1284. ),
  1285. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1286. instcombine<max-iterations=1000;no-use-loop-info>,
  1287. loop(
  1288. loop-idiom,
  1289. indvars,
  1290. loop-deletion,
  1291. loop-unroll-full
  1292. ),
  1293. vector-combine,
  1294. mldst-motion<no-split-footer-bb>,
  1295. gvn<>,
  1296. sccp,
  1297. bdce,
  1298. instcombine<max-iterations=1000;no-use-loop-info>,
  1299. jump-threading,
  1300. correlated-propagation,
  1301. adce,
  1302. memcpyopt,
  1303. dse,
  1304. move-auto-init,
  1305. loop-mssa(
  1306. licm<allowspeculation>
  1307. ),
  1308. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1309. instcombine<max-iterations=1000;no-use-loop-info>
  1310. ),
  1311. function-attrs,
  1312. function(
  1313. require<should-not-run-function-passes>
  1314. )
  1315. )
  1316. ),
  1317. deadargelim,
  1318. globalopt,
  1319. globaldce,
  1320. elim-avail-extern,
  1321. rpo-function-attrs,
  1322. recompute-globalsaa,
  1323. function<eager-inv>(
  1324. float2int,
  1325. lower-constant-intrinsics,
  1326. loop(
  1327. loop-rotate<header-duplication;no-prepare-for-lto>,
  1328. loop-deletion
  1329. ),
  1330. loop-distribute,
  1331. inject-tli-mappings,
  1332. loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,
  1333. loop-load-elim,
  1334. instcombine<max-iterations=1000;no-use-loop-info>,
  1335. simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1336. slp-vectorizer,
  1337. vector-combine,
  1338. instcombine<max-iterations=1000;no-use-loop-info>,
  1339. loop-unroll<O2>,
  1340. transform-warning,
  1341. instcombine<max-iterations=1000;no-use-loop-info>,
  1342. loop-mssa(
  1343. licm<allowspeculation>
  1344. ),
  1345. alignment-from-assumptions,
  1346. loop-sink,
  1347. instsimplify,
  1348. div-rem-pairs,
  1349. tailcallelim,
  1350. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>
  1351. ),
  1352. globaldce,
  1353. constmerge,
  1354. cg-profile,
  1355. rel-lookup-table-converter,
  1356. function(
  1357. annotation-remarks
  1358. ),
  1359. verify
  1360. )");
  1361. #else
  1362. array_add(&passes, u8R"(
  1363. annotation2metadata,
  1364. forceattrs,
  1365. inferattrs,
  1366. function<eager-inv>(
  1367. lower-expect,
  1368. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1369. sroa<modify-cfg>,
  1370. early-cse<>
  1371. ),
  1372. ipsccp,
  1373. called-value-propagation,
  1374. globalopt,
  1375. function<eager-inv>(
  1376. mem2reg,
  1377. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1378. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>
  1379. ),
  1380. always-inline,
  1381. require<globals-aa>,
  1382. function(
  1383. invalidate<aa>
  1384. ),
  1385. require<profile-summary>,
  1386. cgscc(
  1387. devirt<4>(
  1388. inline,
  1389. function-attrs<skip-non-recursive-function-attrs>,
  1390. function<eager-inv;no-rerun>(
  1391. sroa<modify-cfg>,
  1392. early-cse<memssa>,
  1393. speculative-execution<only-if-divergent-target>,
  1394. jump-threading,
  1395. correlated-propagation,
  1396. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1397. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1398. aggressive-instcombine,
  1399. tailcallelim,
  1400. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1401. reassociate,
  1402. constraint-elimination,
  1403. loop-mssa(
  1404. loop-instsimplify,
  1405. loop-simplifycfg,
  1406. licm<no-allowspeculation>,
  1407. loop-rotate<header-duplication;no-prepare-for-lto>,
  1408. licm<allowspeculation>,
  1409. simple-loop-unswitch<no-nontrivial;trivial>
  1410. ),
  1411. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1412. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1413. loop(
  1414. loop-idiom,
  1415. indvars,
  1416. loop-deletion,
  1417. loop-unroll-full
  1418. ),
  1419. sroa<modify-cfg>,
  1420. vector-combine,
  1421. mldst-motion<no-split-footer-bb>,
  1422. gvn<>,
  1423. sccp,
  1424. bdce,
  1425. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1426. jump-threading,
  1427. correlated-propagation,
  1428. adce,
  1429. memcpyopt,
  1430. dse,
  1431. move-auto-init,
  1432. loop-mssa(
  1433. licm<allowspeculation>
  1434. ),
  1435. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1436. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>
  1437. ),
  1438. function-attrs,
  1439. function(
  1440. require<should-not-run-function-passes>
  1441. )
  1442. )
  1443. ),
  1444. deadargelim,
  1445. globalopt,
  1446. globaldce,
  1447. elim-avail-extern,
  1448. rpo-function-attrs,
  1449. recompute-globalsaa,
  1450. function<eager-inv>(
  1451. float2int,
  1452. lower-constant-intrinsics,
  1453. loop(
  1454. loop-rotate<header-duplication;no-prepare-for-lto>,
  1455. loop-deletion
  1456. ),
  1457. loop-distribute,
  1458. inject-tli-mappings,
  1459. loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,
  1460. infer-alignment,
  1461. loop-load-elim,
  1462. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1463. simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1464. slp-vectorizer,
  1465. vector-combine,
  1466. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1467. loop-unroll<O2>,
  1468. transform-warning,
  1469. sroa<preserve-cfg>,
  1470. infer-alignment,
  1471. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1472. loop-mssa(
  1473. licm<allowspeculation>
  1474. ),
  1475. alignment-from-assumptions,
  1476. loop-sink,
  1477. instsimplify,
  1478. div-rem-pairs,
  1479. tailcallelim,
  1480. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>
  1481. ),
  1482. globaldce,
  1483. constmerge,
  1484. cg-profile,
  1485. rel-lookup-table-converter,
  1486. function(
  1487. annotation-remarks
  1488. ),
  1489. verify
  1490. )");
  1491. #endif
  1492. break;
  1493. // default<O2>
  1494. // Passes removed: coro, openmp, sroa
  1495. case 2:
  1496. #if LLVM_VERSION_MAJOR == 17
  1497. array_add(&passes, u8R"(
  1498. annotation2metadata,
  1499. forceattrs,
  1500. inferattrs,
  1501. function<eager-inv>(
  1502. lower-expect,
  1503. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1504. early-cse<>
  1505. ),
  1506. ipsccp,
  1507. called-value-propagation,
  1508. globalopt,
  1509. function<eager-inv>(
  1510. mem2reg,
  1511. instcombine<max-iterations=1000;no-use-loop-info>,
  1512. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>
  1513. ),
  1514. require<globals-aa>,
  1515. function(
  1516. invalidate<aa>
  1517. ),
  1518. require<profile-summary>,
  1519. cgscc(
  1520. devirt<4>(
  1521. inline<only-mandatory>,
  1522. inline,
  1523. function-attrs<skip-non-recursive>,
  1524. function<eager-inv;no-rerun>(
  1525. early-cse<memssa>,
  1526. speculative-execution,
  1527. jump-threading,
  1528. correlated-propagation,
  1529. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1530. instcombine<max-iterations=1000;no-use-loop-info>,
  1531. aggressive-instcombine,
  1532. constraint-elimination,
  1533. libcalls-shrinkwrap,
  1534. tailcallelim,
  1535. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1536. reassociate,
  1537. loop-mssa(
  1538. loop-instsimplify,
  1539. loop-simplifycfg,
  1540. licm<no-allowspeculation>,
  1541. loop-rotate<header-duplication;no-prepare-for-lto>,
  1542. licm<allowspeculation>,
  1543. simple-loop-unswitch<no-nontrivial;trivial>
  1544. ),
  1545. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1546. instcombine<max-iterations=1000;no-use-loop-info>,
  1547. loop(
  1548. loop-idiom,
  1549. indvars,
  1550. loop-deletion,
  1551. loop-unroll-full
  1552. ),
  1553. vector-combine,
  1554. mldst-motion<no-split-footer-bb>,
  1555. gvn<>,
  1556. sccp,
  1557. bdce,
  1558. instcombine<max-iterations=1000;no-use-loop-info>,
  1559. jump-threading,
  1560. correlated-propagation,
  1561. adce,
  1562. memcpyopt,
  1563. dse,
  1564. move-auto-init,
  1565. loop-mssa(
  1566. licm<allowspeculation>
  1567. ),
  1568. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1569. instcombine<max-iterations=1000;no-use-loop-info>
  1570. ),
  1571. function-attrs,
  1572. function(
  1573. require<should-not-run-function-passes>
  1574. )
  1575. )
  1576. ),
  1577. deadargelim,
  1578. globalopt,
  1579. globaldce,
  1580. elim-avail-extern,
  1581. rpo-function-attrs,
  1582. recompute-globalsaa,
  1583. function<eager-inv>(
  1584. float2int,
  1585. lower-constant-intrinsics,
  1586. loop(
  1587. loop-rotate<header-duplication;no-prepare-for-lto>,
  1588. loop-deletion
  1589. ),
  1590. loop-distribute,
  1591. inject-tli-mappings,
  1592. loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,
  1593. loop-load-elim,
  1594. instcombine<max-iterations=1000;no-use-loop-info>,
  1595. simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1596. slp-vectorizer,
  1597. vector-combine,
  1598. instcombine<max-iterations=1000;no-use-loop-info>,
  1599. loop-unroll<O2>,
  1600. transform-warning,
  1601. instcombine<max-iterations=1000;no-use-loop-info>,
  1602. loop-mssa(
  1603. licm<allowspeculation>
  1604. ),
  1605. alignment-from-assumptions,
  1606. loop-sink,
  1607. instsimplify,
  1608. div-rem-pairs,
  1609. tailcallelim,
  1610. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>
  1611. ),
  1612. globaldce,
  1613. constmerge,
  1614. cg-profile,
  1615. rel-lookup-table-converter,
  1616. function(
  1617. annotation-remarks
  1618. ),
  1619. verify
  1620. )");
  1621. #else
  1622. array_add(&passes, u8R"(
  1623. annotation2metadata,
  1624. forceattrs,
  1625. inferattrs,
  1626. function<eager-inv>(
  1627. lower-expect,
  1628. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1629. sroa<modify-cfg>,
  1630. early-cse<>
  1631. ),
  1632. ipsccp,
  1633. called-value-propagation,
  1634. globalopt,
  1635. function<eager-inv>(
  1636. mem2reg,
  1637. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1638. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>
  1639. ),
  1640. always-inline,
  1641. require<globals-aa>,
  1642. function(
  1643. invalidate<aa>
  1644. ),
  1645. require<profile-summary>,
  1646. cgscc(
  1647. devirt<4>(
  1648. inline,
  1649. function-attrs<skip-non-recursive-function-attrs>,
  1650. function<eager-inv;no-rerun>(
  1651. sroa<modify-cfg>,
  1652. early-cse<memssa>,
  1653. speculative-execution<only-if-divergent-target>,
  1654. jump-threading,
  1655. correlated-propagation,
  1656. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1657. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1658. aggressive-instcombine,
  1659. libcalls-shrinkwrap,
  1660. tailcallelim,
  1661. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1662. reassociate,
  1663. constraint-elimination,
  1664. loop-mssa(
  1665. loop-instsimplify,
  1666. loop-simplifycfg,
  1667. licm<no-allowspeculation>,
  1668. loop-rotate<header-duplication;no-prepare-for-lto>,
  1669. licm<allowspeculation>,
  1670. simple-loop-unswitch<no-nontrivial;trivial>
  1671. ),
  1672. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1673. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1674. loop(
  1675. loop-idiom,
  1676. indvars,
  1677. loop-deletion,
  1678. loop-unroll-full
  1679. ),
  1680. sroa<modify-cfg>,
  1681. vector-combine,
  1682. mldst-motion<no-split-footer-bb>,
  1683. gvn<>,
  1684. sccp,
  1685. bdce,
  1686. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1687. jump-threading,
  1688. correlated-propagation,
  1689. adce,
  1690. memcpyopt,
  1691. dse,
  1692. move-auto-init,
  1693. loop-mssa(
  1694. licm<allowspeculation>
  1695. ),
  1696. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1697. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>
  1698. ),
  1699. function-attrs,
  1700. function(
  1701. require<should-not-run-function-passes>
  1702. )
  1703. )
  1704. ),
  1705. deadargelim,
  1706. globalopt,
  1707. globaldce,
  1708. elim-avail-extern,
  1709. rpo-function-attrs,
  1710. recompute-globalsaa,
  1711. function<eager-inv>(
  1712. float2int,
  1713. lower-constant-intrinsics,
  1714. loop(
  1715. loop-rotate<header-duplication;no-prepare-for-lto>,
  1716. loop-deletion
  1717. ),
  1718. loop-distribute,
  1719. inject-tli-mappings,
  1720. loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,
  1721. infer-alignment,
  1722. loop-load-elim,
  1723. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1724. simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1725. slp-vectorizer,
  1726. vector-combine,
  1727. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1728. loop-unroll<O2>,
  1729. transform-warning,
  1730. sroa<modify-cfg>,
  1731. infer-alignment,
  1732. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1733. loop-mssa(
  1734. licm<allowspeculation>
  1735. ),
  1736. alignment-from-assumptions,
  1737. loop-sink,
  1738. instsimplify,
  1739. div-rem-pairs,
  1740. tailcallelim,
  1741. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>
  1742. ),
  1743. globaldce,
  1744. constmerge,
  1745. cg-profile,
  1746. rel-lookup-table-converter,
  1747. function(
  1748. annotation-remarks
  1749. ),
  1750. verify
  1751. )");
  1752. #endif
  1753. break;
  1754. case 3:
  1755. // default<O3>
  1756. // Passes removed: coro, openmp, sroa
  1757. #if LLVM_VERSION_MAJOR == 17
  1758. array_add(&passes, u8R"(
  1759. annotation2metadata,
  1760. forceattrs,
  1761. inferattrs,
  1762. function<eager-inv>(
  1763. lower-expect,
  1764. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1765. early-cse<>,
  1766. callsite-splitting
  1767. ),
  1768. ipsccp,
  1769. called-value-propagation,
  1770. globalopt,
  1771. function<eager-inv>(
  1772. mem2reg,
  1773. instcombine<max-iterations=1000;no-use-loop-info>,
  1774. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>
  1775. ),
  1776. require<globals-aa>,
  1777. function(
  1778. invalidate<aa>
  1779. ),
  1780. require<profile-summary>,
  1781. cgscc(
  1782. devirt<4>(
  1783. inline<only-mandatory>,
  1784. inline,
  1785. function-attrs<skip-non-recursive>,
  1786. argpromotion,
  1787. function<eager-inv;no-rerun>(
  1788. early-cse<memssa>,
  1789. speculative-execution,
  1790. jump-threading,
  1791. correlated-propagation,
  1792. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1793. instcombine<max-iterations=1000;no-use-loop-info>,
  1794. aggressive-instcombine,
  1795. constraint-elimination,
  1796. libcalls-shrinkwrap,
  1797. tailcallelim,
  1798. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1799. reassociate,
  1800. loop-mssa(
  1801. loop-instsimplify,
  1802. loop-simplifycfg,
  1803. licm<no-allowspeculation>,
  1804. loop-rotate<header-duplication;no-prepare-for-lto>,
  1805. licm<allowspeculation>,
  1806. simple-loop-unswitch<nontrivial;trivial>
  1807. ),
  1808. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1809. instcombine<max-iterations=1000;no-use-loop-info>,
  1810. loop(
  1811. loop-idiom,
  1812. indvars,
  1813. loop-deletion,
  1814. loop-unroll-full
  1815. ),
  1816. vector-combine,
  1817. mldst-motion<no-split-footer-bb>,
  1818. gvn<>,
  1819. sccp,
  1820. bdce,
  1821. instcombine<max-iterations=1000;no-use-loop-info>,
  1822. jump-threading,
  1823. correlated-propagation,
  1824. adce,
  1825. memcpyopt,
  1826. dse,
  1827. move-auto-init,
  1828. loop-mssa(
  1829. licm<allowspeculation>
  1830. ),
  1831. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1832. instcombine<max-iterations=1000;no-use-loop-info>
  1833. ),
  1834. function-attrs,
  1835. function(
  1836. require<should-not-run-function-passes>
  1837. )
  1838. )
  1839. ),
  1840. deadargelim,
  1841. globalopt,
  1842. globaldce,
  1843. elim-avail-extern,
  1844. rpo-function-attrs,
  1845. recompute-globalsaa,
  1846. function<eager-inv>(
  1847. float2int,
  1848. lower-constant-intrinsics,
  1849. chr,
  1850. loop(
  1851. loop-rotate<header-duplication;no-prepare-for-lto>,
  1852. loop-deletion
  1853. ),
  1854. loop-distribute,
  1855. inject-tli-mappings,
  1856. loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,
  1857. loop-load-elim,
  1858. instcombine<max-iterations=1000;no-use-loop-info>,
  1859. simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1860. slp-vectorizer,
  1861. vector-combine,
  1862. instcombine<max-iterations=1000;no-use-loop-info>,
  1863. loop-unroll<O3>,
  1864. transform-warning,
  1865. instcombine<max-iterations=1000;no-use-loop-info>,
  1866. loop-mssa(
  1867. licm<allowspeculation>
  1868. ),
  1869. alignment-from-assumptions,
  1870. loop-sink,
  1871. instsimplify,
  1872. div-rem-pairs,
  1873. tailcallelim,
  1874. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>
  1875. ),
  1876. globaldce,
  1877. constmerge,
  1878. cg-profile,
  1879. rel-lookup-table-converter,
  1880. function(
  1881. annotation-remarks
  1882. ),
  1883. verify
  1884. )");
  1885. #else
  1886. array_add(&passes, u8R"(
  1887. annotation2metadata,
  1888. forceattrs,
  1889. inferattrs,
  1890. function<eager-inv>(
  1891. lower-expect,
  1892. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;no-switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1893. sroa<modify-cfg>,
  1894. early-cse<>,
  1895. callsite-splitting
  1896. ),
  1897. ipsccp,
  1898. called-value-propagation,
  1899. globalopt,
  1900. function<eager-inv>(
  1901. mem2reg,
  1902. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1903. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>
  1904. ),
  1905. always-inline,
  1906. require<globals-aa>,
  1907. function(invalidate<aa>),
  1908. require<profile-summary>,
  1909. cgscc(
  1910. devirt<4>(
  1911. inline,
  1912. function-attrs<skip-non-recursive-function-attrs>,
  1913. argpromotion,
  1914. function<eager-inv;no-rerun>(
  1915. sroa<modify-cfg>,
  1916. early-cse<memssa>,
  1917. speculative-execution<only-if-divergent-target>,
  1918. jump-threading,
  1919. correlated-propagation,
  1920. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1921. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1922. aggressive-instcombine,
  1923. libcalls-shrinkwrap,
  1924. tailcallelim,
  1925. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1926. reassociate,
  1927. constraint-elimination,
  1928. loop-mssa(
  1929. loop-instsimplify,
  1930. loop-simplifycfg,
  1931. licm<no-allowspeculation>,
  1932. loop-rotate<header-duplication;no-prepare-for-lto>,
  1933. licm<allowspeculation>,
  1934. simple-loop-unswitch<nontrivial;trivial>
  1935. ),
  1936. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1937. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1938. loop(
  1939. loop-idiom,
  1940. indvars,
  1941. loop-deletion,
  1942. loop-unroll-full
  1943. ),
  1944. sroa<modify-cfg>,
  1945. vector-combine,
  1946. mldst-motion<no-split-footer-bb>,
  1947. gvn<>,
  1948. sccp,
  1949. bdce,
  1950. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1951. jump-threading,
  1952. correlated-propagation,
  1953. adce,
  1954. memcpyopt,
  1955. dse,
  1956. move-auto-init,
  1957. loop-mssa(licm<allowspeculation>),
  1958. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1959. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>
  1960. ),
  1961. function-attrs,
  1962. function(
  1963. require<should-not-run-function-passes>
  1964. )
  1965. )
  1966. ),
  1967. deadargelim,
  1968. globalopt,
  1969. globaldce,
  1970. elim-avail-extern,
  1971. rpo-function-attrs,
  1972. recompute-globalsaa,
  1973. function<eager-inv>(
  1974. float2int,
  1975. lower-constant-intrinsics,
  1976. chr,
  1977. loop(
  1978. loop-rotate<header-duplication;no-prepare-for-lto>,
  1979. loop-deletion
  1980. ),
  1981. loop-distribute,
  1982. inject-tli-mappings,
  1983. loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,
  1984. infer-alignment,
  1985. loop-load-elim,
  1986. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1987. simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;sink-common-insts;speculate-blocks;simplify-cond-branch>,
  1988. slp-vectorizer,
  1989. vector-combine,
  1990. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1991. loop-unroll<O3>,
  1992. transform-warning,
  1993. sroa<preserve-cfg>,
  1994. infer-alignment,
  1995. instcombine<max-iterations=1;no-use-loop-info;no-verify-fixpoint>,
  1996. loop-mssa(licm<allowspeculation>),
  1997. alignment-from-assumptions,
  1998. loop-sink,
  1999. instsimplify,
  2000. div-rem-pairs,
  2001. tailcallelim,
  2002. simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-sink-common-insts;speculate-blocks;simplify-cond-branch>
  2003. ),
  2004. globaldce,
  2005. constmerge,
  2006. cg-profile,
  2007. rel-lookup-table-converter,
  2008. function(
  2009. annotation-remarks
  2010. ),
  2011. verify
  2012. )");
  2013. #endif
  2014. break;
  2015. }
  2016. // asan - Linux, Darwin, Windows
  2017. // msan - linux
  2018. // tsan - Linux, Darwin
  2019. // ubsan - Linux, Darwin, Windows (NOT SUPPORTED WITH LLVM C-API)
  2020. if (build_context.sanitizer_flags & SanitizerFlag_Address) {
  2021. array_add(&passes, "asan");
  2022. }
  2023. if (build_context.sanitizer_flags & SanitizerFlag_Memory) {
  2024. array_add(&passes, "msan");
  2025. }
  2026. if (build_context.sanitizer_flags & SanitizerFlag_Thread) {
  2027. array_add(&passes, "tsan");
  2028. }
  2029. if (passes.count == 0) {
  2030. array_add(&passes, "verify");
  2031. }
  2032. gbString passes_str = gb_string_make_reserve(heap_allocator(), 1024);
  2033. defer (gb_string_free(passes_str));
  2034. for_array(i, passes) {
  2035. if (i != 0) {
  2036. passes_str = gb_string_appendc(passes_str, ",");
  2037. }
  2038. passes_str = gb_string_appendc(passes_str, passes[i]);
  2039. }
  2040. for (isize i = 0; i < gb_string_length(passes_str); /**/) {
  2041. switch (passes_str[i]) {
  2042. case ' ':
  2043. case '\n':
  2044. case '\t':
  2045. gb_memmove(&passes_str[i], &passes_str[i+1], gb_string_length(passes_str)-i);
  2046. GB_STRING_HEADER(passes_str)->length -= 1;
  2047. continue;
  2048. default:
  2049. i += 1;
  2050. break;
  2051. }
  2052. }
  2053. LLVMErrorRef llvm_err = LLVMRunPasses(wd->m->mod, passes_str, wd->target_machine, pb_options);
  2054. defer (LLVMConsumeError(llvm_err));
  2055. if (llvm_err != nullptr) {
  2056. char *llvm_error = LLVMGetErrorMessage(llvm_err);
  2057. gb_printf_err("LLVM Error:\n%s\n", llvm_error);
  2058. LLVMDisposeErrorMessage(llvm_error);
  2059. llvm_error = nullptr;
  2060. if (build_context.keep_temp_files) {
  2061. TIME_SECTION("LLVM Print Module to File");
  2062. String filepath_ll = lb_filepath_ll_for_module(wd->m);
  2063. if (LLVMPrintModuleToFile(wd->m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
  2064. gb_printf_err("LLVM Error: %s\n", llvm_error);
  2065. }
  2066. }
  2067. exit_with_errors();
  2068. return 1;
  2069. }
  2070. #endif
  2071. return 0;
  2072. }
  2073. gb_internal WORKER_TASK_PROC(lb_generate_procedures_worker_proc) {
  2074. lbModule *m = cast(lbModule *)data;
  2075. for (isize i = 0; i < m->procedures_to_generate.count; i++) {
  2076. lbProcedure *p = m->procedures_to_generate[i];
  2077. lb_generate_procedure(p->module, p);
  2078. }
  2079. return 0;
  2080. }
  2081. gb_internal void lb_generate_procedures(lbGenerator *gen, bool do_threading) {
  2082. if (do_threading) {
  2083. for (auto const &entry : gen->modules) {
  2084. lbModule *m = entry.value;
  2085. thread_pool_add_task(lb_generate_procedures_worker_proc, m);
  2086. }
  2087. thread_pool_wait();
  2088. } else {
  2089. for (auto const &entry : gen->modules) {
  2090. lbModule *m = entry.value;
  2091. lb_generate_procedures_worker_proc(m);
  2092. }
  2093. }
  2094. }
  2095. gb_internal WORKER_TASK_PROC(lb_generate_missing_procedures_to_check_worker_proc) {
  2096. lbModule *m = cast(lbModule *)data;
  2097. for (isize i = 0; i < m->missing_procedures_to_check.count; i++) {
  2098. lbProcedure *p = m->missing_procedures_to_check[i];
  2099. debugf("Generate missing procedure: %.*s module %p\n", LIT(p->name), m);
  2100. lb_generate_procedure(m, p);
  2101. }
  2102. return 0;
  2103. }
  2104. gb_internal void lb_generate_missing_procedures(lbGenerator *gen, bool do_threading) {
  2105. if (do_threading) {
  2106. for (auto const &entry : gen->modules) {
  2107. lbModule *m = entry.value;
  2108. // NOTE(bill): procedures may be added during generation
  2109. thread_pool_add_task(lb_generate_missing_procedures_to_check_worker_proc, m);
  2110. }
  2111. thread_pool_wait();
  2112. } else {
  2113. for (auto const &entry : gen->modules) {
  2114. lbModule *m = entry.value;
  2115. // NOTE(bill): procedures may be added during generation
  2116. lb_generate_missing_procedures_to_check_worker_proc(m);
  2117. }
  2118. }
  2119. }
  2120. gb_internal void lb_debug_info_complete_types_and_finalize(lbGenerator *gen) {
  2121. for (auto const &entry : gen->modules) {
  2122. lbModule *m = entry.value;
  2123. if (m->debug_builder != nullptr) {
  2124. LLVMDIBuilderFinalize(m->debug_builder);
  2125. }
  2126. }
  2127. }
  2128. gb_internal void lb_llvm_function_passes(lbGenerator *gen, bool do_threading) {
  2129. if (do_threading) {
  2130. for (auto const &entry : gen->modules) {
  2131. lbModule *m = entry.value;
  2132. thread_pool_add_task(lb_llvm_function_pass_per_module, m);
  2133. }
  2134. thread_pool_wait();
  2135. } else {
  2136. for (auto const &entry : gen->modules) {
  2137. lbModule *m = entry.value;
  2138. lb_llvm_function_pass_per_module(m);
  2139. }
  2140. }
  2141. }
  2142. gb_internal void lb_llvm_module_passes(lbGenerator *gen, bool do_threading) {
  2143. if (do_threading) {
  2144. for (auto const &entry : gen->modules) {
  2145. lbModule *m = entry.value;
  2146. auto wd = gb_alloc_item(permanent_allocator(), lbLLVMModulePassWorkerData);
  2147. wd->m = m;
  2148. wd->target_machine = m->target_machine;
  2149. if (do_threading) {
  2150. thread_pool_add_task(lb_llvm_module_pass_worker_proc, wd);
  2151. } else {
  2152. lb_llvm_module_pass_worker_proc(wd);
  2153. }
  2154. }
  2155. thread_pool_wait();
  2156. } else {
  2157. for (auto const &entry : gen->modules) {
  2158. lbModule *m = entry.value;
  2159. auto wd = gb_alloc_item(permanent_allocator(), lbLLVMModulePassWorkerData);
  2160. wd->m = m;
  2161. wd->target_machine = m->target_machine;
  2162. lb_llvm_module_pass_worker_proc(wd);
  2163. }
  2164. }
  2165. }
  2166. gb_internal String lb_filepath_ll_for_module(lbModule *m) {
  2167. String path = concatenate3_strings(permanent_allocator(),
  2168. build_context.build_paths[BuildPath_Output].basename,
  2169. STR_LIT("/"),
  2170. build_context.build_paths[BuildPath_Output].name
  2171. );
  2172. if (m->file) {
  2173. char buf[32] = {};
  2174. isize n = gb_snprintf(buf, gb_size_of(buf), "-%u", m->file->id);
  2175. String suffix = make_string((u8 *)buf, n-1);
  2176. path = concatenate_strings(permanent_allocator(), path, suffix);
  2177. } else if (m->pkg) {
  2178. path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name);
  2179. } else if (USE_SEPARATE_MODULES) {
  2180. path = concatenate_strings(permanent_allocator(), path, STR_LIT("-builtin"));
  2181. }
  2182. path = concatenate_strings(permanent_allocator(), path, STR_LIT(".ll"));
  2183. return path;
  2184. }
  2185. gb_internal String lb_filepath_obj_for_module(lbModule *m) {
  2186. String path = concatenate3_strings(permanent_allocator(),
  2187. build_context.build_paths[BuildPath_Output].basename,
  2188. STR_LIT("/"),
  2189. build_context.build_paths[BuildPath_Output].name
  2190. );
  2191. if (m->file) {
  2192. char buf[32] = {};
  2193. isize n = gb_snprintf(buf, gb_size_of(buf), "-%u", m->file->id);
  2194. String suffix = make_string((u8 *)buf, n-1);
  2195. path = concatenate_strings(permanent_allocator(), path, suffix);
  2196. } else if (m->pkg) {
  2197. path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name);
  2198. }
  2199. String ext = {};
  2200. if (build_context.build_mode == BuildMode_Assembly) {
  2201. ext = STR_LIT(".S");
  2202. } else {
  2203. if (is_arch_wasm()) {
  2204. ext = STR_LIT(".wasm.o");
  2205. } else {
  2206. switch (build_context.metrics.os) {
  2207. case TargetOs_windows:
  2208. ext = STR_LIT(".obj");
  2209. break;
  2210. default:
  2211. case TargetOs_darwin:
  2212. case TargetOs_linux:
  2213. case TargetOs_essence:
  2214. ext = STR_LIT(".o");
  2215. break;
  2216. case TargetOs_freestanding:
  2217. switch (build_context.metrics.abi) {
  2218. default:
  2219. case TargetABI_Default:
  2220. case TargetABI_SysV:
  2221. ext = STR_LIT(".o");
  2222. break;
  2223. case TargetABI_Win64:
  2224. ext = STR_LIT(".obj");
  2225. break;
  2226. }
  2227. break;
  2228. }
  2229. }
  2230. }
  2231. return concatenate_strings(permanent_allocator(), path, ext);
  2232. }
  2233. gb_internal bool lb_llvm_module_verification(lbGenerator *gen, bool do_threading) {
  2234. if (LLVM_IGNORE_VERIFICATION) {
  2235. return true;
  2236. }
  2237. if (do_threading) {
  2238. for (auto const &entry : gen->modules) {
  2239. lbModule *m = entry.value;
  2240. thread_pool_add_task(lb_llvm_module_verification_worker_proc, m);
  2241. }
  2242. thread_pool_wait();
  2243. } else {
  2244. for (auto const &entry : gen->modules) {
  2245. lbModule *m = entry.value;
  2246. if (lb_llvm_module_verification_worker_proc(m)) {
  2247. return false;
  2248. }
  2249. }
  2250. }
  2251. return true;
  2252. }
  2253. gb_internal void lb_add_foreign_library_paths(lbGenerator *gen) {
  2254. for (auto const &entry : gen->modules) {
  2255. lbModule *m = entry.value;
  2256. for (Entity *e : m->info->required_foreign_imports_through_force) {
  2257. lb_add_foreign_library_path(m, e);
  2258. }
  2259. if (lb_is_module_empty(m)) {
  2260. continue;
  2261. }
  2262. }
  2263. }
  2264. gb_internal bool lb_llvm_object_generation(lbGenerator *gen, bool do_threading) {
  2265. LLVMCodeGenFileType code_gen_file_type = LLVMObjectFile;
  2266. if (build_context.build_mode == BuildMode_Assembly) {
  2267. code_gen_file_type = LLVMAssemblyFile;
  2268. }
  2269. char *llvm_error = nullptr;
  2270. defer (LLVMDisposeMessage(llvm_error));
  2271. if (do_threading) {
  2272. for (auto const &entry : gen->modules) {
  2273. lbModule *m = entry.value;
  2274. if (lb_is_module_empty(m)) {
  2275. continue;
  2276. }
  2277. String filepath_ll = lb_filepath_ll_for_module(m);
  2278. String filepath_obj = lb_filepath_obj_for_module(m);
  2279. // gb_printf_err("%.*s\n", LIT(filepath_obj));
  2280. array_add(&gen->output_object_paths, filepath_obj);
  2281. array_add(&gen->output_temp_paths, filepath_ll);
  2282. auto *wd = gb_alloc_item(permanent_allocator(), lbLLVMEmitWorker);
  2283. wd->target_machine = m->target_machine;
  2284. wd->code_gen_file_type = code_gen_file_type;
  2285. wd->filepath_obj = filepath_obj;
  2286. wd->m = m;
  2287. thread_pool_add_task(lb_llvm_emit_worker_proc, wd);
  2288. }
  2289. thread_pool_wait(&global_thread_pool);
  2290. } else {
  2291. for (auto const &entry : gen->modules) {
  2292. lbModule *m = entry.value;
  2293. if (lb_is_module_empty(m)) {
  2294. continue;
  2295. }
  2296. String filepath_obj = lb_filepath_obj_for_module(m);
  2297. array_add(&gen->output_object_paths, filepath_obj);
  2298. String short_name = remove_directory_from_path(filepath_obj);
  2299. gbString section_name = gb_string_make(permanent_allocator(), "LLVM Generate Object: ");
  2300. section_name = gb_string_append_length(section_name, short_name.text, short_name.len);
  2301. TIME_SECTION_WITH_LEN(section_name, gb_string_length(section_name));
  2302. if (LLVMTargetMachineEmitToFile(m->target_machine, m->mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error)) {
  2303. gb_printf_err("LLVM Error: %s\n", llvm_error);
  2304. exit_with_errors();
  2305. return false;
  2306. }
  2307. debugf("Generated File: %.*s\n", LIT(filepath_obj));
  2308. }
  2309. }
  2310. return true;
  2311. }
  2312. gb_internal lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime, lbProcedure *cleanup_runtime) {
  2313. LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod);
  2314. lb_populate_function_pass_manager(m, default_function_pass_manager, false, build_context.optimization_level);
  2315. LLVMFinalizeFunctionPassManager(default_function_pass_manager);
  2316. Type *params = alloc_type_tuple();
  2317. Type *results = alloc_type_tuple();
  2318. Type *t_ptr_cstring = alloc_type_pointer(t_cstring);
  2319. bool call_cleanup = true;
  2320. bool has_args = false;
  2321. bool is_dll_main = false;
  2322. String name = str_lit("main");
  2323. if (build_context.metrics.os == TargetOs_windows && build_context.build_mode == BuildMode_DynamicLibrary) {
  2324. is_dll_main = true;
  2325. name = str_lit("DllMain");
  2326. slice_init(&params->Tuple.variables, permanent_allocator(), 3);
  2327. params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("hinstDLL"), t_rawptr, false, true);
  2328. params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("fdwReason"), t_u32, false, true);
  2329. params->Tuple.variables[2] = alloc_entity_param(nullptr, make_token_ident("lpReserved"), t_rawptr, false, true);
  2330. call_cleanup = false;
  2331. } else if (build_context.metrics.os == TargetOs_windows && (build_context.metrics.arch == TargetArch_i386 || build_context.no_crt)) {
  2332. name = str_lit("mainCRTStartup");
  2333. } else if (is_arch_wasm()) {
  2334. name = str_lit("_start");
  2335. call_cleanup = false;
  2336. } else {
  2337. has_args = true;
  2338. slice_init(&params->Tuple.variables, permanent_allocator(), 2);
  2339. params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("argc"), t_i32, false, true);
  2340. params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("argv"), t_ptr_cstring, false, true);
  2341. }
  2342. slice_init(&results->Tuple.variables, permanent_allocator(), 1);
  2343. results->Tuple.variables[0] = alloc_entity_param(nullptr, blank_token, t_i32, false, true);
  2344. Type *proc_type = alloc_type_proc(nullptr,
  2345. params, params->Tuple.variables.count,
  2346. results, results->Tuple.variables.count, false, ProcCC_CDecl);
  2347. lbProcedure *p = lb_create_dummy_procedure(m, name, proc_type);
  2348. p->is_startup = true;
  2349. lb_begin_procedure_body(p);
  2350. if (has_args) { // initialize `runtime.args__`
  2351. lbValue argc = {LLVMGetParam(p->value, 0), t_i32};
  2352. lbValue argv = {LLVMGetParam(p->value, 1), t_ptr_cstring};
  2353. LLVMSetValueName2(argc.value, "argc", 4);
  2354. LLVMSetValueName2(argv.value, "argv", 4);
  2355. argc = lb_emit_conv(p, argc, t_int);
  2356. lbAddr args = lb_addr(lb_find_runtime_value(p->module, str_lit("args__")));
  2357. lb_fill_slice(p, args, argv, argc);
  2358. }
  2359. lbValue startup_runtime_value = {startup_runtime->value, startup_runtime->type};
  2360. lb_emit_call(p, startup_runtime_value, {}, ProcInlining_none);
  2361. if (build_context.command_kind == Command_test) {
  2362. Type *t_Internal_Test = find_type_in_pkg(m->info, str_lit("testing"), str_lit("Internal_Test"));
  2363. Type *array_type = alloc_type_array(t_Internal_Test, m->info->testing_procedures.count);
  2364. Type *slice_type = alloc_type_slice(t_Internal_Test);
  2365. lbAddr all_tests_array_addr = lb_add_global_generated(p->module, array_type, {});
  2366. lbValue all_tests_array = lb_addr_get_ptr(p, all_tests_array_addr);
  2367. LLVMValueRef indices[2] = {};
  2368. indices[0] = LLVMConstInt(lb_type(m, t_i32), 0, false);
  2369. isize testing_proc_index = 0;
  2370. for (Entity *testing_proc : m->info->testing_procedures) {
  2371. String name = testing_proc->token.string;
  2372. String pkg_name = {};
  2373. if (testing_proc->pkg != nullptr) {
  2374. pkg_name = testing_proc->pkg->name;
  2375. }
  2376. lbValue v_pkg = lb_find_or_add_entity_string(m, pkg_name);
  2377. lbValue v_name = lb_find_or_add_entity_string(m, name);
  2378. lbValue v_proc = lb_find_procedure_value_from_entity(m, testing_proc);
  2379. indices[1] = LLVMConstInt(lb_type(m, t_int), testing_proc_index++, false);
  2380. LLVMValueRef vals[3] = {};
  2381. vals[0] = v_pkg.value;
  2382. vals[1] = v_name.value;
  2383. vals[2] = v_proc.value;
  2384. GB_ASSERT(LLVMIsConstant(vals[0]));
  2385. GB_ASSERT(LLVMIsConstant(vals[1]));
  2386. GB_ASSERT(LLVMIsConstant(vals[2]));
  2387. LLVMValueRef dst = LLVMConstInBoundsGEP2(llvm_addr_type(m, all_tests_array), all_tests_array.value, indices, gb_count_of(indices));
  2388. LLVMValueRef src = llvm_const_named_struct(m, t_Internal_Test, vals, gb_count_of(vals));
  2389. LLVMBuildStore(p->builder, src, dst);
  2390. }
  2391. lbAddr all_tests_slice = lb_add_local_generated(p, slice_type, true);
  2392. lb_fill_slice(p, all_tests_slice,
  2393. lb_array_elem(p, all_tests_array),
  2394. lb_const_int(m, t_int, m->info->testing_procedures.count));
  2395. lbValue runner = lb_find_package_value(m, str_lit("testing"), str_lit("runner"));
  2396. TEMPORARY_ALLOCATOR_GUARD();
  2397. auto args = array_make<lbValue>(temporary_allocator(), 1);
  2398. args[0] = lb_addr_load(p, all_tests_slice);
  2399. lbValue result = lb_emit_call(p, runner, args);
  2400. lbValue exit_runner = lb_find_package_value(m, str_lit("os"), str_lit("exit"));
  2401. auto exit_args = array_make<lbValue>(temporary_allocator(), 1);
  2402. exit_args[0] = lb_emit_select(p, result, lb_const_int(m, t_int, 0), lb_const_int(m, t_int, 1));
  2403. lb_emit_call(p, exit_runner, exit_args, ProcInlining_none);
  2404. } else {
  2405. if (m->info->entry_point != nullptr) {
  2406. lbValue entry_point = lb_find_procedure_value_from_entity(m, m->info->entry_point);
  2407. lb_emit_call(p, entry_point, {}, ProcInlining_no_inline);
  2408. }
  2409. if (call_cleanup) {
  2410. lbValue cleanup_runtime_value = {cleanup_runtime->value, cleanup_runtime->type};
  2411. lb_emit_call(p, cleanup_runtime_value, {}, ProcInlining_none);
  2412. }
  2413. if (is_dll_main) {
  2414. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_i32), 1, false));
  2415. } else {
  2416. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_i32), 0, false));
  2417. }
  2418. }
  2419. lb_end_procedure_body(p);
  2420. LLVMSetLinkage(p->value, LLVMExternalLinkage);
  2421. if (is_arch_wasm()) {
  2422. lb_set_wasm_export_attributes(p->value, p->name);
  2423. }
  2424. lb_verify_function(m, p);
  2425. lb_run_function_pass_manager(default_function_pass_manager, p, lbFunctionPassManager_default);
  2426. return p;
  2427. }
  2428. gb_internal void lb_generate_procedure(lbModule *m, lbProcedure *p) {
  2429. if (p->is_done) {
  2430. return;
  2431. }
  2432. if (p->body != nullptr) { // Build Procedure
  2433. m->curr_procedure = p;
  2434. lb_begin_procedure_body(p);
  2435. lb_build_stmt(p, p->body);
  2436. lb_end_procedure_body(p);
  2437. p->is_done = true;
  2438. m->curr_procedure = nullptr;
  2439. }
  2440. lb_end_procedure(p);
  2441. // Add Flags
  2442. if (p->entity && p->entity->kind == Entity_Procedure && p->entity->Procedure.is_memcpy_like) {
  2443. p->flags |= lbProcedureFlag_WithoutMemcpyPass;
  2444. }
  2445. lb_verify_function(m, p, true);
  2446. }
  2447. gb_internal bool lb_generate_code(lbGenerator *gen) {
  2448. TIME_SECTION("LLVM Initializtion");
  2449. isize thread_count = gb_max(build_context.thread_count, 1);
  2450. isize worker_count = thread_count-1;
  2451. bool do_threading = !!(LLVMIsMultithreaded() && USE_SEPARATE_MODULES && MULTITHREAD_OBJECT_GENERATION && worker_count > 0);
  2452. lbModule *default_module = &gen->default_module;
  2453. CheckerInfo *info = gen->info;
  2454. auto *min_dep_set = &info->minimum_dependency_set;
  2455. switch (build_context.metrics.arch) {
  2456. case TargetArch_amd64:
  2457. case TargetArch_i386:
  2458. LLVMInitializeX86TargetInfo();
  2459. LLVMInitializeX86Target();
  2460. LLVMInitializeX86TargetMC();
  2461. LLVMInitializeX86AsmPrinter();
  2462. LLVMInitializeX86AsmParser();
  2463. LLVMInitializeX86Disassembler();
  2464. break;
  2465. case TargetArch_arm64:
  2466. LLVMInitializeAArch64TargetInfo();
  2467. LLVMInitializeAArch64Target();
  2468. LLVMInitializeAArch64TargetMC();
  2469. LLVMInitializeAArch64AsmPrinter();
  2470. LLVMInitializeAArch64AsmParser();
  2471. LLVMInitializeAArch64Disassembler();
  2472. break;
  2473. case TargetArch_wasm32:
  2474. case TargetArch_wasm64p32:
  2475. LLVMInitializeWebAssemblyTargetInfo();
  2476. LLVMInitializeWebAssemblyTarget();
  2477. LLVMInitializeWebAssemblyTargetMC();
  2478. LLVMInitializeWebAssemblyAsmPrinter();
  2479. LLVMInitializeWebAssemblyAsmParser();
  2480. LLVMInitializeWebAssemblyDisassembler();
  2481. break;
  2482. default:
  2483. LLVMInitializeAllTargetInfos();
  2484. LLVMInitializeAllTargets();
  2485. LLVMInitializeAllTargetMCs();
  2486. LLVMInitializeAllAsmPrinters();
  2487. LLVMInitializeAllAsmParsers();
  2488. LLVMInitializeAllDisassemblers();
  2489. break;
  2490. }
  2491. if (build_context.microarch == "native") {
  2492. LLVMInitializeNativeTarget();
  2493. }
  2494. char const *target_triple = alloc_cstring(permanent_allocator(), build_context.metrics.target_triplet);
  2495. for (auto const &entry : gen->modules) {
  2496. LLVMSetTarget(entry.value->mod, target_triple);
  2497. }
  2498. LLVMTargetRef target = {};
  2499. char *llvm_error = nullptr;
  2500. LLVMGetTargetFromTriple(target_triple, &target, &llvm_error);
  2501. GB_ASSERT(target != nullptr);
  2502. TIME_SECTION("LLVM Create Target Machine");
  2503. LLVMCodeModel code_mode = LLVMCodeModelDefault;
  2504. if (is_arch_wasm()) {
  2505. code_mode = LLVMCodeModelJITDefault;
  2506. } else if (is_arch_x86() && build_context.metrics.os == TargetOs_freestanding) {
  2507. code_mode = LLVMCodeModelKernel;
  2508. }
  2509. String llvm_cpu = get_final_microarchitecture();
  2510. gbString llvm_features = gb_string_make(temporary_allocator(), "");
  2511. String_Iterator it = {build_context.target_features_string, 0};
  2512. bool first = true;
  2513. for (;;) {
  2514. String str = string_split_iterator(&it, ',');
  2515. if (str == "") break;
  2516. if (!first) {
  2517. llvm_features = gb_string_appendc(llvm_features, ",");
  2518. }
  2519. first = false;
  2520. llvm_features = gb_string_appendc(llvm_features, "+");
  2521. llvm_features = gb_string_append_length(llvm_features, str.text, str.len);
  2522. }
  2523. debugf("CPU: %.*s, Features: %s\n", LIT(llvm_cpu), llvm_features);
  2524. // GB_ASSERT_MSG(LLVMTargetHasAsmBackend(target));
  2525. LLVMCodeGenOptLevel code_gen_level = LLVMCodeGenLevelNone;
  2526. if (!LB_USE_NEW_PASS_SYSTEM) {
  2527. build_context.optimization_level = gb_clamp(build_context.optimization_level, -1, 2);
  2528. }
  2529. switch (build_context.optimization_level) {
  2530. default:/*fallthrough*/
  2531. case 0: code_gen_level = LLVMCodeGenLevelNone; break;
  2532. case 1: code_gen_level = LLVMCodeGenLevelLess; break;
  2533. case 2: code_gen_level = LLVMCodeGenLevelDefault; break;
  2534. case 3: code_gen_level = LLVMCodeGenLevelAggressive; break;
  2535. }
  2536. // NOTE(bill): Target Machine Creation
  2537. // NOTE(bill, 2021-05-04): Target machines must be unique to each module because they are not thread safe
  2538. auto target_machines = array_make<LLVMTargetMachineRef>(permanent_allocator(), 0, gen->modules.count);
  2539. // NOTE(dweiler): Dynamic libraries require position-independent code.
  2540. LLVMRelocMode reloc_mode = LLVMRelocDefault;
  2541. if (build_context.build_mode == BuildMode_DynamicLibrary) {
  2542. reloc_mode = LLVMRelocPIC;
  2543. }
  2544. switch (build_context.reloc_mode) {
  2545. case RelocMode_Default:
  2546. if (build_context.metrics.os == TargetOs_openbsd || build_context.metrics.os == TargetOs_haiku) {
  2547. // Always use PIC for OpenBSD and Haiku: they default to PIE
  2548. reloc_mode = LLVMRelocPIC;
  2549. }
  2550. break;
  2551. case RelocMode_Static:
  2552. reloc_mode = LLVMRelocStatic;
  2553. break;
  2554. case RelocMode_PIC:
  2555. reloc_mode = LLVMRelocPIC;
  2556. break;
  2557. case RelocMode_DynamicNoPIC:
  2558. reloc_mode = LLVMRelocDynamicNoPic;
  2559. break;
  2560. }
  2561. for (auto const &entry : gen->modules) {
  2562. LLVMTargetMachineRef target_machine = LLVMCreateTargetMachine(
  2563. target, target_triple, (const char *)llvm_cpu.text,
  2564. llvm_features,
  2565. code_gen_level,
  2566. reloc_mode,
  2567. code_mode);
  2568. lbModule *m = entry.value;
  2569. m->target_machine = target_machine;
  2570. LLVMSetModuleDataLayout(m->mod, LLVMCreateTargetDataLayout(target_machine));
  2571. array_add(&target_machines, target_machine);
  2572. }
  2573. for (auto const &entry : gen->modules) {
  2574. lbModule *m = entry.value;
  2575. if (m->debug_builder) { // Debug Info
  2576. for (auto const &file_entry : info->files) {
  2577. AstFile *f = file_entry.value;
  2578. LLVMMetadataRef res = LLVMDIBuilderCreateFile(m->debug_builder,
  2579. cast(char const *)f->filename.text, f->filename.len,
  2580. cast(char const *)f->directory.text, f->directory.len);
  2581. lb_set_llvm_metadata(m, f, res);
  2582. }
  2583. TEMPORARY_ALLOCATOR_GUARD();
  2584. gbString producer = gb_string_make(temporary_allocator(), "odin");
  2585. // producer = gb_string_append_fmt(producer, " version %.*s", LIT(ODIN_VERSION));
  2586. // #ifdef NIGHTLY
  2587. // producer = gb_string_appendc(producer, "-nightly");
  2588. // #endif
  2589. // #ifdef GIT_SHA
  2590. // producer = gb_string_append_fmt(producer, "-%s", GIT_SHA);
  2591. // #endif
  2592. gbString split_name = gb_string_make(temporary_allocator(), "");
  2593. LLVMBool is_optimized = build_context.optimization_level > 0;
  2594. AstFile *init_file = m->info->init_package->files[0];
  2595. if (Entity *entry_point = m->info->entry_point) {
  2596. if (Ast *ident = entry_point->identifier.load()) {
  2597. if (ident->file_id) {
  2598. init_file = ident->file();
  2599. }
  2600. }
  2601. }
  2602. LLVMBool split_debug_inlining = build_context.build_mode == BuildMode_Assembly;
  2603. LLVMBool debug_info_for_profiling = false;
  2604. m->debug_compile_unit = LLVMDIBuilderCreateCompileUnit(m->debug_builder, LLVMDWARFSourceLanguageC99,
  2605. lb_get_llvm_metadata(m, init_file),
  2606. producer, gb_string_length(producer),
  2607. is_optimized, "", 0,
  2608. 1, split_name, gb_string_length(split_name),
  2609. LLVMDWARFEmissionFull,
  2610. 0, split_debug_inlining,
  2611. debug_info_for_profiling,
  2612. "", 0, // sys_root
  2613. "", 0 // SDK
  2614. );
  2615. GB_ASSERT(m->debug_compile_unit != nullptr);
  2616. }
  2617. }
  2618. TIME_SECTION("LLVM Global Variables");
  2619. if (!build_context.no_rtti) {
  2620. lbModule *m = default_module;
  2621. { // Add type info data
  2622. isize max_type_info_count = info->minimum_dependency_type_info_set.count+1;
  2623. Type *t = alloc_type_array(t_type_info_ptr, max_type_info_count);
  2624. // IMPORTANT NOTE(bill): As LLVM does not have a union type, an array of unions cannot be initialized
  2625. // at compile time without cheating in some way. This means to emulate an array of unions is to use
  2626. // a giant packed struct of "corrected" data types.
  2627. LLVMTypeRef internal_llvm_type = lb_type(m, t);
  2628. LLVMValueRef g = LLVMAddGlobal(m->mod, internal_llvm_type, LB_TYPE_INFO_DATA_NAME);
  2629. LLVMSetInitializer(g, LLVMConstNull(internal_llvm_type));
  2630. LLVMSetLinkage(g, USE_SEPARATE_MODULES ? LLVMExternalLinkage : LLVMInternalLinkage);
  2631. LLVMSetUnnamedAddress(g, LLVMGlobalUnnamedAddr);
  2632. LLVMSetGlobalConstant(g, true);
  2633. lbValue value = {};
  2634. value.value = g;
  2635. value.type = alloc_type_pointer(t);
  2636. lb_global_type_info_data_entity = alloc_entity_variable(nullptr, make_token_ident(LB_TYPE_INFO_DATA_NAME), t, EntityState_Resolved);
  2637. lb_add_entity(m, lb_global_type_info_data_entity, value);
  2638. }
  2639. { // Type info member buffer
  2640. // NOTE(bill): Removes need for heap allocation by making it global memory
  2641. isize count = 0;
  2642. isize offsets_extra = 0;
  2643. for (Type *t : m->info->type_info_types) {
  2644. isize index = lb_type_info_index(m->info, t, false);
  2645. if (index < 0) {
  2646. continue;
  2647. }
  2648. switch (t->kind) {
  2649. case Type_Union:
  2650. count += t->Union.variants.count;
  2651. break;
  2652. case Type_Struct:
  2653. count += t->Struct.fields.count;
  2654. break;
  2655. case Type_Tuple:
  2656. count += t->Tuple.variables.count;
  2657. break;
  2658. case Type_BitField:
  2659. count += t->BitField.fields.count;
  2660. // Twice is needed for the bit_offsets
  2661. offsets_extra += t->BitField.fields.count;
  2662. break;
  2663. }
  2664. }
  2665. auto const global_type_info_make = [](lbModule *m, char const *name, Type *elem_type, i64 count) -> lbAddr {
  2666. Type *t = alloc_type_array(elem_type, count);
  2667. LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
  2668. LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
  2669. LLVMSetLinkage(g, LLVMInternalLinkage);
  2670. lb_make_global_private_const(g);
  2671. return lb_addr({g, alloc_type_pointer(t)});
  2672. };
  2673. lb_global_type_info_member_types = global_type_info_make(m, LB_TYPE_INFO_TYPES_NAME, t_type_info_ptr, count);
  2674. lb_global_type_info_member_names = global_type_info_make(m, LB_TYPE_INFO_NAMES_NAME, t_string, count);
  2675. lb_global_type_info_member_offsets = global_type_info_make(m, LB_TYPE_INFO_OFFSETS_NAME, t_uintptr, count+offsets_extra);
  2676. lb_global_type_info_member_usings = global_type_info_make(m, LB_TYPE_INFO_USINGS_NAME, t_bool, count);
  2677. lb_global_type_info_member_tags = global_type_info_make(m, LB_TYPE_INFO_TAGS_NAME, t_string, count);
  2678. }
  2679. }
  2680. isize global_variable_max_count = 0;
  2681. bool already_has_entry_point = false;
  2682. for (Entity *e : info->entities) {
  2683. String name = e->token.string;
  2684. if (e->kind == Entity_Variable) {
  2685. global_variable_max_count++;
  2686. } else if (e->kind == Entity_Procedure) {
  2687. if ((e->scope->flags&ScopeFlag_Init) && name == "main") {
  2688. GB_ASSERT(e == info->entry_point);
  2689. }
  2690. if (build_context.command_kind == Command_test &&
  2691. (e->Procedure.is_export || e->Procedure.link_name.len > 0)) {
  2692. String link_name = e->Procedure.link_name;
  2693. if (e->pkg->kind == Package_Runtime) {
  2694. if (link_name == "main" ||
  2695. link_name == "DllMain" ||
  2696. link_name == "WinMain" ||
  2697. link_name == "wWinMain" ||
  2698. link_name == "mainCRTStartup" ||
  2699. link_name == "_start") {
  2700. already_has_entry_point = true;
  2701. }
  2702. }
  2703. }
  2704. }
  2705. }
  2706. auto global_variables = array_make<lbGlobalVariable>(permanent_allocator(), 0, global_variable_max_count);
  2707. for (DeclInfo *d : info->variable_init_order) {
  2708. Entity *e = d->entity;
  2709. if ((e->scope->flags & ScopeFlag_File) == 0) {
  2710. continue;
  2711. }
  2712. if (!ptr_set_exists(min_dep_set, e)) {
  2713. continue;
  2714. }
  2715. DeclInfo *decl = decl_info_of_entity(e);
  2716. if (decl == nullptr) {
  2717. continue;
  2718. }
  2719. GB_ASSERT(e->kind == Entity_Variable);
  2720. bool is_foreign = e->Variable.is_foreign;
  2721. bool is_export = e->Variable.is_export;
  2722. lbModule *m = &gen->default_module;
  2723. String name = lb_get_entity_name(m, e);
  2724. lbValue g = {};
  2725. g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name));
  2726. g.type = alloc_type_pointer(e->type);
  2727. if (e->Variable.thread_local_model != "") {
  2728. LLVMSetThreadLocal(g.value, true);
  2729. String m = e->Variable.thread_local_model;
  2730. LLVMThreadLocalMode mode = LLVMGeneralDynamicTLSModel;
  2731. if (m == "default") {
  2732. mode = LLVMGeneralDynamicTLSModel;
  2733. } else if (m == "localdynamic") {
  2734. mode = LLVMLocalDynamicTLSModel;
  2735. } else if (m == "initialexec") {
  2736. mode = LLVMInitialExecTLSModel;
  2737. } else if (m == "localexec") {
  2738. mode = LLVMLocalExecTLSModel;
  2739. } else {
  2740. GB_PANIC("Unhandled thread local mode %.*s", LIT(m));
  2741. }
  2742. LLVMSetThreadLocalMode(g.value, mode);
  2743. }
  2744. if (is_foreign) {
  2745. LLVMSetLinkage(g.value, LLVMExternalLinkage);
  2746. LLVMSetDLLStorageClass(g.value, LLVMDLLImportStorageClass);
  2747. LLVMSetExternallyInitialized(g.value, true);
  2748. lb_add_foreign_library_path(m, e->Variable.foreign_library);
  2749. // lb_set_wasm_import_attributes(g.value, e, name);
  2750. } else {
  2751. LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, e->type)));
  2752. }
  2753. if (is_export) {
  2754. LLVMSetLinkage(g.value, LLVMDLLExportLinkage);
  2755. LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass);
  2756. } else if (!is_foreign) {
  2757. LLVMSetLinkage(g.value, USE_SEPARATE_MODULES ? LLVMExternalLinkage : LLVMInternalLinkage);
  2758. }
  2759. lb_set_linkage_from_entity_flags(m, g.value, e->flags);
  2760. if (e->Variable.link_section.len > 0) {
  2761. LLVMSetSection(g.value, alloc_cstring(permanent_allocator(), e->Variable.link_section));
  2762. }
  2763. lbGlobalVariable var = {};
  2764. var.var = g;
  2765. var.decl = decl;
  2766. if (decl->init_expr != nullptr) {
  2767. TypeAndValue tav = type_and_value_of_expr(decl->init_expr);
  2768. if (!is_type_any(e->type) && !is_type_union(e->type)) {
  2769. if (tav.mode != Addressing_Invalid) {
  2770. if (tav.value.kind != ExactValue_Invalid) {
  2771. ExactValue v = tav.value;
  2772. lbValue init = lb_const_value(m, tav.type, v);
  2773. LLVMSetInitializer(g.value, init.value);
  2774. var.is_initialized = true;
  2775. if (e->kind == Entity_Variable && e->Variable.is_rodata) {
  2776. LLVMSetGlobalConstant(g.value, true);
  2777. }
  2778. }
  2779. }
  2780. }
  2781. if (!var.is_initialized && is_type_untyped_nil(tav.type)) {
  2782. var.is_initialized = true;
  2783. if (e->kind == Entity_Variable && e->Variable.is_rodata) {
  2784. LLVMSetGlobalConstant(g.value, true);
  2785. }
  2786. }
  2787. } else if (e->kind == Entity_Variable && e->Variable.is_rodata) {
  2788. LLVMSetGlobalConstant(g.value, true);
  2789. }
  2790. array_add(&global_variables, var);
  2791. lb_add_entity(m, e, g);
  2792. lb_add_member(m, name, g);
  2793. if (m->debug_builder) {
  2794. String global_name = e->token.string;
  2795. if (global_name.len != 0 && global_name != "_") {
  2796. LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, e->file);
  2797. LLVMMetadataRef llvm_scope = llvm_file;
  2798. LLVMBool local_to_unit = LLVMGetLinkage(g.value) == LLVMInternalLinkage;
  2799. LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0);
  2800. LLVMMetadataRef llvm_decl = nullptr;
  2801. u32 align_in_bits = cast(u32)(8*type_align_of(e->type));
  2802. LLVMMetadataRef global_variable_metadata = LLVMDIBuilderCreateGlobalVariableExpression(
  2803. m->debug_builder, llvm_scope,
  2804. cast(char const *)global_name.text, global_name.len,
  2805. "", 0, // linkage
  2806. llvm_file, e->token.pos.line,
  2807. lb_debug_type(m, e->type),
  2808. local_to_unit,
  2809. llvm_expr,
  2810. llvm_decl,
  2811. align_in_bits
  2812. );
  2813. lb_set_llvm_metadata(m, g.value, global_variable_metadata);
  2814. LLVMGlobalSetMetadata(g.value, 0, global_variable_metadata);
  2815. }
  2816. }
  2817. }
  2818. TIME_SECTION("LLVM Runtime Objective-C Names Creation");
  2819. gen->objc_names = lb_create_objc_names(default_module);
  2820. TIME_SECTION("LLVM Runtime Startup Creation (Global Variables & @(init))");
  2821. gen->startup_runtime = lb_create_startup_runtime(default_module, gen->objc_names, global_variables);
  2822. TIME_SECTION("LLVM Runtime Cleanup Creation & @(fini)");
  2823. gen->cleanup_runtime = lb_create_cleanup_runtime(default_module);
  2824. if (build_context.ODIN_DEBUG) {
  2825. for (auto const &entry : builtin_pkg->scope->elements) {
  2826. Entity *e = entry.value;
  2827. add_debug_info_for_global_constant_from_entity(gen, e);
  2828. }
  2829. }
  2830. if (gen->modules.count <= 1) {
  2831. do_threading = false;
  2832. }
  2833. TIME_SECTION("LLVM Global Procedures and Types");
  2834. lb_create_global_procedures_and_types(gen, info, do_threading);
  2835. TIME_SECTION("LLVM Procedure Generation");
  2836. lb_generate_procedures(gen, do_threading);
  2837. if (build_context.command_kind == Command_test && !already_has_entry_point) {
  2838. TIME_SECTION("LLVM main");
  2839. lb_create_main_procedure(default_module, gen->startup_runtime, gen->cleanup_runtime);
  2840. }
  2841. TIME_SECTION("LLVM Procedure Generation (missing)");
  2842. lb_generate_missing_procedures(gen, do_threading);
  2843. if (gen->objc_names) {
  2844. TIME_SECTION("Finalize objc names");
  2845. lb_finalize_objc_names(gen->objc_names);
  2846. }
  2847. if (build_context.ODIN_DEBUG) {
  2848. TIME_SECTION("LLVM Debug Info Complete Types and Finalize");
  2849. lb_debug_info_complete_types_and_finalize(gen);
  2850. }
  2851. if (do_threading) {
  2852. isize non_empty_module_count = 0;
  2853. for (auto const &entry : gen->modules) {
  2854. lbModule *m = entry.value;
  2855. if (!lb_is_module_empty(m)) {
  2856. non_empty_module_count += 1;
  2857. }
  2858. }
  2859. if (non_empty_module_count <= 1) {
  2860. do_threading = false;
  2861. }
  2862. }
  2863. TIME_SECTION("LLVM Function Pass");
  2864. lb_llvm_function_passes(gen, do_threading && !build_context.ODIN_DEBUG);
  2865. TIME_SECTION("LLVM Module Pass");
  2866. lb_llvm_module_passes(gen, do_threading);
  2867. TIME_SECTION("LLVM Module Verification");
  2868. if (!lb_llvm_module_verification(gen, do_threading)) {
  2869. return false;
  2870. }
  2871. llvm_error = nullptr;
  2872. defer (LLVMDisposeMessage(llvm_error));
  2873. if (build_context.keep_temp_files ||
  2874. build_context.build_mode == BuildMode_LLVM_IR) {
  2875. TIME_SECTION("LLVM Print Module to File");
  2876. for (auto const &entry : gen->modules) {
  2877. lbModule *m = entry.value;
  2878. if (lb_is_module_empty(m)) {
  2879. continue;
  2880. }
  2881. String filepath_ll = lb_filepath_ll_for_module(m);
  2882. if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
  2883. gb_printf_err("LLVM Error: %s\n", llvm_error);
  2884. exit_with_errors();
  2885. return false;
  2886. }
  2887. array_add(&gen->output_temp_paths, filepath_ll);
  2888. }
  2889. if (build_context.build_mode == BuildMode_LLVM_IR) {
  2890. return true;
  2891. }
  2892. }
  2893. TIME_SECTION("LLVM Add Foreign Library Paths");
  2894. lb_add_foreign_library_paths(gen);
  2895. TIME_SECTION("LLVM Object Generation");
  2896. if (build_context.ignore_llvm_build) {
  2897. gb_printf_err("LLVM object generation has been ignored!\n");
  2898. return false;
  2899. }
  2900. if (!lb_llvm_object_generation(gen, do_threading)) {
  2901. return false;
  2902. }
  2903. if (build_context.sanitizer_flags & SanitizerFlag_Address) {
  2904. if (build_context.metrics.os == TargetOs_windows) {
  2905. auto paths = array_make<String>(heap_allocator(), 0, 1);
  2906. String path = concatenate_strings(permanent_allocator(), build_context.ODIN_ROOT, str_lit("\\bin\\llvm\\windows\\clang_rt.asan-x86_64.lib"));
  2907. array_add(&paths, path);
  2908. Entity *lib = alloc_entity_library_name(nullptr, make_token_ident("asan_lib"), nullptr, slice_from_array(paths), str_lit("asan_lib"));
  2909. array_add(&gen->foreign_libraries, lib);
  2910. } else if (build_context.metrics.os == TargetOs_darwin || build_context.metrics.os == TargetOs_linux) {
  2911. if (!build_context.extra_linker_flags.text) {
  2912. build_context.extra_linker_flags = str_lit("-fsanitize=address");
  2913. } else {
  2914. build_context.extra_linker_flags = concatenate_strings(permanent_allocator(), build_context.extra_linker_flags, str_lit(" -fsanitize=address"));
  2915. }
  2916. }
  2917. }
  2918. if (build_context.sanitizer_flags & SanitizerFlag_Memory) {
  2919. if (build_context.metrics.os == TargetOs_darwin || build_context.metrics.os == TargetOs_linux) {
  2920. if (!build_context.extra_linker_flags.text) {
  2921. build_context.extra_linker_flags = str_lit("-fsanitize=memory");
  2922. } else {
  2923. build_context.extra_linker_flags = concatenate_strings(permanent_allocator(), build_context.extra_linker_flags, str_lit(" -fsanitize=memory"));
  2924. }
  2925. }
  2926. }
  2927. if (build_context.sanitizer_flags & SanitizerFlag_Thread) {
  2928. if (build_context.metrics.os == TargetOs_darwin || build_context.metrics.os == TargetOs_linux) {
  2929. if (!build_context.extra_linker_flags.text) {
  2930. build_context.extra_linker_flags = str_lit("-fsanitize=thread");
  2931. } else {
  2932. build_context.extra_linker_flags = concatenate_strings(permanent_allocator(), build_context.extra_linker_flags, str_lit(" -fsanitize=thread"));
  2933. }
  2934. }
  2935. }
  2936. array_sort(gen->foreign_libraries, foreign_library_cmp);
  2937. return true;
  2938. }