llvm_backend.cpp 472 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086
  1. #define MULTITHREAD_OBJECT_GENERATION 1
  2. #ifndef USE_SEPARTE_MODULES
  3. #define USE_SEPARTE_MODULES build_context.use_separate_modules
  4. #endif
  5. #ifndef MULTITHREAD_OBJECT_GENERATION
  6. #define MULTITHREAD_OBJECT_GENERATION 0
  7. #endif
  8. #include "llvm_backend.hpp"
  9. #include "llvm_abi.cpp"
  10. #include "llvm_backend_opt.cpp"
  11. gb_global ThreadPool lb_thread_pool = {};
  12. gb_global Entity *lb_global_type_info_data_entity = {};
  13. gb_global lbAddr lb_global_type_info_member_types = {};
  14. gb_global lbAddr lb_global_type_info_member_names = {};
  15. gb_global lbAddr lb_global_type_info_member_offsets = {};
  16. gb_global lbAddr lb_global_type_info_member_usings = {};
  17. gb_global lbAddr lb_global_type_info_member_tags = {};
  18. gb_global isize lb_global_type_info_data_index = 0;
  19. gb_global isize lb_global_type_info_member_types_index = 0;
  20. gb_global isize lb_global_type_info_member_names_index = 0;
  21. gb_global isize lb_global_type_info_member_offsets_index = 0;
  22. gb_global isize lb_global_type_info_member_usings_index = 0;
  23. gb_global isize lb_global_type_info_member_tags_index = 0;
  24. lbValue lb_global_type_info_data_ptr(lbModule *m) {
  25. lbValue v = lb_find_value_from_entity(m, lb_global_type_info_data_entity);
  26. return v;
  27. }
  28. struct lbLoopData {
  29. lbAddr idx_addr;
  30. lbValue idx;
  31. lbBlock *body;
  32. lbBlock *done;
  33. lbBlock *loop;
  34. };
  35. struct lbCompoundLitElemTempData {
  36. Ast * expr;
  37. lbValue value;
  38. i32 elem_index;
  39. lbValue gep;
  40. };
  41. lbLoopData lb_loop_start(lbProcedure *p, isize count, Type *index_type=t_i32);
  42. void lb_loop_end(lbProcedure *p, lbLoopData const &data);
  43. LLVMValueRef llvm_zero(lbModule *m) {
  44. return LLVMConstInt(lb_type(m, t_int), 0, false);
  45. }
  46. LLVMValueRef llvm_one(lbModule *m) {
  47. return LLVMConstInt(lb_type(m, t_i32), 1, false);
  48. }
  49. lbValue lb_zero(lbModule *m, Type *t) {
  50. lbValue v = {};
  51. v.value = LLVMConstInt(lb_type(m, t), 0, false);
  52. v.type = t;
  53. return v;
  54. }
  55. LLVMValueRef llvm_cstring(lbModule *m, String const &str) {
  56. lbValue v = lb_find_or_add_entity_string(m, str);
  57. unsigned indices[1] = {0};
  58. return LLVMConstExtractValue(v.value, indices, gb_count_of(indices));
  59. }
  60. bool lb_is_instr_terminating(LLVMValueRef instr) {
  61. if (instr != nullptr) {
  62. LLVMOpcode op = LLVMGetInstructionOpcode(instr);
  63. switch (op) {
  64. case LLVMRet:
  65. case LLVMBr:
  66. case LLVMSwitch:
  67. case LLVMIndirectBr:
  68. case LLVMInvoke:
  69. case LLVMUnreachable:
  70. case LLVMCallBr:
  71. return true;
  72. }
  73. }
  74. return false;
  75. }
  76. lbModule *lb_pkg_module(lbGenerator *gen, AstPackage *pkg) {
  77. auto *found = map_get(&gen->modules, hash_pointer(pkg));
  78. if (found) {
  79. return *found;
  80. }
  81. return &gen->default_module;
  82. }
  83. lbAddr lb_addr(lbValue addr) {
  84. lbAddr v = {lbAddr_Default, addr};
  85. if (addr.type != nullptr && is_type_relative_pointer(type_deref(addr.type))) {
  86. GB_ASSERT(is_type_pointer(addr.type));
  87. v.kind = lbAddr_RelativePointer;
  88. } else if (addr.type != nullptr && is_type_relative_slice(type_deref(addr.type))) {
  89. GB_ASSERT(is_type_pointer(addr.type));
  90. v.kind = lbAddr_RelativeSlice;
  91. }
  92. return v;
  93. }
  94. lbAddr lb_addr_map(lbValue addr, lbValue map_key, Type *map_type, Type *map_result) {
  95. lbAddr v = {lbAddr_Map, addr};
  96. v.map.key = map_key;
  97. v.map.type = map_type;
  98. v.map.result = map_result;
  99. return v;
  100. }
  101. lbAddr lb_addr_soa_variable(lbValue addr, lbValue index, Ast *index_expr) {
  102. lbAddr v = {lbAddr_SoaVariable, addr};
  103. v.soa.index = index;
  104. v.soa.index_expr = index_expr;
  105. return v;
  106. }
  107. Type *lb_addr_type(lbAddr const &addr) {
  108. if (addr.addr.value == nullptr) {
  109. return nullptr;
  110. }
  111. if (addr.kind == lbAddr_Map) {
  112. Type *t = base_type(addr.map.type);
  113. GB_ASSERT(is_type_map(t));
  114. return t->Map.value;
  115. }
  116. return type_deref(addr.addr.type);
  117. }
  118. LLVMTypeRef lb_addr_lb_type(lbAddr const &addr) {
  119. return LLVMGetElementType(LLVMTypeOf(addr.addr.value));
  120. }
  121. lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
  122. if (addr.addr.value == nullptr) {
  123. GB_PANIC("Illegal addr -> nullptr");
  124. return {};
  125. }
  126. switch (addr.kind) {
  127. case lbAddr_Map: {
  128. Type *map_type = base_type(addr.map.type);
  129. lbValue h = lb_gen_map_header(p, addr.addr, map_type);
  130. lbValue key = lb_gen_map_hash(p, addr.map.key, map_type->Map.key);
  131. auto args = array_make<lbValue>(permanent_allocator(), 2);
  132. args[0] = h;
  133. args[1] = key;
  134. lbValue ptr = lb_emit_runtime_call(p, "__dynamic_map_get", args);
  135. return lb_emit_conv(p, ptr, alloc_type_pointer(map_type->Map.value));
  136. }
  137. case lbAddr_RelativePointer: {
  138. Type *rel_ptr = base_type(lb_addr_type(addr));
  139. GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
  140. lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr);
  141. lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
  142. offset = lb_emit_load(p, offset);
  143. if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
  144. offset = lb_emit_conv(p, offset, t_i64);
  145. }
  146. offset = lb_emit_conv(p, offset, t_uintptr);
  147. lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr);
  148. absolute_ptr = lb_emit_conv(p, absolute_ptr, rel_ptr->RelativePointer.pointer_type);
  149. lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer));
  150. // NOTE(bill): nil check
  151. lbValue nil_ptr = lb_const_nil(p->module, rel_ptr->RelativePointer.pointer_type);
  152. lbValue final_ptr = lb_emit_select(p, cond, nil_ptr, absolute_ptr);
  153. return final_ptr;
  154. }
  155. case lbAddr_SoaVariable: {
  156. // TODO(bill): FIX THIS HACK
  157. return lb_address_from_load(p, lb_addr_load(p, addr));
  158. }
  159. case lbAddr_Context:
  160. GB_PANIC("lbAddr_Context should be handled elsewhere");
  161. }
  162. return addr.addr;
  163. }
  164. lbValue lb_build_addr_ptr(lbProcedure *p, Ast *expr) {
  165. lbAddr addr = lb_build_addr(p, expr);
  166. return lb_addr_get_ptr(p, addr);
  167. }
  168. void lb_emit_bounds_check(lbProcedure *p, Token token, lbValue index, lbValue len) {
  169. if (build_context.no_bounds_check) {
  170. return;
  171. }
  172. if ((p->state_flags & StateFlag_no_bounds_check) != 0) {
  173. return;
  174. }
  175. index = lb_emit_conv(p, index, t_int);
  176. len = lb_emit_conv(p, len, t_int);
  177. lbValue file = lb_find_or_add_entity_string(p->module, get_file_path_string(token.pos.file_id));
  178. lbValue line = lb_const_int(p->module, t_i32, token.pos.line);
  179. lbValue column = lb_const_int(p->module, t_i32, token.pos.column);
  180. auto args = array_make<lbValue>(permanent_allocator(), 5);
  181. args[0] = file;
  182. args[1] = line;
  183. args[2] = column;
  184. args[3] = index;
  185. args[4] = len;
  186. lb_emit_runtime_call(p, "bounds_check_error", args);
  187. }
  188. void lb_emit_slice_bounds_check(lbProcedure *p, Token token, lbValue low, lbValue high, lbValue len, bool lower_value_used) {
  189. if (build_context.no_bounds_check) {
  190. return;
  191. }
  192. if ((p->state_flags & StateFlag_no_bounds_check) != 0) {
  193. return;
  194. }
  195. lbValue file = lb_find_or_add_entity_string(p->module, get_file_path_string(token.pos.file_id));
  196. lbValue line = lb_const_int(p->module, t_i32, token.pos.line);
  197. lbValue column = lb_const_int(p->module, t_i32, token.pos.column);
  198. high = lb_emit_conv(p, high, t_int);
  199. if (!lower_value_used) {
  200. auto args = array_make<lbValue>(permanent_allocator(), 5);
  201. args[0] = file;
  202. args[1] = line;
  203. args[2] = column;
  204. args[3] = high;
  205. args[4] = len;
  206. lb_emit_runtime_call(p, "slice_expr_error_hi", args);
  207. } else {
  208. // No need to convert unless used
  209. low = lb_emit_conv(p, low, t_int);
  210. auto args = array_make<lbValue>(permanent_allocator(), 6);
  211. args[0] = file;
  212. args[1] = line;
  213. args[2] = column;
  214. args[3] = low;
  215. args[4] = high;
  216. args[5] = len;
  217. lb_emit_runtime_call(p, "slice_expr_error_lo_hi", args);
  218. }
  219. }
  220. void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
  221. if (addr.addr.value == nullptr) {
  222. return;
  223. }
  224. GB_ASSERT(value.type != nullptr);
  225. if (is_type_untyped_undef(value.type)) {
  226. Type *t = lb_addr_type(addr);
  227. value.type = t;
  228. value.value = LLVMGetUndef(lb_type(p->module, t));
  229. } else if (is_type_untyped_nil(value.type)) {
  230. Type *t = lb_addr_type(addr);
  231. value.type = t;
  232. value.value = LLVMConstNull(lb_type(p->module, t));
  233. }
  234. if (addr.kind == lbAddr_RelativePointer && addr.relative.deref) {
  235. addr = lb_addr(lb_address_from_load(p, lb_addr_load(p, addr)));
  236. }
  237. if (addr.kind == lbAddr_RelativePointer) {
  238. Type *rel_ptr = base_type(lb_addr_type(addr));
  239. GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
  240. value = lb_emit_conv(p, value, rel_ptr->RelativePointer.pointer_type);
  241. GB_ASSERT(is_type_pointer(addr.addr.type));
  242. lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr);
  243. lbValue val_ptr = lb_emit_conv(p, value, t_uintptr);
  244. lbValue offset = {};
  245. offset.value = LLVMBuildSub(p->builder, val_ptr.value, ptr.value, "");
  246. offset.type = t_uintptr;
  247. if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
  248. offset = lb_emit_conv(p, offset, t_i64);
  249. }
  250. offset = lb_emit_conv(p, offset, rel_ptr->RelativePointer.base_integer);
  251. lbValue offset_ptr = lb_emit_conv(p, addr.addr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
  252. offset = lb_emit_select(p,
  253. lb_emit_comp(p, Token_CmpEq, val_ptr, lb_const_nil(p->module, t_uintptr)),
  254. lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer),
  255. offset
  256. );
  257. LLVMBuildStore(p->builder, offset.value, offset_ptr.value);
  258. return;
  259. } else if (addr.kind == lbAddr_RelativeSlice) {
  260. Type *rel_ptr = base_type(lb_addr_type(addr));
  261. GB_ASSERT(rel_ptr->kind == Type_RelativeSlice);
  262. value = lb_emit_conv(p, value, rel_ptr->RelativeSlice.slice_type);
  263. GB_ASSERT(is_type_pointer(addr.addr.type));
  264. lbValue ptr = lb_emit_conv(p, lb_emit_struct_ep(p, addr.addr, 0), t_uintptr);
  265. lbValue val_ptr = lb_emit_conv(p, lb_slice_elem(p, value), t_uintptr);
  266. lbValue offset = {};
  267. offset.value = LLVMBuildSub(p->builder, val_ptr.value, ptr.value, "");
  268. offset.type = t_uintptr;
  269. if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
  270. offset = lb_emit_conv(p, offset, t_i64);
  271. }
  272. offset = lb_emit_conv(p, offset, rel_ptr->RelativePointer.base_integer);
  273. lbValue offset_ptr = lb_emit_conv(p, addr.addr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
  274. offset = lb_emit_select(p,
  275. lb_emit_comp(p, Token_CmpEq, val_ptr, lb_const_nil(p->module, t_uintptr)),
  276. lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer),
  277. offset
  278. );
  279. LLVMBuildStore(p->builder, offset.value, offset_ptr.value);
  280. lbValue len = lb_slice_len(p, value);
  281. len = lb_emit_conv(p, len, rel_ptr->RelativePointer.base_integer);
  282. lbValue len_ptr = lb_emit_struct_ep(p, addr.addr, 1);
  283. LLVMBuildStore(p->builder, len.value, len_ptr.value);
  284. return;
  285. } else if (addr.kind == lbAddr_AtomOp_index_set) {
  286. lbValue ptr = addr.addr;
  287. lbValue index = addr.index_set.index;
  288. Ast *node = addr.index_set.node;
  289. ast_node(ce, CallExpr, node);
  290. Type *proc_type = type_and_value_of_expr(ce->proc).type;
  291. proc_type = base_type(proc_type);
  292. GB_ASSERT(is_type_proc(proc_type));
  293. TypeProc *pt = &proc_type->Proc;
  294. isize arg_count = 3;
  295. isize param_count = 0;
  296. if (pt->params) {
  297. GB_ASSERT(pt->params->kind == Type_Tuple);
  298. param_count = pt->params->Tuple.variables.count;
  299. }
  300. auto args = array_make<lbValue>(permanent_allocator(), gb_max(arg_count, param_count));
  301. args[0] = ptr;
  302. args[1] = index;
  303. args[2] = value;
  304. isize arg_index = arg_count;
  305. if (arg_count < param_count) {
  306. lbModule *m = p->module;
  307. String proc_name = {};
  308. if (p->entity != nullptr) {
  309. proc_name = p->entity->token.string;
  310. }
  311. TokenPos pos = ast_token(ce->proc).pos;
  312. TypeTuple *param_tuple = &pt->params->Tuple;
  313. isize end = cast(isize)param_count;
  314. while (arg_index < end) {
  315. Entity *e = param_tuple->variables[arg_index];
  316. GB_ASSERT(e->kind == Entity_Variable);
  317. args[arg_index++] = lb_handle_param_value(p, e->type, e->Variable.param_value, pos);
  318. }
  319. }
  320. Entity *e = entity_from_expr(ce->proc);
  321. GB_ASSERT(e != nullptr);
  322. GB_ASSERT(is_type_polymorphic(e->type));
  323. {
  324. lb_emit_call(p, lb_find_procedure_value_from_entity(p->module, e), args);
  325. }
  326. return;
  327. } else if (addr.kind == lbAddr_Map) {
  328. lb_insert_dynamic_map_key_and_value(p, addr, addr.map.type, addr.map.key, value, p->curr_stmt);
  329. return;
  330. } else if (addr.kind == lbAddr_Context) {
  331. lbAddr old_addr = lb_find_or_generate_context_ptr(p);
  332. // IMPORTANT NOTE(bill, 2021-04-22): reuse unused 'context' variables to minimize stack usage
  333. // This has to be done manually since the optimizer cannot determine when this is possible
  334. bool create_new = true;
  335. for_array(i, p->context_stack) {
  336. lbContextData *ctx_data = &p->context_stack[i];
  337. if (ctx_data->ctx.addr.value == old_addr.addr.value) {
  338. if (ctx_data->uses > 0) {
  339. create_new = true;
  340. } else if (p->scope_index > ctx_data->scope_index) {
  341. create_new = true;
  342. } else {
  343. // gb_printf_err("%.*s (curr:%td) (ctx:%td) (uses:%td)\n", LIT(p->name), p->scope_index, ctx_data->scope_index, ctx_data->uses);
  344. create_new = false;
  345. }
  346. break;
  347. }
  348. }
  349. lbValue next = {};
  350. if (create_new) {
  351. lbValue old = lb_addr_load(p, old_addr);
  352. lbAddr next_addr = lb_add_local_generated(p, t_context, true);
  353. lb_addr_store(p, next_addr, old);
  354. lb_push_context_onto_stack(p, next_addr);
  355. next = next_addr.addr;
  356. } else {
  357. next = old_addr.addr;
  358. }
  359. if (addr.ctx.sel.index.count > 0) {
  360. lbValue lhs = lb_emit_deep_field_gep(p, next, addr.ctx.sel);
  361. lbValue rhs = lb_emit_conv(p, value, type_deref(lhs.type));
  362. lb_emit_store(p, lhs, rhs);
  363. } else {
  364. lbValue lhs = next;
  365. lbValue rhs = lb_emit_conv(p, value, lb_addr_type(addr));
  366. lb_emit_store(p, lhs, rhs);
  367. }
  368. return;
  369. } else if (addr.kind == lbAddr_SoaVariable) {
  370. Type *t = type_deref(addr.addr.type);
  371. t = base_type(t);
  372. GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
  373. Type *elem_type = t->Struct.soa_elem;
  374. value = lb_emit_conv(p, value, elem_type);
  375. elem_type = base_type(elem_type);
  376. lbValue index = addr.soa.index;
  377. if (!lb_is_const(index) || t->Struct.soa_kind != StructSoa_Fixed) {
  378. Type *t = base_type(type_deref(addr.addr.type));
  379. GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
  380. lbValue len = lb_soa_struct_len(p, addr.addr);
  381. if (addr.soa.index_expr != nullptr) {
  382. lb_emit_bounds_check(p, ast_token(addr.soa.index_expr), index, len);
  383. }
  384. }
  385. isize field_count = 0;
  386. switch (elem_type->kind) {
  387. case Type_Struct:
  388. field_count = elem_type->Struct.fields.count;
  389. break;
  390. case Type_Array:
  391. field_count = elem_type->Array.count;
  392. break;
  393. }
  394. for (isize i = 0; i < field_count; i++) {
  395. lbValue dst = lb_emit_struct_ep(p, addr.addr, cast(i32)i);
  396. lbValue src = lb_emit_struct_ev(p, value, cast(i32)i);
  397. if (t->Struct.soa_kind == StructSoa_Fixed) {
  398. dst = lb_emit_array_ep(p, dst, index);
  399. lb_emit_store(p, dst, src);
  400. } else {
  401. lbValue field = lb_emit_load(p, dst);
  402. dst = lb_emit_ptr_offset(p, field, index);
  403. lb_emit_store(p, dst, src);
  404. }
  405. }
  406. return;
  407. }
  408. GB_ASSERT(value.value != nullptr);
  409. value = lb_emit_conv(p, value, lb_addr_type(addr));
  410. // if (lb_is_const_or_global(value)) {
  411. // // NOTE(bill): Just bypass the actual storage and set the initializer
  412. // if (LLVMGetValueKind(addr.addr.value) == LLVMGlobalVariableValueKind) {
  413. // LLVMValueRef dst = addr.addr.value;
  414. // LLVMValueRef src = value.value;
  415. // LLVMSetInitializer(dst, src);
  416. // return;
  417. // }
  418. // }
  419. lb_emit_store(p, addr.addr, value);
  420. }
  421. void lb_const_store(lbValue ptr, lbValue value) {
  422. GB_ASSERT(lb_is_const(ptr));
  423. GB_ASSERT(lb_is_const(value));
  424. GB_ASSERT(is_type_pointer(ptr.type));
  425. LLVMSetInitializer(ptr.value, value.value);
  426. }
  427. bool lb_is_type_proc_recursive(Type *t) {
  428. for (;;) {
  429. if (t == nullptr) {
  430. return false;
  431. }
  432. switch (t->kind) {
  433. case Type_Named:
  434. t = t->Named.base;
  435. break;
  436. case Type_Pointer:
  437. t = t->Pointer.elem;
  438. break;
  439. case Type_Array:
  440. t = t->Array.elem;
  441. break;
  442. case Type_EnumeratedArray:
  443. t = t->EnumeratedArray.elem;
  444. break;
  445. case Type_Slice:
  446. t = t->Slice.elem;
  447. break;
  448. case Type_DynamicArray:
  449. t = t->DynamicArray.elem;
  450. break;
  451. case Type_Proc:
  452. return true;
  453. default:
  454. return false;
  455. }
  456. }
  457. }
  458. void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) {
  459. GB_ASSERT(value.value != nullptr);
  460. Type *a = type_deref(ptr.type);
  461. if (is_type_boolean(a)) {
  462. // NOTE(bill): There are multiple sized booleans, thus force a conversion (if necessarily)
  463. value = lb_emit_conv(p, value, a);
  464. }
  465. Type *ca = core_type(a);
  466. if (ca->kind == Type_Basic) {
  467. GB_ASSERT_MSG(are_types_identical(ca, core_type(value.type)), "%s != %s", type_to_string(a), type_to_string(value.type));
  468. }
  469. if (lb_is_type_proc_recursive(a)) {
  470. // NOTE(bill, 2020-11-11): Because of certain LLVM rules, a procedure value may be
  471. // stored as regular pointer with no procedure information
  472. LLVMTypeRef src_t = LLVMGetElementType(LLVMTypeOf(ptr.value));
  473. LLVMValueRef v = LLVMBuildPointerCast(p->builder, value.value, src_t, "");
  474. LLVMBuildStore(p->builder, v, ptr.value);
  475. } else {
  476. Type *ca = core_type(a);
  477. if (ca->kind == Type_Basic || ca->kind == Type_Proc) {
  478. GB_ASSERT_MSG(are_types_identical(ca, core_type(value.type)), "%s != %s", type_to_string(a), type_to_string(value.type));
  479. } else {
  480. GB_ASSERT_MSG(are_types_identical(a, value.type), "%s != %s", type_to_string(a), type_to_string(value.type));
  481. }
  482. LLVMBuildStore(p->builder, value.value, ptr.value);
  483. }
  484. }
  485. LLVMTypeRef llvm_addr_type(lbValue addr_val) {
  486. return LLVMGetElementType(LLVMTypeOf(addr_val.value));
  487. }
  488. lbValue lb_emit_load(lbProcedure *p, lbValue value) {
  489. lbModule *m = p->module;
  490. GB_ASSERT(value.value != nullptr);
  491. GB_ASSERT(is_type_pointer(value.type));
  492. Type *t = type_deref(value.type);
  493. LLVMValueRef v = LLVMBuildLoad2(p->builder, llvm_addr_type(value), value.value, "");
  494. return lbValue{v, t};
  495. }
  496. lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) {
  497. GB_ASSERT(addr.addr.value != nullptr);
  498. if (addr.kind == lbAddr_RelativePointer) {
  499. Type *rel_ptr = base_type(lb_addr_type(addr));
  500. GB_ASSERT(rel_ptr->kind == Type_RelativePointer);
  501. lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr);
  502. lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer));
  503. offset = lb_emit_load(p, offset);
  504. if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) {
  505. offset = lb_emit_conv(p, offset, t_i64);
  506. }
  507. offset = lb_emit_conv(p, offset, t_uintptr);
  508. lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr);
  509. absolute_ptr = lb_emit_conv(p, absolute_ptr, rel_ptr->RelativePointer.pointer_type);
  510. lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer));
  511. // NOTE(bill): nil check
  512. lbValue nil_ptr = lb_const_nil(p->module, rel_ptr->RelativePointer.pointer_type);
  513. lbValue final_ptr = {};
  514. final_ptr.type = absolute_ptr.type;
  515. final_ptr.value = LLVMBuildSelect(p->builder, cond.value, nil_ptr.value, absolute_ptr.value, "");
  516. return lb_emit_load(p, final_ptr);
  517. } else if (addr.kind == lbAddr_RelativeSlice) {
  518. Type *rel_ptr = base_type(lb_addr_type(addr));
  519. GB_ASSERT(rel_ptr->kind == Type_RelativeSlice);
  520. lbValue offset_ptr = lb_emit_struct_ep(p, addr.addr, 0);
  521. lbValue ptr = lb_emit_conv(p, offset_ptr, t_uintptr);
  522. lbValue offset = lb_emit_load(p, offset_ptr);
  523. if (!is_type_unsigned(rel_ptr->RelativeSlice.base_integer)) {
  524. offset = lb_emit_conv(p, offset, t_i64);
  525. }
  526. offset = lb_emit_conv(p, offset, t_uintptr);
  527. lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr);
  528. Type *slice_type = base_type(rel_ptr->RelativeSlice.slice_type);
  529. GB_ASSERT(rel_ptr->RelativeSlice.slice_type->kind == Type_Slice);
  530. Type *slice_elem = slice_type->Slice.elem;
  531. Type *slice_elem_ptr = alloc_type_pointer(slice_elem);
  532. absolute_ptr = lb_emit_conv(p, absolute_ptr, slice_elem_ptr);
  533. lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativeSlice.base_integer));
  534. // NOTE(bill): nil check
  535. lbValue nil_ptr = lb_const_nil(p->module, slice_elem_ptr);
  536. lbValue data = {};
  537. data.type = absolute_ptr.type;
  538. data.value = LLVMBuildSelect(p->builder, cond.value, nil_ptr.value, absolute_ptr.value, "");
  539. lbValue len = lb_emit_load(p, lb_emit_struct_ep(p, addr.addr, 1));
  540. len = lb_emit_conv(p, len, t_int);
  541. lbAddr slice = lb_add_local_generated(p, slice_type, false);
  542. lb_fill_slice(p, slice, data, len);
  543. return lb_addr_load(p, slice);
  544. } else if (addr.kind == lbAddr_Map) {
  545. Type *map_type = base_type(addr.map.type);
  546. lbAddr v = lb_add_local_generated(p, map_type->Map.lookup_result_type, true);
  547. lbValue h = lb_gen_map_header(p, addr.addr, map_type);
  548. lbValue key = lb_gen_map_hash(p, addr.map.key, map_type->Map.key);
  549. auto args = array_make<lbValue>(permanent_allocator(), 2);
  550. args[0] = h;
  551. args[1] = key;
  552. lbValue ptr = lb_emit_runtime_call(p, "__dynamic_map_get", args);
  553. lbValue ok = lb_emit_conv(p, lb_emit_comp_against_nil(p, Token_NotEq, ptr), t_bool);
  554. lb_emit_store(p, lb_emit_struct_ep(p, v.addr, 1), ok);
  555. lbBlock *then = lb_create_block(p, "map.get.then");
  556. lbBlock *done = lb_create_block(p, "map.get.done");
  557. lb_emit_if(p, ok, then, done);
  558. lb_start_block(p, then);
  559. {
  560. // TODO(bill): mem copy it instead?
  561. lbValue gep0 = lb_emit_struct_ep(p, v.addr, 0);
  562. lbValue value = lb_emit_conv(p, ptr, gep0.type);
  563. lb_emit_store(p, gep0, lb_emit_load(p, value));
  564. }
  565. lb_emit_jump(p, done);
  566. lb_start_block(p, done);
  567. if (is_type_tuple(addr.map.result)) {
  568. return lb_addr_load(p, v);
  569. } else {
  570. lbValue single = lb_emit_struct_ep(p, v.addr, 0);
  571. return lb_emit_load(p, single);
  572. }
  573. } else if (addr.kind == lbAddr_Context) {
  574. lbValue a = addr.addr;
  575. for_array(i, p->context_stack) {
  576. lbContextData *ctx_data = &p->context_stack[i];
  577. if (ctx_data->ctx.addr.value == a.value) {
  578. ctx_data->uses += 1;
  579. break;
  580. }
  581. }
  582. a.value = LLVMBuildPointerCast(p->builder, a.value, lb_type(p->module, t_context_ptr), "");
  583. if (addr.ctx.sel.index.count > 0) {
  584. lbValue b = lb_emit_deep_field_gep(p, a, addr.ctx.sel);
  585. return lb_emit_load(p, b);
  586. } else {
  587. return lb_emit_load(p, a);
  588. }
  589. } else if (addr.kind == lbAddr_SoaVariable) {
  590. Type *t = type_deref(addr.addr.type);
  591. t = base_type(t);
  592. GB_ASSERT(t->kind == Type_Struct && t->Struct.soa_kind != StructSoa_None);
  593. Type *elem = t->Struct.soa_elem;
  594. lbValue len = {};
  595. if (t->Struct.soa_kind == StructSoa_Fixed) {
  596. len = lb_const_int(p->module, t_int, t->Struct.soa_count);
  597. } else {
  598. lbValue v = lb_emit_load(p, addr.addr);
  599. len = lb_soa_struct_len(p, v);
  600. }
  601. lbAddr res = lb_add_local_generated(p, elem, true);
  602. if (addr.soa.index_expr != nullptr && (!lb_is_const(addr.soa.index) || t->Struct.soa_kind != StructSoa_Fixed)) {
  603. lb_emit_bounds_check(p, ast_token(addr.soa.index_expr), addr.soa.index, len);
  604. }
  605. if (t->Struct.soa_kind == StructSoa_Fixed) {
  606. for_array(i, t->Struct.fields) {
  607. Entity *field = t->Struct.fields[i];
  608. Type *base_type = field->type;
  609. GB_ASSERT(base_type->kind == Type_Array);
  610. lbValue dst = lb_emit_struct_ep(p, res.addr, cast(i32)i);
  611. lbValue src_ptr = lb_emit_struct_ep(p, addr.addr, cast(i32)i);
  612. src_ptr = lb_emit_array_ep(p, src_ptr, addr.soa.index);
  613. lbValue src = lb_emit_load(p, src_ptr);
  614. lb_emit_store(p, dst, src);
  615. }
  616. } else {
  617. isize field_count = t->Struct.fields.count;
  618. if (t->Struct.soa_kind == StructSoa_Slice) {
  619. field_count -= 1;
  620. } else if (t->Struct.soa_kind == StructSoa_Dynamic) {
  621. field_count -= 3;
  622. }
  623. for (isize i = 0; i < field_count; i++) {
  624. Entity *field = t->Struct.fields[i];
  625. Type *base_type = field->type;
  626. GB_ASSERT(base_type->kind == Type_Pointer);
  627. Type *elem = base_type->Pointer.elem;
  628. lbValue dst = lb_emit_struct_ep(p, res.addr, cast(i32)i);
  629. lbValue src_ptr = lb_emit_struct_ep(p, addr.addr, cast(i32)i);
  630. lbValue src = lb_emit_load(p, src_ptr);
  631. src = lb_emit_ptr_offset(p, src, addr.soa.index);
  632. src = lb_emit_load(p, src);
  633. lb_emit_store(p, dst, src);
  634. }
  635. }
  636. return lb_addr_load(p, res);
  637. }
  638. if (is_type_proc(addr.addr.type)) {
  639. return addr.addr;
  640. }
  641. return lb_emit_load(p, addr.addr);
  642. }
  643. lbValue lb_const_union_tag(lbModule *m, Type *u, Type *v) {
  644. return lb_const_value(m, union_tag_type(u), exact_value_i64(union_variant_index(u, v)));
  645. }
  646. lbValue lb_emit_union_tag_ptr(lbProcedure *p, lbValue u) {
  647. Type *t = u.type;
  648. GB_ASSERT_MSG(is_type_pointer(t) &&
  649. is_type_union(type_deref(t)), "%s", type_to_string(t));
  650. Type *ut = type_deref(t);
  651. GB_ASSERT(!is_type_union_maybe_pointer_original_alignment(ut));
  652. GB_ASSERT(!is_type_union_maybe_pointer(ut));
  653. GB_ASSERT(type_size_of(ut) > 0);
  654. Type *tag_type = union_tag_type(ut);
  655. LLVMTypeRef uvt = LLVMGetElementType(LLVMTypeOf(u.value));
  656. unsigned element_count = LLVMCountStructElementTypes(uvt);
  657. GB_ASSERT_MSG(element_count == 3, "(%s) != (%s)", type_to_string(ut), LLVMPrintTypeToString(uvt));
  658. lbValue tag_ptr = {};
  659. tag_ptr.value = LLVMBuildStructGEP(p->builder, u.value, 2, "");
  660. tag_ptr.type = alloc_type_pointer(tag_type);
  661. return tag_ptr;
  662. }
  663. lbValue lb_emit_union_tag_value(lbProcedure *p, lbValue u) {
  664. lbValue ptr = lb_address_from_load_or_generate_local(p, u);
  665. lbValue tag_ptr = lb_emit_union_tag_ptr(p, ptr);
  666. return lb_emit_load(p, tag_ptr);
  667. }
  668. void lb_emit_store_union_variant_tag(lbProcedure *p, lbValue parent, Type *variant_type) {
  669. Type *t = type_deref(parent.type);
  670. if (is_type_union_maybe_pointer(t) || type_size_of(t) == 0) {
  671. // No tag needed!
  672. } else {
  673. lbValue tag_ptr = lb_emit_union_tag_ptr(p, parent);
  674. lb_emit_store(p, tag_ptr, lb_const_union_tag(p->module, t, variant_type));
  675. }
  676. }
  677. void lb_emit_store_union_variant(lbProcedure *p, lbValue parent, lbValue variant, Type *variant_type) {
  678. lbValue underlying = lb_emit_conv(p, parent, alloc_type_pointer(variant_type));
  679. lb_emit_store(p, underlying, variant);
  680. lb_emit_store_union_variant_tag(p, parent, variant_type);
  681. }
  682. void lb_clone_struct_type(LLVMTypeRef dst, LLVMTypeRef src) {
  683. unsigned field_count = LLVMCountStructElementTypes(src);
  684. LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count);
  685. LLVMGetStructElementTypes(src, fields);
  686. LLVMStructSetBody(dst, fields, field_count, LLVMIsPackedStruct(src));
  687. }
  688. LLVMTypeRef lb_alignment_prefix_type_hack(lbModule *m, i64 alignment) {
  689. switch (alignment) {
  690. case 1:
  691. return LLVMArrayType(lb_type(m, t_u8), 0);
  692. case 2:
  693. return LLVMArrayType(lb_type(m, t_u16), 0);
  694. case 4:
  695. return LLVMArrayType(lb_type(m, t_u32), 0);
  696. case 8:
  697. return LLVMArrayType(lb_type(m, t_u64), 0);
  698. case 16:
  699. return LLVMArrayType(LLVMVectorType(lb_type(m, t_u32), 4), 0);
  700. default:
  701. GB_PANIC("Invalid alignment %d", cast(i32)alignment);
  702. break;
  703. }
  704. return nullptr;
  705. }
  706. bool lb_is_elem_const(Ast *elem, Type *elem_type) {
  707. if (!elem_type_can_be_constant(elem_type)) {
  708. return false;
  709. }
  710. if (elem->kind == Ast_FieldValue) {
  711. elem = elem->FieldValue.value;
  712. }
  713. TypeAndValue tav = type_and_value_of_expr(elem);
  714. GB_ASSERT_MSG(tav.mode != Addressing_Invalid, "%s %s", expr_to_string(elem), type_to_string(tav.type));
  715. return tav.value.kind != ExactValue_Invalid;
  716. }
  717. String lb_mangle_name(lbModule *m, Entity *e) {
  718. String name = e->token.string;
  719. AstPackage *pkg = e->pkg;
  720. GB_ASSERT_MSG(pkg != nullptr, "Missing package for '%.*s'", LIT(name));
  721. String pkgn = pkg->name;
  722. GB_ASSERT(!rune_is_digit(pkgn[0]));
  723. if (pkgn == "llvm") {
  724. pkgn = str_lit("llvm$");
  725. }
  726. isize max_len = pkgn.len + 1 + name.len + 1;
  727. bool require_suffix_id = is_type_polymorphic(e->type, true);
  728. if ((e->scope->flags & (ScopeFlag_File | ScopeFlag_Pkg)) == 0) {
  729. require_suffix_id = true;
  730. } else if (is_blank_ident(e->token)) {
  731. require_suffix_id = true;
  732. }if (e->flags & EntityFlag_NotExported) {
  733. require_suffix_id = true;
  734. }
  735. if (require_suffix_id) {
  736. max_len += 21;
  737. }
  738. char *new_name = gb_alloc_array(permanent_allocator(), char, max_len);
  739. isize new_name_len = gb_snprintf(
  740. new_name, max_len,
  741. "%.*s.%.*s", LIT(pkgn), LIT(name)
  742. );
  743. if (require_suffix_id) {
  744. char *str = new_name + new_name_len-1;
  745. isize len = max_len-new_name_len;
  746. isize extra = gb_snprintf(str, len, "-%llu", cast(unsigned long long)e->id);
  747. new_name_len += extra-1;
  748. }
  749. String mangled_name = make_string((u8 const *)new_name, new_name_len-1);
  750. return mangled_name;
  751. }
  752. String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedure *p) {
  753. // NOTE(bill, 2020-03-08): A polymorphic procedure may take a nested type declaration
  754. // and as a result, the declaration does not have time to determine what it should be
  755. GB_ASSERT(e != nullptr && e->kind == Entity_TypeName);
  756. if (e->TypeName.ir_mangled_name.len != 0) {
  757. return e->TypeName.ir_mangled_name;
  758. }
  759. GB_ASSERT((e->scope->flags & ScopeFlag_File) == 0);
  760. if (p == nullptr) {
  761. Entity *proc = nullptr;
  762. if (e->parent_proc_decl != nullptr) {
  763. proc = e->parent_proc_decl->entity;
  764. } else {
  765. Scope *scope = e->scope;
  766. while (scope != nullptr && (scope->flags & ScopeFlag_Proc) == 0) {
  767. scope = scope->parent;
  768. }
  769. GB_ASSERT(scope != nullptr);
  770. GB_ASSERT(scope->flags & ScopeFlag_Proc);
  771. proc = scope->procedure_entity;
  772. }
  773. GB_ASSERT(proc->kind == Entity_Procedure);
  774. if (proc->code_gen_procedure != nullptr) {
  775. p = proc->code_gen_procedure;
  776. }
  777. }
  778. // NOTE(bill): Generate a new name
  779. // parent_proc.name-guid
  780. String ts_name = e->token.string;
  781. if (p != nullptr) {
  782. isize name_len = p->name.len + 1 + ts_name.len + 1 + 10 + 1;
  783. char *name_text = gb_alloc_array(permanent_allocator(), char, name_len);
  784. u32 guid = ++p->module->nested_type_name_guid;
  785. name_len = gb_snprintf(name_text, name_len, "%.*s.%.*s-%u", LIT(p->name), LIT(ts_name), guid);
  786. String name = make_string(cast(u8 *)name_text, name_len-1);
  787. e->TypeName.ir_mangled_name = name;
  788. return name;
  789. } else {
  790. // NOTE(bill): a nested type be required before its parameter procedure exists. Just give it a temp name for now
  791. isize name_len = 9 + 1 + ts_name.len + 1 + 10 + 1;
  792. char *name_text = gb_alloc_array(permanent_allocator(), char, name_len);
  793. static u32 guid = 0;
  794. guid += 1;
  795. name_len = gb_snprintf(name_text, name_len, "_internal.%.*s-%u", LIT(ts_name), guid);
  796. String name = make_string(cast(u8 *)name_text, name_len-1);
  797. e->TypeName.ir_mangled_name = name;
  798. return name;
  799. }
  800. }
  801. String lb_get_entity_name(lbModule *m, Entity *e, String default_name) {
  802. if (e != nullptr && e->kind == Entity_TypeName && e->TypeName.ir_mangled_name.len != 0) {
  803. return e->TypeName.ir_mangled_name;
  804. }
  805. GB_ASSERT(e != nullptr);
  806. if (e->pkg == nullptr) {
  807. return e->token.string;
  808. }
  809. if (e->kind == Entity_TypeName && (e->scope->flags & ScopeFlag_File) == 0) {
  810. return lb_set_nested_type_name_ir_mangled_name(e, nullptr);
  811. }
  812. String name = {};
  813. bool no_name_mangle = false;
  814. if (e->kind == Entity_Variable) {
  815. bool is_foreign = e->Variable.is_foreign;
  816. bool is_export = e->Variable.is_export;
  817. no_name_mangle = e->Variable.link_name.len > 0 || is_foreign || is_export;
  818. if (e->Variable.link_name.len > 0) {
  819. return e->Variable.link_name;
  820. }
  821. } else if (e->kind == Entity_Procedure && e->Procedure.link_name.len > 0) {
  822. return e->Procedure.link_name;
  823. } else if (e->kind == Entity_Procedure && e->Procedure.is_export) {
  824. no_name_mangle = true;
  825. }
  826. if (!no_name_mangle) {
  827. name = lb_mangle_name(m, e);
  828. }
  829. if (name.len == 0) {
  830. name = e->token.string;
  831. }
  832. if (e->kind == Entity_TypeName) {
  833. e->TypeName.ir_mangled_name = name;
  834. } else if (e->kind == Entity_Procedure) {
  835. e->Procedure.link_name = name;
  836. }
  837. return name;
  838. }
  839. LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
  840. Type *original_type = type;
  841. LLVMContextRef ctx = m->ctx;
  842. i64 size = type_size_of(type); // Check size
  843. GB_ASSERT(type != t_invalid);
  844. switch (type->kind) {
  845. case Type_Basic:
  846. switch (type->Basic.kind) {
  847. case Basic_llvm_bool: return LLVMInt1TypeInContext(ctx);
  848. case Basic_bool: return LLVMInt8TypeInContext(ctx);
  849. case Basic_b8: return LLVMInt8TypeInContext(ctx);
  850. case Basic_b16: return LLVMInt16TypeInContext(ctx);
  851. case Basic_b32: return LLVMInt32TypeInContext(ctx);
  852. case Basic_b64: return LLVMInt64TypeInContext(ctx);
  853. case Basic_i8: return LLVMInt8TypeInContext(ctx);
  854. case Basic_u8: return LLVMInt8TypeInContext(ctx);
  855. case Basic_i16: return LLVMInt16TypeInContext(ctx);
  856. case Basic_u16: return LLVMInt16TypeInContext(ctx);
  857. case Basic_i32: return LLVMInt32TypeInContext(ctx);
  858. case Basic_u32: return LLVMInt32TypeInContext(ctx);
  859. case Basic_i64: return LLVMInt64TypeInContext(ctx);
  860. case Basic_u64: return LLVMInt64TypeInContext(ctx);
  861. case Basic_i128: return LLVMInt128TypeInContext(ctx);
  862. case Basic_u128: return LLVMInt128TypeInContext(ctx);
  863. case Basic_rune: return LLVMInt32TypeInContext(ctx);
  864. case Basic_f16: return LLVMHalfTypeInContext(ctx);
  865. case Basic_f32: return LLVMFloatTypeInContext(ctx);
  866. case Basic_f64: return LLVMDoubleTypeInContext(ctx);
  867. case Basic_f16le: return LLVMHalfTypeInContext(ctx);
  868. case Basic_f32le: return LLVMFloatTypeInContext(ctx);
  869. case Basic_f64le: return LLVMDoubleTypeInContext(ctx);
  870. case Basic_f16be: return LLVMHalfTypeInContext(ctx);
  871. case Basic_f32be: return LLVMFloatTypeInContext(ctx);
  872. case Basic_f64be: return LLVMDoubleTypeInContext(ctx);
  873. case Basic_complex32:
  874. {
  875. char const *name = "..complex32";
  876. LLVMTypeRef type = LLVMGetTypeByName(m->mod, name);
  877. if (type != nullptr) {
  878. return type;
  879. }
  880. type = LLVMStructCreateNamed(ctx, name);
  881. LLVMTypeRef fields[2] = {
  882. lb_type(m, t_f16),
  883. lb_type(m, t_f16),
  884. };
  885. LLVMStructSetBody(type, fields, 2, false);
  886. return type;
  887. }
  888. case Basic_complex64:
  889. {
  890. char const *name = "..complex64";
  891. LLVMTypeRef type = LLVMGetTypeByName(m->mod, name);
  892. if (type != nullptr) {
  893. return type;
  894. }
  895. type = LLVMStructCreateNamed(ctx, name);
  896. LLVMTypeRef fields[2] = {
  897. lb_type(m, t_f32),
  898. lb_type(m, t_f32),
  899. };
  900. LLVMStructSetBody(type, fields, 2, false);
  901. return type;
  902. }
  903. case Basic_complex128:
  904. {
  905. char const *name = "..complex128";
  906. LLVMTypeRef type = LLVMGetTypeByName(m->mod, name);
  907. if (type != nullptr) {
  908. return type;
  909. }
  910. type = LLVMStructCreateNamed(ctx, name);
  911. LLVMTypeRef fields[2] = {
  912. lb_type(m, t_f64),
  913. lb_type(m, t_f64),
  914. };
  915. LLVMStructSetBody(type, fields, 2, false);
  916. return type;
  917. }
  918. case Basic_quaternion64:
  919. {
  920. char const *name = "..quaternion64";
  921. LLVMTypeRef type = LLVMGetTypeByName(m->mod, name);
  922. if (type != nullptr) {
  923. return type;
  924. }
  925. type = LLVMStructCreateNamed(ctx, name);
  926. LLVMTypeRef fields[4] = {
  927. lb_type(m, t_f16),
  928. lb_type(m, t_f16),
  929. lb_type(m, t_f16),
  930. lb_type(m, t_f16),
  931. };
  932. LLVMStructSetBody(type, fields, 4, false);
  933. return type;
  934. }
  935. case Basic_quaternion128:
  936. {
  937. char const *name = "..quaternion128";
  938. LLVMTypeRef type = LLVMGetTypeByName(m->mod, name);
  939. if (type != nullptr) {
  940. return type;
  941. }
  942. type = LLVMStructCreateNamed(ctx, name);
  943. LLVMTypeRef fields[4] = {
  944. lb_type(m, t_f32),
  945. lb_type(m, t_f32),
  946. lb_type(m, t_f32),
  947. lb_type(m, t_f32),
  948. };
  949. LLVMStructSetBody(type, fields, 4, false);
  950. return type;
  951. }
  952. case Basic_quaternion256:
  953. {
  954. char const *name = "..quaternion256";
  955. LLVMTypeRef type = LLVMGetTypeByName(m->mod, name);
  956. if (type != nullptr) {
  957. return type;
  958. }
  959. type = LLVMStructCreateNamed(ctx, name);
  960. LLVMTypeRef fields[4] = {
  961. lb_type(m, t_f64),
  962. lb_type(m, t_f64),
  963. lb_type(m, t_f64),
  964. lb_type(m, t_f64),
  965. };
  966. LLVMStructSetBody(type, fields, 4, false);
  967. return type;
  968. }
  969. case Basic_int: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.word_size);
  970. case Basic_uint: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.word_size);
  971. case Basic_uintptr: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.word_size);
  972. case Basic_rawptr: return LLVMPointerType(LLVMInt8TypeInContext(ctx), 0);
  973. case Basic_string:
  974. {
  975. char const *name = "..string";
  976. LLVMTypeRef type = LLVMGetTypeByName(m->mod, name);
  977. if (type != nullptr) {
  978. return type;
  979. }
  980. type = LLVMStructCreateNamed(ctx, name);
  981. LLVMTypeRef fields[2] = {
  982. LLVMPointerType(lb_type(m, t_u8), 0),
  983. lb_type(m, t_int),
  984. };
  985. LLVMStructSetBody(type, fields, 2, false);
  986. return type;
  987. }
  988. case Basic_cstring: return LLVMPointerType(LLVMInt8TypeInContext(ctx), 0);
  989. case Basic_any:
  990. {
  991. char const *name = "..any";
  992. LLVMTypeRef type = LLVMGetTypeByName(m->mod, name);
  993. if (type != nullptr) {
  994. return type;
  995. }
  996. type = LLVMStructCreateNamed(ctx, name);
  997. LLVMTypeRef fields[2] = {
  998. lb_type(m, t_rawptr),
  999. lb_type(m, t_typeid),
  1000. };
  1001. LLVMStructSetBody(type, fields, 2, false);
  1002. return type;
  1003. }
  1004. case Basic_typeid: return LLVMIntTypeInContext(m->ctx, 8*cast(unsigned)build_context.word_size);
  1005. // Endian Specific Types
  1006. case Basic_i16le: return LLVMInt16TypeInContext(ctx);
  1007. case Basic_u16le: return LLVMInt16TypeInContext(ctx);
  1008. case Basic_i32le: return LLVMInt32TypeInContext(ctx);
  1009. case Basic_u32le: return LLVMInt32TypeInContext(ctx);
  1010. case Basic_i64le: return LLVMInt64TypeInContext(ctx);
  1011. case Basic_u64le: return LLVMInt64TypeInContext(ctx);
  1012. case Basic_i128le: return LLVMInt128TypeInContext(ctx);
  1013. case Basic_u128le: return LLVMInt128TypeInContext(ctx);
  1014. case Basic_i16be: return LLVMInt16TypeInContext(ctx);
  1015. case Basic_u16be: return LLVMInt16TypeInContext(ctx);
  1016. case Basic_i32be: return LLVMInt32TypeInContext(ctx);
  1017. case Basic_u32be: return LLVMInt32TypeInContext(ctx);
  1018. case Basic_i64be: return LLVMInt64TypeInContext(ctx);
  1019. case Basic_u64be: return LLVMInt64TypeInContext(ctx);
  1020. case Basic_i128be: return LLVMInt128TypeInContext(ctx);
  1021. case Basic_u128be: return LLVMInt128TypeInContext(ctx);
  1022. // Untyped types
  1023. case Basic_UntypedBool: GB_PANIC("Basic_UntypedBool"); break;
  1024. case Basic_UntypedInteger: GB_PANIC("Basic_UntypedInteger"); break;
  1025. case Basic_UntypedFloat: GB_PANIC("Basic_UntypedFloat"); break;
  1026. case Basic_UntypedComplex: GB_PANIC("Basic_UntypedComplex"); break;
  1027. case Basic_UntypedQuaternion: GB_PANIC("Basic_UntypedQuaternion"); break;
  1028. case Basic_UntypedString: GB_PANIC("Basic_UntypedString"); break;
  1029. case Basic_UntypedRune: GB_PANIC("Basic_UntypedRune"); break;
  1030. case Basic_UntypedNil: GB_PANIC("Basic_UntypedNil"); break;
  1031. case Basic_UntypedUndef: GB_PANIC("Basic_UntypedUndef"); break;
  1032. }
  1033. break;
  1034. case Type_Named:
  1035. {
  1036. Type *base = base_type(type->Named.base);
  1037. switch (base->kind) {
  1038. case Type_Basic:
  1039. return lb_type_internal(m, base);
  1040. case Type_Named:
  1041. case Type_Generic:
  1042. GB_PANIC("INVALID TYPE");
  1043. break;
  1044. case Type_Pointer:
  1045. case Type_Array:
  1046. case Type_EnumeratedArray:
  1047. case Type_Slice:
  1048. case Type_DynamicArray:
  1049. case Type_Map:
  1050. case Type_Enum:
  1051. case Type_BitSet:
  1052. case Type_SimdVector:
  1053. return lb_type_internal(m, base);
  1054. // TODO(bill): Deal with this correctly. Can this be named?
  1055. case Type_Proc:
  1056. return lb_type_internal(m, base);
  1057. case Type_Tuple:
  1058. return lb_type_internal(m, base);
  1059. }
  1060. LLVMTypeRef *found = map_get(&m->types, hash_type(base));
  1061. if (found) {
  1062. LLVMTypeKind kind = LLVMGetTypeKind(*found);
  1063. if (kind == LLVMStructTypeKind) {
  1064. char const *name = alloc_cstring(permanent_allocator(), lb_get_entity_name(m, type->Named.type_name));
  1065. LLVMTypeRef llvm_type = LLVMGetTypeByName(m->mod, name);
  1066. if (llvm_type != nullptr) {
  1067. return llvm_type;
  1068. }
  1069. llvm_type = LLVMStructCreateNamed(ctx, name);
  1070. map_set(&m->types, hash_type(type), llvm_type);
  1071. lb_clone_struct_type(llvm_type, *found);
  1072. return llvm_type;
  1073. }
  1074. }
  1075. switch (base->kind) {
  1076. case Type_Struct:
  1077. case Type_Union:
  1078. {
  1079. char const *name = alloc_cstring(permanent_allocator(), lb_get_entity_name(m, type->Named.type_name));
  1080. LLVMTypeRef llvm_type = LLVMGetTypeByName(m->mod, name);
  1081. if (llvm_type != nullptr) {
  1082. return llvm_type;
  1083. }
  1084. llvm_type = LLVMStructCreateNamed(ctx, name);
  1085. map_set(&m->types, hash_type(type), llvm_type);
  1086. lb_clone_struct_type(llvm_type, lb_type(m, base));
  1087. return llvm_type;
  1088. }
  1089. }
  1090. return lb_type_internal(m, base);
  1091. }
  1092. case Type_Pointer:
  1093. return LLVMPointerType(lb_type(m, type_deref(type)), 0);
  1094. case Type_Array: {
  1095. m->internal_type_level -= 1;
  1096. LLVMTypeRef t = LLVMArrayType(lb_type(m, type->Array.elem), cast(unsigned)type->Array.count);
  1097. m->internal_type_level += 1;
  1098. return t;
  1099. }
  1100. case Type_EnumeratedArray: {
  1101. m->internal_type_level -= 1;
  1102. LLVMTypeRef t = LLVMArrayType(lb_type(m, type->EnumeratedArray.elem), cast(unsigned)type->EnumeratedArray.count);
  1103. m->internal_type_level += 1;
  1104. return t;
  1105. }
  1106. case Type_Slice:
  1107. {
  1108. LLVMTypeRef fields[2] = {
  1109. LLVMPointerType(lb_type(m, type->Slice.elem), 0), // data
  1110. lb_type(m, t_int), // len
  1111. };
  1112. return LLVMStructTypeInContext(ctx, fields, 2, false);
  1113. }
  1114. break;
  1115. case Type_DynamicArray:
  1116. {
  1117. LLVMTypeRef fields[4] = {
  1118. LLVMPointerType(lb_type(m, type->DynamicArray.elem), 0), // data
  1119. lb_type(m, t_int), // len
  1120. lb_type(m, t_int), // cap
  1121. lb_type(m, t_allocator), // allocator
  1122. };
  1123. return LLVMStructTypeInContext(ctx, fields, 4, false);
  1124. }
  1125. break;
  1126. case Type_Map:
  1127. return lb_type(m, type->Map.internal_type);
  1128. case Type_Struct:
  1129. {
  1130. if (type->Struct.is_raw_union) {
  1131. unsigned field_count = 2;
  1132. LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count);
  1133. i64 alignment = type_align_of(type);
  1134. unsigned size_of_union = cast(unsigned)type_size_of(type);
  1135. fields[0] = lb_alignment_prefix_type_hack(m, alignment);
  1136. fields[1] = LLVMArrayType(lb_type(m, t_u8), size_of_union);
  1137. return LLVMStructTypeInContext(ctx, fields, field_count, false);
  1138. }
  1139. isize offset = 0;
  1140. if (type->Struct.custom_align > 0) {
  1141. offset = 1;
  1142. }
  1143. m->internal_type_level += 1;
  1144. defer (m->internal_type_level -= 1);
  1145. unsigned field_count = cast(unsigned)(type->Struct.fields.count + offset);
  1146. LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count);
  1147. for_array(i, type->Struct.fields) {
  1148. Entity *field = type->Struct.fields[i];
  1149. fields[i+offset] = lb_type(m, field->type);
  1150. }
  1151. if (type->Struct.custom_align > 0) {
  1152. fields[0] = lb_alignment_prefix_type_hack(m, type->Struct.custom_align);
  1153. }
  1154. return LLVMStructTypeInContext(ctx, fields, field_count, type->Struct.is_packed);
  1155. }
  1156. break;
  1157. case Type_Union:
  1158. if (type->Union.variants.count == 0) {
  1159. return LLVMStructTypeInContext(ctx, nullptr, 0, false);
  1160. } else {
  1161. // NOTE(bill): The zero size array is used to fix the alignment used in a structure as
  1162. // LLVM takes the first element's alignment as the entire alignment (like C)
  1163. i64 align = type_align_of(type);
  1164. i64 size = type_size_of(type);
  1165. if (is_type_union_maybe_pointer_original_alignment(type)) {
  1166. LLVMTypeRef fields[1] = {lb_type(m, type->Union.variants[0])};
  1167. return LLVMStructTypeInContext(ctx, fields, 1, false);
  1168. }
  1169. unsigned block_size = cast(unsigned)type->Union.variant_block_size;
  1170. LLVMTypeRef fields[3] = {};
  1171. unsigned field_count = 1;
  1172. fields[0] = lb_alignment_prefix_type_hack(m, align);
  1173. if (is_type_union_maybe_pointer(type)) {
  1174. field_count += 1;
  1175. fields[1] = lb_type(m, type->Union.variants[0]);
  1176. } else {
  1177. field_count += 2;
  1178. if (block_size == align) {
  1179. fields[1] = LLVMIntTypeInContext(m->ctx, 8*block_size);
  1180. } else {
  1181. fields[1] = LLVMArrayType(lb_type(m, t_u8), block_size);
  1182. }
  1183. fields[2] = lb_type(m, union_tag_type(type));
  1184. }
  1185. return LLVMStructTypeInContext(ctx, fields, field_count, false);
  1186. }
  1187. break;
  1188. case Type_Enum:
  1189. return lb_type(m, base_enum_type(type));
  1190. case Type_Tuple:
  1191. if (type->Tuple.variables.count == 1) {
  1192. return lb_type(m, type->Tuple.variables[0]->type);
  1193. } else {
  1194. unsigned field_count = cast(unsigned)(type->Tuple.variables.count);
  1195. LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count);
  1196. for_array(i, type->Tuple.variables) {
  1197. Entity *field = type->Tuple.variables[i];
  1198. LLVMTypeRef param_type = nullptr;
  1199. param_type = lb_type(m, field->type);
  1200. fields[i] = param_type;
  1201. }
  1202. return LLVMStructTypeInContext(ctx, fields, field_count, type->Tuple.is_packed);
  1203. }
  1204. case Type_Proc:
  1205. // if (m->internal_type_level > 256) { // TODO HACK(bill): is this really enough?
  1206. if (m->internal_type_level > 1) { // TODO HACK(bill): is this really enough?
  1207. return LLVMPointerType(LLVMIntTypeInContext(m->ctx, 8), 0);
  1208. } else {
  1209. unsigned param_count = 0;
  1210. if (type->Proc.calling_convention == ProcCC_Odin) {
  1211. param_count += 1;
  1212. }
  1213. if (type->Proc.param_count != 0) {
  1214. GB_ASSERT(type->Proc.params->kind == Type_Tuple);
  1215. for_array(i, type->Proc.params->Tuple.variables) {
  1216. Entity *e = type->Proc.params->Tuple.variables[i];
  1217. if (e->kind != Entity_Variable) {
  1218. continue;
  1219. }
  1220. if (e->flags & EntityFlag_CVarArg) {
  1221. continue;
  1222. }
  1223. param_count += 1;
  1224. }
  1225. }
  1226. m->internal_type_level += 1;
  1227. defer (m->internal_type_level -= 1);
  1228. LLVMTypeRef ret = nullptr;
  1229. LLVMTypeRef *params = gb_alloc_array(heap_allocator(), LLVMTypeRef, param_count);
  1230. if (type->Proc.result_count != 0) {
  1231. Type *single_ret = reduce_tuple_to_single_type(type->Proc.results);
  1232. ret = lb_type(m, single_ret);
  1233. if (ret != nullptr) {
  1234. if (is_type_boolean(single_ret) &&
  1235. is_calling_convention_none(type->Proc.calling_convention) &&
  1236. type_size_of(single_ret) <= 1) {
  1237. ret = LLVMInt1TypeInContext(m->ctx);
  1238. }
  1239. }
  1240. }
  1241. isize param_index = 0;
  1242. if (type->Proc.param_count != 0) {
  1243. GB_ASSERT(type->Proc.params->kind == Type_Tuple);
  1244. for_array(i, type->Proc.params->Tuple.variables) {
  1245. Entity *e = type->Proc.params->Tuple.variables[i];
  1246. if (e->kind != Entity_Variable) {
  1247. continue;
  1248. }
  1249. if (e->flags & EntityFlag_CVarArg) {
  1250. continue;
  1251. }
  1252. Type *e_type = reduce_tuple_to_single_type(e->type);
  1253. LLVMTypeRef param_type = nullptr;
  1254. if (is_type_boolean(e_type) &&
  1255. type_size_of(e_type) <= 1) {
  1256. param_type = LLVMInt1TypeInContext(m->ctx);
  1257. } else {
  1258. if (is_type_proc(e_type)) {
  1259. param_type = lb_type(m, t_rawptr);
  1260. } else {
  1261. param_type = lb_type(m, e_type);
  1262. }
  1263. }
  1264. params[param_index++] = param_type;
  1265. }
  1266. }
  1267. if (param_index < param_count) {
  1268. params[param_index++] = lb_type(m, t_rawptr);
  1269. }
  1270. GB_ASSERT(param_index == param_count);
  1271. lbFunctionType *ft = lb_get_abi_info(m->ctx, params, param_count, ret, ret != nullptr, type->Proc.calling_convention);
  1272. {
  1273. for_array(j, ft->args) {
  1274. auto arg = ft->args[j];
  1275. GB_ASSERT_MSG(LLVMGetTypeContext(arg.type) == ft->ctx,
  1276. "\n\t%s %td/%td"
  1277. "\n\tArgTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
  1278. LLVMPrintTypeToString(arg.type),
  1279. j, ft->args.count,
  1280. LLVMGetTypeContext(arg.type), ft->ctx, LLVMGetGlobalContext());
  1281. }
  1282. GB_ASSERT_MSG(LLVMGetTypeContext(ft->ret.type) == ft->ctx,
  1283. "\n\t%s"
  1284. "\n\tRetTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
  1285. LLVMPrintTypeToString(ft->ret.type),
  1286. LLVMGetTypeContext(ft->ret.type), ft->ctx, LLVMGetGlobalContext());
  1287. }
  1288. map_set(&m->function_type_map, hash_type(type), ft);
  1289. LLVMTypeRef new_abi_fn_ptr_type = lb_function_type_to_llvm_ptr(ft, type->Proc.c_vararg);
  1290. LLVMTypeRef new_abi_fn_type = LLVMGetElementType(new_abi_fn_ptr_type);
  1291. GB_ASSERT_MSG(LLVMGetTypeContext(new_abi_fn_type) == m->ctx,
  1292. "\n\tFuncTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
  1293. LLVMGetTypeContext(new_abi_fn_type), m->ctx, LLVMGetGlobalContext());
  1294. return new_abi_fn_ptr_type;
  1295. }
  1296. break;
  1297. case Type_BitSet:
  1298. {
  1299. Type *ut = bit_set_to_int(type);
  1300. return lb_type(m, ut);
  1301. }
  1302. case Type_SimdVector:
  1303. return LLVMVectorType(lb_type(m, type->SimdVector.elem), cast(unsigned)type->SimdVector.count);
  1304. case Type_RelativePointer:
  1305. return lb_type_internal(m, type->RelativePointer.base_integer);
  1306. case Type_RelativeSlice:
  1307. {
  1308. LLVMTypeRef base_integer = lb_type_internal(m, type->RelativeSlice.base_integer);
  1309. unsigned field_count = 2;
  1310. LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count);
  1311. fields[0] = base_integer;
  1312. fields[1] = base_integer;
  1313. return LLVMStructTypeInContext(ctx, fields, field_count, false);
  1314. }
  1315. }
  1316. GB_PANIC("Invalid type %s", type_to_string(type));
  1317. return LLVMInt32TypeInContext(ctx);
  1318. }
  1319. LLVMTypeRef lb_type(lbModule *m, Type *type) {
  1320. type = default_type(type);
  1321. LLVMTypeRef *found = map_get(&m->types, hash_type(type));
  1322. if (found) {
  1323. return *found;
  1324. }
  1325. LLVMTypeRef llvm_type = nullptr;
  1326. m->internal_type_level += 1;
  1327. llvm_type = lb_type_internal(m, type);
  1328. m->internal_type_level -= 1;
  1329. if (m->internal_type_level == 0) {
  1330. map_set(&m->types, hash_type(type), llvm_type);
  1331. if (is_type_named(type)) {
  1332. map_set(&m->llvm_types, hash_pointer(llvm_type), type);
  1333. }
  1334. }
  1335. return llvm_type;
  1336. }
  1337. LLVMMetadataRef lb_get_llvm_metadata(lbModule *m, void *key) {
  1338. if (key == nullptr) {
  1339. return nullptr;
  1340. }
  1341. auto found = map_get(&m->debug_values, hash_pointer(key));
  1342. if (found) {
  1343. return *found;
  1344. }
  1345. return nullptr;
  1346. }
  1347. void lb_set_llvm_metadata(lbModule *m, void *key, LLVMMetadataRef value) {
  1348. if (key != nullptr) {
  1349. map_set(&m->debug_values, hash_pointer(key), value);
  1350. }
  1351. }
  1352. LLVMMetadataRef lb_get_llvm_file_metadata_from_node(lbModule *m, Ast *node) {
  1353. if (node == nullptr) {
  1354. return nullptr;
  1355. }
  1356. return lb_get_llvm_metadata(m, node->file);
  1357. }
  1358. LLVMMetadataRef lb_get_current_debug_scope(lbProcedure *p) {
  1359. GB_ASSERT_MSG(p->debug_info != nullptr, "missing debug information for %.*s", LIT(p->name));
  1360. for (isize i = p->scope_stack.count-1; i >= 0; i--) {
  1361. Scope *s = p->scope_stack[i];
  1362. LLVMMetadataRef md = lb_get_llvm_metadata(p->module, s);
  1363. if (md) {
  1364. return md;
  1365. }
  1366. }
  1367. return p->debug_info;
  1368. }
  1369. LLVMMetadataRef lb_debug_location_from_token_pos(lbProcedure *p, TokenPos pos) {
  1370. LLVMMetadataRef scope = lb_get_current_debug_scope(p);
  1371. GB_ASSERT_MSG(scope != nullptr, "%.*s", LIT(p->name));
  1372. return LLVMDIBuilderCreateDebugLocation(p->module->ctx, cast(unsigned)pos.line, cast(unsigned)pos.column, scope, nullptr);
  1373. }
  1374. LLVMMetadataRef lb_debug_location_from_ast(lbProcedure *p, Ast *node) {
  1375. GB_ASSERT(node != nullptr);
  1376. return lb_debug_location_from_token_pos(p, ast_token(node).pos);
  1377. }
  1378. LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) {
  1379. Type *original_type = type;
  1380. LLVMContextRef ctx = m->ctx;
  1381. i64 size = type_size_of(type); // Check size
  1382. GB_ASSERT(type != t_invalid);
  1383. unsigned const word_size = cast(unsigned)build_context.word_size;
  1384. unsigned const word_bits = cast(unsigned)(8*build_context.word_size);
  1385. GB_ASSERT(type->kind == Type_Proc);
  1386. LLVMTypeRef return_type = LLVMVoidTypeInContext(ctx);
  1387. unsigned parameter_count = 1;
  1388. for (i32 i = 0; i < type->Proc.param_count; i++) {
  1389. Entity *e = type->Proc.params->Tuple.variables[i];
  1390. if (e->kind == Entity_Variable) {
  1391. parameter_count += 1;
  1392. }
  1393. }
  1394. LLVMMetadataRef *parameters = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, parameter_count);
  1395. unsigned param_index = 0;
  1396. if (type->Proc.result_count == 0) {
  1397. parameters[param_index++] = nullptr;
  1398. } else {
  1399. parameters[param_index++] = lb_debug_type(m, type->Proc.results);
  1400. }
  1401. LLVMMetadataRef parent_scope = nullptr;
  1402. LLVMMetadataRef scope = nullptr;
  1403. LLVMMetadataRef file = nullptr;
  1404. for (i32 i = 0; i < type->Proc.param_count; i++) {
  1405. Entity *e = type->Proc.params->Tuple.variables[i];
  1406. if (e->kind != Entity_Variable) {
  1407. continue;
  1408. }
  1409. parameters[param_index] = lb_debug_type(m, e->type);
  1410. param_index += 1;
  1411. }
  1412. LLVMDIFlags flags = LLVMDIFlagZero;
  1413. if (type->Proc.diverging) {
  1414. flags = LLVMDIFlagNoReturn;
  1415. }
  1416. return LLVMDIBuilderCreateSubroutineType(m->debug_builder, file, parameters, parameter_count, flags);
  1417. }
  1418. LLVMMetadataRef lb_debug_struct_field(lbModule *m, String const &name, Type *type, u64 offset_in_bits) {
  1419. unsigned field_line = 1;
  1420. LLVMDIFlags field_flags = LLVMDIFlagZero;
  1421. AstPackage *pkg = m->info->runtime_package;
  1422. GB_ASSERT(pkg->files.count != 0);
  1423. LLVMMetadataRef file = lb_get_llvm_metadata(m, pkg->files[0]);
  1424. LLVMMetadataRef scope = file;
  1425. return LLVMDIBuilderCreateMemberType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, field_line,
  1426. 8*cast(u64)type_size_of(type), 8*cast(u32)type_align_of(type), offset_in_bits,
  1427. field_flags, lb_debug_type(m, type)
  1428. );
  1429. }
  1430. LLVMMetadataRef lb_debug_basic_struct(lbModule *m, String const &name, u64 size_in_bits, u32 align_in_bits, LLVMMetadataRef *elements, unsigned element_count) {
  1431. AstPackage *pkg = m->info->runtime_package;
  1432. GB_ASSERT(pkg->files.count != 0);
  1433. LLVMMetadataRef file = lb_get_llvm_metadata(m, pkg->files[0]);
  1434. LLVMMetadataRef scope = file;
  1435. return LLVMDIBuilderCreateStructType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, 1, size_in_bits, align_in_bits, LLVMDIFlagZero, nullptr, elements, element_count, 0, nullptr, "", 0);
  1436. }
  1437. LLVMMetadataRef lb_debug_type_basic_type(lbModule *m, String const &name, u64 size_in_bits, LLVMDWARFTypeEncoding encoding, LLVMDIFlags flags = LLVMDIFlagZero) {
  1438. LLVMMetadataRef basic_type = LLVMDIBuilderCreateBasicType(m->debug_builder, cast(char const *)name.text, name.len, size_in_bits, encoding, flags);
  1439. #if 1
  1440. LLVMMetadataRef final_decl = LLVMDIBuilderCreateTypedef(m->debug_builder, basic_type, cast(char const *)name.text, name.len, nullptr, 0, nullptr, cast(u32)size_in_bits);
  1441. return final_decl;
  1442. #else
  1443. return basic_type;
  1444. #endif
  1445. }
  1446. LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
  1447. Type *original_type = type;
  1448. LLVMContextRef ctx = m->ctx;
  1449. i64 size = type_size_of(type); // Check size
  1450. GB_ASSERT(type != t_invalid);
  1451. unsigned const word_size = cast(unsigned)build_context.word_size;
  1452. unsigned const word_bits = cast(unsigned)(8*build_context.word_size);
  1453. switch (type->kind) {
  1454. case Type_Basic:
  1455. switch (type->Basic.kind) {
  1456. case Basic_llvm_bool: return lb_debug_type_basic_type(m, str_lit("llvm bool"), 1, LLVMDWARFTypeEncoding_Boolean);
  1457. case Basic_bool: return lb_debug_type_basic_type(m, str_lit("bool"), 8, LLVMDWARFTypeEncoding_Boolean);
  1458. case Basic_b8: return lb_debug_type_basic_type(m, str_lit("b8"), 8, LLVMDWARFTypeEncoding_Boolean);
  1459. case Basic_b16: return lb_debug_type_basic_type(m, str_lit("b16"), 16, LLVMDWARFTypeEncoding_Boolean);
  1460. case Basic_b32: return lb_debug_type_basic_type(m, str_lit("b32"), 32, LLVMDWARFTypeEncoding_Boolean);
  1461. case Basic_b64: return lb_debug_type_basic_type(m, str_lit("b64"), 64, LLVMDWARFTypeEncoding_Boolean);
  1462. case Basic_i8: return lb_debug_type_basic_type(m, str_lit("i8"), 8, LLVMDWARFTypeEncoding_Signed);
  1463. case Basic_u8: return lb_debug_type_basic_type(m, str_lit("u8"), 8, LLVMDWARFTypeEncoding_Unsigned);
  1464. case Basic_i16: return lb_debug_type_basic_type(m, str_lit("i16"), 16, LLVMDWARFTypeEncoding_Signed);
  1465. case Basic_u16: return lb_debug_type_basic_type(m, str_lit("u16"), 16, LLVMDWARFTypeEncoding_Unsigned);
  1466. case Basic_i32: return lb_debug_type_basic_type(m, str_lit("i32"), 32, LLVMDWARFTypeEncoding_Signed);
  1467. case Basic_u32: return lb_debug_type_basic_type(m, str_lit("u32"), 32, LLVMDWARFTypeEncoding_Unsigned);
  1468. case Basic_i64: return lb_debug_type_basic_type(m, str_lit("i64"), 64, LLVMDWARFTypeEncoding_Signed);
  1469. case Basic_u64: return lb_debug_type_basic_type(m, str_lit("u64"), 64, LLVMDWARFTypeEncoding_Unsigned);
  1470. case Basic_i128: return lb_debug_type_basic_type(m, str_lit("i128"), 128, LLVMDWARFTypeEncoding_Signed);
  1471. case Basic_u128: return lb_debug_type_basic_type(m, str_lit("u128"), 128, LLVMDWARFTypeEncoding_Unsigned);
  1472. case Basic_rune: return lb_debug_type_basic_type(m, str_lit("rune"), 32, LLVMDWARFTypeEncoding_Utf);
  1473. case Basic_f16: return lb_debug_type_basic_type(m, str_lit("f16"), 16, LLVMDWARFTypeEncoding_Float);
  1474. case Basic_f32: return lb_debug_type_basic_type(m, str_lit("f32"), 32, LLVMDWARFTypeEncoding_Float);
  1475. case Basic_f64: return lb_debug_type_basic_type(m, str_lit("f64"), 64, LLVMDWARFTypeEncoding_Float);
  1476. case Basic_int: return lb_debug_type_basic_type(m, str_lit("int"), word_bits, LLVMDWARFTypeEncoding_Signed);
  1477. case Basic_uint: return lb_debug_type_basic_type(m, str_lit("uint"), word_bits, LLVMDWARFTypeEncoding_Unsigned);
  1478. case Basic_uintptr: return lb_debug_type_basic_type(m, str_lit("uintptr"), word_bits, LLVMDWARFTypeEncoding_Unsigned);
  1479. case Basic_typeid:
  1480. return lb_debug_type_basic_type(m, str_lit("typeid"), word_bits, LLVMDWARFTypeEncoding_Unsigned);
  1481. // Endian Specific Types
  1482. case Basic_i16le: return lb_debug_type_basic_type(m, str_lit("i16le"), 16, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagLittleEndian);
  1483. case Basic_u16le: return lb_debug_type_basic_type(m, str_lit("u16le"), 16, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagLittleEndian);
  1484. case Basic_i32le: return lb_debug_type_basic_type(m, str_lit("i32le"), 32, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagLittleEndian);
  1485. case Basic_u32le: return lb_debug_type_basic_type(m, str_lit("u32le"), 32, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagLittleEndian);
  1486. case Basic_i64le: return lb_debug_type_basic_type(m, str_lit("i64le"), 64, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagLittleEndian);
  1487. case Basic_u64le: return lb_debug_type_basic_type(m, str_lit("u64le"), 64, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagLittleEndian);
  1488. case Basic_i128le: return lb_debug_type_basic_type(m, str_lit("i128le"), 128, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagLittleEndian);
  1489. case Basic_u128le: return lb_debug_type_basic_type(m, str_lit("u128le"), 128, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagLittleEndian);
  1490. case Basic_f16le: return lb_debug_type_basic_type(m, str_lit("f16le"), 16, LLVMDWARFTypeEncoding_Float, LLVMDIFlagLittleEndian);
  1491. case Basic_f32le: return lb_debug_type_basic_type(m, str_lit("f32le"), 32, LLVMDWARFTypeEncoding_Float, LLVMDIFlagLittleEndian);
  1492. case Basic_f64le: return lb_debug_type_basic_type(m, str_lit("f64le"), 64, LLVMDWARFTypeEncoding_Float, LLVMDIFlagLittleEndian);
  1493. case Basic_i16be: return lb_debug_type_basic_type(m, str_lit("i16be"), 16, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagBigEndian);
  1494. case Basic_u16be: return lb_debug_type_basic_type(m, str_lit("u16be"), 16, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagBigEndian);
  1495. case Basic_i32be: return lb_debug_type_basic_type(m, str_lit("i32be"), 32, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagBigEndian);
  1496. case Basic_u32be: return lb_debug_type_basic_type(m, str_lit("u32be"), 32, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagBigEndian);
  1497. case Basic_i64be: return lb_debug_type_basic_type(m, str_lit("i64be"), 64, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagBigEndian);
  1498. case Basic_u64be: return lb_debug_type_basic_type(m, str_lit("u64be"), 64, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagBigEndian);
  1499. case Basic_i128be: return lb_debug_type_basic_type(m, str_lit("i128be"), 128, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagBigEndian);
  1500. case Basic_u128be: return lb_debug_type_basic_type(m, str_lit("u128be"), 128, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagBigEndian);
  1501. case Basic_f16be: return lb_debug_type_basic_type(m, str_lit("f16be"), 16, LLVMDWARFTypeEncoding_Float, LLVMDIFlagLittleEndian);
  1502. case Basic_f32be: return lb_debug_type_basic_type(m, str_lit("f32be"), 32, LLVMDWARFTypeEncoding_Float, LLVMDIFlagLittleEndian);
  1503. case Basic_f64be: return lb_debug_type_basic_type(m, str_lit("f64be"), 64, LLVMDWARFTypeEncoding_Float, LLVMDIFlagLittleEndian);
  1504. case Basic_complex32:
  1505. {
  1506. LLVMMetadataRef elements[2] = {};
  1507. elements[0] = lb_debug_struct_field(m, str_lit("real"), t_f16, 0);
  1508. elements[1] = lb_debug_struct_field(m, str_lit("imag"), t_f16, 4);
  1509. return lb_debug_basic_struct(m, str_lit("complex32"), 64, 32, elements, gb_count_of(elements));
  1510. }
  1511. case Basic_complex64:
  1512. {
  1513. LLVMMetadataRef elements[2] = {};
  1514. elements[0] = lb_debug_struct_field(m, str_lit("real"), t_f32, 0);
  1515. elements[1] = lb_debug_struct_field(m, str_lit("imag"), t_f32, 4);
  1516. return lb_debug_basic_struct(m, str_lit("complex64"), 64, 32, elements, gb_count_of(elements));
  1517. }
  1518. case Basic_complex128:
  1519. {
  1520. LLVMMetadataRef elements[2] = {};
  1521. elements[0] = lb_debug_struct_field(m, str_lit("real"), t_f64, 0);
  1522. elements[1] = lb_debug_struct_field(m, str_lit("imag"), t_f64, 8);
  1523. return lb_debug_basic_struct(m, str_lit("complex128"), 128, 64, elements, gb_count_of(elements));
  1524. }
  1525. case Basic_quaternion64:
  1526. {
  1527. LLVMMetadataRef elements[4] = {};
  1528. elements[0] = lb_debug_struct_field(m, str_lit("imag"), t_f16, 0);
  1529. elements[1] = lb_debug_struct_field(m, str_lit("jmag"), t_f16, 4);
  1530. elements[2] = lb_debug_struct_field(m, str_lit("kmag"), t_f16, 8);
  1531. elements[3] = lb_debug_struct_field(m, str_lit("real"), t_f16, 12);
  1532. return lb_debug_basic_struct(m, str_lit("quaternion64"), 128, 32, elements, gb_count_of(elements));
  1533. }
  1534. case Basic_quaternion128:
  1535. {
  1536. LLVMMetadataRef elements[4] = {};
  1537. elements[0] = lb_debug_struct_field(m, str_lit("imag"), t_f32, 0);
  1538. elements[1] = lb_debug_struct_field(m, str_lit("jmag"), t_f32, 4);
  1539. elements[2] = lb_debug_struct_field(m, str_lit("kmag"), t_f32, 8);
  1540. elements[3] = lb_debug_struct_field(m, str_lit("real"), t_f32, 12);
  1541. return lb_debug_basic_struct(m, str_lit("quaternion128"), 128, 32, elements, gb_count_of(elements));
  1542. }
  1543. case Basic_quaternion256:
  1544. {
  1545. LLVMMetadataRef elements[4] = {};
  1546. elements[0] = lb_debug_struct_field(m, str_lit("imag"), t_f64, 0);
  1547. elements[1] = lb_debug_struct_field(m, str_lit("jmag"), t_f64, 8);
  1548. elements[2] = lb_debug_struct_field(m, str_lit("kmag"), t_f64, 16);
  1549. elements[3] = lb_debug_struct_field(m, str_lit("real"), t_f64, 24);
  1550. return lb_debug_basic_struct(m, str_lit("quaternion256"), 256, 32, elements, gb_count_of(elements));
  1551. }
  1552. case Basic_rawptr:
  1553. {
  1554. LLVMMetadataRef void_type = lb_debug_type_basic_type(m, str_lit("void"), 8, LLVMDWARFTypeEncoding_Unsigned);
  1555. return LLVMDIBuilderCreatePointerType(m->debug_builder, void_type, word_bits, word_bits, LLVMDWARFTypeEncoding_Address, "rawptr", 6);
  1556. }
  1557. case Basic_string:
  1558. {
  1559. LLVMMetadataRef elements[2] = {};
  1560. elements[0] = lb_debug_struct_field(m, str_lit("data"), t_u8_ptr, 0);
  1561. elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, word_bits);
  1562. return lb_debug_basic_struct(m, str_lit("string"), 2*word_bits, word_bits, elements, gb_count_of(elements));
  1563. }
  1564. case Basic_cstring:
  1565. {
  1566. LLVMMetadataRef char_type = lb_debug_type_basic_type(m, str_lit("char"), 8, LLVMDWARFTypeEncoding_Unsigned);
  1567. return LLVMDIBuilderCreatePointerType(m->debug_builder, char_type, word_bits, word_bits, 0, "cstring", 7);
  1568. }
  1569. case Basic_any:
  1570. {
  1571. LLVMMetadataRef elements[2] = {};
  1572. elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0);
  1573. elements[1] = lb_debug_struct_field(m, str_lit("id"), t_typeid, word_bits);
  1574. return lb_debug_basic_struct(m, str_lit("any"), 2*word_bits, word_bits, elements, gb_count_of(elements));
  1575. }
  1576. // Untyped types
  1577. case Basic_UntypedBool: GB_PANIC("Basic_UntypedBool"); break;
  1578. case Basic_UntypedInteger: GB_PANIC("Basic_UntypedInteger"); break;
  1579. case Basic_UntypedFloat: GB_PANIC("Basic_UntypedFloat"); break;
  1580. case Basic_UntypedComplex: GB_PANIC("Basic_UntypedComplex"); break;
  1581. case Basic_UntypedQuaternion: GB_PANIC("Basic_UntypedQuaternion"); break;
  1582. case Basic_UntypedString: GB_PANIC("Basic_UntypedString"); break;
  1583. case Basic_UntypedRune: GB_PANIC("Basic_UntypedRune"); break;
  1584. case Basic_UntypedNil: GB_PANIC("Basic_UntypedNil"); break;
  1585. case Basic_UntypedUndef: GB_PANIC("Basic_UntypedUndef"); break;
  1586. default: GB_PANIC("Basic Unhandled"); break;
  1587. }
  1588. break;
  1589. case Type_Named:
  1590. GB_PANIC("Type_Named should be handled in lb_debug_type separately");
  1591. case Type_Pointer:
  1592. return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->Pointer.elem), word_bits, word_bits, 0, nullptr, 0);
  1593. case Type_Array: {
  1594. LLVMMetadataRef subscripts[1] = {};
  1595. subscripts[0] = LLVMDIBuilderGetOrCreateSubrange(m->debug_builder,
  1596. 0ll,
  1597. type->Array.count
  1598. );
  1599. return LLVMDIBuilderCreateArrayType(m->debug_builder,
  1600. 8*cast(uint64_t)type_size_of(type),
  1601. 8*cast(unsigned)type_align_of(type),
  1602. lb_debug_type(m, type->Array.elem),
  1603. subscripts, gb_count_of(subscripts));
  1604. }
  1605. case Type_EnumeratedArray: {
  1606. LLVMMetadataRef subscripts[1] = {};
  1607. subscripts[0] = LLVMDIBuilderGetOrCreateSubrange(m->debug_builder,
  1608. 0ll,
  1609. type->EnumeratedArray.count
  1610. );
  1611. LLVMMetadataRef array_type = LLVMDIBuilderCreateArrayType(m->debug_builder,
  1612. 8*cast(uint64_t)type_size_of(type),
  1613. 8*cast(unsigned)type_align_of(type),
  1614. lb_debug_type(m, type->EnumeratedArray.elem),
  1615. subscripts, gb_count_of(subscripts));
  1616. gbString name = type_to_string(type, temporary_allocator());
  1617. return LLVMDIBuilderCreateTypedef(m->debug_builder, array_type, name, gb_string_length(name), nullptr, 0, nullptr, cast(u32)(8*type_align_of(type)));
  1618. }
  1619. case Type_Struct:
  1620. case Type_Union:
  1621. case Type_Slice:
  1622. case Type_DynamicArray:
  1623. case Type_Map:
  1624. case Type_BitSet:
  1625. {
  1626. unsigned tag = DW_TAG_structure_type;
  1627. if (is_type_raw_union(type) || is_type_union(type)) {
  1628. tag = DW_TAG_union_type;
  1629. }
  1630. u64 size_in_bits = cast(u64)(8*type_size_of(type));
  1631. u32 align_in_bits = cast(u32)(8*type_size_of(type));
  1632. LLVMDIFlags flags = LLVMDIFlagZero;
  1633. LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType(
  1634. m->debug_builder, tag, "", 0, nullptr, nullptr, 0, 0, size_in_bits, align_in_bits, flags, "", 0
  1635. );
  1636. lbIncompleteDebugType idt = {};
  1637. idt.type = type;
  1638. idt.metadata = temp_forward_decl;
  1639. array_add(&m->debug_incomplete_types, idt);
  1640. lb_set_llvm_metadata(m, type, temp_forward_decl);
  1641. return temp_forward_decl;
  1642. }
  1643. case Type_Enum:
  1644. {
  1645. LLVMMetadataRef scope = nullptr;
  1646. LLVMMetadataRef file = nullptr;
  1647. unsigned line = 0;
  1648. unsigned element_count = cast(unsigned)type->Enum.fields.count;
  1649. LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count);
  1650. Type *bt = base_enum_type(type);
  1651. LLVMBool is_unsigned = is_type_unsigned(bt);
  1652. for (unsigned i = 0; i < element_count; i++) {
  1653. Entity *f = type->Enum.fields[i];
  1654. GB_ASSERT(f->kind == Entity_Constant);
  1655. String name = f->token.string;
  1656. i64 value = exact_value_to_i64(f->Constant.value);
  1657. elements[i] = LLVMDIBuilderCreateEnumerator(m->debug_builder, cast(char const *)name.text, cast(size_t)name.len, value, is_unsigned);
  1658. }
  1659. LLVMMetadataRef class_type = lb_debug_type(m, bt);
  1660. return LLVMDIBuilderCreateEnumerationType(m->debug_builder, scope, "", 0, file, line, 8*type_size_of(type), 8*cast(unsigned)type_align_of(type), elements, element_count, class_type);
  1661. }
  1662. case Type_Tuple:
  1663. if (type->Tuple.variables.count == 1) {
  1664. return lb_debug_type(m, type->Tuple.variables[0]->type);
  1665. } else {
  1666. type_set_offsets(type);
  1667. LLVMMetadataRef parent_scope = nullptr;
  1668. LLVMMetadataRef scope = nullptr;
  1669. LLVMMetadataRef file = nullptr;
  1670. unsigned line = 0;
  1671. u64 size_in_bits = 8*cast(u64)type_size_of(type);
  1672. u32 align_in_bits = 8*cast(u32)type_align_of(type);
  1673. LLVMDIFlags flags = LLVMDIFlagZero;
  1674. unsigned element_count = cast(unsigned)type->Tuple.variables.count;
  1675. LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count);
  1676. for (unsigned i = 0; i < element_count; i++) {
  1677. Entity *f = type->Tuple.variables[i];
  1678. GB_ASSERT(f->kind == Entity_Variable);
  1679. String name = f->token.string;
  1680. unsigned field_line = 0;
  1681. LLVMDIFlags field_flags = LLVMDIFlagZero;
  1682. u64 offset_in_bits = 8*cast(u64)type->Tuple.offsets[i];
  1683. elements[i] = LLVMDIBuilderCreateMemberType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, field_line,
  1684. 8*cast(u64)type_size_of(f->type), 8*cast(u32)type_align_of(f->type), offset_in_bits,
  1685. field_flags, lb_debug_type(m, f->type)
  1686. );
  1687. }
  1688. return LLVMDIBuilderCreateStructType(m->debug_builder, parent_scope, "", 0, file, line,
  1689. size_in_bits, align_in_bits, flags,
  1690. nullptr, elements, element_count, 0, nullptr,
  1691. "", 0
  1692. );
  1693. }
  1694. case Type_Proc:
  1695. {
  1696. LLVMMetadataRef proc_underlying_type = lb_debug_type_internal_proc(m, type);
  1697. LLVMMetadataRef pointer_type = LLVMDIBuilderCreatePointerType(m->debug_builder, proc_underlying_type, word_bits, word_bits, 0, nullptr, 0);
  1698. gbString name = type_to_string(type, temporary_allocator());
  1699. return LLVMDIBuilderCreateTypedef(m->debug_builder, pointer_type, name, gb_string_length(name), nullptr, 0, nullptr, cast(u32)(8*type_align_of(type)));
  1700. }
  1701. break;
  1702. case Type_SimdVector:
  1703. return LLVMDIBuilderCreateVectorType(m->debug_builder, cast(unsigned)type->SimdVector.count, 8*cast(unsigned)type_align_of(type), lb_debug_type(m, type->SimdVector.elem), nullptr, 0);
  1704. case Type_RelativePointer: {
  1705. LLVMMetadataRef base_integer = lb_debug_type(m, type->RelativePointer.base_integer);
  1706. gbString name = type_to_string(type, temporary_allocator());
  1707. return LLVMDIBuilderCreateTypedef(m->debug_builder, base_integer, name, gb_string_length(name), nullptr, 0, nullptr, cast(u32)(8*type_align_of(type)));
  1708. }
  1709. case Type_RelativeSlice:
  1710. {
  1711. unsigned element_count = 0;
  1712. LLVMMetadataRef elements[2] = {};
  1713. Type *base_integer = type->RelativeSlice.base_integer;
  1714. elements[0] = lb_debug_struct_field(m, str_lit("data_offset"), base_integer, 0);
  1715. elements[1] = lb_debug_struct_field(m, str_lit("len"), base_integer, 8*type_size_of(base_integer));
  1716. gbString name = type_to_string(type, temporary_allocator());
  1717. return LLVMDIBuilderCreateStructType(m->debug_builder, nullptr, name, gb_string_length(name), nullptr, 0, 2*word_bits, word_bits, LLVMDIFlagZero, nullptr, elements, element_count, 0, nullptr, "", 0);
  1718. }
  1719. }
  1720. GB_PANIC("Invalid type %s", type_to_string(type));
  1721. return nullptr;
  1722. }
  1723. LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
  1724. GB_ASSERT(type != nullptr);
  1725. LLVMMetadataRef found = lb_get_llvm_metadata(m, type);
  1726. if (found != nullptr) {
  1727. return found;
  1728. }
  1729. if (type->kind == Type_Named) {
  1730. LLVMMetadataRef file = nullptr;
  1731. unsigned line = 0;
  1732. LLVMMetadataRef scope = nullptr;
  1733. if (type->Named.type_name != nullptr) {
  1734. Entity *e = type->Named.type_name;
  1735. scope = lb_get_llvm_metadata(m, e->scope);
  1736. if (scope != nullptr) {
  1737. file = LLVMDIScopeGetFile(scope);
  1738. }
  1739. line = cast(unsigned)e->token.pos.line;
  1740. }
  1741. // TODO(bill): location data for Type_Named
  1742. u64 size_in_bits = 8*type_size_of(type);
  1743. u32 align_in_bits = 8*cast(u32)type_align_of(type);
  1744. String name = type->Named.name;
  1745. char const *name_text = cast(char const *)name.text;
  1746. size_t name_len = cast(size_t)name.len;
  1747. unsigned tag = DW_TAG_structure_type;
  1748. if (is_type_raw_union(type) || is_type_union(type)) {
  1749. tag = DW_TAG_union_type;
  1750. }
  1751. LLVMDIFlags flags = LLVMDIFlagZero;
  1752. Type *bt = base_type(type->Named.base);
  1753. lbIncompleteDebugType idt = {};
  1754. idt.type = type;
  1755. switch (bt->kind) {
  1756. case Type_Enum:
  1757. {
  1758. LLVMMetadataRef scope = nullptr;
  1759. LLVMMetadataRef file = nullptr;
  1760. unsigned line = 0;
  1761. unsigned element_count = cast(unsigned)bt->Enum.fields.count;
  1762. LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count);
  1763. Type *ct = base_enum_type(type);
  1764. LLVMBool is_unsigned = is_type_unsigned(ct);
  1765. for (unsigned i = 0; i < element_count; i++) {
  1766. Entity *f = bt->Enum.fields[i];
  1767. GB_ASSERT(f->kind == Entity_Constant);
  1768. String name = f->token.string;
  1769. i64 value = exact_value_to_i64(f->Constant.value);
  1770. elements[i] = LLVMDIBuilderCreateEnumerator(m->debug_builder, cast(char const *)name.text, cast(size_t)name.len, value, is_unsigned);
  1771. }
  1772. LLVMMetadataRef class_type = lb_debug_type(m, ct);
  1773. return LLVMDIBuilderCreateEnumerationType(m->debug_builder, scope, name_text, name_len, file, line, 8*type_size_of(type), 8*cast(unsigned)type_align_of(type), elements, element_count, class_type);
  1774. }
  1775. case Type_Basic:
  1776. case Type_Pointer:
  1777. case Type_Array:
  1778. case Type_EnumeratedArray:
  1779. case Type_Tuple:
  1780. case Type_Proc:
  1781. case Type_SimdVector:
  1782. case Type_RelativePointer:
  1783. case Type_RelativeSlice:
  1784. {
  1785. LLVMMetadataRef debug_bt = lb_debug_type(m, bt);
  1786. LLVMMetadataRef final_decl = LLVMDIBuilderCreateTypedef(m->debug_builder, debug_bt, name_text, name_len, file, line, scope, align_in_bits);
  1787. lb_set_llvm_metadata(m, type, final_decl);
  1788. return final_decl;
  1789. }
  1790. case Type_Slice:
  1791. case Type_DynamicArray:
  1792. case Type_Map:
  1793. case Type_Struct:
  1794. case Type_Union:
  1795. case Type_BitSet:
  1796. LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType(
  1797. m->debug_builder, tag, name_text, name_len, nullptr, nullptr, 0, 0, size_in_bits, align_in_bits, flags, "", 0
  1798. );
  1799. idt.metadata = temp_forward_decl;
  1800. array_add(&m->debug_incomplete_types, idt);
  1801. lb_set_llvm_metadata(m, type, temp_forward_decl);
  1802. return temp_forward_decl;
  1803. }
  1804. }
  1805. LLVMMetadataRef dt = lb_debug_type_internal(m, type);
  1806. lb_set_llvm_metadata(m, type, dt);
  1807. return dt;
  1808. }
  1809. void lb_debug_complete_types(lbModule *m) {
  1810. unsigned const word_size = cast(unsigned)build_context.word_size;
  1811. unsigned const word_bits = cast(unsigned)(8*build_context.word_size);
  1812. for_array(debug_incomplete_type_index, m->debug_incomplete_types) {
  1813. auto const &idt = m->debug_incomplete_types[debug_incomplete_type_index];
  1814. GB_ASSERT(idt.type != nullptr);
  1815. GB_ASSERT(idt.metadata != nullptr);
  1816. Type *t = idt.type;
  1817. Type *bt = base_type(t);
  1818. LLVMMetadataRef parent_scope = nullptr;
  1819. LLVMMetadataRef file = nullptr;
  1820. unsigned line_number = 0;
  1821. u64 size_in_bits = 8*type_size_of(t);
  1822. u32 align_in_bits = cast(u32)(8*type_align_of(t));
  1823. LLVMDIFlags flags = LLVMDIFlagZero;
  1824. LLVMMetadataRef derived_from = nullptr;
  1825. LLVMMetadataRef *elements = nullptr;
  1826. unsigned element_count = 0;
  1827. unsigned runtime_lang = 0; // Objective-C runtime version
  1828. char const *unique_id = "";
  1829. LLVMMetadataRef vtable_holder = nullptr;
  1830. size_t unique_id_len = 0;
  1831. LLVMMetadataRef record_scope = nullptr;
  1832. switch (bt->kind) {
  1833. case Type_Slice:
  1834. case Type_DynamicArray:
  1835. case Type_Map:
  1836. case Type_Struct:
  1837. case Type_Union:
  1838. case Type_BitSet: {
  1839. bool is_union = is_type_raw_union(bt) || is_type_union(bt);
  1840. String name = str_lit("<anonymous-struct>");
  1841. if (t->kind == Type_Named) {
  1842. name = t->Named.name;
  1843. if (t->Named.type_name && t->Named.type_name->pkg && t->Named.type_name->pkg->name.len != 0) {
  1844. name = concatenate3_strings(temporary_allocator(), t->Named.type_name->pkg->name, str_lit("."), t->Named.name);
  1845. }
  1846. LLVMMetadataRef file = nullptr;
  1847. unsigned line = 0;
  1848. LLVMMetadataRef file_scope = nullptr;
  1849. if (t->Named.type_name != nullptr) {
  1850. Entity *e = t->Named.type_name;
  1851. file_scope = lb_get_llvm_metadata(m, e->scope);
  1852. if (file_scope != nullptr) {
  1853. file = LLVMDIScopeGetFile(file_scope);
  1854. }
  1855. line = cast(unsigned)e->token.pos.line;
  1856. }
  1857. // TODO(bill): location data for Type_Named
  1858. } else {
  1859. name = make_string_c(type_to_string(t, temporary_allocator()));
  1860. }
  1861. switch (bt->kind) {
  1862. case Type_Slice:
  1863. element_count = 2;
  1864. elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
  1865. elements[0] = lb_debug_struct_field(m, str_lit("data"), alloc_type_pointer(bt->Slice.elem), 0*word_bits);
  1866. elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, 1*word_bits);
  1867. break;
  1868. case Type_DynamicArray:
  1869. element_count = 4;
  1870. elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
  1871. elements[0] = lb_debug_struct_field(m, str_lit("data"), alloc_type_pointer(bt->DynamicArray.elem), 0*word_bits);
  1872. elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, 1*word_bits);
  1873. elements[2] = lb_debug_struct_field(m, str_lit("cap"), t_int, 2*word_bits);
  1874. elements[3] = lb_debug_struct_field(m, str_lit("allocator"), t_allocator, 3*word_bits);
  1875. break;
  1876. case Type_Map:
  1877. bt = bt->Map.internal_type;
  1878. /*fallthrough*/
  1879. case Type_Struct:
  1880. if (file == nullptr) {
  1881. if (bt->Struct.node) {
  1882. file = lb_get_llvm_metadata(m, bt->Struct.node->file);
  1883. line_number = cast(unsigned)ast_token(bt->Struct.node).pos.line;
  1884. }
  1885. }
  1886. type_set_offsets(bt);
  1887. {
  1888. isize element_offset = 0;
  1889. record_scope = lb_get_llvm_metadata(m, bt->Struct.scope);
  1890. switch (bt->Struct.soa_kind) {
  1891. case StructSoa_Slice: element_offset = 1; break;
  1892. case StructSoa_Dynamic: element_offset = 3; break;
  1893. }
  1894. element_count = cast(unsigned)(bt->Struct.fields.count + element_offset);
  1895. elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
  1896. switch (bt->Struct.soa_kind) {
  1897. case StructSoa_Slice:
  1898. elements[0] = LLVMDIBuilderCreateMemberType(
  1899. m->debug_builder, record_scope,
  1900. ".len", 4,
  1901. file, 0,
  1902. 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
  1903. 8*type_size_of(bt)-word_bits,
  1904. LLVMDIFlagZero, lb_debug_type(m, t_int)
  1905. );
  1906. break;
  1907. case StructSoa_Dynamic:
  1908. elements[0] = LLVMDIBuilderCreateMemberType(
  1909. m->debug_builder, record_scope,
  1910. ".len", 4,
  1911. file, 0,
  1912. 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
  1913. 8*type_size_of(bt)-word_bits + 0*word_bits,
  1914. LLVMDIFlagZero, lb_debug_type(m, t_int)
  1915. );
  1916. elements[1] = LLVMDIBuilderCreateMemberType(
  1917. m->debug_builder, record_scope,
  1918. ".cap", 4,
  1919. file, 0,
  1920. 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
  1921. 8*type_size_of(bt)-word_bits + 1*word_bits,
  1922. LLVMDIFlagZero, lb_debug_type(m, t_int)
  1923. );
  1924. elements[2] = LLVMDIBuilderCreateMemberType(
  1925. m->debug_builder, record_scope,
  1926. ".allocator", 12,
  1927. file, 0,
  1928. 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
  1929. 8*type_size_of(bt)-word_bits + 2*word_bits,
  1930. LLVMDIFlagZero, lb_debug_type(m, t_allocator)
  1931. );
  1932. break;
  1933. }
  1934. for_array(j, bt->Struct.fields) {
  1935. Entity *f = bt->Struct.fields[j];
  1936. String fname = f->token.string;
  1937. unsigned field_line = 0;
  1938. LLVMDIFlags field_flags = LLVMDIFlagZero;
  1939. u64 offset_in_bits = 8*cast(u64)bt->Struct.offsets[j];
  1940. elements[element_offset+j] = LLVMDIBuilderCreateMemberType(
  1941. m->debug_builder, record_scope,
  1942. cast(char const *)fname.text, cast(size_t)fname.len,
  1943. file, field_line,
  1944. 8*cast(u64)type_size_of(f->type), 8*cast(u32)type_align_of(f->type),
  1945. offset_in_bits,
  1946. field_flags, lb_debug_type(m, f->type)
  1947. );
  1948. }
  1949. }
  1950. break;
  1951. case Type_Union:
  1952. {
  1953. if (file == nullptr) {
  1954. GB_ASSERT(bt->Union.node != nullptr);
  1955. file = lb_get_llvm_metadata(m, bt->Union.node->file);
  1956. line_number = cast(unsigned)ast_token(bt->Union.node).pos.line;
  1957. }
  1958. isize index_offset = 1;
  1959. if (is_type_union_maybe_pointer(bt)) {
  1960. index_offset = 0;
  1961. }
  1962. record_scope = lb_get_llvm_metadata(m, bt->Union.scope);
  1963. element_count = cast(unsigned)bt->Union.variants.count;
  1964. if (index_offset > 0) {
  1965. element_count += 1;
  1966. }
  1967. elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
  1968. if (index_offset > 0) {
  1969. Type *tag_type = union_tag_type(bt);
  1970. unsigned field_line = 0;
  1971. u64 offset_in_bits = 8*cast(u64)bt->Union.variant_block_size;
  1972. LLVMDIFlags field_flags = LLVMDIFlagZero;
  1973. elements[0] = LLVMDIBuilderCreateMemberType(
  1974. m->debug_builder, record_scope,
  1975. "tag", 3,
  1976. file, field_line,
  1977. 8*cast(u64)type_size_of(tag_type), 8*cast(u32)type_align_of(tag_type),
  1978. offset_in_bits,
  1979. field_flags, lb_debug_type(m, tag_type)
  1980. );
  1981. }
  1982. for_array(j, bt->Union.variants) {
  1983. Type *variant = bt->Union.variants[j];
  1984. unsigned field_index = cast(unsigned)(index_offset+j);
  1985. char name[16] = {};
  1986. gb_snprintf(name, gb_size_of(name), "v%u", field_index);
  1987. isize name_len = gb_strlen(name);
  1988. unsigned field_line = 0;
  1989. LLVMDIFlags field_flags = LLVMDIFlagZero;
  1990. u64 offset_in_bits = 0;
  1991. elements[field_index] = LLVMDIBuilderCreateMemberType(
  1992. m->debug_builder, record_scope,
  1993. name, name_len,
  1994. file, field_line,
  1995. 8*cast(u64)type_size_of(variant), 8*cast(u32)type_align_of(variant),
  1996. offset_in_bits,
  1997. field_flags, lb_debug_type(m, variant)
  1998. );
  1999. }
  2000. }
  2001. break;
  2002. case Type_BitSet:
  2003. {
  2004. if (file == nullptr) {
  2005. GB_ASSERT(bt->BitSet.node != nullptr);
  2006. file = lb_get_llvm_metadata(m, bt->BitSet.node->file);
  2007. line_number = cast(unsigned)ast_token(bt->BitSet.node).pos.line;
  2008. }
  2009. LLVMMetadataRef bit_set_field_type = lb_debug_type(m, t_bool);
  2010. LLVMMetadataRef scope = file;
  2011. Type *elem = base_type(bt->BitSet.elem);
  2012. if (elem->kind == Type_Enum) {
  2013. element_count = cast(unsigned)elem->Enum.fields.count;
  2014. elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
  2015. for_array(i, elem->Enum.fields) {
  2016. Entity *f = elem->Enum.fields[i];
  2017. GB_ASSERT(f->kind == Entity_Constant);
  2018. i64 val = exact_value_to_i64(f->Constant.value);
  2019. String name = f->token.string;
  2020. u64 offset_in_bits = cast(u64)(val - bt->BitSet.lower);
  2021. elements[i] = LLVMDIBuilderCreateBitFieldMemberType(
  2022. m->debug_builder,
  2023. scope,
  2024. cast(char const *)name.text, name.len,
  2025. file, line_number,
  2026. 1,
  2027. offset_in_bits,
  2028. 0,
  2029. LLVMDIFlagZero,
  2030. bit_set_field_type
  2031. );
  2032. }
  2033. } else {
  2034. char name[32] = {};
  2035. GB_ASSERT(is_type_integer(elem));
  2036. i64 count = bt->BitSet.upper - bt->BitSet.lower + 1;
  2037. GB_ASSERT(0 <= count);
  2038. element_count = cast(unsigned)count;
  2039. elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
  2040. for (unsigned i = 0; i < element_count; i++) {
  2041. u64 offset_in_bits = i;
  2042. i64 val = bt->BitSet.lower + cast(i64)i;
  2043. gb_snprintf(name, gb_count_of(name), "%lld", cast(long long)val);
  2044. elements[i] = LLVMDIBuilderCreateBitFieldMemberType(
  2045. m->debug_builder,
  2046. scope,
  2047. name, gb_strlen(name),
  2048. file, line_number,
  2049. 1,
  2050. offset_in_bits,
  2051. 0,
  2052. LLVMDIFlagZero,
  2053. bit_set_field_type
  2054. );
  2055. }
  2056. }
  2057. }
  2058. }
  2059. LLVMMetadataRef final_metadata = nullptr;
  2060. if (is_union) {
  2061. final_metadata = LLVMDIBuilderCreateUnionType(
  2062. m->debug_builder,
  2063. parent_scope,
  2064. cast(char const *)name.text, cast(size_t)name.len,
  2065. file, line_number,
  2066. size_in_bits, align_in_bits,
  2067. flags,
  2068. elements, element_count,
  2069. runtime_lang,
  2070. unique_id, unique_id_len
  2071. );
  2072. } else {
  2073. final_metadata = LLVMDIBuilderCreateStructType(
  2074. m->debug_builder,
  2075. parent_scope,
  2076. cast(char const *)name.text, cast(size_t)name.len,
  2077. file, line_number,
  2078. size_in_bits, align_in_bits,
  2079. flags,
  2080. derived_from,
  2081. elements, element_count,
  2082. runtime_lang,
  2083. vtable_holder,
  2084. unique_id, unique_id_len
  2085. );
  2086. }
  2087. LLVMMetadataReplaceAllUsesWith(idt.metadata, final_metadata);
  2088. lb_set_llvm_metadata(m, idt.type, final_metadata);
  2089. } break;
  2090. default:
  2091. GB_PANIC("invalid incomplete debug type");
  2092. break;
  2093. }
  2094. }
  2095. array_clear(&m->debug_incomplete_types);
  2096. }
  2097. void lb_add_entity(lbModule *m, Entity *e, lbValue val) {
  2098. if (e != nullptr) {
  2099. map_set(&m->values, hash_entity(e), val);
  2100. }
  2101. }
  2102. void lb_add_member(lbModule *m, String const &name, lbValue val) {
  2103. if (name.len > 0) {
  2104. string_map_set(&m->members, name, val);
  2105. }
  2106. }
  2107. void lb_add_member(lbModule *m, StringHashKey const &key, lbValue val) {
  2108. string_map_set(&m->members, key, val);
  2109. }
  2110. void lb_add_procedure_value(lbModule *m, lbProcedure *p) {
  2111. if (p->entity != nullptr) {
  2112. map_set(&m->procedure_values, hash_pointer(p->value), p->entity);
  2113. }
  2114. string_map_set(&m->procedures, p->name, p);
  2115. }
  2116. LLVMValueRef llvm_const_cast(LLVMValueRef val, LLVMTypeRef dst) {
  2117. LLVMTypeRef src = LLVMTypeOf(val);
  2118. if (src == dst) {
  2119. return val;
  2120. }
  2121. if (LLVMIsNull(val)) {
  2122. return LLVMConstNull(dst);
  2123. }
  2124. GB_ASSERT(LLVMSizeOf(dst) == LLVMSizeOf(src));
  2125. LLVMTypeKind kind = LLVMGetTypeKind(dst);
  2126. switch (kind) {
  2127. case LLVMPointerTypeKind:
  2128. return LLVMConstPointerCast(val, dst);
  2129. case LLVMStructTypeKind:
  2130. return LLVMConstBitCast(val, dst);
  2131. default:
  2132. GB_PANIC("Unhandled const cast %s to %s", LLVMPrintTypeToString(src), LLVMPrintTypeToString(dst));
  2133. }
  2134. return val;
  2135. }
  2136. LLVMValueRef llvm_const_named_struct(LLVMTypeRef t, LLVMValueRef *values, isize value_count_) {
  2137. unsigned value_count = cast(unsigned)value_count_;
  2138. unsigned elem_count = LLVMCountStructElementTypes(t);
  2139. GB_ASSERT(value_count == elem_count);
  2140. for (unsigned i = 0; i < elem_count; i++) {
  2141. LLVMTypeRef elem_type = LLVMStructGetTypeAtIndex(t, i);
  2142. values[i] = llvm_const_cast(values[i], elem_type);
  2143. }
  2144. return LLVMConstNamedStruct(t, values, value_count);
  2145. }
  2146. LLVMValueRef llvm_const_array(LLVMTypeRef elem_type, LLVMValueRef *values, isize value_count_) {
  2147. unsigned value_count = cast(unsigned)value_count_;
  2148. for (unsigned i = 0; i < value_count; i++) {
  2149. values[i] = llvm_const_cast(values[i], elem_type);
  2150. }
  2151. return LLVMConstArray(elem_type, values, value_count);
  2152. }
  2153. lbValue lb_emit_string(lbProcedure *p, lbValue str_elem, lbValue str_len) {
  2154. if (false && lb_is_const(str_elem) && lb_is_const(str_len)) {
  2155. LLVMValueRef values[2] = {
  2156. str_elem.value,
  2157. str_len.value,
  2158. };
  2159. lbValue res = {};
  2160. res.type = t_string;
  2161. res.value = llvm_const_named_struct(lb_type(p->module, t_string), values, gb_count_of(values));
  2162. return res;
  2163. } else {
  2164. lbAddr res = lb_add_local_generated(p, t_string, false);
  2165. lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 0), str_elem);
  2166. lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 1), str_len);
  2167. return lb_addr_load(p, res);
  2168. }
  2169. }
  2170. LLVMAttributeRef lb_create_enum_attribute_with_type(LLVMContextRef ctx, char const *name, LLVMTypeRef type) {
  2171. String s = make_string_c(name);
  2172. // NOTE(2021-02-25, bill); All this attributes require a type associated with them
  2173. // and the current LLVM C API does not expose this functionality yet.
  2174. // It is better to ignore the attributes for the time being
  2175. if (s == "byval") {
  2176. // return nullptr;
  2177. } else if (s == "byref") {
  2178. return nullptr;
  2179. } else if (s == "preallocated") {
  2180. return nullptr;
  2181. } else if (s == "sret") {
  2182. // return nullptr;
  2183. }
  2184. unsigned kind = LLVMGetEnumAttributeKindForName(name, s.len);
  2185. GB_ASSERT_MSG(kind != 0, "unknown attribute: %s", name);
  2186. return LLVMCreateEnumAttribute(ctx, kind, 0);
  2187. }
  2188. LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value) {
  2189. String s = make_string_c(name);
  2190. // NOTE(2021-02-25, bill); All this attributes require a type associated with them
  2191. // and the current LLVM C API does not expose this functionality yet.
  2192. // It is better to ignore the attributes for the time being
  2193. if (s == "byval") {
  2194. GB_PANIC("lb_create_enum_attribute_with_type should be used for %s", name);
  2195. } else if (s == "byref") {
  2196. GB_PANIC("lb_create_enum_attribute_with_type should be used for %s", name);
  2197. } else if (s == "preallocated") {
  2198. GB_PANIC("lb_create_enum_attribute_with_type should be used for %s", name);
  2199. } else if (s == "sret") {
  2200. GB_PANIC("lb_create_enum_attribute_with_type should be used for %s", name);
  2201. }
  2202. unsigned kind = LLVMGetEnumAttributeKindForName(name, s.len);
  2203. GB_ASSERT_MSG(kind != 0, "unknown attribute: %s", name);
  2204. return LLVMCreateEnumAttribute(ctx, kind, value);
  2205. }
  2206. void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name, u64 value) {
  2207. LLVMAttributeRef attr = lb_create_enum_attribute(p->module->ctx, name, value);
  2208. GB_ASSERT(attr != nullptr);
  2209. LLVMAddAttributeAtIndex(p->value, cast(unsigned)index, attr);
  2210. }
  2211. void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name) {
  2212. lb_add_proc_attribute_at_index(p, index, name, 0);
  2213. }
  2214. void lb_add_attribute_to_proc(lbModule *m, LLVMValueRef proc_value, char const *name, u64 value=0) {
  2215. LLVMAddAttributeAtIndex(proc_value, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(m->ctx, name, value));
  2216. }
  2217. void lb_ensure_abi_function_type(lbModule *m, lbProcedure *p) {
  2218. if (p->abi_function_type != nullptr) {
  2219. return;
  2220. }
  2221. auto hash = hash_type(p->type);
  2222. lbFunctionType **ft_found = map_get(&m->function_type_map, hash);
  2223. if (ft_found == nullptr) {
  2224. LLVMTypeRef llvm_proc_type = lb_type(p->module, p->type);
  2225. ft_found = map_get(&m->function_type_map, hash);
  2226. }
  2227. GB_ASSERT(ft_found != nullptr);
  2228. p->abi_function_type = *ft_found;
  2229. GB_ASSERT(p->abi_function_type != nullptr);
  2230. }
  2231. lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) {
  2232. GB_ASSERT(entity != nullptr);
  2233. GB_ASSERT(entity->kind == Entity_Procedure);
  2234. String link_name = {};
  2235. if (ignore_body) {
  2236. lbModule *other_module = lb_pkg_module(m->gen, entity->pkg);
  2237. link_name = lb_get_entity_name(other_module, entity);
  2238. } else {
  2239. link_name = lb_get_entity_name(m, entity);
  2240. }
  2241. {
  2242. StringHashKey key = string_hash_string(link_name);
  2243. lbValue *found = string_map_get(&m->members, key);
  2244. if (found) {
  2245. lb_add_entity(m, entity, *found);
  2246. lbProcedure **p_found = string_map_get(&m->procedures, key);
  2247. GB_ASSERT(p_found != nullptr);
  2248. return *p_found;
  2249. }
  2250. }
  2251. lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure);
  2252. p->module = m;
  2253. entity->code_gen_module = m;
  2254. entity->code_gen_procedure = p;
  2255. p->entity = entity;
  2256. p->name = link_name;
  2257. DeclInfo *decl = entity->decl_info;
  2258. ast_node(pl, ProcLit, decl->proc_lit);
  2259. Type *pt = base_type(entity->type);
  2260. GB_ASSERT(pt->kind == Type_Proc);
  2261. p->type = entity->type;
  2262. p->type_expr = decl->type_expr;
  2263. p->body = pl->body;
  2264. p->inlining = pl->inlining;
  2265. p->is_foreign = entity->Procedure.is_foreign;
  2266. p->is_export = entity->Procedure.is_export;
  2267. p->is_entry_point = false;
  2268. gbAllocator a = heap_allocator();
  2269. p->children.allocator = a;
  2270. p->params.allocator = a;
  2271. p->defer_stmts.allocator = a;
  2272. p->blocks.allocator = a;
  2273. p->branch_blocks.allocator = a;
  2274. p->context_stack.allocator = a;
  2275. p->scope_stack.allocator = a;
  2276. if (p->is_foreign) {
  2277. lb_add_foreign_library_path(p->module, entity->Procedure.foreign_library);
  2278. }
  2279. char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
  2280. LLVMTypeRef func_ptr_type = lb_type(m, p->type);
  2281. LLVMTypeRef func_type = LLVMGetElementType(func_ptr_type);
  2282. p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
  2283. lb_ensure_abi_function_type(m, p);
  2284. lb_add_function_type_attributes(p->value, p->abi_function_type, p->abi_function_type->calling_convention);
  2285. if (false) {
  2286. lbCallingConventionKind cc_kind = lbCallingConvention_C;
  2287. // TODO(bill): Clean up this logic
  2288. if (build_context.metrics.os != TargetOs_js) {
  2289. cc_kind = lb_calling_convention_map[pt->Proc.calling_convention];
  2290. }
  2291. LLVMSetFunctionCallConv(p->value, cc_kind);
  2292. }
  2293. if (pt->Proc.diverging) {
  2294. lb_add_attribute_to_proc(m, p->value, "noreturn");
  2295. }
  2296. if (pt->Proc.calling_convention == ProcCC_Naked) {
  2297. lb_add_attribute_to_proc(m, p->value, "naked");
  2298. }
  2299. switch (p->inlining) {
  2300. case ProcInlining_inline:
  2301. lb_add_attribute_to_proc(m, p->value, "alwaysinline");
  2302. break;
  2303. case ProcInlining_no_inline:
  2304. lb_add_attribute_to_proc(m, p->value, "noinline");
  2305. break;
  2306. }
  2307. if (entity->flags & EntityFlag_Cold) {
  2308. lb_add_attribute_to_proc(m, p->value, "cold");
  2309. }
  2310. switch (entity->Procedure.optimization_mode) {
  2311. case ProcedureOptimizationMode_None:
  2312. lb_add_attribute_to_proc(m, p->value, "optnone");
  2313. break;
  2314. case ProcedureOptimizationMode_Minimal:
  2315. lb_add_attribute_to_proc(m, p->value, "optnone");
  2316. break;
  2317. case ProcedureOptimizationMode_Size:
  2318. lb_add_attribute_to_proc(m, p->value, "optsize");
  2319. break;
  2320. case ProcedureOptimizationMode_Speed:
  2321. // TODO(bill): handle this correctly
  2322. lb_add_attribute_to_proc(m, p->value, "optsize");
  2323. break;
  2324. }
  2325. // lbCallingConventionKind cc_kind = lbCallingConvention_C;
  2326. // // TODO(bill): Clean up this logic
  2327. // if (build_context.metrics.os != TargetOs_js) {
  2328. // cc_kind = lb_calling_convention_map[pt->Proc.calling_convention];
  2329. // }
  2330. // LLVMSetFunctionCallConv(p->value, cc_kind);
  2331. lbValue proc_value = {p->value, p->type};
  2332. lb_add_entity(m, entity, proc_value);
  2333. lb_add_member(m, p->name, proc_value);
  2334. lb_add_procedure_value(m, p);
  2335. if (p->is_export) {
  2336. LLVMSetLinkage(p->value, LLVMDLLExportLinkage);
  2337. LLVMSetDLLStorageClass(p->value, LLVMDLLExportStorageClass);
  2338. LLVMSetVisibility(p->value, LLVMDefaultVisibility);
  2339. if (build_context.metrics.os == TargetOs_js) {
  2340. char const *export_name = alloc_cstring(permanent_allocator(), p->name);
  2341. LLVMAddTargetDependentFunctionAttr(p->value, "wasm-export-name", export_name);
  2342. }
  2343. }
  2344. if (p->is_foreign) {
  2345. if (build_context.metrics.os == TargetOs_js) {
  2346. char const *import_name = alloc_cstring(permanent_allocator(), p->name);
  2347. char const *module_name = "env";
  2348. if (entity->Procedure.foreign_library != nullptr) {
  2349. Entity *foreign_library = entity->Procedure.foreign_library;
  2350. GB_ASSERT(foreign_library->kind == Entity_LibraryName);
  2351. if (foreign_library->LibraryName.paths.count > 0) {
  2352. module_name = alloc_cstring(permanent_allocator(), foreign_library->LibraryName.paths[0]);
  2353. }
  2354. }
  2355. LLVMAddTargetDependentFunctionAttr(p->value, "wasm-import-name", import_name);
  2356. LLVMAddTargetDependentFunctionAttr(p->value, "wasm-import-module", module_name);
  2357. }
  2358. }
  2359. // NOTE(bill): offset==0 is the return value
  2360. isize offset = 1;
  2361. if (pt->Proc.return_by_pointer) {
  2362. offset = 2;
  2363. }
  2364. isize parameter_index = 0;
  2365. if (pt->Proc.param_count) {
  2366. TypeTuple *params = &pt->Proc.params->Tuple;
  2367. for (isize i = 0; i < pt->Proc.param_count; i++) {
  2368. Entity *e = params->variables[i];
  2369. Type *original_type = e->type;
  2370. if (e->kind != Entity_Variable) continue;
  2371. if (i+1 == params->variables.count && pt->Proc.c_vararg) {
  2372. continue;
  2373. }
  2374. if (e->flags&EntityFlag_NoAlias) {
  2375. lb_add_proc_attribute_at_index(p, offset+parameter_index, "noalias");
  2376. }
  2377. parameter_index += 1;
  2378. }
  2379. }
  2380. if (ignore_body) {
  2381. p->body = nullptr;
  2382. LLVMSetLinkage(p->value, LLVMExternalLinkage);
  2383. }
  2384. if (m->debug_builder) { // Debug Information
  2385. Type *bt = base_type(p->type);
  2386. unsigned line = cast(unsigned)entity->token.pos.line;
  2387. LLVMMetadataRef scope = nullptr;
  2388. LLVMMetadataRef file = nullptr;
  2389. LLVMMetadataRef type = nullptr;
  2390. scope = p->module->debug_compile_unit;
  2391. type = lb_debug_type_internal_proc(m, bt);
  2392. if (entity->file != nullptr) {
  2393. file = lb_get_llvm_metadata(m, entity->file);
  2394. scope = file;
  2395. } else if (entity->identifier != nullptr && entity->identifier->file != nullptr) {
  2396. file = lb_get_llvm_metadata(m, entity->identifier->file);
  2397. scope = file;
  2398. } else if (entity->scope != nullptr) {
  2399. file = lb_get_llvm_metadata(m, entity->scope->file);
  2400. scope = file;
  2401. }
  2402. GB_ASSERT_MSG(file != nullptr, "%.*s", LIT(entity->token.string));
  2403. // LLVMBool is_local_to_unit = !entity->Procedure.is_export;
  2404. LLVMBool is_local_to_unit = false;
  2405. LLVMBool is_definition = p->body != nullptr;
  2406. unsigned scope_line = line;
  2407. u32 flags = LLVMDIFlagStaticMember;
  2408. LLVMBool is_optimized = false;
  2409. if (bt->Proc.diverging) {
  2410. flags |= LLVMDIFlagNoReturn;
  2411. }
  2412. if (p->body == nullptr) {
  2413. flags |= LLVMDIFlagPrototyped;
  2414. is_optimized = false;
  2415. }
  2416. if (p->body != nullptr) {
  2417. p->debug_info = LLVMDIBuilderCreateFunction(m->debug_builder, scope,
  2418. cast(char const *)entity->token.string.text, entity->token.string.len,
  2419. cast(char const *)p->name.text, p->name.len,
  2420. file, line, type,
  2421. is_local_to_unit, is_definition,
  2422. scope_line, cast(LLVMDIFlags)flags, is_optimized
  2423. );
  2424. GB_ASSERT(p->debug_info != nullptr);
  2425. LLVMSetSubprogram(p->value, p->debug_info);
  2426. lb_set_llvm_metadata(m, p, p->debug_info);
  2427. }
  2428. }
  2429. return p;
  2430. }
  2431. lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type) {
  2432. {
  2433. lbValue *found = string_map_get(&m->members, link_name);
  2434. GB_ASSERT(found == nullptr);
  2435. }
  2436. lbProcedure *p = gb_alloc_item(permanent_allocator(), lbProcedure);
  2437. p->module = m;
  2438. p->name = link_name;
  2439. p->type = type;
  2440. p->type_expr = nullptr;
  2441. p->body = nullptr;
  2442. p->tags = 0;
  2443. p->inlining = ProcInlining_none;
  2444. p->is_foreign = false;
  2445. p->is_export = false;
  2446. p->is_entry_point = false;
  2447. gbAllocator a = permanent_allocator();
  2448. p->children.allocator = a;
  2449. p->params.allocator = a;
  2450. p->defer_stmts.allocator = a;
  2451. p->blocks.allocator = a;
  2452. p->branch_blocks.allocator = a;
  2453. p->context_stack.allocator = a;
  2454. char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
  2455. LLVMTypeRef func_ptr_type = lb_type(m, p->type);
  2456. LLVMTypeRef func_type = LLVMGetElementType(func_ptr_type);
  2457. p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
  2458. Type *pt = p->type;
  2459. lbCallingConventionKind cc_kind = lbCallingConvention_C;
  2460. // TODO(bill): Clean up this logic
  2461. if (build_context.metrics.os != TargetOs_js) {
  2462. cc_kind = lb_calling_convention_map[pt->Proc.calling_convention];
  2463. }
  2464. LLVMSetFunctionCallConv(p->value, cc_kind);
  2465. lbValue proc_value = {p->value, p->type};
  2466. lb_add_member(m, p->name, proc_value);
  2467. lb_add_procedure_value(m, p);
  2468. // NOTE(bill): offset==0 is the return value
  2469. isize offset = 1;
  2470. if (pt->Proc.return_by_pointer) {
  2471. lb_add_proc_attribute_at_index(p, 1, "sret");
  2472. lb_add_proc_attribute_at_index(p, 1, "noalias");
  2473. offset = 2;
  2474. }
  2475. isize parameter_index = 0;
  2476. if (pt->Proc.calling_convention == ProcCC_Odin) {
  2477. lb_add_proc_attribute_at_index(p, offset+parameter_index, "noalias");
  2478. lb_add_proc_attribute_at_index(p, offset+parameter_index, "nonnull");
  2479. lb_add_proc_attribute_at_index(p, offset+parameter_index, "nocapture");
  2480. }
  2481. return p;
  2482. }
  2483. lbValue lb_value_param(lbProcedure *p, Entity *e, Type *abi_type, i32 index, lbParamPasskind *kind_) {
  2484. lbParamPasskind kind = lbParamPass_Value;
  2485. if (e != nullptr && !are_types_identical(abi_type, e->type)) {
  2486. if (is_type_pointer(abi_type)) {
  2487. GB_ASSERT(e->kind == Entity_Variable);
  2488. Type *av = core_type(type_deref(abi_type));
  2489. if (are_types_identical(av, core_type(e->type))) {
  2490. kind = lbParamPass_Pointer;
  2491. if (e->flags&EntityFlag_Value) {
  2492. kind = lbParamPass_ConstRef;
  2493. }
  2494. } else {
  2495. kind = lbParamPass_BitCast;
  2496. }
  2497. } else if (is_type_integer(abi_type)) {
  2498. kind = lbParamPass_Integer;
  2499. } else if (abi_type == t_llvm_bool) {
  2500. kind = lbParamPass_Value;
  2501. } else if (is_type_boolean(abi_type)) {
  2502. kind = lbParamPass_Integer;
  2503. } else if (is_type_simd_vector(abi_type)) {
  2504. kind = lbParamPass_BitCast;
  2505. } else if (is_type_float(abi_type)) {
  2506. kind = lbParamPass_BitCast;
  2507. } else if (is_type_tuple(abi_type)) {
  2508. kind = lbParamPass_Tuple;
  2509. } else if (is_type_proc(abi_type)) {
  2510. kind = lbParamPass_Value;
  2511. } else {
  2512. GB_PANIC("Invalid abi type pass kind %s", type_to_string(abi_type));
  2513. }
  2514. }
  2515. if (kind_) *kind_ = kind;
  2516. lbValue res = {};
  2517. res.value = LLVMGetParam(p->value, cast(unsigned)index);
  2518. res.type = abi_type;
  2519. return res;
  2520. }
  2521. Type *struct_type_from_systemv_distribute_struct_fields(Type *abi_type) {
  2522. GB_ASSERT(is_type_tuple(abi_type));
  2523. Type *final_type = alloc_type_struct();
  2524. final_type->Struct.fields = abi_type->Tuple.variables;
  2525. return final_type;
  2526. }
  2527. void lb_start_block(lbProcedure *p, lbBlock *b) {
  2528. GB_ASSERT(b != nullptr);
  2529. if (!b->appended) {
  2530. b->appended = true;
  2531. LLVMAppendExistingBasicBlock(p->value, b->block);
  2532. }
  2533. LLVMPositionBuilderAtEnd(p->builder, b->block);
  2534. p->curr_block = b;
  2535. }
  2536. LLVMValueRef OdinLLVMBuildTransmute(lbProcedure *p, LLVMValueRef val, LLVMTypeRef dst_type) {
  2537. LLVMContextRef ctx = p->module->ctx;
  2538. LLVMTypeRef src_type = LLVMTypeOf(val);
  2539. if (src_type == dst_type) {
  2540. return val;
  2541. }
  2542. i64 src_size = lb_sizeof(src_type);
  2543. i64 dst_size = lb_sizeof(dst_type);
  2544. i64 src_align = lb_alignof(src_type);
  2545. i64 dst_align = lb_alignof(dst_type);
  2546. if (LLVMIsALoadInst(val)) {
  2547. src_align = gb_min(src_align, LLVMGetAlignment(val));
  2548. }
  2549. LLVMTypeKind src_kind = LLVMGetTypeKind(src_type);
  2550. LLVMTypeKind dst_kind = LLVMGetTypeKind(dst_type);
  2551. if (dst_type == LLVMInt1TypeInContext(ctx)) {
  2552. GB_ASSERT(lb_is_type_kind(src_type, LLVMIntegerTypeKind));
  2553. return LLVMBuildICmp(p->builder, LLVMIntNE, val, LLVMConstNull(src_type), "");
  2554. } else if (src_type == LLVMInt1TypeInContext(ctx)) {
  2555. GB_ASSERT(lb_is_type_kind(src_type, LLVMIntegerTypeKind));
  2556. return LLVMBuildZExtOrBitCast(p->builder, val, dst_type, "");
  2557. }
  2558. if (src_size != dst_size) {
  2559. if ((lb_is_type_kind(src_type, LLVMVectorTypeKind) ^ lb_is_type_kind(dst_type, LLVMVectorTypeKind))) {
  2560. // Okay
  2561. } else {
  2562. goto general_end;
  2563. }
  2564. }
  2565. if (src_kind == dst_kind) {
  2566. if (src_kind == LLVMPointerTypeKind) {
  2567. return LLVMBuildPointerCast(p->builder, val, dst_type, "");
  2568. } else if (src_kind == LLVMArrayTypeKind) {
  2569. // ignore
  2570. } else if (src_kind != LLVMStructTypeKind) {
  2571. return LLVMBuildBitCast(p->builder, val, dst_type, "");
  2572. }
  2573. } else {
  2574. if (src_kind == LLVMPointerTypeKind && dst_kind == LLVMIntegerTypeKind) {
  2575. return LLVMBuildPtrToInt(p->builder, val, dst_type, "");
  2576. } else if (src_kind == LLVMIntegerTypeKind && dst_kind == LLVMPointerTypeKind) {
  2577. return LLVMBuildIntToPtr(p->builder, val, dst_type, "");
  2578. }
  2579. }
  2580. general_end:;
  2581. // make the alignment big if necessary
  2582. if (LLVMIsALoadInst(val) && src_align < dst_align) {
  2583. LLVMValueRef val_ptr = LLVMGetOperand(val, 0);
  2584. if (LLVMGetInstructionOpcode(val_ptr) == LLVMAlloca) {
  2585. src_align = gb_max(LLVMGetAlignment(val_ptr), dst_align);
  2586. LLVMSetAlignment(val_ptr, cast(unsigned)src_align);
  2587. }
  2588. }
  2589. src_size = align_formula(src_size, src_align);
  2590. dst_size = align_formula(dst_size, dst_align);
  2591. if (LLVMIsALoadInst(val) && (src_size >= dst_size && src_align >= dst_align)) {
  2592. LLVMValueRef val_ptr = LLVMGetOperand(val, 0);
  2593. val_ptr = LLVMBuildPointerCast(p->builder, val_ptr, LLVMPointerType(dst_type, 0), "");
  2594. LLVMValueRef loaded_val = LLVMBuildLoad(p->builder, val_ptr, "");
  2595. // LLVMSetAlignment(loaded_val, gb_min(src_align, dst_align));
  2596. return loaded_val;
  2597. } else {
  2598. GB_ASSERT(p->decl_block != p->curr_block);
  2599. LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
  2600. LLVMValueRef ptr = LLVMBuildAlloca(p->builder, dst_type, "");
  2601. LLVMPositionBuilderAtEnd(p->builder, p->curr_block->block);
  2602. i64 max_align = gb_max(lb_alignof(src_type), lb_alignof(dst_type));
  2603. max_align = gb_max(max_align, 4);
  2604. LLVMSetAlignment(ptr, cast(unsigned)max_align);
  2605. LLVMValueRef nptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(src_type, 0), "");
  2606. LLVMBuildStore(p->builder, val, nptr);
  2607. return LLVMBuildLoad(p->builder, ptr, "");
  2608. }
  2609. }
  2610. void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token) {
  2611. if (p->debug_info == nullptr) {
  2612. return;
  2613. }
  2614. if (type == nullptr) {
  2615. return;
  2616. }
  2617. if (type == t_invalid) {
  2618. return;
  2619. }
  2620. if (p->body == nullptr) {
  2621. return;
  2622. }
  2623. lbModule *m = p->module;
  2624. String const &name = token.string;
  2625. if (name == "" || name == "_") {
  2626. return;
  2627. }
  2628. if (lb_get_llvm_metadata(m, ptr) != nullptr) {
  2629. // Already been set
  2630. return;
  2631. }
  2632. AstFile *file = p->body->file;
  2633. LLVMMetadataRef llvm_scope = lb_get_current_debug_scope(p);
  2634. LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, file);
  2635. GB_ASSERT(llvm_scope != nullptr);
  2636. if (llvm_file == nullptr) {
  2637. llvm_file = LLVMDIScopeGetFile(llvm_scope);
  2638. }
  2639. if (llvm_file == nullptr) {
  2640. return;
  2641. }
  2642. unsigned alignment_in_bits = cast(unsigned)(8*type_align_of(type));
  2643. LLVMDIFlags flags = LLVMDIFlagZero;
  2644. LLVMBool always_preserve = build_context.optimization_level == 0;
  2645. LLVMMetadataRef debug_type = lb_debug_type(m, type);
  2646. LLVMMetadataRef var_info = LLVMDIBuilderCreateAutoVariable(
  2647. m->debug_builder, llvm_scope,
  2648. cast(char const *)name.text, cast(size_t)name.len,
  2649. llvm_file, token.pos.line,
  2650. debug_type,
  2651. always_preserve, flags, alignment_in_bits
  2652. );
  2653. LLVMValueRef storage = ptr;
  2654. LLVMValueRef instr = ptr;
  2655. LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, token.pos);
  2656. LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0);
  2657. lb_set_llvm_metadata(m, ptr, llvm_expr);
  2658. LLVMDIBuilderInsertDeclareBefore(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, instr);
  2659. }
  2660. void lb_add_debug_context_variable(lbProcedure *p, lbAddr const &ctx) {
  2661. if (!p->debug_info || !p->body) {
  2662. return;
  2663. }
  2664. LLVMMetadataRef loc = LLVMGetCurrentDebugLocation2(p->builder);
  2665. if (!loc) {
  2666. return;
  2667. }
  2668. TokenPos pos = {};
  2669. pos.file_id = p->body->file ? p->body->file->id : 0;
  2670. pos.line = LLVMDILocationGetLine(loc);
  2671. pos.column = LLVMDILocationGetColumn(loc);
  2672. Token token = {};
  2673. token.kind = Token_context;
  2674. token.string = str_lit("context");
  2675. token.pos = pos;
  2676. lb_add_debug_local_variable(p, ctx.addr.value, t_context, token);
  2677. }
  2678. void lb_begin_procedure_body(lbProcedure *p) {
  2679. DeclInfo *decl = decl_info_of_entity(p->entity);
  2680. if (decl != nullptr) {
  2681. for_array(i, decl->labels) {
  2682. BlockLabel bl = decl->labels[i];
  2683. lbBranchBlocks bb = {bl.label, nullptr, nullptr};
  2684. array_add(&p->branch_blocks, bb);
  2685. }
  2686. }
  2687. p->builder = LLVMCreateBuilderInContext(p->module->ctx);
  2688. p->decl_block = lb_create_block(p, "decls", true);
  2689. p->entry_block = lb_create_block(p, "entry", true);
  2690. lb_start_block(p, p->entry_block);
  2691. GB_ASSERT(p->type != nullptr);
  2692. lb_ensure_abi_function_type(p->module, p);
  2693. {
  2694. lbFunctionType *ft = p->abi_function_type;
  2695. unsigned param_offset = 0;
  2696. lbValue return_ptr_value = {};
  2697. if (ft->ret.kind == lbArg_Indirect) {
  2698. // NOTE(bill): this must be parameter 0
  2699. String name = str_lit("agg.result");
  2700. Type *ptr_type = alloc_type_pointer(reduce_tuple_to_single_type(p->type->Proc.results));
  2701. Entity *e = alloc_entity_param(nullptr, make_token_ident(name), ptr_type, false, false);
  2702. e->flags |= EntityFlag_Sret | EntityFlag_NoAlias;
  2703. return_ptr_value.value = LLVMGetParam(p->value, 0);
  2704. LLVMSetValueName2(return_ptr_value.value, cast(char const *)name.text, name.len);
  2705. return_ptr_value.type = ptr_type;
  2706. p->return_ptr = lb_addr(return_ptr_value);
  2707. lb_add_entity(p->module, e, return_ptr_value);
  2708. param_offset += 1;
  2709. }
  2710. if (p->type->Proc.params != nullptr) {
  2711. TypeTuple *params = &p->type->Proc.params->Tuple;
  2712. unsigned param_index = 0;
  2713. for_array(i, params->variables) {
  2714. Entity *e = params->variables[i];
  2715. if (e->kind != Entity_Variable) {
  2716. continue;
  2717. }
  2718. lbArgType *arg_type = &ft->args[param_index];
  2719. if (arg_type->kind == lbArg_Ignore) {
  2720. continue;
  2721. } else if (arg_type->kind == lbArg_Direct) {
  2722. lbParamPasskind kind = lbParamPass_Value;
  2723. LLVMTypeRef param_type = lb_type(p->module, e->type);
  2724. if (param_type != arg_type->type) {
  2725. kind = lbParamPass_BitCast;
  2726. }
  2727. LLVMValueRef value = LLVMGetParam(p->value, param_offset+param_index);
  2728. value = OdinLLVMBuildTransmute(p, value, param_type);
  2729. lbValue param = {};
  2730. param.value = value;
  2731. param.type = e->type;
  2732. array_add(&p->params, param);
  2733. if (e->token.string.len != 0) {
  2734. lbAddr l = lb_add_local(p, e->type, e, false, param_index);
  2735. lb_addr_store(p, l, param);
  2736. }
  2737. param_index += 1;
  2738. } else if (arg_type->kind == lbArg_Indirect) {
  2739. LLVMValueRef value_ptr = LLVMGetParam(p->value, param_offset+param_index);
  2740. LLVMValueRef value = LLVMBuildLoad(p->builder, value_ptr, "");
  2741. lbValue param = {};
  2742. param.value = value;
  2743. param.type = e->type;
  2744. array_add(&p->params, param);
  2745. lbValue ptr = {};
  2746. ptr.value = value_ptr;
  2747. ptr.type = alloc_type_pointer(e->type);
  2748. lb_add_entity(p->module, e, ptr);
  2749. param_index += 1;
  2750. }
  2751. }
  2752. }
  2753. if (p->type->Proc.has_named_results) {
  2754. GB_ASSERT(p->type->Proc.result_count > 0);
  2755. TypeTuple *results = &p->type->Proc.results->Tuple;
  2756. for_array(i, results->variables) {
  2757. Entity *e = results->variables[i];
  2758. GB_ASSERT(e->kind == Entity_Variable);
  2759. if (e->token.string != "") {
  2760. GB_ASSERT(!is_blank_ident(e->token));
  2761. lbAddr res = {};
  2762. if (return_ptr_value.value) {
  2763. lbValue ptr = return_ptr_value;
  2764. if (results->variables.count != 1) {
  2765. ptr = lb_emit_struct_ep(p, ptr, cast(i32)i);
  2766. }
  2767. res = lb_addr(ptr);
  2768. lb_add_entity(p->module, e, ptr);
  2769. } else {
  2770. res = lb_add_local(p, e->type, e);
  2771. }
  2772. if (e->Variable.param_value.kind != ParameterValue_Invalid) {
  2773. lbValue c = lb_handle_param_value(p, e->type, e->Variable.param_value, e->token.pos);
  2774. lb_addr_store(p, res, c);
  2775. }
  2776. }
  2777. }
  2778. }
  2779. }
  2780. if (p->type->Proc.calling_convention == ProcCC_Odin) {
  2781. lb_push_context_onto_stack_from_implicit_parameter(p);
  2782. }
  2783. lb_start_block(p, p->entry_block);
  2784. if (p->debug_info != nullptr) {
  2785. TokenPos pos = {};
  2786. if (p->body != nullptr) {
  2787. pos = ast_token(p->body).pos;
  2788. } else if (p->type_expr != nullptr) {
  2789. pos = ast_token(p->type_expr).pos;
  2790. } else if (p->entity != nullptr) {
  2791. pos = p->entity->token.pos;
  2792. }
  2793. if (pos.file_id != 0) {
  2794. LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_token_pos(p, pos));
  2795. }
  2796. if (p->context_stack.count != 0) {
  2797. lb_add_debug_context_variable(p, lb_find_or_generate_context_ptr(p));
  2798. }
  2799. }
  2800. }
  2801. void lb_end_procedure_body(lbProcedure *p) {
  2802. LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
  2803. LLVMBuildBr(p->builder, p->entry_block->block);
  2804. LLVMPositionBuilderAtEnd(p->builder, p->curr_block->block);
  2805. LLVMValueRef instr = nullptr;
  2806. // Make sure there is a "ret void" at the end of a procedure with no return type
  2807. if (p->type->Proc.result_count == 0) {
  2808. instr = LLVMGetLastInstruction(p->curr_block->block);
  2809. if (!lb_is_instr_terminating(instr)) {
  2810. lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
  2811. LLVMBuildRetVoid(p->builder);
  2812. }
  2813. }
  2814. LLVMBasicBlockRef first_block = LLVMGetFirstBasicBlock(p->value);
  2815. LLVMBasicBlockRef block = nullptr;
  2816. // Make sure every block terminates, and if not, make it unreachable
  2817. for (block = first_block; block != nullptr; block = LLVMGetNextBasicBlock(block)) {
  2818. instr = LLVMGetLastInstruction(block);
  2819. if (instr == nullptr || !lb_is_instr_terminating(instr)) {
  2820. LLVMPositionBuilderAtEnd(p->builder, block);
  2821. LLVMBuildUnreachable(p->builder);
  2822. }
  2823. }
  2824. p->curr_block = nullptr;
  2825. p->state_flags = 0;
  2826. }
  2827. void lb_end_procedure(lbProcedure *p) {
  2828. LLVMDisposeBuilder(p->builder);
  2829. }
  2830. void lb_add_edge(lbBlock *from, lbBlock *to) {
  2831. LLVMValueRef instr = LLVMGetLastInstruction(from->block);
  2832. if (instr == nullptr || !LLVMIsATerminatorInst(instr)) {
  2833. array_add(&from->succs, to);
  2834. array_add(&to->preds, from);
  2835. }
  2836. }
  2837. lbBlock *lb_create_block(lbProcedure *p, char const *name, bool append) {
  2838. lbBlock *b = gb_alloc_item(permanent_allocator(), lbBlock);
  2839. b->block = LLVMCreateBasicBlockInContext(p->module->ctx, name);
  2840. b->appended = false;
  2841. if (append) {
  2842. b->appended = true;
  2843. LLVMAppendExistingBasicBlock(p->value, b->block);
  2844. }
  2845. b->scope = p->curr_scope;
  2846. b->scope_index = p->scope_index;
  2847. b->preds.allocator = heap_allocator();
  2848. b->succs.allocator = heap_allocator();
  2849. array_add(&p->blocks, b);
  2850. return b;
  2851. }
  2852. void lb_emit_jump(lbProcedure *p, lbBlock *target_block) {
  2853. if (p->curr_block == nullptr) {
  2854. return;
  2855. }
  2856. LLVMValueRef last_instr = LLVMGetLastInstruction(p->curr_block->block);
  2857. if (last_instr != nullptr && LLVMIsATerminatorInst(last_instr)) {
  2858. return;
  2859. }
  2860. lb_add_edge(p->curr_block, target_block);
  2861. LLVMBuildBr(p->builder, target_block->block);
  2862. p->curr_block = nullptr;
  2863. }
  2864. void lb_emit_if(lbProcedure *p, lbValue cond, lbBlock *true_block, lbBlock *false_block) {
  2865. lbBlock *b = p->curr_block;
  2866. if (b == nullptr) {
  2867. return;
  2868. }
  2869. LLVMValueRef last_instr = LLVMGetLastInstruction(p->curr_block->block);
  2870. if (last_instr != nullptr && LLVMIsATerminatorInst(last_instr)) {
  2871. return;
  2872. }
  2873. lb_add_edge(b, true_block);
  2874. lb_add_edge(b, false_block);
  2875. LLVMValueRef cv = cond.value;
  2876. cv = LLVMBuildTruncOrBitCast(p->builder, cv, lb_type(p->module, t_llvm_bool), "");
  2877. LLVMBuildCondBr(p->builder, cv, true_block->block, false_block->block);
  2878. }
  2879. lbValue lb_build_cond(lbProcedure *p, Ast *cond, lbBlock *true_block, lbBlock *false_block) {
  2880. GB_ASSERT(cond != nullptr);
  2881. GB_ASSERT(true_block != nullptr);
  2882. GB_ASSERT(false_block != nullptr);
  2883. switch (cond->kind) {
  2884. case_ast_node(pe, ParenExpr, cond);
  2885. return lb_build_cond(p, pe->expr, true_block, false_block);
  2886. case_end;
  2887. case_ast_node(ue, UnaryExpr, cond);
  2888. if (ue->op.kind == Token_Not) {
  2889. return lb_build_cond(p, ue->expr, false_block, true_block);
  2890. }
  2891. case_end;
  2892. case_ast_node(be, BinaryExpr, cond);
  2893. if (be->op.kind == Token_CmpAnd) {
  2894. lbBlock *block = lb_create_block(p, "cmp.and");
  2895. lb_build_cond(p, be->left, block, false_block);
  2896. lb_start_block(p, block);
  2897. return lb_build_cond(p, be->right, true_block, false_block);
  2898. } else if (be->op.kind == Token_CmpOr) {
  2899. lbBlock *block = lb_create_block(p, "cmp.or");
  2900. lb_build_cond(p, be->left, true_block, block);
  2901. lb_start_block(p, block);
  2902. return lb_build_cond(p, be->right, true_block, false_block);
  2903. }
  2904. case_end;
  2905. }
  2906. lbValue v = lb_build_expr(p, cond);
  2907. // v = lb_emit_conv(p, v, t_bool);
  2908. v = lb_emit_conv(p, v, t_llvm_bool);
  2909. lb_emit_if(p, v, true_block, false_block);
  2910. return v;
  2911. }
  2912. lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero_init, i32 param_index) {
  2913. GB_ASSERT(p->decl_block != p->curr_block);
  2914. LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
  2915. char const *name = "";
  2916. if (e != nullptr) {
  2917. // name = alloc_cstring(permanent_allocator(), e->token.string);
  2918. }
  2919. LLVMTypeRef llvm_type = lb_type(p->module, type);
  2920. LLVMValueRef ptr = LLVMBuildAlloca(p->builder, llvm_type, name);
  2921. // unsigned alignment = 16; // TODO(bill): Make this configurable
  2922. unsigned alignment = cast(unsigned)lb_alignof(llvm_type);
  2923. LLVMSetAlignment(ptr, alignment);
  2924. LLVMPositionBuilderAtEnd(p->builder, p->curr_block->block);
  2925. if (!zero_init) {
  2926. // If there is any padding of any kind, just zero init regardless of zero_init parameter
  2927. LLVMTypeKind kind = LLVMGetTypeKind(llvm_type);
  2928. if (kind == LLVMStructTypeKind) {
  2929. i64 sz = type_size_of(type);
  2930. if (type_size_of_struct_pretend_is_packed(type) != sz) {
  2931. zero_init = true;
  2932. }
  2933. } else if (kind == LLVMArrayTypeKind) {
  2934. zero_init = true;
  2935. }
  2936. }
  2937. if (zero_init) {
  2938. LLVMTypeKind kind = LLVMGetTypeKind(llvm_type);
  2939. switch (kind) {
  2940. case LLVMStructTypeKind:
  2941. case LLVMArrayTypeKind:
  2942. {
  2943. // NOTE(bill): Enforce zeroing through memset to make sure padding is zeroed too
  2944. LLVMTypeRef type_i8 = LLVMInt8TypeInContext(p->module->ctx);
  2945. LLVMTypeRef type_i32 = LLVMInt32TypeInContext(p->module->ctx);
  2946. i32 sz = cast(i32)type_size_of(type);
  2947. LLVMBuildMemSet(p->builder, ptr, LLVMConstNull(type_i8), LLVMConstInt(type_i32, sz, false), alignment);
  2948. }
  2949. break;
  2950. default:
  2951. LLVMBuildStore(p->builder, LLVMConstNull(lb_type(p->module, type)), ptr);
  2952. break;
  2953. }
  2954. }
  2955. lbValue val = {};
  2956. val.value = ptr;
  2957. val.type = alloc_type_pointer(type);
  2958. if (e != nullptr) {
  2959. lb_add_entity(p->module, e, val);
  2960. lb_add_debug_local_variable(p, ptr, type, e->token);
  2961. }
  2962. return lb_addr(val);
  2963. }
  2964. lbAddr lb_add_local_generated(lbProcedure *p, Type *type, bool zero_init) {
  2965. return lb_add_local(p, type, nullptr, zero_init);
  2966. }
  2967. void lb_build_nested_proc(lbProcedure *p, AstProcLit *pd, Entity *e) {
  2968. GB_ASSERT(pd->body != nullptr);
  2969. lbModule *m = p->module;
  2970. auto *min_dep_set = &m->info->minimum_dependency_set;
  2971. if (ptr_set_exists(min_dep_set, e) == false) {
  2972. // NOTE(bill): Nothing depends upon it so doesn't need to be built
  2973. return;
  2974. }
  2975. // NOTE(bill): Generate a new name
  2976. // parent.name-guid
  2977. String original_name = e->token.string;
  2978. String pd_name = original_name;
  2979. if (e->Procedure.link_name.len > 0) {
  2980. pd_name = e->Procedure.link_name;
  2981. }
  2982. isize name_len = p->name.len + 1 + pd_name.len + 1 + 10 + 1;
  2983. char *name_text = gb_alloc_array(permanent_allocator(), char, name_len);
  2984. i32 guid = cast(i32)p->children.count;
  2985. name_len = gb_snprintf(name_text, name_len, "%.*s.%.*s-%d", LIT(p->name), LIT(pd_name), guid);
  2986. String name = make_string(cast(u8 *)name_text, name_len-1);
  2987. e->Procedure.link_name = name;
  2988. lbProcedure *nested_proc = lb_create_procedure(p->module, e);
  2989. e->code_gen_procedure = nested_proc;
  2990. lbValue value = {};
  2991. value.value = nested_proc->value;
  2992. value.type = nested_proc->type;
  2993. lb_add_entity(m, e, value);
  2994. array_add(&p->children, nested_proc);
  2995. array_add(&m->procedures_to_generate, nested_proc);
  2996. }
  2997. void lb_add_foreign_library_path(lbModule *m, Entity *e) {
  2998. if (e == nullptr) {
  2999. return;
  3000. }
  3001. GB_ASSERT(e->kind == Entity_LibraryName);
  3002. GB_ASSERT(e->flags & EntityFlag_Used);
  3003. for_array(i, e->LibraryName.paths) {
  3004. String library_path = e->LibraryName.paths[i];
  3005. if (library_path.len == 0) {
  3006. continue;
  3007. }
  3008. bool ok = true;
  3009. for_array(path_index, m->foreign_library_paths) {
  3010. String path = m->foreign_library_paths[path_index];
  3011. #if defined(GB_SYSTEM_WINDOWS)
  3012. if (str_eq_ignore_case(path, library_path)) {
  3013. #else
  3014. if (str_eq(path, library_path)) {
  3015. #endif
  3016. ok = false;
  3017. break;
  3018. }
  3019. }
  3020. if (ok) {
  3021. array_add(&m->foreign_library_paths, library_path);
  3022. }
  3023. }
  3024. }
  3025. void lb_build_constant_value_decl(lbProcedure *p, AstValueDecl *vd) {
  3026. if (vd == nullptr || vd->is_mutable) {
  3027. return;
  3028. }
  3029. auto *min_dep_set = &p->module->info->minimum_dependency_set;
  3030. static i32 global_guid = 0;
  3031. for_array(i, vd->names) {
  3032. Ast *ident = vd->names[i];
  3033. GB_ASSERT(ident->kind == Ast_Ident);
  3034. Entity *e = entity_of_node(ident);
  3035. GB_ASSERT(e != nullptr);
  3036. if (e->kind != Entity_TypeName) {
  3037. continue;
  3038. }
  3039. bool polymorphic_struct = false;
  3040. if (e->type != nullptr && e->kind == Entity_TypeName) {
  3041. Type *bt = base_type(e->type);
  3042. if (bt->kind == Type_Struct) {
  3043. polymorphic_struct = bt->Struct.is_polymorphic;
  3044. }
  3045. }
  3046. if (!polymorphic_struct && !ptr_set_exists(min_dep_set, e)) {
  3047. continue;
  3048. }
  3049. if (e->TypeName.ir_mangled_name.len != 0) {
  3050. // NOTE(bill): Already set
  3051. continue;
  3052. }
  3053. lb_set_nested_type_name_ir_mangled_name(e, p);
  3054. }
  3055. for_array(i, vd->names) {
  3056. Ast *ident = vd->names[i];
  3057. GB_ASSERT(ident->kind == Ast_Ident);
  3058. Entity *e = entity_of_node(ident);
  3059. GB_ASSERT(e != nullptr);
  3060. if (e->kind != Entity_Procedure) {
  3061. continue;
  3062. }
  3063. GB_ASSERT (vd->values[i] != nullptr);
  3064. Ast *value = unparen_expr(vd->values[i]);
  3065. if (value->kind != Ast_ProcLit) {
  3066. continue; // It's an alias
  3067. }
  3068. CheckerInfo *info = p->module->info;
  3069. DeclInfo *decl = decl_info_of_entity(e);
  3070. ast_node(pl, ProcLit, decl->proc_lit);
  3071. if (pl->body != nullptr) {
  3072. auto *found = map_get(&info->gen_procs, hash_pointer(ident));
  3073. if (found) {
  3074. auto procs = *found;
  3075. for_array(i, procs) {
  3076. Entity *e = procs[i];
  3077. if (!ptr_set_exists(min_dep_set, e)) {
  3078. continue;
  3079. }
  3080. DeclInfo *d = decl_info_of_entity(e);
  3081. lb_build_nested_proc(p, &d->proc_lit->ProcLit, e);
  3082. }
  3083. } else {
  3084. lb_build_nested_proc(p, pl, e);
  3085. }
  3086. } else {
  3087. // FFI - Foreign function interace
  3088. String original_name = e->token.string;
  3089. String name = original_name;
  3090. if (e->Procedure.is_foreign) {
  3091. lb_add_foreign_library_path(p->module, e->Procedure.foreign_library);
  3092. }
  3093. if (e->Procedure.link_name.len > 0) {
  3094. name = e->Procedure.link_name;
  3095. }
  3096. lbValue *prev_value = string_map_get(&p->module->members, name);
  3097. if (prev_value != nullptr) {
  3098. // NOTE(bill): Don't do mutliple declarations in the IR
  3099. return;
  3100. }
  3101. e->Procedure.link_name = name;
  3102. lbProcedure *nested_proc = lb_create_procedure(p->module, e);
  3103. lbValue value = {};
  3104. value.value = nested_proc->value;
  3105. value.type = nested_proc->type;
  3106. array_add(&p->module->procedures_to_generate, nested_proc);
  3107. if (p != nullptr) {
  3108. array_add(&p->children, nested_proc);
  3109. } else {
  3110. string_map_set(&p->module->members, name, value);
  3111. }
  3112. }
  3113. }
  3114. }
  3115. void lb_build_stmt_list(lbProcedure *p, Slice<Ast *> const &stmts) {
  3116. for_array(i, stmts) {
  3117. Ast *stmt = stmts[i];
  3118. switch (stmt->kind) {
  3119. case_ast_node(vd, ValueDecl, stmt);
  3120. lb_build_constant_value_decl(p, vd);
  3121. case_end;
  3122. case_ast_node(fb, ForeignBlockDecl, stmt);
  3123. ast_node(block, BlockStmt, fb->body);
  3124. lb_build_stmt_list(p, block->stmts);
  3125. case_end;
  3126. }
  3127. }
  3128. for_array(i, stmts) {
  3129. lb_build_stmt(p, stmts[i]);
  3130. }
  3131. }
  3132. lbBranchBlocks lb_lookup_branch_blocks(lbProcedure *p, Ast *ident) {
  3133. GB_ASSERT(ident->kind == Ast_Ident);
  3134. Entity *e = entity_of_node(ident);
  3135. GB_ASSERT(e->kind == Entity_Label);
  3136. for_array(i, p->branch_blocks) {
  3137. lbBranchBlocks *b = &p->branch_blocks[i];
  3138. if (b->label == e->Label.node) {
  3139. return *b;
  3140. }
  3141. }
  3142. GB_PANIC("Unreachable");
  3143. lbBranchBlocks empty = {};
  3144. return empty;
  3145. }
  3146. lbTargetList *lb_push_target_list(lbProcedure *p, Ast *label, lbBlock *break_, lbBlock *continue_, lbBlock *fallthrough_) {
  3147. lbTargetList *tl = gb_alloc_item(permanent_allocator(), lbTargetList);
  3148. tl->prev = p->target_list;
  3149. tl->break_ = break_;
  3150. tl->continue_ = continue_;
  3151. tl->fallthrough_ = fallthrough_;
  3152. p->target_list = tl;
  3153. if (label != nullptr) { // Set label blocks
  3154. GB_ASSERT(label->kind == Ast_Label);
  3155. for_array(i, p->branch_blocks) {
  3156. lbBranchBlocks *b = &p->branch_blocks[i];
  3157. GB_ASSERT(b->label != nullptr && label != nullptr);
  3158. GB_ASSERT(b->label->kind == Ast_Label);
  3159. if (b->label == label) {
  3160. b->break_ = break_;
  3161. b->continue_ = continue_;
  3162. return tl;
  3163. }
  3164. }
  3165. GB_PANIC("Unreachable");
  3166. }
  3167. return tl;
  3168. }
  3169. void lb_pop_target_list(lbProcedure *p) {
  3170. p->target_list = p->target_list->prev;
  3171. }
  3172. void lb_open_scope(lbProcedure *p, Scope *s) {
  3173. lbModule *m = p->module;
  3174. if (m->debug_builder) {
  3175. LLVMMetadataRef curr_metadata = lb_get_llvm_metadata(m, s);
  3176. if (s != nullptr && s->node != nullptr && curr_metadata == nullptr) {
  3177. Token token = ast_token(s->node);
  3178. unsigned line = cast(unsigned)token.pos.line;
  3179. unsigned column = cast(unsigned)token.pos.column;
  3180. LLVMMetadataRef file = nullptr;
  3181. if (s->node->file != nullptr) {
  3182. file = lb_get_llvm_metadata(m, s->node->file);
  3183. }
  3184. LLVMMetadataRef scope = nullptr;
  3185. if (p->scope_stack.count > 0) {
  3186. scope = lb_get_llvm_metadata(m, p->scope_stack[p->scope_stack.count-1]);
  3187. }
  3188. if (scope == nullptr) {
  3189. scope = lb_get_llvm_metadata(m, p);
  3190. }
  3191. GB_ASSERT_MSG(scope != nullptr, "%.*s", LIT(p->name));
  3192. if (m->debug_builder) {
  3193. LLVMMetadataRef res = LLVMDIBuilderCreateLexicalBlock(m->debug_builder, scope,
  3194. file, line, column
  3195. );
  3196. lb_set_llvm_metadata(m, s, res);
  3197. }
  3198. }
  3199. }
  3200. p->scope_index += 1;
  3201. array_add(&p->scope_stack, s);
  3202. }
  3203. void lb_close_scope(lbProcedure *p, lbDeferExitKind kind, lbBlock *block, bool pop_stack=true) {
  3204. lb_emit_defer_stmts(p, kind, block);
  3205. GB_ASSERT(p->scope_index > 0);
  3206. // NOTE(bill): Remove `context`s made in that scope
  3207. while (p->context_stack.count > 0) {
  3208. lbContextData *ctx = &p->context_stack[p->context_stack.count-1];
  3209. if (ctx->scope_index >= p->scope_index) {
  3210. array_pop(&p->context_stack);
  3211. } else {
  3212. break;
  3213. }
  3214. }
  3215. p->scope_index -= 1;
  3216. array_pop(&p->scope_stack);
  3217. }
  3218. void lb_build_when_stmt(lbProcedure *p, AstWhenStmt *ws) {
  3219. TypeAndValue tv = type_and_value_of_expr(ws->cond);
  3220. GB_ASSERT(is_type_boolean(tv.type));
  3221. GB_ASSERT(tv.value.kind == ExactValue_Bool);
  3222. if (tv.value.value_bool) {
  3223. lb_build_stmt_list(p, ws->body->BlockStmt.stmts);
  3224. } else if (ws->else_stmt) {
  3225. switch (ws->else_stmt->kind) {
  3226. case Ast_BlockStmt:
  3227. lb_build_stmt_list(p, ws->else_stmt->BlockStmt.stmts);
  3228. break;
  3229. case Ast_WhenStmt:
  3230. lb_build_when_stmt(p, &ws->else_stmt->WhenStmt);
  3231. break;
  3232. default:
  3233. GB_PANIC("Invalid 'else' statement in 'when' statement");
  3234. break;
  3235. }
  3236. }
  3237. }
  3238. void lb_build_range_indexed(lbProcedure *p, lbValue expr, Type *val_type, lbValue count_ptr,
  3239. lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
  3240. lbModule *m = p->module;
  3241. lbValue count = {};
  3242. Type *expr_type = base_type(type_deref(expr.type));
  3243. switch (expr_type->kind) {
  3244. case Type_Array:
  3245. count = lb_const_int(m, t_int, expr_type->Array.count);
  3246. break;
  3247. }
  3248. lbValue val = {};
  3249. lbValue idx = {};
  3250. lbBlock *loop = nullptr;
  3251. lbBlock *done = nullptr;
  3252. lbBlock *body = nullptr;
  3253. lbAddr index = lb_add_local_generated(p, t_int, false);
  3254. lb_addr_store(p, index, lb_const_int(m, t_int, cast(u64)-1));
  3255. loop = lb_create_block(p, "for.index.loop");
  3256. lb_emit_jump(p, loop);
  3257. lb_start_block(p, loop);
  3258. lbValue incr = lb_emit_arith(p, Token_Add, lb_addr_load(p, index), lb_const_int(m, t_int, 1), t_int);
  3259. lb_addr_store(p, index, incr);
  3260. body = lb_create_block(p, "for.index.body");
  3261. done = lb_create_block(p, "for.index.done");
  3262. if (count.value == nullptr) {
  3263. GB_ASSERT(count_ptr.value != nullptr);
  3264. count = lb_emit_load(p, count_ptr);
  3265. }
  3266. lbValue cond = lb_emit_comp(p, Token_Lt, incr, count);
  3267. lb_emit_if(p, cond, body, done);
  3268. lb_start_block(p, body);
  3269. idx = lb_addr_load(p, index);
  3270. switch (expr_type->kind) {
  3271. case Type_Array: {
  3272. if (val_type != nullptr) {
  3273. val = lb_emit_load(p, lb_emit_array_ep(p, expr, idx));
  3274. }
  3275. break;
  3276. }
  3277. case Type_EnumeratedArray: {
  3278. if (val_type != nullptr) {
  3279. val = lb_emit_load(p, lb_emit_array_ep(p, expr, idx));
  3280. // NOTE(bill): Override the idx value for the enumeration
  3281. Type *index_type = expr_type->EnumeratedArray.index;
  3282. if (compare_exact_values(Token_NotEq, expr_type->EnumeratedArray.min_value, exact_value_u64(0))) {
  3283. idx = lb_emit_arith(p, Token_Add, idx, lb_const_value(m, index_type, expr_type->EnumeratedArray.min_value), index_type);
  3284. }
  3285. }
  3286. break;
  3287. }
  3288. case Type_Slice: {
  3289. if (val_type != nullptr) {
  3290. lbValue elem = lb_slice_elem(p, expr);
  3291. val = lb_emit_load(p, lb_emit_ptr_offset(p, elem, idx));
  3292. }
  3293. break;
  3294. }
  3295. case Type_DynamicArray: {
  3296. if (val_type != nullptr) {
  3297. lbValue elem = lb_emit_struct_ep(p, expr, 0);
  3298. elem = lb_emit_load(p, elem);
  3299. val = lb_emit_load(p, lb_emit_ptr_offset(p, elem, idx));
  3300. }
  3301. break;
  3302. }
  3303. case Type_Map: {
  3304. lbValue entries = lb_map_entries_ptr(p, expr);
  3305. lbValue elem = lb_emit_struct_ep(p, entries, 0);
  3306. elem = lb_emit_load(p, elem);
  3307. lbValue entry = lb_emit_ptr_offset(p, elem, idx);
  3308. idx = lb_emit_load(p, lb_emit_struct_ep(p, entry, 2));
  3309. val = lb_emit_load(p, lb_emit_struct_ep(p, entry, 3));
  3310. break;
  3311. }
  3312. case Type_Struct: {
  3313. GB_ASSERT(is_type_soa_struct(expr_type));
  3314. break;
  3315. }
  3316. default:
  3317. GB_PANIC("Cannot do range_indexed of %s", type_to_string(expr_type));
  3318. break;
  3319. }
  3320. if (val_) *val_ = val;
  3321. if (idx_) *idx_ = idx;
  3322. if (loop_) *loop_ = loop;
  3323. if (done_) *done_ = done;
  3324. }
  3325. void lb_build_range_string(lbProcedure *p, lbValue expr, Type *val_type,
  3326. lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
  3327. lbModule *m = p->module;
  3328. lbValue count = lb_const_int(m, t_int, 0);
  3329. Type *expr_type = base_type(expr.type);
  3330. switch (expr_type->kind) {
  3331. case Type_Basic:
  3332. count = lb_string_len(p, expr);
  3333. break;
  3334. default:
  3335. GB_PANIC("Cannot do range_string of %s", type_to_string(expr_type));
  3336. break;
  3337. }
  3338. lbValue val = {};
  3339. lbValue idx = {};
  3340. lbBlock *loop = nullptr;
  3341. lbBlock *done = nullptr;
  3342. lbBlock *body = nullptr;
  3343. lbAddr offset_ = lb_add_local_generated(p, t_int, false);
  3344. lb_addr_store(p, offset_, lb_const_int(m, t_int, 0));
  3345. loop = lb_create_block(p, "for.string.loop");
  3346. lb_emit_jump(p, loop);
  3347. lb_start_block(p, loop);
  3348. body = lb_create_block(p, "for.string.body");
  3349. done = lb_create_block(p, "for.string.done");
  3350. lbValue offset = lb_addr_load(p, offset_);
  3351. lbValue cond = lb_emit_comp(p, Token_Lt, offset, count);
  3352. lb_emit_if(p, cond, body, done);
  3353. lb_start_block(p, body);
  3354. lbValue str_elem = lb_emit_ptr_offset(p, lb_string_elem(p, expr), offset);
  3355. lbValue str_len = lb_emit_arith(p, Token_Sub, count, offset, t_int);
  3356. auto args = array_make<lbValue>(permanent_allocator(), 1);
  3357. args[0] = lb_emit_string(p, str_elem, str_len);
  3358. lbValue rune_and_len = lb_emit_runtime_call(p, "string_decode_rune", args);
  3359. lbValue len = lb_emit_struct_ev(p, rune_and_len, 1);
  3360. lb_addr_store(p, offset_, lb_emit_arith(p, Token_Add, offset, len, t_int));
  3361. idx = offset;
  3362. if (val_type != nullptr) {
  3363. val = lb_emit_struct_ev(p, rune_and_len, 0);
  3364. }
  3365. if (val_) *val_ = val;
  3366. if (idx_) *idx_ = idx;
  3367. if (loop_) *loop_ = loop;
  3368. if (done_) *done_ = done;
  3369. }
  3370. void lb_build_range_interval(lbProcedure *p, AstBinaryExpr *node,
  3371. AstRangeStmt *rs, Scope *scope) {
  3372. bool ADD_EXTRA_WRAPPING_CHECK = true;
  3373. lbModule *m = p->module;
  3374. lb_open_scope(p, scope);
  3375. Type *val0_type = nullptr;
  3376. Type *val1_type = nullptr;
  3377. if (rs->vals.count > 0 && rs->vals[0] != nullptr && !is_blank_ident(rs->vals[0])) {
  3378. val0_type = type_of_expr(rs->vals[0]);
  3379. }
  3380. if (rs->vals.count > 1 && rs->vals[1] != nullptr && !is_blank_ident(rs->vals[1])) {
  3381. val1_type = type_of_expr(rs->vals[1]);
  3382. }
  3383. if (val0_type != nullptr) {
  3384. Entity *e = entity_of_node(rs->vals[0]);
  3385. lb_add_local(p, e->type, e, true);
  3386. }
  3387. if (val1_type != nullptr) {
  3388. Entity *e = entity_of_node(rs->vals[1]);
  3389. lb_add_local(p, e->type, e, true);
  3390. }
  3391. TokenKind op = Token_Lt;
  3392. switch (node->op.kind) {
  3393. case Token_Ellipsis: op = Token_LtEq; break;
  3394. case Token_RangeFull: op = Token_LtEq; break;
  3395. case Token_RangeHalf: op = Token_Lt; break;
  3396. default: GB_PANIC("Invalid interval operator"); break;
  3397. }
  3398. lbValue lower = lb_build_expr(p, node->left);
  3399. lbValue upper = {}; // initialized each time in the loop
  3400. lbAddr value = lb_add_local_generated(p, val0_type ? val0_type : lower.type, false);
  3401. lb_addr_store(p, value, lower);
  3402. lbAddr index = lb_add_local_generated(p, t_int, false);
  3403. lb_addr_store(p, index, lb_const_int(m, t_int, 0));
  3404. lbBlock *loop = lb_create_block(p, "for.interval.loop");
  3405. lbBlock *body = lb_create_block(p, "for.interval.body");
  3406. lbBlock *done = lb_create_block(p, "for.interval.done");
  3407. lb_emit_jump(p, loop);
  3408. lb_start_block(p, loop);
  3409. upper = lb_build_expr(p, node->right);
  3410. lbValue curr_value = lb_addr_load(p, value);
  3411. lbValue cond = lb_emit_comp(p, op, curr_value, upper);
  3412. lb_emit_if(p, cond, body, done);
  3413. lb_start_block(p, body);
  3414. lbValue val = lb_addr_load(p, value);
  3415. lbValue idx = lb_addr_load(p, index);
  3416. if (val0_type) lb_store_range_stmt_val(p, rs->vals[0], val);
  3417. if (val1_type) lb_store_range_stmt_val(p, rs->vals[1], idx);
  3418. {
  3419. // NOTE: this check block will most likely be optimized out, and is here
  3420. // to make this code easier to read
  3421. lbBlock *check = nullptr;
  3422. lbBlock *post = lb_create_block(p, "for.interval.post");
  3423. lbBlock *continue_block = post;
  3424. if (ADD_EXTRA_WRAPPING_CHECK &&
  3425. op == Token_LtEq) {
  3426. check = lb_create_block(p, "for.interval.check");
  3427. continue_block = check;
  3428. }
  3429. lb_push_target_list(p, rs->label, done, continue_block, nullptr);
  3430. lb_build_stmt(p, rs->body);
  3431. lb_close_scope(p, lbDeferExit_Default, nullptr);
  3432. lb_pop_target_list(p);
  3433. if (check != nullptr) {
  3434. lb_emit_jump(p, check);
  3435. lb_start_block(p, check);
  3436. lbValue check_cond = lb_emit_comp(p, Token_NotEq, curr_value, upper);
  3437. lb_emit_if(p, check_cond, post, done);
  3438. } else {
  3439. lb_emit_jump(p, post);
  3440. }
  3441. lb_start_block(p, post);
  3442. lb_emit_increment(p, value.addr);
  3443. lb_emit_increment(p, index.addr);
  3444. lb_emit_jump(p, loop);
  3445. }
  3446. lb_start_block(p, done);
  3447. }
  3448. void lb_build_range_enum(lbProcedure *p, Type *enum_type, Type *val_type, lbValue *val_, lbValue *idx_, lbBlock **loop_, lbBlock **done_) {
  3449. lbModule *m = p->module;
  3450. Type *t = enum_type;
  3451. GB_ASSERT(is_type_enum(t));
  3452. Type *enum_ptr = alloc_type_pointer(t);
  3453. t = base_type(t);
  3454. Type *core_elem = core_type(t);
  3455. GB_ASSERT(t->kind == Type_Enum);
  3456. i64 enum_count = t->Enum.fields.count;
  3457. lbValue max_count = lb_const_int(m, t_int, enum_count);
  3458. lbValue ti = lb_type_info(m, t);
  3459. lbValue variant = lb_emit_struct_ep(p, ti, 4);
  3460. lbValue eti_ptr = lb_emit_conv(p, variant, t_type_info_enum_ptr);
  3461. lbValue values = lb_emit_load(p, lb_emit_struct_ep(p, eti_ptr, 2));
  3462. lbValue values_data = lb_slice_elem(p, values);
  3463. lbAddr offset_ = lb_add_local_generated(p, t_int, false);
  3464. lb_addr_store(p, offset_, lb_const_int(m, t_int, 0));
  3465. lbBlock *loop = lb_create_block(p, "for.enum.loop");
  3466. lb_emit_jump(p, loop);
  3467. lb_start_block(p, loop);
  3468. lbBlock *body = lb_create_block(p, "for.enum.body");
  3469. lbBlock *done = lb_create_block(p, "for.enum.done");
  3470. lbValue offset = lb_addr_load(p, offset_);
  3471. lbValue cond = lb_emit_comp(p, Token_Lt, offset, max_count);
  3472. lb_emit_if(p, cond, body, done);
  3473. lb_start_block(p, body);
  3474. lbValue val_ptr = lb_emit_ptr_offset(p, values_data, offset);
  3475. lb_emit_increment(p, offset_.addr);
  3476. lbValue val = {};
  3477. if (val_type != nullptr) {
  3478. GB_ASSERT(are_types_identical(enum_type, val_type));
  3479. if (is_type_integer(core_elem)) {
  3480. lbValue i = lb_emit_load(p, lb_emit_conv(p, val_ptr, t_i64_ptr));
  3481. val = lb_emit_conv(p, i, t);
  3482. } else {
  3483. GB_PANIC("TODO(bill): enum core type %s", type_to_string(core_elem));
  3484. }
  3485. }
  3486. if (val_) *val_ = val;
  3487. if (idx_) *idx_ = offset;
  3488. if (loop_) *loop_ = loop;
  3489. if (done_) *done_ = done;
  3490. }
  3491. void lb_build_range_tuple(lbProcedure *p, Ast *expr, Type *val0_type, Type *val1_type,
  3492. lbValue *val0_, lbValue *val1_, lbBlock **loop_, lbBlock **done_) {
  3493. lbBlock *loop = lb_create_block(p, "for.tuple.loop");
  3494. lb_emit_jump(p, loop);
  3495. lb_start_block(p, loop);
  3496. lbBlock *body = lb_create_block(p, "for.tuple.body");
  3497. lbBlock *done = lb_create_block(p, "for.tuple.done");
  3498. lbValue tuple_value = lb_build_expr(p, expr);
  3499. Type *tuple = tuple_value.type;
  3500. GB_ASSERT(tuple->kind == Type_Tuple);
  3501. i32 tuple_count = cast(i32)tuple->Tuple.variables.count;
  3502. i32 cond_index = tuple_count-1;
  3503. lbValue cond = lb_emit_struct_ev(p, tuple_value, cond_index);
  3504. lb_emit_if(p, cond, body, done);
  3505. lb_start_block(p, body);
  3506. if (val0_) *val0_ = lb_emit_struct_ev(p, tuple_value, 0);
  3507. if (val1_) *val1_ = lb_emit_struct_ev(p, tuple_value, 1);
  3508. if (loop_) *loop_ = loop;
  3509. if (done_) *done_ = done;
  3510. }
  3511. void lb_build_range_stmt_struct_soa(lbProcedure *p, AstRangeStmt *rs, Scope *scope) {
  3512. Ast *expr = unparen_expr(rs->expr);
  3513. TypeAndValue tav = type_and_value_of_expr(expr);
  3514. lbBlock *loop = nullptr;
  3515. lbBlock *body = nullptr;
  3516. lbBlock *done = nullptr;
  3517. lb_open_scope(p, scope);
  3518. Type *val_types[2] = {};
  3519. if (rs->vals.count > 0 && rs->vals[0] != nullptr && !is_blank_ident(rs->vals[0])) {
  3520. val_types[0] = type_of_expr(rs->vals[0]);
  3521. }
  3522. if (rs->vals.count > 1 && rs->vals[1] != nullptr && !is_blank_ident(rs->vals[1])) {
  3523. val_types[1] = type_of_expr(rs->vals[1]);
  3524. }
  3525. lbAddr array = lb_build_addr(p, expr);
  3526. if (is_type_pointer(type_deref(lb_addr_type(array)))) {
  3527. array = lb_addr(lb_addr_load(p, array));
  3528. }
  3529. lbValue count = lb_soa_struct_len(p, lb_addr_load(p, array));
  3530. lbAddr index = lb_add_local_generated(p, t_int, false);
  3531. lb_addr_store(p, index, lb_const_int(p->module, t_int, cast(u64)-1));
  3532. loop = lb_create_block(p, "for.soa.loop");
  3533. lb_emit_jump(p, loop);
  3534. lb_start_block(p, loop);
  3535. lbValue incr = lb_emit_arith(p, Token_Add, lb_addr_load(p, index), lb_const_int(p->module, t_int, 1), t_int);
  3536. lb_addr_store(p, index, incr);
  3537. body = lb_create_block(p, "for.soa.body");
  3538. done = lb_create_block(p, "for.soa.done");
  3539. lbValue cond = lb_emit_comp(p, Token_Lt, incr, count);
  3540. lb_emit_if(p, cond, body, done);
  3541. lb_start_block(p, body);
  3542. if (val_types[0]) {
  3543. Entity *e = entity_of_node(rs->vals[0]);
  3544. if (e != nullptr) {
  3545. lbAddr soa_val = lb_addr_soa_variable(array.addr, lb_addr_load(p, index), nullptr);
  3546. map_set(&p->module->soa_values, hash_entity(e), soa_val);
  3547. }
  3548. }
  3549. if (val_types[1]) {
  3550. lb_store_range_stmt_val(p, rs->vals[1], lb_addr_load(p, index));
  3551. }
  3552. lb_push_target_list(p, rs->label, done, loop, nullptr);
  3553. lb_build_stmt(p, rs->body);
  3554. lb_close_scope(p, lbDeferExit_Default, nullptr);
  3555. lb_pop_target_list(p);
  3556. lb_emit_jump(p, loop);
  3557. lb_start_block(p, done);
  3558. }
  3559. void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *scope) {
  3560. Ast *expr = unparen_expr(rs->expr);
  3561. if (is_ast_range(expr)) {
  3562. lb_build_range_interval(p, &expr->BinaryExpr, rs, scope);
  3563. return;
  3564. }
  3565. Type *expr_type = type_of_expr(expr);
  3566. if (expr_type != nullptr) {
  3567. Type *et = base_type(type_deref(expr_type));
  3568. if (is_type_soa_struct(et)) {
  3569. lb_build_range_stmt_struct_soa(p, rs, scope);
  3570. return;
  3571. }
  3572. }
  3573. lb_open_scope(p, scope);
  3574. Type *val0_type = nullptr;
  3575. Type *val1_type = nullptr;
  3576. if (rs->vals.count > 0 && rs->vals[0] != nullptr && !is_blank_ident(rs->vals[0])) {
  3577. val0_type = type_of_expr(rs->vals[0]);
  3578. }
  3579. if (rs->vals.count > 1 && rs->vals[1] != nullptr && !is_blank_ident(rs->vals[1])) {
  3580. val1_type = type_of_expr(rs->vals[1]);
  3581. }
  3582. if (val0_type != nullptr) {
  3583. Entity *e = entity_of_node(rs->vals[0]);
  3584. lb_add_local(p, e->type, e, true);
  3585. }
  3586. if (val1_type != nullptr) {
  3587. Entity *e = entity_of_node(rs->vals[1]);
  3588. lb_add_local(p, e->type, e, true);
  3589. }
  3590. lbValue val = {};
  3591. lbValue key = {};
  3592. lbBlock *loop = nullptr;
  3593. lbBlock *done = nullptr;
  3594. bool is_map = false;
  3595. TypeAndValue tav = type_and_value_of_expr(expr);
  3596. if (tav.mode == Addressing_Type) {
  3597. lb_build_range_enum(p, type_deref(tav.type), val0_type, &val, &key, &loop, &done);
  3598. } else {
  3599. Type *expr_type = type_of_expr(expr);
  3600. Type *et = base_type(type_deref(expr_type));
  3601. switch (et->kind) {
  3602. case Type_Map: {
  3603. is_map = true;
  3604. lbValue map = lb_build_addr_ptr(p, expr);
  3605. if (is_type_pointer(type_deref(map.type))) {
  3606. map = lb_emit_load(p, map);
  3607. }
  3608. lbValue entries_ptr = lb_map_entries_ptr(p, map);
  3609. lbValue count_ptr = lb_emit_struct_ep(p, entries_ptr, 1);
  3610. lb_build_range_indexed(p, map, val1_type, count_ptr, &val, &key, &loop, &done);
  3611. break;
  3612. }
  3613. case Type_Array: {
  3614. lbValue array = lb_build_addr_ptr(p, expr);
  3615. if (is_type_pointer(type_deref(array.type))) {
  3616. array = lb_emit_load(p, array);
  3617. }
  3618. lbAddr count_ptr = lb_add_local_generated(p, t_int, false);
  3619. lb_addr_store(p, count_ptr, lb_const_int(p->module, t_int, et->Array.count));
  3620. lb_build_range_indexed(p, array, val0_type, count_ptr.addr, &val, &key, &loop, &done);
  3621. break;
  3622. }
  3623. case Type_EnumeratedArray: {
  3624. lbValue array = lb_build_addr_ptr(p, expr);
  3625. if (is_type_pointer(type_deref(array.type))) {
  3626. array = lb_emit_load(p, array);
  3627. }
  3628. lbAddr count_ptr = lb_add_local_generated(p, t_int, false);
  3629. lb_addr_store(p, count_ptr, lb_const_int(p->module, t_int, et->EnumeratedArray.count));
  3630. lb_build_range_indexed(p, array, val0_type, count_ptr.addr, &val, &key, &loop, &done);
  3631. break;
  3632. }
  3633. case Type_DynamicArray: {
  3634. lbValue count_ptr = {};
  3635. lbValue array = lb_build_addr_ptr(p, expr);
  3636. if (is_type_pointer(type_deref(array.type))) {
  3637. array = lb_emit_load(p, array);
  3638. }
  3639. count_ptr = lb_emit_struct_ep(p, array, 1);
  3640. lb_build_range_indexed(p, array, val0_type, count_ptr, &val, &key, &loop, &done);
  3641. break;
  3642. }
  3643. case Type_Slice: {
  3644. lbValue count_ptr = {};
  3645. lbValue slice = lb_build_expr(p, expr);
  3646. if (is_type_pointer(slice.type)) {
  3647. count_ptr = lb_emit_struct_ep(p, slice, 1);
  3648. slice = lb_emit_load(p, slice);
  3649. } else {
  3650. count_ptr = lb_add_local_generated(p, t_int, false).addr;
  3651. lb_emit_store(p, count_ptr, lb_slice_len(p, slice));
  3652. }
  3653. lb_build_range_indexed(p, slice, val0_type, count_ptr, &val, &key, &loop, &done);
  3654. break;
  3655. }
  3656. case Type_Basic: {
  3657. lbValue string = lb_build_expr(p, expr);
  3658. if (is_type_pointer(string.type)) {
  3659. string = lb_emit_load(p, string);
  3660. }
  3661. if (is_type_untyped(expr_type)) {
  3662. lbAddr s = lb_add_local_generated(p, default_type(string.type), false);
  3663. lb_addr_store(p, s, string);
  3664. string = lb_addr_load(p, s);
  3665. }
  3666. Type *t = base_type(string.type);
  3667. GB_ASSERT(!is_type_cstring(t));
  3668. lb_build_range_string(p, string, val0_type, &val, &key, &loop, &done);
  3669. break;
  3670. }
  3671. case Type_Tuple:
  3672. lb_build_range_tuple(p, expr, val0_type, val1_type, &val, &key, &loop, &done);
  3673. break;
  3674. default:
  3675. GB_PANIC("Cannot range over %s", type_to_string(expr_type));
  3676. break;
  3677. }
  3678. }
  3679. if (is_map) {
  3680. if (val0_type) lb_store_range_stmt_val(p, rs->vals[0], key);
  3681. if (val1_type) lb_store_range_stmt_val(p, rs->vals[1], val);
  3682. } else {
  3683. if (val0_type) lb_store_range_stmt_val(p, rs->vals[0], val);
  3684. if (val1_type) lb_store_range_stmt_val(p, rs->vals[1], key);
  3685. }
  3686. lb_push_target_list(p, rs->label, done, loop, nullptr);
  3687. lb_build_stmt(p, rs->body);
  3688. lb_close_scope(p, lbDeferExit_Default, nullptr);
  3689. lb_pop_target_list(p);
  3690. lb_emit_jump(p, loop);
  3691. lb_start_block(p, done);
  3692. }
  3693. void lb_build_inline_range_stmt(lbProcedure *p, AstUnrollRangeStmt *rs, Scope *scope) {
  3694. lbModule *m = p->module;
  3695. lb_open_scope(p, scope); // Open scope here
  3696. Type *val0_type = nullptr;
  3697. Type *val1_type = nullptr;
  3698. if (rs->val0 != nullptr && !is_blank_ident(rs->val0)) {
  3699. val0_type = type_of_expr(rs->val0);
  3700. }
  3701. if (rs->val1 != nullptr && !is_blank_ident(rs->val1)) {
  3702. val1_type = type_of_expr(rs->val1);
  3703. }
  3704. if (val0_type != nullptr) {
  3705. Entity *e = entity_of_node(rs->val0);
  3706. lb_add_local(p, e->type, e, true);
  3707. }
  3708. if (val1_type != nullptr) {
  3709. Entity *e = entity_of_node(rs->val1);
  3710. lb_add_local(p, e->type, e, true);
  3711. }
  3712. lbValue val = {};
  3713. lbValue key = {};
  3714. lbBlock *loop = nullptr;
  3715. lbBlock *done = nullptr;
  3716. Ast *expr = unparen_expr(rs->expr);
  3717. TypeAndValue tav = type_and_value_of_expr(expr);
  3718. if (is_ast_range(expr)) {
  3719. lbAddr val0_addr = {};
  3720. lbAddr val1_addr = {};
  3721. if (val0_type) val0_addr = lb_build_addr(p, rs->val0);
  3722. if (val1_type) val1_addr = lb_build_addr(p, rs->val1);
  3723. TokenKind op = expr->BinaryExpr.op.kind;
  3724. Ast *start_expr = expr->BinaryExpr.left;
  3725. Ast *end_expr = expr->BinaryExpr.right;
  3726. GB_ASSERT(start_expr->tav.mode == Addressing_Constant);
  3727. GB_ASSERT(end_expr->tav.mode == Addressing_Constant);
  3728. ExactValue start = start_expr->tav.value;
  3729. ExactValue end = end_expr->tav.value;
  3730. if (op != Token_RangeHalf) { // .. [start, end] (or ..=)
  3731. ExactValue index = exact_value_i64(0);
  3732. for (ExactValue val = start;
  3733. compare_exact_values(Token_LtEq, val, end);
  3734. val = exact_value_increment_one(val), index = exact_value_increment_one(index)) {
  3735. if (val0_type) lb_addr_store(p, val0_addr, lb_const_value(m, val0_type, val));
  3736. if (val1_type) lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, index));
  3737. lb_build_stmt(p, rs->body);
  3738. }
  3739. } else { // ..< [start, end)
  3740. ExactValue index = exact_value_i64(0);
  3741. for (ExactValue val = start;
  3742. compare_exact_values(Token_Lt, val, end);
  3743. val = exact_value_increment_one(val), index = exact_value_increment_one(index)) {
  3744. if (val0_type) lb_addr_store(p, val0_addr, lb_const_value(m, val0_type, val));
  3745. if (val1_type) lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, index));
  3746. lb_build_stmt(p, rs->body);
  3747. }
  3748. }
  3749. } else if (tav.mode == Addressing_Type) {
  3750. GB_ASSERT(is_type_enum(type_deref(tav.type)));
  3751. Type *et = type_deref(tav.type);
  3752. Type *bet = base_type(et);
  3753. lbAddr val0_addr = {};
  3754. lbAddr val1_addr = {};
  3755. if (val0_type) val0_addr = lb_build_addr(p, rs->val0);
  3756. if (val1_type) val1_addr = lb_build_addr(p, rs->val1);
  3757. for_array(i, bet->Enum.fields) {
  3758. Entity *field = bet->Enum.fields[i];
  3759. GB_ASSERT(field->kind == Entity_Constant);
  3760. if (val0_type) lb_addr_store(p, val0_addr, lb_const_value(m, val0_type, field->Constant.value));
  3761. if (val1_type) lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, exact_value_i64(i)));
  3762. lb_build_stmt(p, rs->body);
  3763. }
  3764. } else {
  3765. lbAddr val0_addr = {};
  3766. lbAddr val1_addr = {};
  3767. if (val0_type) val0_addr = lb_build_addr(p, rs->val0);
  3768. if (val1_type) val1_addr = lb_build_addr(p, rs->val1);
  3769. GB_ASSERT(expr->tav.mode == Addressing_Constant);
  3770. Type *t = base_type(expr->tav.type);
  3771. switch (t->kind) {
  3772. case Type_Basic:
  3773. GB_ASSERT(is_type_string(t));
  3774. {
  3775. ExactValue value = expr->tav.value;
  3776. GB_ASSERT(value.kind == ExactValue_String);
  3777. String str = value.value_string;
  3778. Rune codepoint = 0;
  3779. isize offset = 0;
  3780. do {
  3781. isize width = gb_utf8_decode(str.text+offset, str.len-offset, &codepoint);
  3782. if (val0_type) lb_addr_store(p, val0_addr, lb_const_value(m, val0_type, exact_value_i64(codepoint)));
  3783. if (val1_type) lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, exact_value_i64(offset)));
  3784. lb_build_stmt(p, rs->body);
  3785. offset += width;
  3786. } while (offset < str.len);
  3787. }
  3788. break;
  3789. case Type_Array:
  3790. if (t->Array.count > 0) {
  3791. lbValue val = lb_build_expr(p, expr);
  3792. lbValue val_addr = lb_address_from_load_or_generate_local(p, val);
  3793. for (i64 i = 0; i < t->Array.count; i++) {
  3794. if (val0_type) {
  3795. // NOTE(bill): Due to weird legacy issues in LLVM, this needs to be an i32
  3796. lbValue elem = lb_emit_array_epi(p, val_addr, cast(i32)i);
  3797. lb_addr_store(p, val0_addr, lb_emit_load(p, elem));
  3798. }
  3799. if (val1_type) lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, exact_value_i64(i)));
  3800. lb_build_stmt(p, rs->body);
  3801. }
  3802. }
  3803. break;
  3804. case Type_EnumeratedArray:
  3805. if (t->EnumeratedArray.count > 0) {
  3806. lbValue val = lb_build_expr(p, expr);
  3807. lbValue val_addr = lb_address_from_load_or_generate_local(p, val);
  3808. for (i64 i = 0; i < t->EnumeratedArray.count; i++) {
  3809. if (val0_type) {
  3810. // NOTE(bill): Due to weird legacy issues in LLVM, this needs to be an i32
  3811. lbValue elem = lb_emit_array_epi(p, val_addr, cast(i32)i);
  3812. lb_addr_store(p, val0_addr, lb_emit_load(p, elem));
  3813. }
  3814. if (val1_type) {
  3815. ExactValue idx = exact_value_add(exact_value_i64(i), t->EnumeratedArray.min_value);
  3816. lb_addr_store(p, val1_addr, lb_const_value(m, val1_type, idx));
  3817. }
  3818. lb_build_stmt(p, rs->body);
  3819. }
  3820. }
  3821. break;
  3822. default:
  3823. GB_PANIC("Invalid '#unroll for' type");
  3824. break;
  3825. }
  3826. }
  3827. lb_close_scope(p, lbDeferExit_Default, nullptr);
  3828. }
  3829. void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope *scope) {
  3830. lb_open_scope(p, scope);
  3831. if (ss->init != nullptr) {
  3832. lb_build_stmt(p, ss->init);
  3833. }
  3834. lbValue tag = lb_const_bool(p->module, t_llvm_bool, true);
  3835. if (ss->tag != nullptr) {
  3836. tag = lb_build_expr(p, ss->tag);
  3837. }
  3838. lbBlock *done = lb_create_block(p, "switch.done"); // NOTE(bill): Append later
  3839. ast_node(body, BlockStmt, ss->body);
  3840. Slice<Ast *> default_stmts = {};
  3841. lbBlock *default_fall = nullptr;
  3842. lbBlock *default_block = nullptr;
  3843. lbBlock *fall = nullptr;
  3844. isize case_count = body->stmts.count;
  3845. for_array(i, body->stmts) {
  3846. Ast *clause = body->stmts[i];
  3847. ast_node(cc, CaseClause, clause);
  3848. lbBlock *body = fall;
  3849. if (body == nullptr) {
  3850. body = lb_create_block(p, "switch.case.body");
  3851. }
  3852. fall = done;
  3853. if (i+1 < case_count) {
  3854. fall = lb_create_block(p, "switch.fall.body");
  3855. }
  3856. if (cc->list.count == 0) {
  3857. // default case
  3858. default_stmts = cc->stmts;
  3859. default_fall = fall;
  3860. default_block = body;
  3861. continue;
  3862. }
  3863. lbBlock *next_cond = nullptr;
  3864. for_array(j, cc->list) {
  3865. Ast *expr = unparen_expr(cc->list[j]);
  3866. next_cond = lb_create_block(p, "switch.case.next");
  3867. lbValue cond = lb_const_bool(p->module, t_llvm_bool, false);
  3868. if (is_ast_range(expr)) {
  3869. ast_node(ie, BinaryExpr, expr);
  3870. TokenKind op = Token_Invalid;
  3871. switch (ie->op.kind) {
  3872. case Token_Ellipsis: op = Token_LtEq; break;
  3873. case Token_RangeFull: op = Token_LtEq; break;
  3874. case Token_RangeHalf: op = Token_Lt; break;
  3875. default: GB_PANIC("Invalid interval operator"); break;
  3876. }
  3877. lbValue lhs = lb_build_expr(p, ie->left);
  3878. lbValue rhs = lb_build_expr(p, ie->right);
  3879. // TODO(bill): do short circuit here
  3880. lbValue cond_lhs = lb_emit_comp(p, Token_LtEq, lhs, tag);
  3881. lbValue cond_rhs = lb_emit_comp(p, op, tag, rhs);
  3882. cond = lb_emit_arith(p, Token_And, cond_lhs, cond_rhs, t_bool);
  3883. } else {
  3884. if (expr->tav.mode == Addressing_Type) {
  3885. GB_ASSERT(is_type_typeid(tag.type));
  3886. lbValue e = lb_typeid(p->module, expr->tav.type);
  3887. e = lb_emit_conv(p, e, tag.type);
  3888. cond = lb_emit_comp(p, Token_CmpEq, tag, e);
  3889. } else {
  3890. cond = lb_emit_comp(p, Token_CmpEq, tag, lb_build_expr(p, expr));
  3891. }
  3892. }
  3893. lb_emit_if(p, cond, body, next_cond);
  3894. lb_start_block(p, next_cond);
  3895. }
  3896. lb_start_block(p, body);
  3897. lb_push_target_list(p, ss->label, done, nullptr, fall);
  3898. lb_open_scope(p, body->scope);
  3899. lb_build_stmt_list(p, cc->stmts);
  3900. lb_close_scope(p, lbDeferExit_Default, body);
  3901. lb_pop_target_list(p);
  3902. lb_emit_jump(p, done);
  3903. lb_start_block(p, next_cond);
  3904. }
  3905. if (default_block != nullptr) {
  3906. lb_emit_jump(p, default_block);
  3907. lb_start_block(p, default_block);
  3908. lb_push_target_list(p, ss->label, done, nullptr, default_fall);
  3909. lb_open_scope(p, default_block->scope);
  3910. lb_build_stmt_list(p, default_stmts);
  3911. lb_close_scope(p, lbDeferExit_Default, default_block);
  3912. lb_pop_target_list(p);
  3913. }
  3914. lb_emit_jump(p, done);
  3915. lb_close_scope(p, lbDeferExit_Default, done);
  3916. lb_start_block(p, done);
  3917. }
  3918. void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValue value) {
  3919. Entity *e = implicit_entity_of_node(clause);
  3920. GB_ASSERT(e != nullptr);
  3921. if (e->flags & EntityFlag_Value) {
  3922. // by value
  3923. GB_ASSERT(are_types_identical(e->type, value.type));
  3924. lbAddr x = lb_add_local(p, e->type, e, false);
  3925. lb_addr_store(p, x, value);
  3926. } else {
  3927. // by reference
  3928. GB_ASSERT(are_types_identical(e->type, type_deref(value.type)));
  3929. lb_add_entity(p->module, e, value);
  3930. }
  3931. }
  3932. lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValue value) {
  3933. Entity *e = entity_of_node(stmt_val);
  3934. if (e == nullptr) {
  3935. return {};
  3936. }
  3937. if ((e->flags & EntityFlag_Value) == 0) {
  3938. if (LLVMIsALoadInst(value.value)) {
  3939. lbValue ptr = lb_address_from_load_or_generate_local(p, value);
  3940. lb_add_entity(p->module, e, ptr);
  3941. return lb_addr(ptr);
  3942. }
  3943. }
  3944. // by value
  3945. lbAddr addr = lb_add_local(p, e->type, e, false);
  3946. lb_addr_store(p, addr, value);
  3947. return addr;
  3948. }
  3949. void lb_type_case_body(lbProcedure *p, Ast *label, Ast *clause, lbBlock *body, lbBlock *done) {
  3950. ast_node(cc, CaseClause, clause);
  3951. lb_push_target_list(p, label, done, nullptr, nullptr);
  3952. lb_open_scope(p, body->scope);
  3953. lb_build_stmt_list(p, cc->stmts);
  3954. lb_close_scope(p, lbDeferExit_Default, body);
  3955. lb_pop_target_list(p);
  3956. lb_emit_jump(p, done);
  3957. }
  3958. void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss) {
  3959. lbModule *m = p->module;
  3960. ast_node(as, AssignStmt, ss->tag);
  3961. GB_ASSERT(as->lhs.count == 1);
  3962. GB_ASSERT(as->rhs.count == 1);
  3963. lbValue parent = lb_build_expr(p, as->rhs[0]);
  3964. bool is_parent_ptr = is_type_pointer(parent.type);
  3965. TypeSwitchKind switch_kind = check_valid_type_switch_type(parent.type);
  3966. GB_ASSERT(switch_kind != TypeSwitch_Invalid);
  3967. lbValue parent_value = parent;
  3968. lbValue parent_ptr = parent;
  3969. if (!is_parent_ptr) {
  3970. parent_ptr = lb_address_from_load_or_generate_local(p, parent);
  3971. }
  3972. lbValue tag_index = {};
  3973. lbValue union_data = {};
  3974. if (switch_kind == TypeSwitch_Union) {
  3975. union_data = lb_emit_conv(p, parent_ptr, t_rawptr);
  3976. if (is_type_union_maybe_pointer(type_deref(parent_ptr.type))) {
  3977. tag_index = lb_emit_conv(p, lb_emit_comp_against_nil(p, Token_NotEq, union_data), t_int);
  3978. } else {
  3979. lbValue tag_ptr = lb_emit_union_tag_ptr(p, parent_ptr);
  3980. tag_index = lb_emit_load(p, tag_ptr);
  3981. }
  3982. }
  3983. lbBlock *start_block = lb_create_block(p, "typeswitch.case.first");
  3984. lb_emit_jump(p, start_block);
  3985. lb_start_block(p, start_block);
  3986. // NOTE(bill): Append this later
  3987. lbBlock *done = lb_create_block(p, "typeswitch.done");
  3988. Ast *default_ = nullptr;
  3989. ast_node(body, BlockStmt, ss->body);
  3990. gb_local_persist i32 weird_count = 0;
  3991. for_array(i, body->stmts) {
  3992. Ast *clause = body->stmts[i];
  3993. ast_node(cc, CaseClause, clause);
  3994. if (cc->list.count == 0) {
  3995. default_ = clause;
  3996. continue;
  3997. }
  3998. lbBlock *body = lb_create_block(p, "typeswitch.body");
  3999. lbBlock *next = nullptr;
  4000. Type *case_type = nullptr;
  4001. for_array(type_index, cc->list) {
  4002. next = lb_create_block(p, "typeswitch.next");
  4003. case_type = type_of_expr(cc->list[type_index]);
  4004. lbValue cond = {};
  4005. if (switch_kind == TypeSwitch_Union) {
  4006. Type *ut = base_type(type_deref(parent.type));
  4007. lbValue variant_tag = lb_const_union_tag(m, ut, case_type);
  4008. cond = lb_emit_comp(p, Token_CmpEq, tag_index, variant_tag);
  4009. } else if (switch_kind == TypeSwitch_Any) {
  4010. lbValue any_typeid = lb_emit_load(p, lb_emit_struct_ep(p, parent_ptr, 1));
  4011. lbValue case_typeid = lb_typeid(m, case_type);
  4012. cond = lb_emit_comp(p, Token_CmpEq, any_typeid, case_typeid);
  4013. }
  4014. GB_ASSERT(cond.value != nullptr);
  4015. lb_emit_if(p, cond, body, next);
  4016. lb_start_block(p, next);
  4017. }
  4018. Entity *case_entity = implicit_entity_of_node(clause);
  4019. lbValue value = parent_value;
  4020. lb_start_block(p, body);
  4021. bool by_reference = (case_entity->flags & EntityFlag_Value) == 0;
  4022. if (cc->list.count == 1) {
  4023. lbValue data = {};
  4024. if (switch_kind == TypeSwitch_Union) {
  4025. data = union_data;
  4026. } else if (switch_kind == TypeSwitch_Any) {
  4027. lbValue any_data = lb_emit_load(p, lb_emit_struct_ep(p, parent_ptr, 0));
  4028. data = any_data;
  4029. }
  4030. Type *ct = case_entity->type;
  4031. Type *ct_ptr = alloc_type_pointer(ct);
  4032. value = lb_emit_conv(p, data, ct_ptr);
  4033. if (!by_reference) {
  4034. value = lb_emit_load(p, value);
  4035. }
  4036. }
  4037. lb_store_type_case_implicit(p, clause, value);
  4038. lb_type_case_body(p, ss->label, clause, body, done);
  4039. lb_start_block(p, next);
  4040. }
  4041. if (default_ != nullptr) {
  4042. lb_store_type_case_implicit(p, default_, parent_value);
  4043. lb_type_case_body(p, ss->label, default_, p->curr_block, done);
  4044. } else {
  4045. lb_emit_jump(p, done);
  4046. }
  4047. lb_start_block(p, done);
  4048. }
  4049. lbValue lb_emit_logical_binary_expr(lbProcedure *p, TokenKind op, Ast *left, Ast *right, Type *type) {
  4050. lbModule *m = p->module;
  4051. lbBlock *rhs = lb_create_block(p, "logical.cmp.rhs");
  4052. lbBlock *done = lb_create_block(p, "logical.cmp.done");
  4053. type = default_type(type);
  4054. lbValue short_circuit = {};
  4055. if (op == Token_CmpAnd) {
  4056. lb_build_cond(p, left, rhs, done);
  4057. short_circuit = lb_const_bool(m, type, false);
  4058. } else if (op == Token_CmpOr) {
  4059. lb_build_cond(p, left, done, rhs);
  4060. short_circuit = lb_const_bool(m, type, true);
  4061. }
  4062. if (rhs->preds.count == 0) {
  4063. lb_start_block(p, done);
  4064. return short_circuit;
  4065. }
  4066. if (done->preds.count == 0) {
  4067. lb_start_block(p, rhs);
  4068. return lb_build_expr(p, right);
  4069. }
  4070. Array<LLVMValueRef> incoming_values = {};
  4071. Array<LLVMBasicBlockRef> incoming_blocks = {};
  4072. array_init(&incoming_values, heap_allocator(), done->preds.count+1);
  4073. array_init(&incoming_blocks, heap_allocator(), done->preds.count+1);
  4074. for_array(i, done->preds) {
  4075. incoming_values[i] = short_circuit.value;
  4076. incoming_blocks[i] = done->preds[i]->block;
  4077. }
  4078. lb_start_block(p, rhs);
  4079. lbValue edge = lb_build_expr(p, right);
  4080. incoming_values[done->preds.count] = edge.value;
  4081. incoming_blocks[done->preds.count] = p->curr_block->block;
  4082. lb_emit_jump(p, done);
  4083. lb_start_block(p, done);
  4084. lbValue res = {};
  4085. res.type = type;
  4086. res.value = LLVMBuildPhi(p->builder, lb_type(m, type), "");
  4087. GB_ASSERT(incoming_values.count == incoming_blocks.count);
  4088. LLVMAddIncoming(res.value, incoming_values.data, incoming_blocks.data, cast(unsigned)incoming_values.count);
  4089. return res;
  4090. }
  4091. void lb_build_stmt(lbProcedure *p, Ast *node) {
  4092. Ast *prev_stmt = p->curr_stmt;
  4093. defer (p->curr_stmt = prev_stmt);
  4094. p->curr_stmt = node;
  4095. if (p->curr_block != nullptr) {
  4096. LLVMValueRef last_instr = LLVMGetLastInstruction(p->curr_block->block);
  4097. if (lb_is_instr_terminating(last_instr)) {
  4098. return;
  4099. }
  4100. }
  4101. LLVMMetadataRef prev_debug_location = nullptr;
  4102. if (p->debug_info != nullptr) {
  4103. prev_debug_location = LLVMGetCurrentDebugLocation2(p->builder);
  4104. LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, node));
  4105. }
  4106. defer (if (prev_debug_location != nullptr) {
  4107. LLVMSetCurrentDebugLocation2(p->builder, prev_debug_location);
  4108. });
  4109. u16 prev_state_flags = p->state_flags;
  4110. defer (p->state_flags = prev_state_flags);
  4111. if (node->state_flags != 0) {
  4112. u16 in = node->state_flags;
  4113. u16 out = p->state_flags;
  4114. if (in & StateFlag_bounds_check) {
  4115. out |= StateFlag_bounds_check;
  4116. out &= ~StateFlag_no_bounds_check;
  4117. } else if (in & StateFlag_no_bounds_check) {
  4118. out |= StateFlag_no_bounds_check;
  4119. out &= ~StateFlag_bounds_check;
  4120. }
  4121. p->state_flags = out;
  4122. }
  4123. switch (node->kind) {
  4124. case_ast_node(bs, EmptyStmt, node);
  4125. case_end;
  4126. case_ast_node(us, UsingStmt, node);
  4127. case_end;
  4128. case_ast_node(ws, WhenStmt, node);
  4129. lb_build_when_stmt(p, ws);
  4130. case_end;
  4131. case_ast_node(bs, BlockStmt, node);
  4132. lbBlock *done = nullptr;
  4133. if (bs->label != nullptr) {
  4134. done = lb_create_block(p, "block.done");
  4135. lbTargetList *tl = lb_push_target_list(p, bs->label, done, nullptr, nullptr);
  4136. tl->is_block = true;
  4137. }
  4138. lb_open_scope(p, node->scope);
  4139. lb_build_stmt_list(p, bs->stmts);
  4140. lb_close_scope(p, lbDeferExit_Default, nullptr);
  4141. if (done != nullptr) {
  4142. lb_emit_jump(p, done);
  4143. lb_start_block(p, done);
  4144. }
  4145. case_end;
  4146. case_ast_node(vd, ValueDecl, node);
  4147. if (!vd->is_mutable) {
  4148. return;
  4149. }
  4150. bool is_static = false;
  4151. if (vd->names.count > 0) {
  4152. Entity *e = entity_of_node(vd->names[0]);
  4153. if (e->flags & EntityFlag_Static) {
  4154. // NOTE(bill): If one of the entities is static, they all are
  4155. is_static = true;
  4156. }
  4157. }
  4158. if (is_static) {
  4159. for_array(i, vd->names) {
  4160. lbValue value = {};
  4161. if (vd->values.count > 0) {
  4162. GB_ASSERT(vd->names.count == vd->values.count);
  4163. Ast *ast_value = vd->values[i];
  4164. GB_ASSERT(ast_value->tav.mode == Addressing_Constant ||
  4165. ast_value->tav.mode == Addressing_Invalid);
  4166. bool allow_local = false;
  4167. value = lb_const_value(p->module, ast_value->tav.type, ast_value->tav.value, allow_local);
  4168. }
  4169. Ast *ident = vd->names[i];
  4170. GB_ASSERT(!is_blank_ident(ident));
  4171. Entity *e = entity_of_node(ident);
  4172. GB_ASSERT(e->flags & EntityFlag_Static);
  4173. String name = e->token.string;
  4174. String mangled_name = {};
  4175. {
  4176. gbString str = gb_string_make_length(permanent_allocator(), p->name.text, p->name.len);
  4177. str = gb_string_appendc(str, "-");
  4178. str = gb_string_append_fmt(str, ".%.*s-%llu", LIT(name), cast(long long)e->id);
  4179. mangled_name.text = cast(u8 *)str;
  4180. mangled_name.len = gb_string_length(str);
  4181. }
  4182. char *c_name = alloc_cstring(permanent_allocator(), mangled_name);
  4183. LLVMValueRef global = LLVMAddGlobal(p->module->mod, lb_type(p->module, e->type), c_name);
  4184. LLVMSetInitializer(global, LLVMConstNull(lb_type(p->module, e->type)));
  4185. if (value.value != nullptr) {
  4186. LLVMSetInitializer(global, value.value);
  4187. } else {
  4188. }
  4189. if (e->Variable.thread_local_model != "") {
  4190. LLVMSetThreadLocal(global, true);
  4191. String m = e->Variable.thread_local_model;
  4192. LLVMThreadLocalMode mode = LLVMGeneralDynamicTLSModel;
  4193. if (m == "default") {
  4194. mode = LLVMGeneralDynamicTLSModel;
  4195. } else if (m == "localdynamic") {
  4196. mode = LLVMLocalDynamicTLSModel;
  4197. } else if (m == "initialexec") {
  4198. mode = LLVMInitialExecTLSModel;
  4199. } else if (m == "localexec") {
  4200. mode = LLVMLocalExecTLSModel;
  4201. } else {
  4202. GB_PANIC("Unhandled thread local mode %.*s", LIT(m));
  4203. }
  4204. LLVMSetThreadLocalMode(global, mode);
  4205. } else {
  4206. LLVMSetLinkage(global, LLVMInternalLinkage);
  4207. }
  4208. lbValue global_val = {global, alloc_type_pointer(e->type)};
  4209. lb_add_entity(p->module, e, global_val);
  4210. lb_add_member(p->module, mangled_name, global_val);
  4211. }
  4212. return;
  4213. }
  4214. if (vd->values.count == 0) { // declared and zero-initialized
  4215. for_array(i, vd->names) {
  4216. Ast *name = vd->names[i];
  4217. if (!is_blank_ident(name)) {
  4218. Entity *e = entity_of_node(name);
  4219. lb_add_local(p, e->type, e, true);
  4220. }
  4221. }
  4222. } else { // Tuple(s)
  4223. auto lvals = array_make<lbAddr>(permanent_allocator(), 0, vd->names.count);
  4224. auto inits = array_make<lbValue>(permanent_allocator(), 0, vd->names.count);
  4225. for_array(i, vd->names) {
  4226. Ast *name = vd->names[i];
  4227. lbAddr lval = {};
  4228. if (!is_blank_ident(name)) {
  4229. Entity *e = entity_of_node(name);
  4230. lval = lb_add_local(p, e->type, e, false);
  4231. }
  4232. array_add(&lvals, lval);
  4233. }
  4234. for_array(i, vd->values) {
  4235. lbValue init = lb_build_expr(p, vd->values[i]);
  4236. Type *t = init.type;
  4237. if (t->kind == Type_Tuple) {
  4238. for_array(i, t->Tuple.variables) {
  4239. Entity *e = t->Tuple.variables[i];
  4240. lbValue v = lb_emit_struct_ev(p, init, cast(i32)i);
  4241. array_add(&inits, v);
  4242. }
  4243. } else {
  4244. array_add(&inits, init);
  4245. }
  4246. }
  4247. for_array(i, inits) {
  4248. lbAddr lval = lvals[i];
  4249. lbValue init = inits[i];
  4250. lb_addr_store(p, lval, init);
  4251. }
  4252. }
  4253. case_end;
  4254. case_ast_node(as, AssignStmt, node);
  4255. if (as->op.kind == Token_Eq) {
  4256. auto lvals = array_make<lbAddr>(permanent_allocator(), 0, as->lhs.count);
  4257. for_array(i, as->lhs) {
  4258. Ast *lhs = as->lhs[i];
  4259. lbAddr lval = {};
  4260. if (!is_blank_ident(lhs)) {
  4261. lval = lb_build_addr(p, lhs);
  4262. }
  4263. array_add(&lvals, lval);
  4264. }
  4265. if (as->lhs.count == as->rhs.count) {
  4266. if (as->lhs.count == 1) {
  4267. lbAddr lval = lvals[0];
  4268. Ast *rhs = as->rhs[0];
  4269. lbValue init = lb_build_expr(p, rhs);
  4270. lb_addr_store(p, lvals[0], init);
  4271. } else {
  4272. auto inits = array_make<lbValue>(permanent_allocator(), 0, lvals.count);
  4273. for_array(i, as->rhs) {
  4274. lbValue init = lb_build_expr(p, as->rhs[i]);
  4275. array_add(&inits, init);
  4276. }
  4277. for_array(i, inits) {
  4278. lbAddr lval = lvals[i];
  4279. lbValue init = inits[i];
  4280. lb_addr_store(p, lval, init);
  4281. }
  4282. }
  4283. } else {
  4284. auto inits = array_make<lbValue>(permanent_allocator(), 0, lvals.count);
  4285. for_array(i, as->rhs) {
  4286. lbValue init = lb_build_expr(p, as->rhs[i]);
  4287. Type *t = init.type;
  4288. // TODO(bill): refactor for code reuse as this is repeated a bit
  4289. if (t->kind == Type_Tuple) {
  4290. for_array(i, t->Tuple.variables) {
  4291. Entity *e = t->Tuple.variables[i];
  4292. lbValue v = lb_emit_struct_ev(p, init, cast(i32)i);
  4293. array_add(&inits, v);
  4294. }
  4295. } else {
  4296. array_add(&inits, init);
  4297. }
  4298. }
  4299. for_array(i, inits) {
  4300. lbAddr lval = lvals[i];
  4301. lbValue init = inits[i];
  4302. lb_addr_store(p, lval, init);
  4303. }
  4304. }
  4305. } else {
  4306. // NOTE(bill): Only 1 += 1 is allowed, no tuples
  4307. // +=, -=, etc
  4308. i32 op = cast(i32)as->op.kind;
  4309. op += Token_Add - Token_AddEq; // Convert += to +
  4310. if (op == Token_CmpAnd || op == Token_CmpOr) {
  4311. Type *type = as->lhs[0]->tav.type;
  4312. lbValue new_value = lb_emit_logical_binary_expr(p, cast(TokenKind)op, as->lhs[0], as->rhs[0], type);
  4313. lbAddr lhs = lb_build_addr(p, as->lhs[0]);
  4314. lb_addr_store(p, lhs, new_value);
  4315. } else {
  4316. lbAddr lhs = lb_build_addr(p, as->lhs[0]);
  4317. lbValue value = lb_build_expr(p, as->rhs[0]);
  4318. lbValue old_value = lb_addr_load(p, lhs);
  4319. Type *type = old_value.type;
  4320. lbValue change = lb_emit_conv(p, value, type);
  4321. lbValue new_value = lb_emit_arith(p, cast(TokenKind)op, old_value, change, type);
  4322. lb_addr_store(p, lhs, new_value);
  4323. }
  4324. return;
  4325. }
  4326. case_end;
  4327. case_ast_node(es, ExprStmt, node);
  4328. lb_build_expr(p, es->expr);
  4329. case_end;
  4330. case_ast_node(ds, DeferStmt, node);
  4331. isize scope_index = p->scope_index;
  4332. lb_add_defer_node(p, scope_index, ds->stmt);
  4333. case_end;
  4334. case_ast_node(rs, ReturnStmt, node);
  4335. lbValue res = {};
  4336. TypeTuple *tuple = &p->type->Proc.results->Tuple;
  4337. isize return_count = p->type->Proc.result_count;
  4338. isize res_count = rs->results.count;
  4339. if (return_count == 0) {
  4340. // No return values
  4341. lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
  4342. LLVMBuildRetVoid(p->builder);
  4343. return;
  4344. } else if (return_count == 1) {
  4345. Entity *e = tuple->variables[0];
  4346. if (res_count == 0) {
  4347. lbValue *found = map_get(&p->module->values, hash_entity(e));
  4348. GB_ASSERT(found);
  4349. res = lb_emit_load(p, *found);
  4350. } else {
  4351. res = lb_build_expr(p, rs->results[0]);
  4352. res = lb_emit_conv(p, res, e->type);
  4353. }
  4354. if (p->type->Proc.has_named_results) {
  4355. // NOTE(bill): store the named values before returning
  4356. if (e->token.string != "") {
  4357. lbValue *found = map_get(&p->module->values, hash_entity(e));
  4358. GB_ASSERT(found != nullptr);
  4359. lb_emit_store(p, *found, lb_emit_conv(p, res, e->type));
  4360. }
  4361. }
  4362. } else {
  4363. auto results = array_make<lbValue>(permanent_allocator(), 0, return_count);
  4364. if (res_count != 0) {
  4365. for (isize res_index = 0; res_index < res_count; res_index++) {
  4366. lbValue res = lb_build_expr(p, rs->results[res_index]);
  4367. Type *t = res.type;
  4368. if (t->kind == Type_Tuple) {
  4369. for_array(i, t->Tuple.variables) {
  4370. Entity *e = t->Tuple.variables[i];
  4371. lbValue v = lb_emit_struct_ev(p, res, cast(i32)i);
  4372. array_add(&results, v);
  4373. }
  4374. } else {
  4375. array_add(&results, res);
  4376. }
  4377. }
  4378. } else {
  4379. for (isize res_index = 0; res_index < return_count; res_index++) {
  4380. Entity *e = tuple->variables[res_index];
  4381. lbValue *found = map_get(&p->module->values, hash_entity(e));
  4382. GB_ASSERT(found);
  4383. lbValue res = lb_emit_load(p, *found);
  4384. array_add(&results, res);
  4385. }
  4386. }
  4387. GB_ASSERT(results.count == return_count);
  4388. if (p->type->Proc.has_named_results) {
  4389. // NOTE(bill): store the named values before returning
  4390. for_array(i, p->type->Proc.results->Tuple.variables) {
  4391. Entity *e = p->type->Proc.results->Tuple.variables[i];
  4392. if (e->kind != Entity_Variable) {
  4393. continue;
  4394. }
  4395. if (e->token.string == "") {
  4396. continue;
  4397. }
  4398. lbValue *found = map_get(&p->module->values, hash_entity(e));
  4399. GB_ASSERT(found != nullptr);
  4400. lb_emit_store(p, *found, lb_emit_conv(p, results[i], e->type));
  4401. }
  4402. }
  4403. Type *ret_type = p->type->Proc.results;
  4404. // NOTE(bill): Doesn't need to be zero because it will be initialized in the loops
  4405. res = lb_add_local_generated(p, ret_type, false).addr;
  4406. for_array(i, results) {
  4407. Entity *e = tuple->variables[i];
  4408. lbValue field = lb_emit_struct_ep(p, res, cast(i32)i);
  4409. lbValue val = lb_emit_conv(p, results[i], e->type);
  4410. lb_emit_store(p, field, val);
  4411. }
  4412. res = lb_emit_load(p, res);
  4413. }
  4414. lb_ensure_abi_function_type(p->module, p);
  4415. if (p->abi_function_type->ret.kind == lbArg_Indirect) {
  4416. if (res.value != nullptr) {
  4417. LLVMBuildStore(p->builder, res.value, p->return_ptr.addr.value);
  4418. } else {
  4419. LLVMBuildStore(p->builder, LLVMConstNull(p->abi_function_type->ret.type), p->return_ptr.addr.value);
  4420. }
  4421. lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
  4422. LLVMBuildRetVoid(p->builder);
  4423. } else {
  4424. LLVMValueRef ret_val = res.value;
  4425. ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.type);
  4426. if (p->abi_function_type->ret.cast_type != nullptr) {
  4427. ret_val = OdinLLVMBuildTransmute(p, ret_val, p->abi_function_type->ret.cast_type);
  4428. }
  4429. lb_emit_defer_stmts(p, lbDeferExit_Return, nullptr);
  4430. LLVMBuildRet(p->builder, ret_val);
  4431. }
  4432. case_end;
  4433. case_ast_node(is, IfStmt, node);
  4434. lb_open_scope(p, node->scope); // Scope #1
  4435. if (is->init != nullptr) {
  4436. // TODO(bill): Should this have a separate block to begin with?
  4437. #if 1
  4438. lbBlock *init = lb_create_block(p, "if.init");
  4439. lb_emit_jump(p, init);
  4440. lb_start_block(p, init);
  4441. #endif
  4442. lb_build_stmt(p, is->init);
  4443. }
  4444. lbBlock *then = lb_create_block(p, "if.then");
  4445. lbBlock *done = lb_create_block(p, "if.done");
  4446. lbBlock *else_ = done;
  4447. if (is->else_stmt != nullptr) {
  4448. else_ = lb_create_block(p, "if.else");
  4449. }
  4450. lb_build_cond(p, is->cond, then, else_);
  4451. lb_start_block(p, then);
  4452. if (is->label != nullptr) {
  4453. lbTargetList *tl = lb_push_target_list(p, is->label, done, nullptr, nullptr);
  4454. tl->is_block = true;
  4455. }
  4456. lb_build_stmt(p, is->body);
  4457. lb_emit_jump(p, done);
  4458. if (is->else_stmt != nullptr) {
  4459. lb_start_block(p, else_);
  4460. lb_open_scope(p, is->else_stmt->scope);
  4461. lb_build_stmt(p, is->else_stmt);
  4462. lb_close_scope(p, lbDeferExit_Default, nullptr);
  4463. lb_emit_jump(p, done);
  4464. }
  4465. lb_start_block(p, done);
  4466. lb_close_scope(p, lbDeferExit_Default, nullptr);
  4467. case_end;
  4468. case_ast_node(fs, ForStmt, node);
  4469. lb_open_scope(p, node->scope); // Open Scope here
  4470. if (fs->init != nullptr) {
  4471. #if 1
  4472. lbBlock *init = lb_create_block(p, "for.init");
  4473. lb_emit_jump(p, init);
  4474. lb_start_block(p, init);
  4475. #endif
  4476. lb_build_stmt(p, fs->init);
  4477. }
  4478. lbBlock *body = lb_create_block(p, "for.body");
  4479. lbBlock *done = lb_create_block(p, "for.done"); // NOTE(bill): Append later
  4480. lbBlock *loop = body;
  4481. if (fs->cond != nullptr) {
  4482. loop = lb_create_block(p, "for.loop");
  4483. }
  4484. lbBlock *post = loop;
  4485. if (fs->post != nullptr) {
  4486. post = lb_create_block(p, "for.post");
  4487. }
  4488. lb_emit_jump(p, loop);
  4489. lb_start_block(p, loop);
  4490. if (loop != body) {
  4491. lb_build_cond(p, fs->cond, body, done);
  4492. lb_start_block(p, body);
  4493. }
  4494. lb_push_target_list(p, fs->label, done, post, nullptr);
  4495. lb_build_stmt(p, fs->body);
  4496. lb_close_scope(p, lbDeferExit_Default, nullptr);
  4497. lb_pop_target_list(p);
  4498. lb_emit_jump(p, post);
  4499. if (fs->post != nullptr) {
  4500. lb_start_block(p, post);
  4501. lb_build_stmt(p, fs->post);
  4502. lb_emit_jump(p, loop);
  4503. }
  4504. lb_start_block(p, done);
  4505. case_end;
  4506. case_ast_node(rs, RangeStmt, node);
  4507. lb_build_range_stmt(p, rs, node->scope);
  4508. case_end;
  4509. case_ast_node(rs, UnrollRangeStmt, node);
  4510. lb_build_inline_range_stmt(p, rs, node->scope);
  4511. case_end;
  4512. case_ast_node(ss, SwitchStmt, node);
  4513. lb_build_switch_stmt(p, ss, node->scope);
  4514. case_end;
  4515. case_ast_node(ss, TypeSwitchStmt, node);
  4516. lb_build_type_switch_stmt(p, ss);
  4517. case_end;
  4518. case_ast_node(bs, BranchStmt, node);
  4519. lbBlock *block = nullptr;
  4520. if (bs->label != nullptr) {
  4521. lbBranchBlocks bb = lb_lookup_branch_blocks(p, bs->label);
  4522. switch (bs->token.kind) {
  4523. case Token_break: block = bb.break_; break;
  4524. case Token_continue: block = bb.continue_; break;
  4525. case Token_fallthrough:
  4526. GB_PANIC("fallthrough cannot have a label");
  4527. break;
  4528. }
  4529. } else {
  4530. for (lbTargetList *t = p->target_list; t != nullptr && block == nullptr; t = t->prev) {
  4531. if (t->is_block) {
  4532. continue;
  4533. }
  4534. switch (bs->token.kind) {
  4535. case Token_break: block = t->break_; break;
  4536. case Token_continue: block = t->continue_; break;
  4537. case Token_fallthrough: block = t->fallthrough_; break;
  4538. }
  4539. }
  4540. }
  4541. if (block != nullptr) {
  4542. lb_emit_defer_stmts(p, lbDeferExit_Branch, block);
  4543. }
  4544. lb_emit_jump(p, block);
  4545. case_end;
  4546. }
  4547. }
  4548. lbValue lb_emit_select(lbProcedure *p, lbValue cond, lbValue x, lbValue y) {
  4549. cond = lb_emit_conv(p, cond, t_llvm_bool);
  4550. lbValue res = {};
  4551. res.value = LLVMBuildSelect(p->builder, cond.value, x.value, y.value, "");
  4552. res.type = x.type;
  4553. return res;
  4554. }
  4555. lbValue lb_const_nil(lbModule *m, Type *type) {
  4556. LLVMValueRef v = LLVMConstNull(lb_type(m, type));
  4557. return lbValue{v, type};
  4558. }
  4559. lbValue lb_const_undef(lbModule *m, Type *type) {
  4560. LLVMValueRef v = LLVMGetUndef(lb_type(m, type));
  4561. return lbValue{v, type};
  4562. }
  4563. lbValue lb_const_int(lbModule *m, Type *type, u64 value) {
  4564. lbValue res = {};
  4565. res.value = LLVMConstInt(lb_type(m, type), cast(unsigned long long)value, !is_type_unsigned(type));
  4566. res.type = type;
  4567. return res;
  4568. }
  4569. lbValue lb_const_string(lbModule *m, String const &value) {
  4570. return lb_const_value(m, t_string, exact_value_string(value));
  4571. }
  4572. lbValue lb_const_bool(lbModule *m, Type *type, bool value) {
  4573. lbValue res = {};
  4574. res.value = LLVMConstInt(lb_type(m, type), value, false);
  4575. res.type = type;
  4576. return res;
  4577. }
  4578. LLVMValueRef lb_const_f16(lbModule *m, f32 f, Type *type=t_f16) {
  4579. GB_ASSERT(type_size_of(type) == 2);
  4580. u16 u = f32_to_f16(f);
  4581. if (is_type_different_to_arch_endianness(type)) {
  4582. u = gb_endian_swap16(u);
  4583. }
  4584. LLVMValueRef i = LLVMConstInt(LLVMInt16TypeInContext(m->ctx), u, false);
  4585. return LLVMConstBitCast(i, lb_type(m, type));
  4586. }
  4587. LLVMValueRef lb_const_f32(lbModule *m, f32 f, Type *type=t_f32) {
  4588. GB_ASSERT(type_size_of(type) == 4);
  4589. u32 u = bit_cast<u32>(f);
  4590. if (is_type_different_to_arch_endianness(type)) {
  4591. u = gb_endian_swap32(u);
  4592. }
  4593. LLVMValueRef i = LLVMConstInt(LLVMInt32TypeInContext(m->ctx), u, false);
  4594. return LLVMConstBitCast(i, lb_type(m, type));
  4595. }
  4596. lbValue lb_emit_min(lbProcedure *p, Type *t, lbValue x, lbValue y) {
  4597. x = lb_emit_conv(p, x, t);
  4598. y = lb_emit_conv(p, y, t);
  4599. if (is_type_float(t)) {
  4600. i64 sz = 8*type_size_of(t);
  4601. auto args = array_make<lbValue>(permanent_allocator(), 2);
  4602. args[0] = x;
  4603. args[1] = y;
  4604. switch (sz) {
  4605. case 16: return lb_emit_runtime_call(p, "min_f16", args);
  4606. case 32: return lb_emit_runtime_call(p, "min_f32", args);
  4607. case 64: return lb_emit_runtime_call(p, "min_f64", args);
  4608. }
  4609. GB_PANIC("Unknown float type");
  4610. }
  4611. return lb_emit_select(p, lb_emit_comp(p, Token_Lt, x, y), x, y);
  4612. }
  4613. lbValue lb_emit_max(lbProcedure *p, Type *t, lbValue x, lbValue y) {
  4614. x = lb_emit_conv(p, x, t);
  4615. y = lb_emit_conv(p, y, t);
  4616. if (is_type_float(t)) {
  4617. i64 sz = 8*type_size_of(t);
  4618. auto args = array_make<lbValue>(permanent_allocator(), 2);
  4619. args[0] = x;
  4620. args[1] = y;
  4621. switch (sz) {
  4622. case 16: return lb_emit_runtime_call(p, "max_f16", args);
  4623. case 32: return lb_emit_runtime_call(p, "max_f32", args);
  4624. case 64: return lb_emit_runtime_call(p, "max_f64", args);
  4625. }
  4626. GB_PANIC("Unknown float type");
  4627. }
  4628. return lb_emit_select(p, lb_emit_comp(p, Token_Gt, x, y), x, y);
  4629. }
  4630. lbValue lb_emit_clamp(lbProcedure *p, Type *t, lbValue x, lbValue min, lbValue max) {
  4631. lbValue z = {};
  4632. z = lb_emit_max(p, t, x, min);
  4633. z = lb_emit_min(p, t, z, max);
  4634. return z;
  4635. }
  4636. LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) {
  4637. StringHashKey key = string_hash_string(str);
  4638. LLVMValueRef *found = string_map_get(&m->const_strings, key);
  4639. if (found != nullptr) {
  4640. return *found;
  4641. } else {
  4642. LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
  4643. LLVMValueRef data = LLVMConstStringInContext(m->ctx,
  4644. cast(char const *)str.text,
  4645. cast(unsigned)str.len,
  4646. false);
  4647. isize max_len = 7+8+1;
  4648. char *name = gb_alloc_array(permanent_allocator(), char, max_len);
  4649. u32 id = cast(u32)gb_atomic32_fetch_add(&m->gen->global_array_index, 1);
  4650. isize len = gb_snprintf(name, max_len, "csbs$%x", id);
  4651. len -= 1;
  4652. LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name);
  4653. LLVMSetInitializer(global_data, data);
  4654. LLVMSetLinkage(global_data, LLVMInternalLinkage);
  4655. LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2);
  4656. string_map_set(&m->const_strings, key, ptr);
  4657. return ptr;
  4658. }
  4659. }
  4660. lbValue lb_find_or_add_entity_string(lbModule *m, String const &str) {
  4661. LLVMValueRef ptr = nullptr;
  4662. if (str.len != 0) {
  4663. ptr = lb_find_or_add_entity_string_ptr(m, str);
  4664. } else {
  4665. ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
  4666. }
  4667. LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), str.len, true);
  4668. LLVMValueRef values[2] = {ptr, str_len};
  4669. lbValue res = {};
  4670. res.value = llvm_const_named_struct(lb_type(m, t_string), values, 2);
  4671. res.type = t_string;
  4672. return res;
  4673. }
  4674. lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str) {
  4675. LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
  4676. LLVMValueRef data = LLVMConstStringInContext(m->ctx,
  4677. cast(char const *)str.text,
  4678. cast(unsigned)str.len,
  4679. false);
  4680. char *name = nullptr;
  4681. {
  4682. isize max_len = 7+8+1;
  4683. name = gb_alloc_array(permanent_allocator(), char, max_len);
  4684. u32 id = cast(u32)gb_atomic32_fetch_add(&m->gen->global_array_index, 1);
  4685. isize len = gb_snprintf(name, max_len, "csbs$%x", id);
  4686. len -= 1;
  4687. }
  4688. LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name);
  4689. LLVMSetInitializer(global_data, data);
  4690. LLVMSetLinkage(global_data, LLVMInternalLinkage);
  4691. LLVMValueRef ptr = nullptr;
  4692. if (str.len != 0) {
  4693. ptr = LLVMConstInBoundsGEP(global_data, indices, 2);
  4694. } else {
  4695. ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
  4696. }
  4697. LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), str.len, true);
  4698. LLVMValueRef values[2] = {ptr, len};
  4699. lbValue res = {};
  4700. res.value = llvm_const_named_struct(lb_type(m, t_u8_slice), values, 2);
  4701. res.type = t_u8_slice;
  4702. return res;
  4703. }
  4704. isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=true) {
  4705. isize index = type_info_index(info, type, false);
  4706. if (index >= 0) {
  4707. auto *set = &info->minimum_dependency_type_info_set;
  4708. for_array(i, set->entries) {
  4709. if (set->entries[i].ptr == index) {
  4710. return i+1;
  4711. }
  4712. }
  4713. }
  4714. if (err_on_not_found) {
  4715. GB_PANIC("NOT FOUND lb_type_info_index %s @ index %td", type_to_string(type), index);
  4716. }
  4717. return -1;
  4718. }
  4719. lbValue lb_typeid(lbModule *m, Type *type) {
  4720. type = default_type(type);
  4721. u64 id = cast(u64)lb_type_info_index(m->info, type);
  4722. GB_ASSERT(id >= 0);
  4723. u64 kind = Typeid_Invalid;
  4724. u64 named = is_type_named(type) && type->kind != Type_Basic;
  4725. u64 special = 0;
  4726. u64 reserved = 0;
  4727. Type *bt = base_type(type);
  4728. TypeKind tk = bt->kind;
  4729. switch (tk) {
  4730. case Type_Basic: {
  4731. u32 flags = bt->Basic.flags;
  4732. if (flags & BasicFlag_Boolean) kind = Typeid_Boolean;
  4733. if (flags & BasicFlag_Integer) kind = Typeid_Integer;
  4734. if (flags & BasicFlag_Unsigned) kind = Typeid_Integer;
  4735. if (flags & BasicFlag_Float) kind = Typeid_Float;
  4736. if (flags & BasicFlag_Complex) kind = Typeid_Complex;
  4737. if (flags & BasicFlag_Pointer) kind = Typeid_Pointer;
  4738. if (flags & BasicFlag_String) kind = Typeid_String;
  4739. if (flags & BasicFlag_Rune) kind = Typeid_Rune;
  4740. } break;
  4741. case Type_Pointer: kind = Typeid_Pointer; break;
  4742. case Type_Array: kind = Typeid_Array; break;
  4743. case Type_EnumeratedArray: kind = Typeid_Enumerated_Array; break;
  4744. case Type_Slice: kind = Typeid_Slice; break;
  4745. case Type_DynamicArray: kind = Typeid_Dynamic_Array; break;
  4746. case Type_Map: kind = Typeid_Map; break;
  4747. case Type_Struct: kind = Typeid_Struct; break;
  4748. case Type_Enum: kind = Typeid_Enum; break;
  4749. case Type_Union: kind = Typeid_Union; break;
  4750. case Type_Tuple: kind = Typeid_Tuple; break;
  4751. case Type_Proc: kind = Typeid_Procedure; break;
  4752. case Type_BitSet: kind = Typeid_Bit_Set; break;
  4753. case Type_SimdVector: kind = Typeid_Simd_Vector; break;
  4754. case Type_RelativePointer: kind = Typeid_Relative_Pointer; break;
  4755. case Type_RelativeSlice: kind = Typeid_Relative_Slice; break;
  4756. }
  4757. if (is_type_cstring(type)) {
  4758. special = 1;
  4759. } else if (is_type_integer(type) && !is_type_unsigned(type)) {
  4760. special = 1;
  4761. }
  4762. u64 data = 0;
  4763. if (build_context.word_size == 4) {
  4764. GB_ASSERT(id <= (1u<<24u));
  4765. data |= (id &~ (1u<<24)) << 0u; // index
  4766. data |= (kind &~ (1u<<5)) << 24u; // kind
  4767. data |= (named &~ (1u<<1)) << 29u; // kind
  4768. data |= (special &~ (1u<<1)) << 30u; // kind
  4769. data |= (reserved &~ (1u<<1)) << 31u; // kind
  4770. } else {
  4771. GB_ASSERT(build_context.word_size == 8);
  4772. GB_ASSERT(id <= (1ull<<56u));
  4773. data |= (id &~ (1ull<<56)) << 0ul; // index
  4774. data |= (kind &~ (1ull<<5)) << 56ull; // kind
  4775. data |= (named &~ (1ull<<1)) << 61ull; // kind
  4776. data |= (special &~ (1ull<<1)) << 62ull; // kind
  4777. data |= (reserved &~ (1ull<<1)) << 63ull; // kind
  4778. }
  4779. lbValue res = {};
  4780. res.value = LLVMConstInt(lb_type(m, t_typeid), data, false);
  4781. res.type = t_typeid;
  4782. return res;
  4783. }
  4784. lbValue lb_type_info(lbModule *m, Type *type) {
  4785. type = default_type(type);
  4786. isize index = lb_type_info_index(m->info, type);
  4787. GB_ASSERT(index >= 0);
  4788. LLVMTypeRef it = lb_type(m, t_int);
  4789. LLVMValueRef indices[2] = {
  4790. LLVMConstInt(it, 0, false),
  4791. LLVMConstInt(it, index, true),
  4792. };
  4793. lbValue value = {};
  4794. value.value = LLVMConstGEP(lb_global_type_info_data_ptr(m).value, indices, gb_count_of(indices));
  4795. value.type = t_type_info_ptr;
  4796. return value;
  4797. }
  4798. LLVMValueRef lb_build_constant_array_values(lbModule *m, Type *type, Type *elem_type, isize count, LLVMValueRef *values, bool allow_local) {
  4799. bool is_local = allow_local && m->curr_procedure != nullptr;
  4800. bool is_const = true;
  4801. if (is_local) {
  4802. for (isize i = 0; i < count; i++) {
  4803. GB_ASSERT(values[i] != nullptr);
  4804. if (!LLVMIsConstant(values[i])) {
  4805. is_const = false;
  4806. break;
  4807. }
  4808. }
  4809. }
  4810. if (!is_const) {
  4811. lbProcedure *p = m->curr_procedure;
  4812. GB_ASSERT(p != nullptr);
  4813. lbAddr v = lb_add_local_generated(p, type, false);
  4814. lbValue ptr = lb_addr_get_ptr(p, v);
  4815. for (isize i = 0; i < count; i++) {
  4816. lbValue elem = lb_emit_array_epi(p, ptr, i);
  4817. LLVMBuildStore(p->builder, values[i], elem.value);
  4818. }
  4819. return lb_addr_load(p, v).value;
  4820. }
  4821. return llvm_const_array(lb_type(m, elem_type), values, cast(unsigned int)count);
  4822. }
  4823. lbValue lb_find_procedure_value_from_entity(lbModule *m, Entity *e) {
  4824. GB_ASSERT(is_type_proc(e->type));
  4825. e = strip_entity_wrapping(e);
  4826. GB_ASSERT(e != nullptr);
  4827. auto *found = map_get(&m->values, hash_entity(e));
  4828. if (found) {
  4829. return *found;
  4830. }
  4831. bool ignore_body = false;
  4832. if (USE_SEPARTE_MODULES) {
  4833. lbModule *other_module = lb_pkg_module(m->gen, e->pkg);
  4834. ignore_body = other_module != m;
  4835. }
  4836. lbProcedure *missing_proc = lb_create_procedure(m, e, ignore_body);
  4837. found = map_get(&m->values, hash_entity(e));
  4838. if (found) {
  4839. return *found;
  4840. }
  4841. GB_PANIC("Error in: %s, missing procedure %.*s\n", token_pos_to_string(e->token.pos), LIT(e->token.string));
  4842. return {};
  4843. }
  4844. lbValue lb_find_value_from_entity(lbModule *m, Entity *e) {
  4845. e = strip_entity_wrapping(e);
  4846. GB_ASSERT(e != nullptr);
  4847. GB_ASSERT(e->token.string != "_");
  4848. if (e->kind == Entity_Procedure) {
  4849. return lb_find_procedure_value_from_entity(m, e);
  4850. }
  4851. auto *found = map_get(&m->values, hash_entity(e));
  4852. if (found) {
  4853. return *found;
  4854. }
  4855. if (USE_SEPARTE_MODULES) {
  4856. lbModule *other_module = lb_pkg_module(m->gen, e->pkg);
  4857. // TODO(bill): correct this logic
  4858. bool is_external = other_module != m;
  4859. if (!is_external) {
  4860. if (e->code_gen_module != nullptr) {
  4861. other_module = e->code_gen_module;
  4862. } else {
  4863. other_module = nullptr;
  4864. }
  4865. is_external = other_module != m;
  4866. }
  4867. if (is_external) {
  4868. String name = lb_get_entity_name(other_module, e);
  4869. lbValue g = {};
  4870. g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name));
  4871. g.type = alloc_type_pointer(e->type);
  4872. lb_add_entity(m, e, g);
  4873. lb_add_member(m, name, g);
  4874. LLVMSetLinkage(g.value, LLVMExternalLinkage);
  4875. // if (other_module != nullptr) {
  4876. // lbValue *other_found = string_map_get(&other_module->members, name);
  4877. // if (other_found) {
  4878. // lbValue other_g = *other_found;
  4879. // }
  4880. // }
  4881. // LLVMSetLinkage(other_g.value, LLVMExternalLinkage);
  4882. if (e->Variable.thread_local_model != "") {
  4883. LLVMSetThreadLocal(g.value, true);
  4884. String m = e->Variable.thread_local_model;
  4885. LLVMThreadLocalMode mode = LLVMGeneralDynamicTLSModel;
  4886. if (m == "default") {
  4887. mode = LLVMGeneralDynamicTLSModel;
  4888. } else if (m == "localdynamic") {
  4889. mode = LLVMLocalDynamicTLSModel;
  4890. } else if (m == "initialexec") {
  4891. mode = LLVMInitialExecTLSModel;
  4892. } else if (m == "localexec") {
  4893. mode = LLVMLocalExecTLSModel;
  4894. } else {
  4895. GB_PANIC("Unhandled thread local mode %.*s", LIT(m));
  4896. }
  4897. LLVMSetThreadLocalMode(g.value, mode);
  4898. }
  4899. return g;
  4900. }
  4901. }
  4902. GB_PANIC("\n\tError in: %s, missing value %.*s\n", token_pos_to_string(e->token.pos), LIT(e->token.string));
  4903. return {};
  4904. }
  4905. lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_local) {
  4906. LLVMContextRef ctx = m->ctx;
  4907. type = default_type(type);
  4908. Type *original_type = type;
  4909. lbValue res = {};
  4910. res.type = original_type;
  4911. type = core_type(type);
  4912. value = convert_exact_value_for_type(value, type);
  4913. if (value.kind == ExactValue_Typeid) {
  4914. return lb_typeid(m, value.value_typeid);
  4915. }
  4916. if (value.kind == ExactValue_Invalid) {
  4917. return lb_const_nil(m, type);
  4918. }
  4919. if (value.kind == ExactValue_Procedure) {
  4920. Ast *expr = unparen_expr(value.value_procedure);
  4921. if (expr->kind == Ast_ProcLit) {
  4922. return lb_generate_anonymous_proc_lit(m, str_lit("_proclit"), expr);
  4923. }
  4924. Entity *e = entity_from_expr(expr);
  4925. return lb_find_procedure_value_from_entity(m, e);
  4926. }
  4927. bool is_local = allow_local && m->curr_procedure != nullptr;
  4928. // GB_ASSERT_MSG(is_type_typed(type), "%s", type_to_string(type));
  4929. if (is_type_slice(type)) {
  4930. if (value.kind == ExactValue_String) {
  4931. GB_ASSERT(is_type_u8_slice(type));
  4932. res.value = lb_find_or_add_entity_string_byte_slice(m, value.value_string).value;
  4933. return res;
  4934. } else {
  4935. ast_node(cl, CompoundLit, value.value_compound);
  4936. isize count = cl->elems.count;
  4937. if (count == 0) {
  4938. return lb_const_nil(m, type);
  4939. }
  4940. count = gb_max(cl->max_count, count);
  4941. Type *elem = base_type(type)->Slice.elem;
  4942. Type *t = alloc_type_array(elem, count);
  4943. lbValue backing_array = lb_const_value(m, t, value, allow_local);
  4944. LLVMValueRef array_data = nullptr;
  4945. if (is_local) {
  4946. // NOTE(bill, 2020-06-08): This is a bit of a hack but a "constant" slice needs
  4947. // its backing data on the stack
  4948. lbProcedure *p = m->curr_procedure;
  4949. LLVMPositionBuilderAtEnd(p->builder, p->decl_block->block);
  4950. LLVMTypeRef llvm_type = lb_type(m, t);
  4951. array_data = LLVMBuildAlloca(p->builder, llvm_type, "");
  4952. LLVMSetAlignment(array_data, 16); // TODO(bill): Make this configurable
  4953. LLVMPositionBuilderAtEnd(p->builder, p->curr_block->block);
  4954. LLVMBuildStore(p->builder, backing_array.value, array_data);
  4955. {
  4956. LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
  4957. LLVMValueRef ptr = LLVMBuildInBoundsGEP(p->builder, array_data, indices, 2, "");
  4958. LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), count, true);
  4959. lbAddr slice = lb_add_local_generated(p, type, false);
  4960. lb_fill_slice(p, slice, {ptr, alloc_type_pointer(elem)}, {len, t_int});
  4961. return lb_addr_load(p, slice);
  4962. }
  4963. } else {
  4964. isize max_len = 7+8+1;
  4965. char *str = gb_alloc_array(permanent_allocator(), char, max_len);
  4966. u32 id = cast(u32)gb_atomic32_fetch_add(&m->gen->global_array_index, 1);
  4967. isize len = gb_snprintf(str, max_len, "csba$%x", id);
  4968. String name = make_string(cast(u8 *)str, len-1);
  4969. Entity *e = alloc_entity_constant(nullptr, make_token_ident(name), t, value);
  4970. array_data = LLVMAddGlobal(m->mod, lb_type(m, t), str);
  4971. LLVMSetInitializer(array_data, backing_array.value);
  4972. lbValue g = {};
  4973. g.value = array_data;
  4974. g.type = t;
  4975. lb_add_entity(m, e, g);
  4976. lb_add_member(m, name, g);
  4977. {
  4978. LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
  4979. LLVMValueRef ptr = LLVMConstInBoundsGEP(array_data, indices, 2);
  4980. LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), count, true);
  4981. LLVMValueRef values[2] = {ptr, len};
  4982. res.value = llvm_const_named_struct(lb_type(m, original_type), values, 2);
  4983. return res;
  4984. }
  4985. }
  4986. }
  4987. } else if (is_type_array(type) && value.kind == ExactValue_String && !is_type_u8(core_array_type(type))) {
  4988. if (is_type_rune_array(type) && value.kind == ExactValue_String) {
  4989. i64 count = type->Array.count;
  4990. Type *elem = type->Array.elem;
  4991. LLVMTypeRef et = lb_type(m, elem);
  4992. Rune rune;
  4993. isize offset = 0;
  4994. isize width = 1;
  4995. String s = value.value_string;
  4996. LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, count);
  4997. for (i64 i = 0; i < count && offset < s.len; i++) {
  4998. width = gb_utf8_decode(s.text+offset, s.len-offset, &rune);
  4999. offset += width;
  5000. elems[i] = LLVMConstInt(et, rune, true);
  5001. }
  5002. GB_ASSERT(offset == s.len);
  5003. res.value = llvm_const_array(et, elems, cast(unsigned)count);
  5004. return res;
  5005. }
  5006. GB_PANIC("This should not have happened!\n");
  5007. LLVMValueRef data = LLVMConstStringInContext(ctx,
  5008. cast(char const *)value.value_string.text,
  5009. cast(unsigned)value.value_string.len,
  5010. false /*DontNullTerminate*/);
  5011. res.value = data;
  5012. return res;
  5013. } else if (is_type_u8_array(type) && value.kind == ExactValue_String) {
  5014. GB_ASSERT(type->Array.count == value.value_string.len);
  5015. LLVMValueRef data = LLVMConstStringInContext(ctx,
  5016. cast(char const *)value.value_string.text,
  5017. cast(unsigned)value.value_string.len,
  5018. true /*DontNullTerminate*/);
  5019. res.value = data;
  5020. return res;
  5021. } else if (is_type_array(type) &&
  5022. value.kind != ExactValue_Invalid &&
  5023. value.kind != ExactValue_String &&
  5024. value.kind != ExactValue_Compound) {
  5025. i64 count = type->Array.count;
  5026. Type *elem = type->Array.elem;
  5027. lbValue single_elem = lb_const_value(m, elem, value, allow_local);
  5028. LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, count);
  5029. for (i64 i = 0; i < count; i++) {
  5030. elems[i] = single_elem.value;
  5031. }
  5032. res.value = llvm_const_array(lb_type(m, elem), elems, cast(unsigned)count);
  5033. return res;
  5034. }
  5035. switch (value.kind) {
  5036. case ExactValue_Invalid:
  5037. res.value = LLVMConstNull(lb_type(m, original_type));
  5038. return res;
  5039. case ExactValue_Bool:
  5040. res.value = LLVMConstInt(lb_type(m, original_type), value.value_bool, false);
  5041. return res;
  5042. case ExactValue_String:
  5043. {
  5044. LLVMValueRef ptr = lb_find_or_add_entity_string_ptr(m, value.value_string);
  5045. lbValue res = {};
  5046. res.type = default_type(original_type);
  5047. if (is_type_cstring(res.type)) {
  5048. res.value = ptr;
  5049. } else {
  5050. if (value.value_string.len == 0) {
  5051. ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
  5052. }
  5053. LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), value.value_string.len, true);
  5054. LLVMValueRef values[2] = {ptr, str_len};
  5055. res.value = llvm_const_named_struct(lb_type(m, original_type), values, 2);
  5056. }
  5057. return res;
  5058. }
  5059. case ExactValue_Integer:
  5060. if (is_type_pointer(type)) {
  5061. unsigned len = cast(unsigned)value.value_integer.len;
  5062. LLVMTypeRef t = lb_type(m, original_type);
  5063. if (len == 0) {
  5064. res.value = LLVMConstNull(t);
  5065. } else {
  5066. LLVMValueRef i = LLVMConstIntOfArbitraryPrecision(lb_type(m, t_uintptr), len, big_int_ptr(&value.value_integer));
  5067. res.value = LLVMConstIntToPtr(i, t);
  5068. }
  5069. } else {
  5070. unsigned len = cast(unsigned)value.value_integer.len;
  5071. if (len == 0) {
  5072. res.value = LLVMConstNull(lb_type(m, original_type));
  5073. } else {
  5074. u64 *words = big_int_ptr(&value.value_integer);
  5075. if (is_type_different_to_arch_endianness(type)) {
  5076. // NOTE(bill): Swap byte order for different endianness
  5077. i64 sz = type_size_of(type);
  5078. isize byte_len = gb_size_of(u64)*len;
  5079. u8 *old_bytes = cast(u8 *)words;
  5080. // TODO(bill): Use a different allocator here for a temporary allocation
  5081. u8 *new_bytes = cast(u8 *)gb_alloc_align(permanent_allocator(), byte_len, gb_align_of(u64));
  5082. for (i64 i = 0; i < sz; i++) {
  5083. new_bytes[i] = old_bytes[sz-1-i];
  5084. }
  5085. words = cast(u64 *)new_bytes;
  5086. }
  5087. res.value = LLVMConstIntOfArbitraryPrecision(lb_type(m, original_type), len, words);
  5088. if (value.value_integer.neg) {
  5089. res.value = LLVMConstNeg(res.value);
  5090. }
  5091. }
  5092. }
  5093. return res;
  5094. case ExactValue_Float:
  5095. if (is_type_different_to_arch_endianness(type)) {
  5096. u64 u = bit_cast<u64>(value.value_float);
  5097. u = gb_endian_swap64(u);
  5098. res.value = LLVMConstReal(lb_type(m, original_type), bit_cast<f64>(u));
  5099. } else {
  5100. res.value = LLVMConstReal(lb_type(m, original_type), value.value_float);
  5101. }
  5102. return res;
  5103. case ExactValue_Complex:
  5104. {
  5105. LLVMValueRef values[2] = {};
  5106. switch (8*type_size_of(type)) {
  5107. case 32:
  5108. values[0] = lb_const_f16(m, cast(f32)value.value_complex->real);
  5109. values[1] = lb_const_f16(m, cast(f32)value.value_complex->imag);
  5110. break;
  5111. case 64:
  5112. values[0] = lb_const_f32(m, cast(f32)value.value_complex->real);
  5113. values[1] = lb_const_f32(m, cast(f32)value.value_complex->imag);
  5114. break;
  5115. case 128:
  5116. values[0] = LLVMConstReal(lb_type(m, t_f64), value.value_complex->real);
  5117. values[1] = LLVMConstReal(lb_type(m, t_f64), value.value_complex->imag);
  5118. break;
  5119. }
  5120. res.value = llvm_const_named_struct(lb_type(m, original_type), values, 2);
  5121. return res;
  5122. }
  5123. break;
  5124. case ExactValue_Quaternion:
  5125. {
  5126. LLVMValueRef values[4] = {};
  5127. switch (8*type_size_of(type)) {
  5128. case 64:
  5129. // @QuaternionLayout
  5130. values[3] = lb_const_f16(m, cast(f32)value.value_quaternion->real);
  5131. values[0] = lb_const_f16(m, cast(f32)value.value_quaternion->imag);
  5132. values[1] = lb_const_f16(m, cast(f32)value.value_quaternion->jmag);
  5133. values[2] = lb_const_f16(m, cast(f32)value.value_quaternion->kmag);
  5134. break;
  5135. case 128:
  5136. // @QuaternionLayout
  5137. values[3] = lb_const_f32(m, cast(f32)value.value_quaternion->real);
  5138. values[0] = lb_const_f32(m, cast(f32)value.value_quaternion->imag);
  5139. values[1] = lb_const_f32(m, cast(f32)value.value_quaternion->jmag);
  5140. values[2] = lb_const_f32(m, cast(f32)value.value_quaternion->kmag);
  5141. break;
  5142. case 256:
  5143. // @QuaternionLayout
  5144. values[3] = LLVMConstReal(lb_type(m, t_f64), value.value_quaternion->real);
  5145. values[0] = LLVMConstReal(lb_type(m, t_f64), value.value_quaternion->imag);
  5146. values[1] = LLVMConstReal(lb_type(m, t_f64), value.value_quaternion->jmag);
  5147. values[2] = LLVMConstReal(lb_type(m, t_f64), value.value_quaternion->kmag);
  5148. break;
  5149. }
  5150. res.value = llvm_const_named_struct(lb_type(m, original_type), values, 4);
  5151. return res;
  5152. }
  5153. break;
  5154. case ExactValue_Pointer:
  5155. res.value = LLVMConstIntToPtr(LLVMConstInt(lb_type(m, t_uintptr), value.value_pointer, false), lb_type(m, original_type));
  5156. return res;
  5157. case ExactValue_Compound:
  5158. if (is_type_slice(type)) {
  5159. return lb_const_value(m, type, value, allow_local);
  5160. } else if (is_type_array(type)) {
  5161. ast_node(cl, CompoundLit, value.value_compound);
  5162. Type *elem_type = type->Array.elem;
  5163. isize elem_count = cl->elems.count;
  5164. if (elem_count == 0 || !elem_type_can_be_constant(elem_type)) {
  5165. return lb_const_nil(m, original_type);
  5166. }
  5167. if (cl->elems[0]->kind == Ast_FieldValue) {
  5168. // TODO(bill): This is O(N*M) and will be quite slow; it should probably be sorted before hand
  5169. LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->Array.count);
  5170. isize value_index = 0;
  5171. for (i64 i = 0; i < type->Array.count; i++) {
  5172. bool found = false;
  5173. for (isize j = 0; j < elem_count; j++) {
  5174. Ast *elem = cl->elems[j];
  5175. ast_node(fv, FieldValue, elem);
  5176. if (is_ast_range(fv->field)) {
  5177. ast_node(ie, BinaryExpr, fv->field);
  5178. TypeAndValue lo_tav = ie->left->tav;
  5179. TypeAndValue hi_tav = ie->right->tav;
  5180. GB_ASSERT(lo_tav.mode == Addressing_Constant);
  5181. GB_ASSERT(hi_tav.mode == Addressing_Constant);
  5182. TokenKind op = ie->op.kind;
  5183. i64 lo = exact_value_to_i64(lo_tav.value);
  5184. i64 hi = exact_value_to_i64(hi_tav.value);
  5185. if (op == Token_Ellipsis) {
  5186. hi += 1;
  5187. }
  5188. if (lo == i) {
  5189. TypeAndValue tav = fv->value->tav;
  5190. LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value;
  5191. for (i64 k = lo; k < hi; k++) {
  5192. values[value_index++] = val;
  5193. }
  5194. found = true;
  5195. i += (hi-lo-1);
  5196. break;
  5197. }
  5198. } else {
  5199. TypeAndValue index_tav = fv->field->tav;
  5200. GB_ASSERT(index_tav.mode == Addressing_Constant);
  5201. i64 index = exact_value_to_i64(index_tav.value);
  5202. if (index == i) {
  5203. TypeAndValue tav = fv->value->tav;
  5204. LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value;
  5205. values[value_index++] = val;
  5206. found = true;
  5207. break;
  5208. }
  5209. }
  5210. }
  5211. if (!found) {
  5212. values[value_index++] = LLVMConstNull(lb_type(m, elem_type));
  5213. }
  5214. }
  5215. res.value = lb_build_constant_array_values(m, type, elem_type, type->Array.count, values, allow_local);
  5216. return res;
  5217. } else {
  5218. GB_ASSERT_MSG(elem_count == type->Array.count, "%td != %td", elem_count, type->Array.count);
  5219. LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->Array.count);
  5220. for (isize i = 0; i < elem_count; i++) {
  5221. TypeAndValue tav = cl->elems[i]->tav;
  5222. GB_ASSERT(tav.mode != Addressing_Invalid);
  5223. values[i] = lb_const_value(m, elem_type, tav.value, allow_local).value;
  5224. }
  5225. for (isize i = elem_count; i < type->Array.count; i++) {
  5226. values[i] = LLVMConstNull(lb_type(m, elem_type));
  5227. }
  5228. res.value = lb_build_constant_array_values(m, type, elem_type, type->Array.count, values, allow_local);
  5229. return res;
  5230. }
  5231. } else if (is_type_enumerated_array(type)) {
  5232. ast_node(cl, CompoundLit, value.value_compound);
  5233. Type *elem_type = type->EnumeratedArray.elem;
  5234. isize elem_count = cl->elems.count;
  5235. if (elem_count == 0 || !elem_type_can_be_constant(elem_type)) {
  5236. return lb_const_nil(m, original_type);
  5237. }
  5238. if (cl->elems[0]->kind == Ast_FieldValue) {
  5239. // TODO(bill): This is O(N*M) and will be quite slow; it should probably be sorted before hand
  5240. LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->EnumeratedArray.count);
  5241. isize value_index = 0;
  5242. i64 total_lo = exact_value_to_i64(type->EnumeratedArray.min_value);
  5243. i64 total_hi = exact_value_to_i64(type->EnumeratedArray.max_value);
  5244. for (i64 i = total_lo; i <= total_hi; i++) {
  5245. bool found = false;
  5246. for (isize j = 0; j < elem_count; j++) {
  5247. Ast *elem = cl->elems[j];
  5248. ast_node(fv, FieldValue, elem);
  5249. if (is_ast_range(fv->field)) {
  5250. ast_node(ie, BinaryExpr, fv->field);
  5251. TypeAndValue lo_tav = ie->left->tav;
  5252. TypeAndValue hi_tav = ie->right->tav;
  5253. GB_ASSERT(lo_tav.mode == Addressing_Constant);
  5254. GB_ASSERT(hi_tav.mode == Addressing_Constant);
  5255. TokenKind op = ie->op.kind;
  5256. i64 lo = exact_value_to_i64(lo_tav.value);
  5257. i64 hi = exact_value_to_i64(hi_tav.value);
  5258. if (op == Token_Ellipsis) {
  5259. hi += 1;
  5260. }
  5261. if (lo == i) {
  5262. TypeAndValue tav = fv->value->tav;
  5263. LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value;
  5264. for (i64 k = lo; k < hi; k++) {
  5265. values[value_index++] = val;
  5266. }
  5267. found = true;
  5268. i += (hi-lo-1);
  5269. break;
  5270. }
  5271. } else {
  5272. TypeAndValue index_tav = fv->field->tav;
  5273. GB_ASSERT(index_tav.mode == Addressing_Constant);
  5274. i64 index = exact_value_to_i64(index_tav.value);
  5275. if (index == i) {
  5276. TypeAndValue tav = fv->value->tav;
  5277. LLVMValueRef val = lb_const_value(m, elem_type, tav.value, allow_local).value;
  5278. values[value_index++] = val;
  5279. found = true;
  5280. break;
  5281. }
  5282. }
  5283. }
  5284. if (!found) {
  5285. values[value_index++] = LLVMConstNull(lb_type(m, elem_type));
  5286. }
  5287. }
  5288. res.value = lb_build_constant_array_values(m, type, elem_type, type->EnumeratedArray.count, values, allow_local);
  5289. return res;
  5290. } else {
  5291. GB_ASSERT_MSG(elem_count == type->EnumeratedArray.count, "%td != %td", elem_count, type->EnumeratedArray.count);
  5292. LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, type->EnumeratedArray.count);
  5293. for (isize i = 0; i < elem_count; i++) {
  5294. TypeAndValue tav = cl->elems[i]->tav;
  5295. GB_ASSERT(tav.mode != Addressing_Invalid);
  5296. values[i] = lb_const_value(m, elem_type, tav.value, allow_local).value;
  5297. }
  5298. for (isize i = elem_count; i < type->EnumeratedArray.count; i++) {
  5299. values[i] = LLVMConstNull(lb_type(m, elem_type));
  5300. }
  5301. res.value = lb_build_constant_array_values(m, type, elem_type, type->EnumeratedArray.count, values, allow_local);
  5302. return res;
  5303. }
  5304. } else if (is_type_simd_vector(type)) {
  5305. ast_node(cl, CompoundLit, value.value_compound);
  5306. Type *elem_type = type->SimdVector.elem;
  5307. isize elem_count = cl->elems.count;
  5308. if (elem_count == 0) {
  5309. return lb_const_nil(m, original_type);
  5310. }
  5311. GB_ASSERT(elem_type_can_be_constant(elem_type));
  5312. isize total_elem_count = type->SimdVector.count;
  5313. LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, total_elem_count);
  5314. for (isize i = 0; i < elem_count; i++) {
  5315. TypeAndValue tav = cl->elems[i]->tav;
  5316. GB_ASSERT(tav.mode != Addressing_Invalid);
  5317. values[i] = lb_const_value(m, elem_type, tav.value, allow_local).value;
  5318. }
  5319. LLVMTypeRef et = lb_type(m, elem_type);
  5320. for (isize i = elem_count; i < type->SimdVector.count; i++) {
  5321. values[i] = LLVMConstNull(et);
  5322. }
  5323. for (isize i = 0; i< total_elem_count; i++) {
  5324. values[i] = llvm_const_cast(values[i], et);
  5325. }
  5326. res.value = LLVMConstVector(values, cast(unsigned)total_elem_count);
  5327. return res;
  5328. } else if (is_type_struct(type)) {
  5329. ast_node(cl, CompoundLit, value.value_compound);
  5330. if (cl->elems.count == 0) {
  5331. return lb_const_nil(m, original_type);
  5332. }
  5333. isize offset = 0;
  5334. if (type->Struct.custom_align > 0) {
  5335. offset = 1;
  5336. }
  5337. isize value_count = type->Struct.fields.count + offset;
  5338. LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, value_count);
  5339. bool *visited = gb_alloc_array(temporary_allocator(), bool, value_count);
  5340. if (cl->elems.count > 0) {
  5341. if (cl->elems[0]->kind == Ast_FieldValue) {
  5342. isize elem_count = cl->elems.count;
  5343. for (isize i = 0; i < elem_count; i++) {
  5344. ast_node(fv, FieldValue, cl->elems[i]);
  5345. String name = fv->field->Ident.token.string;
  5346. TypeAndValue tav = fv->value->tav;
  5347. GB_ASSERT(tav.mode != Addressing_Invalid);
  5348. Selection sel = lookup_field(type, name, false);
  5349. Entity *f = type->Struct.fields[sel.index[0]];
  5350. if (elem_type_can_be_constant(f->type)) {
  5351. values[offset+f->Variable.field_index] = lb_const_value(m, f->type, tav.value, allow_local).value;
  5352. visited[offset+f->Variable.field_index] = true;
  5353. }
  5354. }
  5355. } else {
  5356. for_array(i, cl->elems) {
  5357. Entity *f = type->Struct.fields[i];
  5358. TypeAndValue tav = cl->elems[i]->tav;
  5359. ExactValue val = {};
  5360. if (tav.mode != Addressing_Invalid) {
  5361. val = tav.value;
  5362. }
  5363. if (elem_type_can_be_constant(f->type)) {
  5364. values[offset+f->Variable.field_index] = lb_const_value(m, f->type, val, allow_local).value;
  5365. visited[offset+f->Variable.field_index] = true;
  5366. }
  5367. }
  5368. }
  5369. }
  5370. for (isize i = 0; i < type->Struct.fields.count; i++) {
  5371. if (!visited[offset+i]) {
  5372. GB_ASSERT(values[offset+i] == nullptr);
  5373. values[offset+i] = lb_const_nil(m, get_struct_field_type(type, i)).value;
  5374. }
  5375. }
  5376. if (type->Struct.custom_align > 0) {
  5377. values[0] = LLVMConstNull(lb_alignment_prefix_type_hack(m, type->Struct.custom_align));
  5378. }
  5379. bool is_constant = true;
  5380. for (isize i = 0; i < value_count; i++) {
  5381. LLVMValueRef val = values[i];
  5382. if (!LLVMIsConstant(val)) {
  5383. GB_ASSERT(is_local);
  5384. GB_ASSERT(LLVMGetInstructionOpcode(val) == LLVMLoad);
  5385. is_constant = false;
  5386. }
  5387. }
  5388. if (is_constant) {
  5389. res.value = llvm_const_named_struct(lb_type(m, original_type), values, cast(unsigned)value_count);
  5390. return res;
  5391. } else {
  5392. // TODO(bill): THIS IS HACK BUT IT WORKS FOR WHAT I NEED
  5393. LLVMValueRef *old_values = values;
  5394. LLVMValueRef *new_values = gb_alloc_array(temporary_allocator(), LLVMValueRef, value_count);
  5395. for (isize i = 0; i < value_count; i++) {
  5396. LLVMValueRef old_value = old_values[i];
  5397. if (LLVMIsConstant(old_value)) {
  5398. new_values[i] = old_value;
  5399. } else {
  5400. new_values[i] = LLVMConstNull(LLVMTypeOf(old_value));
  5401. }
  5402. }
  5403. LLVMValueRef constant_value = llvm_const_named_struct(lb_type(m, original_type), new_values, cast(unsigned)value_count);
  5404. GB_ASSERT(is_local);
  5405. lbProcedure *p = m->curr_procedure;
  5406. lbAddr v = lb_add_local_generated(p, res.type, true);
  5407. LLVMBuildStore(p->builder, constant_value, v.addr.value);
  5408. for (isize i = 0; i < value_count; i++) {
  5409. LLVMValueRef val = old_values[i];
  5410. if (!LLVMIsConstant(val)) {
  5411. LLVMValueRef dst = LLVMBuildStructGEP(p->builder, v.addr.value, cast(unsigned)i, "");
  5412. LLVMBuildStore(p->builder, val, dst);
  5413. }
  5414. }
  5415. return lb_addr_load(p, v);
  5416. }
  5417. } else if (is_type_bit_set(type)) {
  5418. ast_node(cl, CompoundLit, value.value_compound);
  5419. if (cl->elems.count == 0) {
  5420. return lb_const_nil(m, original_type);
  5421. }
  5422. i64 sz = type_size_of(type);
  5423. if (sz == 0) {
  5424. return lb_const_nil(m, original_type);
  5425. }
  5426. u64 bits = 0;
  5427. for_array(i, cl->elems) {
  5428. Ast *e = cl->elems[i];
  5429. GB_ASSERT(e->kind != Ast_FieldValue);
  5430. TypeAndValue tav = e->tav;
  5431. if (tav.mode != Addressing_Constant) {
  5432. continue;
  5433. }
  5434. GB_ASSERT(tav.value.kind == ExactValue_Integer);
  5435. i64 v = big_int_to_i64(&tav.value.value_integer);
  5436. i64 lower = type->BitSet.lower;
  5437. bits |= 1ull<<cast(u64)(v-lower);
  5438. }
  5439. if (is_type_different_to_arch_endianness(type)) {
  5440. i64 size = type_size_of(type);
  5441. switch (size) {
  5442. case 2: bits = cast(u64)gb_endian_swap16(cast(u16)bits); break;
  5443. case 4: bits = cast(u64)gb_endian_swap32(cast(u32)bits); break;
  5444. case 8: bits = cast(u64)gb_endian_swap64(cast(u64)bits); break;
  5445. }
  5446. }
  5447. res.value = LLVMConstInt(lb_type(m, original_type), bits, false);
  5448. return res;
  5449. } else {
  5450. return lb_const_nil(m, original_type);
  5451. }
  5452. break;
  5453. case ExactValue_Procedure:
  5454. {
  5455. Ast *expr = value.value_procedure;
  5456. GB_ASSERT(expr != nullptr);
  5457. if (expr->kind == Ast_ProcLit) {
  5458. return lb_generate_anonymous_proc_lit(m, str_lit("_proclit"), expr);
  5459. }
  5460. }
  5461. break;
  5462. case ExactValue_Typeid:
  5463. return lb_typeid(m, value.value_typeid);
  5464. }
  5465. return lb_const_nil(m, original_type);
  5466. }
  5467. lbValue lb_emit_source_code_location(lbProcedure *p, String const &procedure, TokenPos const &pos) {
  5468. lbModule *m = p->module;
  5469. LLVMValueRef fields[4] = {};
  5470. fields[0]/*file*/ = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id)).value;
  5471. fields[1]/*line*/ = lb_const_int(m, t_i32, pos.line).value;
  5472. fields[2]/*column*/ = lb_const_int(m, t_i32, pos.column).value;
  5473. fields[3]/*procedure*/ = lb_find_or_add_entity_string(p->module, procedure).value;
  5474. lbValue res = {};
  5475. res.value = llvm_const_named_struct(lb_type(m, t_source_code_location), fields, gb_count_of(fields));
  5476. res.type = t_source_code_location;
  5477. return res;
  5478. }
  5479. lbValue lb_emit_source_code_location(lbProcedure *p, Ast *node) {
  5480. String proc_name = {};
  5481. if (p->entity) {
  5482. proc_name = p->entity->token.string;
  5483. }
  5484. TokenPos pos = {};
  5485. if (node) {
  5486. pos = ast_token(node).pos;
  5487. }
  5488. return lb_emit_source_code_location(p, proc_name, pos);
  5489. }
  5490. lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x, Type *type) {
  5491. switch (op) {
  5492. case Token_Add:
  5493. return x;
  5494. case Token_Not: // Boolean not
  5495. case Token_Xor: // Bitwise not
  5496. case Token_Sub: // Number negation
  5497. break;
  5498. case Token_Pointer:
  5499. GB_PANIC("This should be handled elsewhere");
  5500. break;
  5501. }
  5502. if (is_type_array(x.type)) {
  5503. // IMPORTANT TODO(bill): This is very wasteful with regards to stack memory
  5504. Type *tl = base_type(x.type);
  5505. lbValue val = lb_address_from_load_or_generate_local(p, x);
  5506. GB_ASSERT(is_type_array(type));
  5507. Type *elem_type = base_array_type(type);
  5508. // NOTE(bill): Doesn't need to be zero because it will be initialized in the loops
  5509. lbAddr res_addr = lb_add_local_generated(p, type, false);
  5510. lbValue res = lb_addr_get_ptr(p, res_addr);
  5511. bool inline_array_arith = type_size_of(type) <= build_context.max_align;
  5512. i32 count = cast(i32)tl->Array.count;
  5513. if (inline_array_arith) {
  5514. // inline
  5515. for (i32 i = 0; i < count; i++) {
  5516. lbValue e = lb_emit_load(p, lb_emit_array_epi(p, val, i));
  5517. lbValue z = lb_emit_unary_arith(p, op, e, elem_type);
  5518. lb_emit_store(p, lb_emit_array_epi(p, res, i), z);
  5519. }
  5520. } else {
  5521. auto loop_data = lb_loop_start(p, count, t_i32);
  5522. lbValue e = lb_emit_load(p, lb_emit_array_ep(p, val, loop_data.idx));
  5523. lbValue z = lb_emit_unary_arith(p, op, e, elem_type);
  5524. lb_emit_store(p, lb_emit_array_ep(p, res, loop_data.idx), z);
  5525. lb_loop_end(p, loop_data);
  5526. }
  5527. return lb_emit_load(p, res);
  5528. }
  5529. if (op == Token_Xor) {
  5530. lbValue cmp = {};
  5531. cmp.value = LLVMBuildNot(p->builder, x.value, "");
  5532. cmp.type = x.type;
  5533. return lb_emit_conv(p, cmp, type);
  5534. }
  5535. if (op == Token_Not) {
  5536. lbValue cmp = {};
  5537. LLVMValueRef zero = LLVMConstInt(lb_type(p->module, x.type), 0, false);
  5538. cmp.value = LLVMBuildICmp(p->builder, LLVMIntEQ, x.value, zero, "");
  5539. cmp.type = t_llvm_bool;
  5540. return lb_emit_conv(p, cmp, type);
  5541. }
  5542. if (op == Token_Sub && is_type_integer(type) && is_type_different_to_arch_endianness(type)) {
  5543. Type *platform_type = integer_endian_type_to_platform_type(type);
  5544. lbValue v = lb_emit_byte_swap(p, x, platform_type);
  5545. lbValue res = {};
  5546. res.value = LLVMBuildNeg(p->builder, v.value, "");
  5547. res.type = platform_type;
  5548. return lb_emit_byte_swap(p, res, type);
  5549. }
  5550. if (op == Token_Sub && is_type_float(type) && is_type_different_to_arch_endianness(type)) {
  5551. Type *platform_type = integer_endian_type_to_platform_type(type);
  5552. lbValue v = lb_emit_byte_swap(p, x, platform_type);
  5553. lbValue res = {};
  5554. res.value = LLVMBuildFNeg(p->builder, v.value, "");
  5555. res.type = platform_type;
  5556. return lb_emit_byte_swap(p, res, type);
  5557. }
  5558. lbValue res = {};
  5559. switch (op) {
  5560. case Token_Not: // Boolean not
  5561. case Token_Xor: // Bitwise not
  5562. res.value = LLVMBuildNot(p->builder, x.value, "");
  5563. res.type = x.type;
  5564. return res;
  5565. case Token_Sub: // Number negation
  5566. if (is_type_integer(x.type)) {
  5567. res.value = LLVMBuildNeg(p->builder, x.value, "");
  5568. } else if (is_type_float(x.type)) {
  5569. res.value = LLVMBuildFNeg(p->builder, x.value, "");
  5570. } else if (is_type_complex(x.type)) {
  5571. LLVMValueRef v0 = LLVMBuildFNeg(p->builder, LLVMBuildExtractValue(p->builder, x.value, 0, ""), "");
  5572. LLVMValueRef v1 = LLVMBuildFNeg(p->builder, LLVMBuildExtractValue(p->builder, x.value, 1, ""), "");
  5573. lbAddr addr = lb_add_local_generated(p, x.type, false);
  5574. LLVMBuildStore(p->builder, v0, LLVMBuildStructGEP(p->builder, addr.addr.value, 0, ""));
  5575. LLVMBuildStore(p->builder, v1, LLVMBuildStructGEP(p->builder, addr.addr.value, 1, ""));
  5576. return lb_addr_load(p, addr);
  5577. } else if (is_type_quaternion(x.type)) {
  5578. LLVMValueRef v0 = LLVMBuildFNeg(p->builder, LLVMBuildExtractValue(p->builder, x.value, 0, ""), "");
  5579. LLVMValueRef v1 = LLVMBuildFNeg(p->builder, LLVMBuildExtractValue(p->builder, x.value, 1, ""), "");
  5580. LLVMValueRef v2 = LLVMBuildFNeg(p->builder, LLVMBuildExtractValue(p->builder, x.value, 2, ""), "");
  5581. LLVMValueRef v3 = LLVMBuildFNeg(p->builder, LLVMBuildExtractValue(p->builder, x.value, 3, ""), "");
  5582. lbAddr addr = lb_add_local_generated(p, x.type, false);
  5583. LLVMBuildStore(p->builder, v0, LLVMBuildStructGEP(p->builder, addr.addr.value, 0, ""));
  5584. LLVMBuildStore(p->builder, v1, LLVMBuildStructGEP(p->builder, addr.addr.value, 1, ""));
  5585. LLVMBuildStore(p->builder, v2, LLVMBuildStructGEP(p->builder, addr.addr.value, 2, ""));
  5586. LLVMBuildStore(p->builder, v3, LLVMBuildStructGEP(p->builder, addr.addr.value, 3, ""));
  5587. return lb_addr_load(p, addr);
  5588. } else {
  5589. GB_PANIC("Unhandled type %s", type_to_string(x.type));
  5590. }
  5591. res.type = x.type;
  5592. return res;
  5593. }
  5594. return res;
  5595. }
  5596. lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbValue rhs, Type *type) {
  5597. lbModule *m = p->module;
  5598. if (is_type_array(lhs.type) || is_type_array(rhs.type)) {
  5599. lhs = lb_emit_conv(p, lhs, type);
  5600. rhs = lb_emit_conv(p, rhs, type);
  5601. lbValue x = lb_address_from_load_or_generate_local(p, lhs);
  5602. lbValue y = lb_address_from_load_or_generate_local(p, rhs);
  5603. GB_ASSERT(is_type_array(type));
  5604. Type *elem_type = base_array_type(type);
  5605. lbAddr res = lb_add_local_generated(p, type, false);
  5606. i64 count = base_type(type)->Array.count;
  5607. bool inline_array_arith = type_size_of(type) <= build_context.max_align;
  5608. if (inline_array_arith) {
  5609. for (i64 i = 0; i < count; i++) {
  5610. lbValue a_ptr = lb_emit_array_epi(p, x, i);
  5611. lbValue b_ptr = lb_emit_array_epi(p, y, i);
  5612. lbValue dst_ptr = lb_emit_array_epi(p, res.addr, i);
  5613. lbValue a = lb_emit_load(p, a_ptr);
  5614. lbValue b = lb_emit_load(p, b_ptr);
  5615. lbValue c = lb_emit_arith(p, op, a, b, elem_type);
  5616. lb_emit_store(p, dst_ptr, c);
  5617. }
  5618. } else {
  5619. auto loop_data = lb_loop_start(p, count, t_i32);
  5620. lbValue a_ptr = lb_emit_array_ep(p, x, loop_data.idx);
  5621. lbValue b_ptr = lb_emit_array_ep(p, y, loop_data.idx);
  5622. lbValue dst_ptr = lb_emit_array_ep(p, res.addr, loop_data.idx);
  5623. lbValue a = lb_emit_load(p, a_ptr);
  5624. lbValue b = lb_emit_load(p, b_ptr);
  5625. lbValue c = lb_emit_arith(p, op, a, b, elem_type);
  5626. lb_emit_store(p, dst_ptr, c);
  5627. lb_loop_end(p, loop_data);
  5628. }
  5629. return lb_addr_load(p, res);
  5630. } else if (is_type_complex(type)) {
  5631. lhs = lb_emit_conv(p, lhs, type);
  5632. rhs = lb_emit_conv(p, rhs, type);
  5633. Type *ft = base_complex_elem_type(type);
  5634. if (op == Token_Quo) {
  5635. auto args = array_make<lbValue>(permanent_allocator(), 2);
  5636. args[0] = lhs;
  5637. args[1] = rhs;
  5638. switch (type_size_of(ft)) {
  5639. case 4: return lb_emit_runtime_call(p, "quo_complex64", args);
  5640. case 8: return lb_emit_runtime_call(p, "quo_complex128", args);
  5641. default: GB_PANIC("Unknown float type"); break;
  5642. }
  5643. }
  5644. lbAddr res = lb_add_local_generated(p, type, false); // NOTE: initialized in full later
  5645. lbValue a = lb_emit_struct_ev(p, lhs, 0);
  5646. lbValue b = lb_emit_struct_ev(p, lhs, 1);
  5647. lbValue c = lb_emit_struct_ev(p, rhs, 0);
  5648. lbValue d = lb_emit_struct_ev(p, rhs, 1);
  5649. lbValue real = {};
  5650. lbValue imag = {};
  5651. switch (op) {
  5652. case Token_Add:
  5653. real = lb_emit_arith(p, Token_Add, a, c, ft);
  5654. imag = lb_emit_arith(p, Token_Add, b, d, ft);
  5655. break;
  5656. case Token_Sub:
  5657. real = lb_emit_arith(p, Token_Sub, a, c, ft);
  5658. imag = lb_emit_arith(p, Token_Sub, b, d, ft);
  5659. break;
  5660. case Token_Mul: {
  5661. lbValue x = lb_emit_arith(p, Token_Mul, a, c, ft);
  5662. lbValue y = lb_emit_arith(p, Token_Mul, b, d, ft);
  5663. real = lb_emit_arith(p, Token_Sub, x, y, ft);
  5664. lbValue z = lb_emit_arith(p, Token_Mul, b, c, ft);
  5665. lbValue w = lb_emit_arith(p, Token_Mul, a, d, ft);
  5666. imag = lb_emit_arith(p, Token_Add, z, w, ft);
  5667. break;
  5668. }
  5669. }
  5670. lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 0), real);
  5671. lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 1), imag);
  5672. return lb_addr_load(p, res);
  5673. } else if (is_type_quaternion(type)) {
  5674. lhs = lb_emit_conv(p, lhs, type);
  5675. rhs = lb_emit_conv(p, rhs, type);
  5676. Type *ft = base_complex_elem_type(type);
  5677. if (op == Token_Add || op == Token_Sub) {
  5678. lbAddr res = lb_add_local_generated(p, type, false); // NOTE: initialized in full later
  5679. lbValue x0 = lb_emit_struct_ev(p, lhs, 0);
  5680. lbValue x1 = lb_emit_struct_ev(p, lhs, 1);
  5681. lbValue x2 = lb_emit_struct_ev(p, lhs, 2);
  5682. lbValue x3 = lb_emit_struct_ev(p, lhs, 3);
  5683. lbValue y0 = lb_emit_struct_ev(p, rhs, 0);
  5684. lbValue y1 = lb_emit_struct_ev(p, rhs, 1);
  5685. lbValue y2 = lb_emit_struct_ev(p, rhs, 2);
  5686. lbValue y3 = lb_emit_struct_ev(p, rhs, 3);
  5687. lbValue z0 = lb_emit_arith(p, op, x0, y0, ft);
  5688. lbValue z1 = lb_emit_arith(p, op, x1, y1, ft);
  5689. lbValue z2 = lb_emit_arith(p, op, x2, y2, ft);
  5690. lbValue z3 = lb_emit_arith(p, op, x3, y3, ft);
  5691. lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 0), z0);
  5692. lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 1), z1);
  5693. lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 2), z2);
  5694. lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 3), z3);
  5695. return lb_addr_load(p, res);
  5696. } else if (op == Token_Mul) {
  5697. auto args = array_make<lbValue>(permanent_allocator(), 2);
  5698. args[0] = lhs;
  5699. args[1] = rhs;
  5700. switch (8*type_size_of(ft)) {
  5701. case 32: return lb_emit_runtime_call(p, "mul_quaternion128", args);
  5702. case 64: return lb_emit_runtime_call(p, "mul_quaternion256", args);
  5703. default: GB_PANIC("Unknown float type"); break;
  5704. }
  5705. } else if (op == Token_Quo) {
  5706. auto args = array_make<lbValue>(permanent_allocator(), 2);
  5707. args[0] = lhs;
  5708. args[1] = rhs;
  5709. switch (8*type_size_of(ft)) {
  5710. case 32: return lb_emit_runtime_call(p, "quo_quaternion128", args);
  5711. case 64: return lb_emit_runtime_call(p, "quo_quaternion256", args);
  5712. default: GB_PANIC("Unknown float type"); break;
  5713. }
  5714. }
  5715. }
  5716. if (is_type_integer(type) && is_type_different_to_arch_endianness(type)) {
  5717. switch (op) {
  5718. case Token_AndNot:
  5719. case Token_And:
  5720. case Token_Or:
  5721. case Token_Xor:
  5722. goto handle_op;
  5723. }
  5724. Type *platform_type = integer_endian_type_to_platform_type(type);
  5725. lbValue x = lb_emit_byte_swap(p, lhs, integer_endian_type_to_platform_type(lhs.type));
  5726. lbValue y = lb_emit_byte_swap(p, rhs, integer_endian_type_to_platform_type(rhs.type));
  5727. lbValue res = lb_emit_arith(p, op, x, y, platform_type);
  5728. return lb_emit_byte_swap(p, res, type);
  5729. }
  5730. if (is_type_float(type) && is_type_different_to_arch_endianness(type)) {
  5731. Type *platform_type = integer_endian_type_to_platform_type(type);
  5732. lbValue x = lb_emit_conv(p, lhs, integer_endian_type_to_platform_type(lhs.type));
  5733. lbValue y = lb_emit_conv(p, rhs, integer_endian_type_to_platform_type(rhs.type));
  5734. lbValue res = lb_emit_arith(p, op, x, y, platform_type);
  5735. return lb_emit_byte_swap(p, res, type);
  5736. }
  5737. handle_op:
  5738. lhs = lb_emit_conv(p, lhs, type);
  5739. rhs = lb_emit_conv(p, rhs, type);
  5740. lbValue res = {};
  5741. res.type = type;
  5742. // NOTE(bill): Bit Set Aliases for + and -
  5743. if (is_type_bit_set(type)) {
  5744. switch (op) {
  5745. case Token_Add: op = Token_Or; break;
  5746. case Token_Sub: op = Token_AndNot; break;
  5747. }
  5748. }
  5749. switch (op) {
  5750. case Token_Add:
  5751. if (is_type_float(type)) {
  5752. res.value = LLVMBuildFAdd(p->builder, lhs.value, rhs.value, "");
  5753. return res;
  5754. }
  5755. res.value = LLVMBuildAdd(p->builder, lhs.value, rhs.value, "");
  5756. return res;
  5757. case Token_Sub:
  5758. if (is_type_float(type)) {
  5759. res.value = LLVMBuildFSub(p->builder, lhs.value, rhs.value, "");
  5760. return res;
  5761. }
  5762. res.value = LLVMBuildSub(p->builder, lhs.value, rhs.value, "");
  5763. return res;
  5764. case Token_Mul:
  5765. if (is_type_float(type)) {
  5766. res.value = LLVMBuildFMul(p->builder, lhs.value, rhs.value, "");
  5767. return res;
  5768. }
  5769. res.value = LLVMBuildMul(p->builder, lhs.value, rhs.value, "");
  5770. return res;
  5771. case Token_Quo:
  5772. if (is_type_float(type)) {
  5773. res.value = LLVMBuildFDiv(p->builder, lhs.value, rhs.value, "");
  5774. return res;
  5775. } else if (is_type_unsigned(type)) {
  5776. res.value = LLVMBuildUDiv(p->builder, lhs.value, rhs.value, "");
  5777. return res;
  5778. }
  5779. res.value = LLVMBuildSDiv(p->builder, lhs.value, rhs.value, "");
  5780. return res;
  5781. case Token_Mod:
  5782. if (is_type_float(type)) {
  5783. res.value = LLVMBuildFRem(p->builder, lhs.value, rhs.value, "");
  5784. return res;
  5785. } else if (is_type_unsigned(type)) {
  5786. res.value = LLVMBuildURem(p->builder, lhs.value, rhs.value, "");
  5787. return res;
  5788. }
  5789. res.value = LLVMBuildSRem(p->builder, lhs.value, rhs.value, "");
  5790. return res;
  5791. case Token_ModMod:
  5792. if (is_type_unsigned(type)) {
  5793. res.value = LLVMBuildURem(p->builder, lhs.value, rhs.value, "");
  5794. return res;
  5795. } else {
  5796. LLVMValueRef a = LLVMBuildSRem(p->builder, lhs.value, rhs.value, "");
  5797. LLVMValueRef b = LLVMBuildAdd(p->builder, a, rhs.value, "");
  5798. LLVMValueRef c = LLVMBuildSRem(p->builder, b, rhs.value, "");
  5799. res.value = c;
  5800. return res;
  5801. }
  5802. case Token_And:
  5803. res.value = LLVMBuildAnd(p->builder, lhs.value, rhs.value, "");
  5804. return res;
  5805. case Token_Or:
  5806. res.value = LLVMBuildOr(p->builder, lhs.value, rhs.value, "");
  5807. return res;
  5808. case Token_Xor:
  5809. res.value = LLVMBuildXor(p->builder, lhs.value, rhs.value, "");
  5810. return res;
  5811. case Token_Shl:
  5812. {
  5813. rhs = lb_emit_conv(p, rhs, lhs.type);
  5814. LLVMValueRef lhsval = lhs.value;
  5815. LLVMValueRef bits = rhs.value;
  5816. LLVMValueRef bit_size = LLVMConstInt(lb_type(p->module, rhs.type), 8*type_size_of(lhs.type), false);
  5817. LLVMValueRef width_test = LLVMBuildICmp(p->builder, LLVMIntULT, bits, bit_size, "");
  5818. res.value = LLVMBuildShl(p->builder, lhsval, bits, "");
  5819. LLVMValueRef zero = LLVMConstNull(lb_type(p->module, lhs.type));
  5820. res.value = LLVMBuildSelect(p->builder, width_test, res.value, zero, "");
  5821. return res;
  5822. }
  5823. case Token_Shr:
  5824. {
  5825. rhs = lb_emit_conv(p, rhs, lhs.type);
  5826. LLVMValueRef lhsval = lhs.value;
  5827. LLVMValueRef bits = rhs.value;
  5828. bool is_unsigned = is_type_unsigned(type);
  5829. LLVMValueRef bit_size = LLVMConstInt(lb_type(p->module, rhs.type), 8*type_size_of(lhs.type), false);
  5830. LLVMValueRef width_test = LLVMBuildICmp(p->builder, LLVMIntULT, bits, bit_size, "");
  5831. if (is_unsigned) {
  5832. res.value = LLVMBuildLShr(p->builder, lhsval, bits, "");
  5833. } else {
  5834. res.value = LLVMBuildAShr(p->builder, lhsval, bits, "");
  5835. }
  5836. LLVMValueRef zero = LLVMConstNull(lb_type(p->module, lhs.type));
  5837. res.value = LLVMBuildSelect(p->builder, width_test, res.value, zero, "");
  5838. return res;
  5839. }
  5840. case Token_AndNot:
  5841. {
  5842. LLVMValueRef new_rhs = LLVMBuildNot(p->builder, rhs.value, "");
  5843. res.value = LLVMBuildAnd(p->builder, lhs.value, new_rhs, "");
  5844. return res;
  5845. }
  5846. break;
  5847. }
  5848. GB_PANIC("unhandled operator of lb_emit_arith");
  5849. return {};
  5850. }
  5851. lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) {
  5852. ast_node(be, BinaryExpr, expr);
  5853. TypeAndValue tv = type_and_value_of_expr(expr);
  5854. switch (be->op.kind) {
  5855. case Token_Add:
  5856. case Token_Sub:
  5857. case Token_Mul:
  5858. case Token_Quo:
  5859. case Token_Mod:
  5860. case Token_ModMod:
  5861. case Token_And:
  5862. case Token_Or:
  5863. case Token_Xor:
  5864. case Token_AndNot:
  5865. case Token_Shl:
  5866. case Token_Shr: {
  5867. Type *type = default_type(tv.type);
  5868. lbValue left = lb_build_expr(p, be->left);
  5869. lbValue right = lb_build_expr(p, be->right);
  5870. return lb_emit_arith(p, be->op.kind, left, right, type);
  5871. }
  5872. case Token_CmpEq:
  5873. case Token_NotEq:
  5874. case Token_Lt:
  5875. case Token_LtEq:
  5876. case Token_Gt:
  5877. case Token_GtEq:
  5878. {
  5879. lbValue left = {};
  5880. lbValue right = {};
  5881. if (be->left->tav.mode == Addressing_Type) {
  5882. left = lb_typeid(p->module, be->left->tav.type);
  5883. }
  5884. if (be->right->tav.mode == Addressing_Type) {
  5885. right = lb_typeid(p->module, be->right->tav.type);
  5886. }
  5887. if (left.value == nullptr) left = lb_build_expr(p, be->left);
  5888. if (right.value == nullptr) right = lb_build_expr(p, be->right);
  5889. lbValue cmp = lb_emit_comp(p, be->op.kind, left, right);
  5890. Type *type = default_type(tv.type);
  5891. return lb_emit_conv(p, cmp, type);
  5892. }
  5893. case Token_CmpAnd:
  5894. case Token_CmpOr:
  5895. return lb_emit_logical_binary_expr(p, be->op.kind, be->left, be->right, tv.type);
  5896. case Token_in:
  5897. case Token_not_in:
  5898. {
  5899. lbValue left = lb_build_expr(p, be->left);
  5900. Type *type = default_type(tv.type);
  5901. lbValue right = lb_build_expr(p, be->right);
  5902. Type *rt = base_type(right.type);
  5903. switch (rt->kind) {
  5904. case Type_Map:
  5905. {
  5906. lbValue addr = lb_address_from_load_or_generate_local(p, right);
  5907. lbValue h = lb_gen_map_header(p, addr, rt);
  5908. lbValue key = lb_gen_map_hash(p, left, rt->Map.key);
  5909. auto args = array_make<lbValue>(permanent_allocator(), 2);
  5910. args[0] = h;
  5911. args[1] = key;
  5912. lbValue ptr = lb_emit_runtime_call(p, "__dynamic_map_get", args);
  5913. if (be->op.kind == Token_in) {
  5914. return lb_emit_conv(p, lb_emit_comp_against_nil(p, Token_NotEq, ptr), t_bool);
  5915. } else {
  5916. return lb_emit_conv(p, lb_emit_comp_against_nil(p, Token_CmpEq, ptr), t_bool);
  5917. }
  5918. }
  5919. break;
  5920. case Type_BitSet:
  5921. {
  5922. Type *key_type = rt->BitSet.elem;
  5923. GB_ASSERT(are_types_identical(left.type, key_type));
  5924. Type *it = bit_set_to_int(rt);
  5925. left = lb_emit_conv(p, left, it);
  5926. lbValue lower = lb_const_value(p->module, it, exact_value_i64(rt->BitSet.lower));
  5927. lbValue key = lb_emit_arith(p, Token_Sub, left, lower, it);
  5928. lbValue bit = lb_emit_arith(p, Token_Shl, lb_const_int(p->module, it, 1), key, it);
  5929. bit = lb_emit_conv(p, bit, it);
  5930. lbValue old_value = lb_emit_transmute(p, right, it);
  5931. lbValue new_value = lb_emit_arith(p, Token_And, old_value, bit, it);
  5932. if (be->op.kind == Token_in) {
  5933. return lb_emit_conv(p, lb_emit_comp(p, Token_NotEq, new_value, lb_const_int(p->module, new_value.type, 0)), t_bool);
  5934. } else {
  5935. return lb_emit_conv(p, lb_emit_comp(p, Token_CmpEq, new_value, lb_const_int(p->module, new_value.type, 0)), t_bool);
  5936. }
  5937. }
  5938. break;
  5939. default:
  5940. GB_PANIC("Invalid 'in' type");
  5941. }
  5942. break;
  5943. }
  5944. break;
  5945. default:
  5946. GB_PANIC("Invalid binary expression");
  5947. break;
  5948. }
  5949. return {};
  5950. }
  5951. String lookup_subtype_polymorphic_field(CheckerInfo *info, Type *dst, Type *src) {
  5952. Type *prev_src = src;
  5953. // Type *prev_dst = dst;
  5954. src = base_type(type_deref(src));
  5955. // dst = base_type(type_deref(dst));
  5956. bool src_is_ptr = src != prev_src;
  5957. // bool dst_is_ptr = dst != prev_dst;
  5958. GB_ASSERT(is_type_struct(src) || is_type_union(src));
  5959. for_array(i, src->Struct.fields) {
  5960. Entity *f = src->Struct.fields[i];
  5961. if (f->kind == Entity_Variable && f->flags & EntityFlag_Using) {
  5962. if (are_types_identical(dst, f->type)) {
  5963. return f->token.string;
  5964. }
  5965. if (src_is_ptr && is_type_pointer(dst)) {
  5966. if (are_types_identical(type_deref(dst), f->type)) {
  5967. return f->token.string;
  5968. }
  5969. }
  5970. if (is_type_struct(f->type)) {
  5971. String name = lookup_subtype_polymorphic_field(info, dst, f->type);
  5972. if (name.len > 0) {
  5973. return name;
  5974. }
  5975. }
  5976. }
  5977. }
  5978. return str_lit("");
  5979. }
  5980. lbValue lb_const_ptr_cast(lbModule *m, lbValue value, Type *t) {
  5981. GB_ASSERT(is_type_pointer(value.type));
  5982. GB_ASSERT(is_type_pointer(t));
  5983. GB_ASSERT(lb_is_const(value));
  5984. lbValue res = {};
  5985. res.value = LLVMConstPointerCast(value.value, lb_type(m, t));
  5986. res.type = t;
  5987. return res;
  5988. }
  5989. lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
  5990. lbModule *m = p->module;
  5991. t = reduce_tuple_to_single_type(t);
  5992. Type *src_type = value.type;
  5993. if (are_types_identical(t, src_type)) {
  5994. return value;
  5995. }
  5996. Type *src = core_type(src_type);
  5997. Type *dst = core_type(t);
  5998. GB_ASSERT(src != nullptr);
  5999. GB_ASSERT(dst != nullptr);
  6000. if (is_type_untyped_nil(src)) {
  6001. return lb_const_nil(m, t);
  6002. }
  6003. if (is_type_untyped_undef(src)) {
  6004. return lb_const_undef(m, t);
  6005. }
  6006. if (LLVMIsConstant(value.value)) {
  6007. if (is_type_any(dst)) {
  6008. Type *st = default_type(src_type);
  6009. lbAddr default_value = lb_add_local_generated(p, st, false);
  6010. lb_addr_store(p, default_value, value);
  6011. lbValue data = lb_emit_conv(p, default_value.addr, t_rawptr);
  6012. lbValue id = lb_typeid(m, st);
  6013. lbAddr res = lb_add_local_generated(p, t, false);
  6014. lbValue a0 = lb_emit_struct_ep(p, res.addr, 0);
  6015. lbValue a1 = lb_emit_struct_ep(p, res.addr, 1);
  6016. lb_emit_store(p, a0, data);
  6017. lb_emit_store(p, a1, id);
  6018. return lb_addr_load(p, res);
  6019. } else if (dst->kind == Type_Basic) {
  6020. if (src->Basic.kind == Basic_string && dst->Basic.kind == Basic_cstring) {
  6021. String str = lb_get_const_string(m, value);
  6022. lbValue res = {};
  6023. res.type = t;
  6024. res.value = llvm_cstring(m, str);
  6025. return res;
  6026. }
  6027. // if (is_type_float(dst)) {
  6028. // return value;
  6029. // } else if (is_type_integer(dst)) {
  6030. // return value;
  6031. // }
  6032. // ExactValue ev = value->Constant.value;
  6033. // if (is_type_float(dst)) {
  6034. // ev = exact_value_to_float(ev);
  6035. // } else if (is_type_complex(dst)) {
  6036. // ev = exact_value_to_complex(ev);
  6037. // } else if (is_type_quaternion(dst)) {
  6038. // ev = exact_value_to_quaternion(ev);
  6039. // } else if (is_type_string(dst)) {
  6040. // // Handled elsewhere
  6041. // GB_ASSERT_MSG(ev.kind == ExactValue_String, "%d", ev.kind);
  6042. // } else if (is_type_integer(dst)) {
  6043. // ev = exact_value_to_integer(ev);
  6044. // } else if (is_type_pointer(dst)) {
  6045. // // IMPORTANT NOTE(bill): LLVM doesn't support pointer constants expect 'null'
  6046. // lbValue i = lb_add_module_constant(p->module, t_uintptr, ev);
  6047. // return lb_emit(p, lb_instr_conv(p, irConv_inttoptr, i, t_uintptr, dst));
  6048. // }
  6049. // return lb_const_value(p->module, t, ev);
  6050. }
  6051. }
  6052. if (are_types_identical(src, dst)) {
  6053. if (!are_types_identical(src_type, t)) {
  6054. return lb_emit_transmute(p, value, t);
  6055. }
  6056. return value;
  6057. }
  6058. // bool <-> llvm bool
  6059. if (is_type_boolean(src) && dst == t_llvm_bool) {
  6060. lbValue res = {};
  6061. res.value = LLVMBuildTrunc(p->builder, value.value, lb_type(m, dst), "");
  6062. res.type = dst;
  6063. return res;
  6064. }
  6065. if (src == t_llvm_bool && is_type_boolean(dst)) {
  6066. lbValue res = {};
  6067. res.value = LLVMBuildZExt(p->builder, value.value, lb_type(m, dst), "");
  6068. res.type = dst;
  6069. return res;
  6070. }
  6071. // integer -> integer
  6072. if (is_type_integer(src) && is_type_integer(dst)) {
  6073. GB_ASSERT(src->kind == Type_Basic &&
  6074. dst->kind == Type_Basic);
  6075. i64 sz = type_size_of(default_type(src));
  6076. i64 dz = type_size_of(default_type(dst));
  6077. if (sz == dz) {
  6078. if (dz > 1 && !types_have_same_internal_endian(src, dst)) {
  6079. return lb_emit_byte_swap(p, value, t);
  6080. }
  6081. lbValue res = {};
  6082. res.value = value.value;
  6083. res.type = t;
  6084. return res;
  6085. }
  6086. if (sz > 1 && is_type_different_to_arch_endianness(src)) {
  6087. Type *platform_src_type = integer_endian_type_to_platform_type(src);
  6088. value = lb_emit_byte_swap(p, value, platform_src_type);
  6089. }
  6090. LLVMOpcode op = LLVMTrunc;
  6091. if (dz < sz) {
  6092. op = LLVMTrunc;
  6093. } else if (dz == sz) {
  6094. // NOTE(bill): In LLVM, all integers are signed and rely upon 2's compliment
  6095. // NOTE(bill): Copy the value just for type correctness
  6096. op = LLVMBitCast;
  6097. } else if (dz > sz) {
  6098. op = is_type_unsigned(src) ? LLVMZExt : LLVMSExt; // zero extent
  6099. }
  6100. if (dz > 1 && is_type_different_to_arch_endianness(dst)) {
  6101. Type *platform_dst_type = integer_endian_type_to_platform_type(dst);
  6102. lbValue res = {};
  6103. res.value = LLVMBuildCast(p->builder, op, value.value, lb_type(m, platform_dst_type), "");
  6104. res.type = t;
  6105. return lb_emit_byte_swap(p, res, t);
  6106. } else {
  6107. lbValue res = {};
  6108. res.value = LLVMBuildCast(p->builder, op, value.value, lb_type(m, t), "");
  6109. res.type = t;
  6110. return res;
  6111. }
  6112. }
  6113. // boolean -> boolean/integer
  6114. if (is_type_boolean(src) && (is_type_boolean(dst) || is_type_integer(dst))) {
  6115. LLVMValueRef b = LLVMBuildICmp(p->builder, LLVMIntNE, value.value, LLVMConstNull(lb_type(m, value.type)), "");
  6116. lbValue res = {};
  6117. res.value = LLVMBuildIntCast2(p->builder, value.value, lb_type(m, t), false, "");
  6118. res.type = t;
  6119. return res;
  6120. }
  6121. if (is_type_cstring(src) && is_type_u8_ptr(dst)) {
  6122. return lb_emit_transmute(p, value, dst);
  6123. }
  6124. if (is_type_u8_ptr(src) && is_type_cstring(dst)) {
  6125. return lb_emit_transmute(p, value, dst);
  6126. }
  6127. if (is_type_cstring(src) && is_type_rawptr(dst)) {
  6128. return lb_emit_transmute(p, value, dst);
  6129. }
  6130. if (is_type_rawptr(src) && is_type_cstring(dst)) {
  6131. return lb_emit_transmute(p, value, dst);
  6132. }
  6133. if (are_types_identical(src, t_cstring) && are_types_identical(dst, t_string)) {
  6134. lbValue c = lb_emit_conv(p, value, t_cstring);
  6135. auto args = array_make<lbValue>(permanent_allocator(), 1);
  6136. args[0] = c;
  6137. lbValue s = lb_emit_runtime_call(p, "cstring_to_string", args);
  6138. return lb_emit_conv(p, s, dst);
  6139. }
  6140. // integer -> boolean
  6141. if (is_type_integer(src) && is_type_boolean(dst)) {
  6142. lbValue res = {};
  6143. res.value = LLVMBuildICmp(p->builder, LLVMIntNE, value.value, LLVMConstNull(lb_type(m, value.type)), "");
  6144. res.type = t_llvm_bool;
  6145. return lb_emit_conv(p, res, t);
  6146. }
  6147. // float -> float
  6148. if (is_type_float(src) && is_type_float(dst)) {
  6149. i64 sz = type_size_of(src);
  6150. i64 dz = type_size_of(dst);
  6151. if (dz == sz) {
  6152. if (types_have_same_internal_endian(src, dst)) {
  6153. lbValue res = {};
  6154. res.type = t;
  6155. res.value = value.value;
  6156. return res;
  6157. } else {
  6158. return lb_emit_byte_swap(p, value, t);
  6159. }
  6160. }
  6161. if (is_type_different_to_arch_endianness(src) || is_type_different_to_arch_endianness(dst)) {
  6162. Type *platform_src_type = integer_endian_type_to_platform_type(src);
  6163. Type *platform_dst_type = integer_endian_type_to_platform_type(dst);
  6164. lbValue res = {};
  6165. res = lb_emit_conv(p, value, platform_src_type);
  6166. res = lb_emit_conv(p, res, platform_dst_type);
  6167. if (is_type_different_to_arch_endianness(dst)) {
  6168. res = lb_emit_byte_swap(p, res, t);
  6169. }
  6170. return lb_emit_conv(p, res, t);
  6171. }
  6172. lbValue res = {};
  6173. res.type = t;
  6174. if (dz >= sz) {
  6175. res.value = LLVMBuildFPExt(p->builder, value.value, lb_type(m, t), "");
  6176. } else {
  6177. res.value = LLVMBuildFPTrunc(p->builder, value.value, lb_type(m, t), "");
  6178. }
  6179. return res;
  6180. }
  6181. if (is_type_complex(src) && is_type_complex(dst)) {
  6182. Type *ft = base_complex_elem_type(dst);
  6183. lbAddr gen = lb_add_local_generated(p, dst, false);
  6184. lbValue gp = lb_addr_get_ptr(p, gen);
  6185. lbValue real = lb_emit_conv(p, lb_emit_struct_ev(p, value, 0), ft);
  6186. lbValue imag = lb_emit_conv(p, lb_emit_struct_ev(p, value, 1), ft);
  6187. lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real);
  6188. lb_emit_store(p, lb_emit_struct_ep(p, gp, 1), imag);
  6189. return lb_addr_load(p, gen);
  6190. }
  6191. if (is_type_quaternion(src) && is_type_quaternion(dst)) {
  6192. // @QuaternionLayout
  6193. Type *ft = base_complex_elem_type(dst);
  6194. lbAddr gen = lb_add_local_generated(p, dst, false);
  6195. lbValue gp = lb_addr_get_ptr(p, gen);
  6196. lbValue q0 = lb_emit_conv(p, lb_emit_struct_ev(p, value, 0), ft);
  6197. lbValue q1 = lb_emit_conv(p, lb_emit_struct_ev(p, value, 1), ft);
  6198. lbValue q2 = lb_emit_conv(p, lb_emit_struct_ev(p, value, 2), ft);
  6199. lbValue q3 = lb_emit_conv(p, lb_emit_struct_ev(p, value, 3), ft);
  6200. lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), q0);
  6201. lb_emit_store(p, lb_emit_struct_ep(p, gp, 1), q1);
  6202. lb_emit_store(p, lb_emit_struct_ep(p, gp, 2), q2);
  6203. lb_emit_store(p, lb_emit_struct_ep(p, gp, 3), q3);
  6204. return lb_addr_load(p, gen);
  6205. }
  6206. if (is_type_float(src) && is_type_complex(dst)) {
  6207. Type *ft = base_complex_elem_type(dst);
  6208. lbAddr gen = lb_add_local_generated(p, dst, true);
  6209. lbValue gp = lb_addr_get_ptr(p, gen);
  6210. lbValue real = lb_emit_conv(p, value, ft);
  6211. lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), real);
  6212. return lb_addr_load(p, gen);
  6213. }
  6214. if (is_type_float(src) && is_type_quaternion(dst)) {
  6215. Type *ft = base_complex_elem_type(dst);
  6216. lbAddr gen = lb_add_local_generated(p, dst, true);
  6217. lbValue gp = lb_addr_get_ptr(p, gen);
  6218. lbValue real = lb_emit_conv(p, value, ft);
  6219. // @QuaternionLayout
  6220. lb_emit_store(p, lb_emit_struct_ep(p, gp, 3), real);
  6221. return lb_addr_load(p, gen);
  6222. }
  6223. if (is_type_complex(src) && is_type_quaternion(dst)) {
  6224. Type *ft = base_complex_elem_type(dst);
  6225. lbAddr gen = lb_add_local_generated(p, dst, true);
  6226. lbValue gp = lb_addr_get_ptr(p, gen);
  6227. lbValue real = lb_emit_conv(p, lb_emit_struct_ev(p, value, 0), ft);
  6228. lbValue imag = lb_emit_conv(p, lb_emit_struct_ev(p, value, 1), ft);
  6229. // @QuaternionLayout
  6230. lb_emit_store(p, lb_emit_struct_ep(p, gp, 3), real);
  6231. lb_emit_store(p, lb_emit_struct_ep(p, gp, 0), imag);
  6232. return lb_addr_load(p, gen);
  6233. }
  6234. // float <-> integer
  6235. if (is_type_float(src) && is_type_integer(dst)) {
  6236. if (is_type_different_to_arch_endianness(src) || is_type_different_to_arch_endianness(dst)) {
  6237. Type *platform_src_type = integer_endian_type_to_platform_type(src);
  6238. Type *platform_dst_type = integer_endian_type_to_platform_type(dst);
  6239. lbValue res = {};
  6240. res = lb_emit_conv(p, value, platform_src_type);
  6241. res = lb_emit_conv(p, res, platform_dst_type);
  6242. if (is_type_different_to_arch_endianness(dst)) {
  6243. res = lb_emit_byte_swap(p, res, t);
  6244. }
  6245. return lb_emit_conv(p, res, t);
  6246. }
  6247. lbValue res = {};
  6248. res.type = t;
  6249. if (is_type_unsigned(dst)) {
  6250. res.value = LLVMBuildFPToUI(p->builder, value.value, lb_type(m, t), "");
  6251. } else {
  6252. res.value = LLVMBuildFPToSI(p->builder, value.value, lb_type(m, t), "");
  6253. }
  6254. return res;
  6255. }
  6256. if (is_type_integer(src) && is_type_float(dst)) {
  6257. if (is_type_different_to_arch_endianness(src) || is_type_different_to_arch_endianness(dst)) {
  6258. Type *platform_src_type = integer_endian_type_to_platform_type(src);
  6259. Type *platform_dst_type = integer_endian_type_to_platform_type(dst);
  6260. lbValue res = {};
  6261. res = lb_emit_conv(p, value, platform_src_type);
  6262. res = lb_emit_conv(p, res, platform_dst_type);
  6263. if (is_type_different_to_arch_endianness(dst)) {
  6264. res = lb_emit_byte_swap(p, res, t);
  6265. }
  6266. return lb_emit_conv(p, res, t);
  6267. }
  6268. lbValue res = {};
  6269. res.type = t;
  6270. if (is_type_unsigned(src)) {
  6271. res.value = LLVMBuildUIToFP(p->builder, value.value, lb_type(m, t), "");
  6272. } else {
  6273. res.value = LLVMBuildSIToFP(p->builder, value.value, lb_type(m, t), "");
  6274. }
  6275. return res;
  6276. }
  6277. // Pointer <-> uintptr
  6278. if (is_type_pointer(src) && is_type_uintptr(dst)) {
  6279. lbValue res = {};
  6280. res.type = t;
  6281. res.value = LLVMBuildPtrToInt(p->builder, value.value, lb_type(m, t), "");
  6282. return res;
  6283. }
  6284. if (is_type_uintptr(src) && is_type_pointer(dst)) {
  6285. lbValue res = {};
  6286. res.type = t;
  6287. res.value = LLVMBuildIntToPtr(p->builder, value.value, lb_type(m, t), "");
  6288. return res;
  6289. }
  6290. #if 1
  6291. if (is_type_union(dst)) {
  6292. for_array(i, dst->Union.variants) {
  6293. Type *vt = dst->Union.variants[i];
  6294. if (are_types_identical(vt, src_type)) {
  6295. lbAddr parent = lb_add_local_generated(p, t, true);
  6296. lb_emit_store_union_variant(p, parent.addr, value, vt);
  6297. return lb_addr_load(p, parent);
  6298. }
  6299. }
  6300. }
  6301. #endif
  6302. // NOTE(bill): This has to be done before 'Pointer <-> Pointer' as it's
  6303. // subtype polymorphism casting
  6304. if (check_is_assignable_to_using_subtype(src_type, t)) {
  6305. Type *st = type_deref(src_type);
  6306. Type *pst = st;
  6307. st = type_deref(st);
  6308. bool st_is_ptr = is_type_pointer(src_type);
  6309. st = base_type(st);
  6310. Type *dt = t;
  6311. bool dt_is_ptr = type_deref(dt) != dt;
  6312. GB_ASSERT(is_type_struct(st) || is_type_raw_union(st));
  6313. String field_name = lookup_subtype_polymorphic_field(p->module->info, t, src_type);
  6314. if (field_name.len > 0) {
  6315. // NOTE(bill): It can be casted
  6316. Selection sel = lookup_field(st, field_name, false, true);
  6317. if (sel.entity != nullptr) {
  6318. if (st_is_ptr) {
  6319. lbValue res = lb_emit_deep_field_gep(p, value, sel);
  6320. Type *rt = res.type;
  6321. if (!are_types_identical(rt, dt) && are_types_identical(type_deref(rt), dt)) {
  6322. res = lb_emit_load(p, res);
  6323. }
  6324. return res;
  6325. } else {
  6326. if (is_type_pointer(value.type)) {
  6327. Type *rt = value.type;
  6328. if (!are_types_identical(rt, dt) && are_types_identical(type_deref(rt), dt)) {
  6329. value = lb_emit_load(p, value);
  6330. } else {
  6331. value = lb_emit_deep_field_gep(p, value, sel);
  6332. return lb_emit_load(p, value);
  6333. }
  6334. }
  6335. return lb_emit_deep_field_ev(p, value, sel);
  6336. }
  6337. } else {
  6338. GB_PANIC("invalid subtype cast %s.%.*s", type_to_string(src_type), LIT(field_name));
  6339. }
  6340. }
  6341. }
  6342. // Pointer <-> Pointer
  6343. if (is_type_pointer(src) && is_type_pointer(dst)) {
  6344. lbValue res = {};
  6345. res.type = t;
  6346. res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(m, t), "");
  6347. return res;
  6348. }
  6349. // proc <-> proc
  6350. if (is_type_proc(src) && is_type_proc(dst)) {
  6351. lbValue res = {};
  6352. res.type = t;
  6353. res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(m, t), "");
  6354. return res;
  6355. }
  6356. // pointer -> proc
  6357. if (is_type_pointer(src) && is_type_proc(dst)) {
  6358. lbValue res = {};
  6359. res.type = t;
  6360. res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(m, t), "");
  6361. return res;
  6362. }
  6363. // proc -> pointer
  6364. if (is_type_proc(src) && is_type_pointer(dst)) {
  6365. lbValue res = {};
  6366. res.type = t;
  6367. res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(m, t), "");
  6368. return res;
  6369. }
  6370. // []byte/[]u8 <-> string
  6371. if (is_type_u8_slice(src) && is_type_string(dst)) {
  6372. return lb_emit_transmute(p, value, t);
  6373. }
  6374. if (is_type_string(src) && is_type_u8_slice(dst)) {
  6375. return lb_emit_transmute(p, value, t);
  6376. }
  6377. if (is_type_array(dst)) {
  6378. Type *elem = dst->Array.elem;
  6379. lbValue e = lb_emit_conv(p, value, elem);
  6380. // NOTE(bill): Doesn't need to be zero because it will be initialized in the loops
  6381. lbAddr v = lb_add_local_generated(p, t, false);
  6382. isize index_count = cast(isize)dst->Array.count;
  6383. for (isize i = 0; i < index_count; i++) {
  6384. lbValue elem = lb_emit_array_epi(p, v.addr, i);
  6385. lb_emit_store(p, elem, e);
  6386. }
  6387. return lb_addr_load(p, v);
  6388. }
  6389. if (is_type_any(dst)) {
  6390. if (is_type_untyped_nil(src)) {
  6391. return lb_const_nil(p->module, t);
  6392. }
  6393. if (is_type_untyped_undef(src)) {
  6394. return lb_const_undef(p->module, t);
  6395. }
  6396. lbAddr result = lb_add_local_generated(p, t, true);
  6397. Type *st = default_type(src_type);
  6398. lbValue data = lb_address_from_load_or_generate_local(p, value);
  6399. GB_ASSERT_MSG(is_type_pointer(data.type), "%s", type_to_string(data.type));
  6400. GB_ASSERT_MSG(is_type_typed(st), "%s", type_to_string(st));
  6401. data = lb_emit_conv(p, data, t_rawptr);
  6402. lbValue id = lb_typeid(p->module, st);
  6403. lbValue any_data = lb_emit_struct_ep(p, result.addr, 0);
  6404. lbValue any_id = lb_emit_struct_ep(p, result.addr, 1);
  6405. lb_emit_store(p, any_data, data);
  6406. lb_emit_store(p, any_id, id);
  6407. return lb_addr_load(p, result);
  6408. }
  6409. i64 src_sz = type_size_of(src);
  6410. i64 dst_sz = type_size_of(dst);
  6411. if (src_sz == dst_sz) {
  6412. // bit_set <-> integer
  6413. if (is_type_integer(src) && is_type_bit_set(dst)) {
  6414. lbValue res = lb_emit_conv(p, value, bit_set_to_int(dst));
  6415. res.type = dst;
  6416. return res;
  6417. }
  6418. if (is_type_bit_set(src) && is_type_integer(dst)) {
  6419. lbValue bs = value;
  6420. bs.type = bit_set_to_int(src);
  6421. return lb_emit_conv(p, bs, dst);
  6422. }
  6423. // typeid <-> integer
  6424. if (is_type_integer(src) && is_type_typeid(dst)) {
  6425. return lb_emit_transmute(p, value, dst);
  6426. }
  6427. if (is_type_typeid(src) && is_type_integer(dst)) {
  6428. return lb_emit_transmute(p, value, dst);
  6429. }
  6430. }
  6431. if (is_type_untyped(src)) {
  6432. if (is_type_string(src) && is_type_string(dst)) {
  6433. lbAddr result = lb_add_local_generated(p, t, false);
  6434. lb_addr_store(p, result, value);
  6435. return lb_addr_load(p, result);
  6436. }
  6437. }
  6438. gb_printf_err("%.*s\n", LIT(p->name));
  6439. gb_printf_err("lb_emit_conv: src -> dst\n");
  6440. gb_printf_err("Not Identical %s != %s\n", type_to_string(src_type), type_to_string(t));
  6441. gb_printf_err("Not Identical %s != %s\n", type_to_string(src), type_to_string(dst));
  6442. gb_printf_err("Not Identical %p != %p\n", src_type, t);
  6443. gb_printf_err("Not Identical %p != %p\n", src, dst);
  6444. GB_PANIC("Invalid type conversion: '%s' to '%s' for procedure '%.*s'",
  6445. type_to_string(src_type), type_to_string(t),
  6446. LIT(p->name));
  6447. return {};
  6448. }
  6449. bool lb_is_type_aggregate(Type *t) {
  6450. t = base_type(t);
  6451. switch (t->kind) {
  6452. case Type_Basic:
  6453. switch (t->Basic.kind) {
  6454. case Basic_string:
  6455. case Basic_any:
  6456. return true;
  6457. case Basic_complex32:
  6458. case Basic_complex64:
  6459. case Basic_complex128:
  6460. case Basic_quaternion64:
  6461. case Basic_quaternion128:
  6462. case Basic_quaternion256:
  6463. return true;
  6464. }
  6465. break;
  6466. case Type_Pointer:
  6467. return false;
  6468. case Type_Array:
  6469. case Type_Slice:
  6470. case Type_Struct:
  6471. case Type_Union:
  6472. case Type_Tuple:
  6473. case Type_DynamicArray:
  6474. case Type_Map:
  6475. case Type_SimdVector:
  6476. return true;
  6477. case Type_Named:
  6478. return lb_is_type_aggregate(t->Named.base);
  6479. }
  6480. return false;
  6481. }
  6482. lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) {
  6483. Type *src_type = value.type;
  6484. if (are_types_identical(t, src_type)) {
  6485. return value;
  6486. }
  6487. lbValue res = {};
  6488. res.type = t;
  6489. Type *src = base_type(src_type);
  6490. Type *dst = base_type(t);
  6491. lbModule *m = p->module;
  6492. i64 sz = type_size_of(src);
  6493. i64 dz = type_size_of(dst);
  6494. if (sz != dz) {
  6495. LLVMTypeRef s = lb_type(m, src);
  6496. LLVMTypeRef d = lb_type(m, dst);
  6497. i64 llvm_sz = lb_sizeof(s);
  6498. i64 llvm_dz = lb_sizeof(d);
  6499. GB_ASSERT_MSG(llvm_sz == llvm_dz, "%s %s", LLVMPrintTypeToString(s), LLVMPrintTypeToString(d));
  6500. }
  6501. GB_ASSERT_MSG(sz == dz, "Invalid transmute conversion: '%s' to '%s'", type_to_string(src_type), type_to_string(t));
  6502. // NOTE(bill): Casting between an integer and a pointer cannot be done through a bitcast
  6503. if (is_type_uintptr(src) && is_type_pointer(dst)) {
  6504. res.value = LLVMBuildIntToPtr(p->builder, value.value, lb_type(m, t), "");
  6505. return res;
  6506. }
  6507. if (is_type_pointer(src) && is_type_uintptr(dst)) {
  6508. res.value = LLVMBuildPtrToInt(p->builder, value.value, lb_type(m, t), "");
  6509. return res;
  6510. }
  6511. if (is_type_uintptr(src) && is_type_proc(dst)) {
  6512. res.value = LLVMBuildIntToPtr(p->builder, value.value, lb_type(m, t), "");
  6513. return res;
  6514. }
  6515. if (is_type_proc(src) && is_type_uintptr(dst)) {
  6516. res.value = LLVMBuildPtrToInt(p->builder, value.value, lb_type(m, t), "");
  6517. return res;
  6518. }
  6519. if (is_type_integer(src) && (is_type_pointer(dst) || is_type_cstring(dst))) {
  6520. res.value = LLVMBuildIntToPtr(p->builder, value.value, lb_type(m, t), "");
  6521. return res;
  6522. } else if ((is_type_pointer(src) || is_type_cstring(src)) && is_type_integer(dst)) {
  6523. res.value = LLVMBuildPtrToInt(p->builder, value.value, lb_type(m, t), "");
  6524. return res;
  6525. }
  6526. if (is_type_pointer(src) && is_type_pointer(dst)) {
  6527. res.value = LLVMBuildPointerCast(p->builder, value.value, lb_type(p->module, t), "");
  6528. return res;
  6529. }
  6530. if (lb_is_type_aggregate(src) || lb_is_type_aggregate(dst)) {
  6531. lbValue s = lb_address_from_load_or_generate_local(p, value);
  6532. lbValue d = lb_emit_transmute(p, s, alloc_type_pointer(t));
  6533. return lb_emit_load(p, d);
  6534. }
  6535. res.value = LLVMBuildBitCast(p->builder, value.value, lb_type(p->module, t), "");
  6536. // GB_PANIC("lb_emit_transmute");
  6537. return res;
  6538. }
  6539. void lb_emit_init_context(lbProcedure *p, lbAddr addr) {
  6540. GB_ASSERT(addr.kind == lbAddr_Context);
  6541. GB_ASSERT(addr.ctx.sel.index.count == 0);
  6542. lbModule *m = p->module;
  6543. auto args = array_make<lbValue>(permanent_allocator(), 1);
  6544. args[0] = addr.addr;
  6545. lb_emit_runtime_call(p, "__init_context", args);
  6546. }
  6547. lbContextData *lb_push_context_onto_stack_from_implicit_parameter(lbProcedure *p) {
  6548. Type *pt = base_type(p->type);
  6549. GB_ASSERT(pt->kind == Type_Proc);
  6550. GB_ASSERT(pt->Proc.calling_convention == ProcCC_Odin);
  6551. String name = str_lit("__.context_ptr");
  6552. Entity *e = alloc_entity_param(nullptr, make_token_ident(name), t_context_ptr, false, false);
  6553. e->flags |= EntityFlag_NoAlias;
  6554. LLVMValueRef context_ptr = LLVMGetParam(p->value, LLVMCountParams(p->value)-1);
  6555. LLVMSetValueName2(context_ptr, cast(char const *)name.text, name.len);
  6556. context_ptr = LLVMBuildPointerCast(p->builder, context_ptr, lb_type(p->module, e->type), "");
  6557. lbValue param = {context_ptr, e->type};
  6558. lb_add_entity(p->module, e, param);
  6559. lbAddr ctx_addr = {};
  6560. ctx_addr.kind = lbAddr_Context;
  6561. ctx_addr.addr = param;
  6562. lbContextData *cd = array_add_and_get(&p->context_stack);
  6563. cd->ctx = ctx_addr;
  6564. cd->scope_index = -1;
  6565. cd->uses = +1; // make sure it has been used already
  6566. return cd;
  6567. }
  6568. lbContextData *lb_push_context_onto_stack(lbProcedure *p, lbAddr ctx) {
  6569. ctx.kind = lbAddr_Context;
  6570. lbContextData *cd = array_add_and_get(&p->context_stack);
  6571. cd->ctx = ctx;
  6572. cd->scope_index = p->scope_index;
  6573. return cd;
  6574. }
  6575. lbAddr lb_find_or_generate_context_ptr(lbProcedure *p) {
  6576. if (p->context_stack.count > 0) {
  6577. return p->context_stack[p->context_stack.count-1].ctx;
  6578. }
  6579. Type *pt = base_type(p->type);
  6580. GB_ASSERT(pt->kind == Type_Proc);
  6581. GB_ASSERT(pt->Proc.calling_convention != ProcCC_Odin);
  6582. lbAddr c = lb_add_local_generated(p, t_context, true);
  6583. c.kind = lbAddr_Context;
  6584. lb_emit_init_context(p, c);
  6585. lb_push_context_onto_stack(p, c);
  6586. lb_add_debug_context_variable(p, c);
  6587. return c;
  6588. }
  6589. lbValue lb_address_from_load_or_generate_local(lbProcedure *p, lbValue value) {
  6590. if (LLVMIsALoadInst(value.value)) {
  6591. lbValue res = {};
  6592. res.value = LLVMGetOperand(value.value, 0);
  6593. res.type = alloc_type_pointer(value.type);
  6594. return res;
  6595. }
  6596. GB_ASSERT(is_type_typed(value.type));
  6597. lbAddr res = lb_add_local_generated(p, value.type, false);
  6598. lb_addr_store(p, res, value);
  6599. return res.addr;
  6600. }
  6601. lbValue lb_address_from_load(lbProcedure *p, lbValue value) {
  6602. if (LLVMIsALoadInst(value.value)) {
  6603. lbValue res = {};
  6604. res.value = LLVMGetOperand(value.value, 0);
  6605. res.type = alloc_type_pointer(value.type);
  6606. return res;
  6607. }
  6608. GB_PANIC("lb_address_from_load");
  6609. return {};
  6610. }
  6611. lbValue lb_copy_value_to_ptr(lbProcedure *p, lbValue val, Type *new_type, i64 alignment) {
  6612. i64 type_alignment = type_align_of(new_type);
  6613. if (alignment < type_alignment) {
  6614. alignment = type_alignment;
  6615. }
  6616. GB_ASSERT_MSG(are_types_identical(new_type, val.type), "%s %s", type_to_string(new_type), type_to_string(val.type));
  6617. lbAddr ptr = lb_add_local_generated(p, new_type, false);
  6618. LLVMSetAlignment(ptr.addr.value, cast(unsigned)alignment);
  6619. lb_addr_store(p, ptr, val);
  6620. // ptr.kind = lbAddr_Context;
  6621. return ptr.addr;
  6622. }
  6623. lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
  6624. GB_ASSERT(is_type_pointer(s.type));
  6625. Type *t = base_type(type_deref(s.type));
  6626. Type *result_type = nullptr;
  6627. if (is_type_relative_pointer(t)) {
  6628. s = lb_addr_get_ptr(p, lb_addr(s));
  6629. }
  6630. if (is_type_struct(t)) {
  6631. result_type = get_struct_field_type(t, index);
  6632. } else if (is_type_union(t)) {
  6633. GB_ASSERT(index == -1);
  6634. return lb_emit_union_tag_ptr(p, s);
  6635. } else if (is_type_tuple(t)) {
  6636. GB_ASSERT(t->Tuple.variables.count > 0);
  6637. result_type = t->Tuple.variables[index]->type;
  6638. } else if (is_type_complex(t)) {
  6639. Type *ft = base_complex_elem_type(t);
  6640. switch (index) {
  6641. case 0: result_type = ft; break;
  6642. case 1: result_type = ft; break;
  6643. }
  6644. } else if (is_type_quaternion(t)) {
  6645. Type *ft = base_complex_elem_type(t);
  6646. switch (index) {
  6647. case 0: result_type = ft; break;
  6648. case 1: result_type = ft; break;
  6649. case 2: result_type = ft; break;
  6650. case 3: result_type = ft; break;
  6651. }
  6652. } else if (is_type_slice(t)) {
  6653. switch (index) {
  6654. case 0: result_type = alloc_type_pointer(t->Slice.elem); break;
  6655. case 1: result_type = t_int; break;
  6656. }
  6657. } else if (is_type_string(t)) {
  6658. switch (index) {
  6659. case 0: result_type = t_u8_ptr; break;
  6660. case 1: result_type = t_int; break;
  6661. }
  6662. } else if (is_type_any(t)) {
  6663. switch (index) {
  6664. case 0: result_type = t_rawptr; break;
  6665. case 1: result_type = t_typeid; break;
  6666. }
  6667. } else if (is_type_dynamic_array(t)) {
  6668. switch (index) {
  6669. case 0: result_type = alloc_type_pointer(t->DynamicArray.elem); break;
  6670. case 1: result_type = t_int; break;
  6671. case 2: result_type = t_int; break;
  6672. case 3: result_type = t_allocator; break;
  6673. }
  6674. } else if (is_type_map(t)) {
  6675. init_map_internal_types(t);
  6676. Type *itp = alloc_type_pointer(t->Map.internal_type);
  6677. s = lb_emit_transmute(p, s, itp);
  6678. Type *gst = t->Map.internal_type;
  6679. GB_ASSERT(gst->kind == Type_Struct);
  6680. switch (index) {
  6681. case 0: result_type = get_struct_field_type(gst, 0); break;
  6682. case 1: result_type = get_struct_field_type(gst, 1); break;
  6683. }
  6684. } else if (is_type_array(t)) {
  6685. return lb_emit_array_epi(p, s, index);
  6686. } else if (is_type_relative_slice(t)) {
  6687. switch (index) {
  6688. case 0: result_type = t->RelativeSlice.base_integer; break;
  6689. case 1: result_type = t->RelativeSlice.base_integer; break;
  6690. }
  6691. } else {
  6692. GB_PANIC("TODO(bill): struct_gep type: %s, %d", type_to_string(s.type), index);
  6693. }
  6694. GB_ASSERT_MSG(result_type != nullptr, "%s %d", type_to_string(t), index);
  6695. if (t->kind == Type_Struct && t->Struct.custom_align != 0) {
  6696. index += 1;
  6697. }
  6698. if (lb_is_const(s)) {
  6699. lbModule *m = p->module;
  6700. lbValue res = {};
  6701. LLVMValueRef indices[2] = {llvm_zero(m), LLVMConstInt(lb_type(m, t_i32), index, false)};
  6702. res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
  6703. res.type = alloc_type_pointer(result_type);
  6704. return res;
  6705. } else {
  6706. lbValue res = {};
  6707. res.value = LLVMBuildStructGEP(p->builder, s.value, cast(unsigned)index, "");
  6708. res.type = alloc_type_pointer(result_type);
  6709. return res;
  6710. }
  6711. }
  6712. lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) {
  6713. if (LLVMIsALoadInst(s.value)) {
  6714. lbValue res = {};
  6715. res.value = LLVMGetOperand(s.value, 0);
  6716. res.type = alloc_type_pointer(s.type);
  6717. lbValue ptr = lb_emit_struct_ep(p, res, index);
  6718. return lb_emit_load(p, ptr);
  6719. }
  6720. Type *t = base_type(s.type);
  6721. Type *result_type = nullptr;
  6722. switch (t->kind) {
  6723. case Type_Basic:
  6724. switch (t->Basic.kind) {
  6725. case Basic_string:
  6726. switch (index) {
  6727. case 0: result_type = t_u8_ptr; break;
  6728. case 1: result_type = t_int; break;
  6729. }
  6730. break;
  6731. case Basic_any:
  6732. switch (index) {
  6733. case 0: result_type = t_rawptr; break;
  6734. case 1: result_type = t_typeid; break;
  6735. }
  6736. break;
  6737. case Basic_complex32:
  6738. case Basic_complex64:
  6739. case Basic_complex128:
  6740. {
  6741. Type *ft = base_complex_elem_type(t);
  6742. switch (index) {
  6743. case 0: result_type = ft; break;
  6744. case 1: result_type = ft; break;
  6745. }
  6746. break;
  6747. }
  6748. case Basic_quaternion64:
  6749. case Basic_quaternion128:
  6750. case Basic_quaternion256:
  6751. {
  6752. Type *ft = base_complex_elem_type(t);
  6753. switch (index) {
  6754. case 0: result_type = ft; break;
  6755. case 1: result_type = ft; break;
  6756. case 2: result_type = ft; break;
  6757. case 3: result_type = ft; break;
  6758. }
  6759. break;
  6760. }
  6761. }
  6762. break;
  6763. case Type_Struct:
  6764. result_type = get_struct_field_type(t, index);
  6765. break;
  6766. case Type_Union:
  6767. GB_ASSERT(index == -1);
  6768. // return lb_emit_union_tag_value(p, s);
  6769. GB_PANIC("lb_emit_union_tag_value");
  6770. case Type_Tuple:
  6771. GB_ASSERT(t->Tuple.variables.count > 0);
  6772. result_type = t->Tuple.variables[index]->type;
  6773. if (t->Tuple.variables.count == 1) {
  6774. return s;
  6775. }
  6776. break;
  6777. case Type_Slice:
  6778. switch (index) {
  6779. case 0: result_type = alloc_type_pointer(t->Slice.elem); break;
  6780. case 1: result_type = t_int; break;
  6781. }
  6782. break;
  6783. case Type_DynamicArray:
  6784. switch (index) {
  6785. case 0: result_type = alloc_type_pointer(t->DynamicArray.elem); break;
  6786. case 1: result_type = t_int; break;
  6787. case 2: result_type = t_int; break;
  6788. case 3: result_type = t_allocator; break;
  6789. }
  6790. break;
  6791. case Type_Map:
  6792. {
  6793. init_map_internal_types(t);
  6794. Type *gst = t->Map.generated_struct_type;
  6795. switch (index) {
  6796. case 0: result_type = get_struct_field_type(gst, 0); break;
  6797. case 1: result_type = get_struct_field_type(gst, 1); break;
  6798. }
  6799. }
  6800. break;
  6801. case Type_Array:
  6802. result_type = t->Array.elem;
  6803. break;
  6804. default:
  6805. GB_PANIC("TODO(bill): struct_ev type: %s, %d", type_to_string(s.type), index);
  6806. break;
  6807. }
  6808. GB_ASSERT_MSG(result_type != nullptr, "%s, %d", type_to_string(s.type), index);
  6809. if (t->kind == Type_Struct && t->Struct.custom_align != 0) {
  6810. index += 1;
  6811. }
  6812. lbValue res = {};
  6813. res.value = LLVMBuildExtractValue(p->builder, s.value, cast(unsigned)index, "");
  6814. res.type = result_type;
  6815. return res;
  6816. }
  6817. lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel) {
  6818. GB_ASSERT(sel.index.count > 0);
  6819. Type *type = type_deref(e.type);
  6820. for_array(i, sel.index) {
  6821. i32 index = cast(i32)sel.index[i];
  6822. if (is_type_pointer(type)) {
  6823. type = type_deref(type);
  6824. e = lb_emit_load(p, e);
  6825. }
  6826. type = core_type(type);
  6827. if (is_type_quaternion(type)) {
  6828. e = lb_emit_struct_ep(p, e, index);
  6829. } else if (is_type_raw_union(type)) {
  6830. type = get_struct_field_type(type, index);
  6831. GB_ASSERT(is_type_pointer(e.type));
  6832. e = lb_emit_transmute(p, e, alloc_type_pointer(type));
  6833. } else if (is_type_struct(type)) {
  6834. type = get_struct_field_type(type, index);
  6835. e = lb_emit_struct_ep(p, e, index);
  6836. } else if (type->kind == Type_Union) {
  6837. GB_ASSERT(index == -1);
  6838. type = t_type_info_ptr;
  6839. e = lb_emit_struct_ep(p, e, index);
  6840. } else if (type->kind == Type_Tuple) {
  6841. type = type->Tuple.variables[index]->type;
  6842. e = lb_emit_struct_ep(p, e, index);
  6843. } else if (type->kind == Type_Basic) {
  6844. switch (type->Basic.kind) {
  6845. case Basic_any: {
  6846. if (index == 0) {
  6847. type = t_rawptr;
  6848. } else if (index == 1) {
  6849. type = t_type_info_ptr;
  6850. }
  6851. e = lb_emit_struct_ep(p, e, index);
  6852. break;
  6853. }
  6854. case Basic_string:
  6855. e = lb_emit_struct_ep(p, e, index);
  6856. break;
  6857. default:
  6858. GB_PANIC("un-gep-able type %s", type_to_string(type));
  6859. break;
  6860. }
  6861. } else if (type->kind == Type_Slice) {
  6862. e = lb_emit_struct_ep(p, e, index);
  6863. } else if (type->kind == Type_DynamicArray) {
  6864. e = lb_emit_struct_ep(p, e, index);
  6865. } else if (type->kind == Type_Array) {
  6866. e = lb_emit_array_epi(p, e, index);
  6867. } else if (type->kind == Type_Map) {
  6868. e = lb_emit_struct_ep(p, e, index);
  6869. } else if (type->kind == Type_RelativePointer) {
  6870. e = lb_emit_struct_ep(p, e, index);
  6871. } else {
  6872. GB_PANIC("un-gep-able type %s", type_to_string(type));
  6873. }
  6874. }
  6875. return e;
  6876. }
  6877. lbValue lb_emit_deep_field_ev(lbProcedure *p, lbValue e, Selection sel) {
  6878. lbValue ptr = lb_address_from_load_or_generate_local(p, e);
  6879. lbValue res = lb_emit_deep_field_gep(p, ptr, sel);
  6880. return lb_emit_load(p, res);
  6881. }
  6882. void lb_build_defer_stmt(lbProcedure *p, lbDefer const &d) {
  6883. // NOTE(bill): The prev block may defer injection before it's terminator
  6884. LLVMValueRef last_instr = LLVMGetLastInstruction(p->curr_block->block);
  6885. if (last_instr != nullptr && LLVMIsAReturnInst(last_instr)) {
  6886. // NOTE(bill): ReturnStmt defer stuff will be handled previously
  6887. return;
  6888. }
  6889. isize prev_context_stack_count = p->context_stack.count;
  6890. GB_ASSERT(prev_context_stack_count <= p->context_stack.capacity);
  6891. defer (p->context_stack.count = prev_context_stack_count);
  6892. p->context_stack.count = d.context_stack_count;
  6893. lbBlock *b = lb_create_block(p, "defer");
  6894. if (last_instr == nullptr || !LLVMIsATerminatorInst(last_instr)) {
  6895. lb_emit_jump(p, b);
  6896. }
  6897. lb_start_block(p, b);
  6898. if (d.kind == lbDefer_Node) {
  6899. lb_build_stmt(p, d.stmt);
  6900. } else if (d.kind == lbDefer_Instr) {
  6901. // NOTE(bill): Need to make a new copy
  6902. LLVMValueRef instr = LLVMInstructionClone(d.instr.value);
  6903. LLVMInsertIntoBuilder(p->builder, instr);
  6904. } else if (d.kind == lbDefer_Proc) {
  6905. lb_emit_call(p, d.proc.deferred, d.proc.result_as_args);
  6906. }
  6907. }
  6908. void lb_emit_defer_stmts(lbProcedure *p, lbDeferExitKind kind, lbBlock *block) {
  6909. isize count = p->defer_stmts.count;
  6910. isize i = count;
  6911. while (i --> 0) {
  6912. lbDefer const &d = p->defer_stmts[i];
  6913. if (kind == lbDeferExit_Default) {
  6914. if (p->scope_index == d.scope_index &&
  6915. d.scope_index > 0) { // TODO(bill): Which is correct: > 0 or > 1?
  6916. lb_build_defer_stmt(p, d);
  6917. array_pop(&p->defer_stmts);
  6918. continue;
  6919. } else {
  6920. break;
  6921. }
  6922. } else if (kind == lbDeferExit_Return) {
  6923. lb_build_defer_stmt(p, d);
  6924. } else if (kind == lbDeferExit_Branch) {
  6925. GB_ASSERT(block != nullptr);
  6926. isize lower_limit = block->scope_index;
  6927. if (lower_limit < d.scope_index) {
  6928. lb_build_defer_stmt(p, d);
  6929. }
  6930. }
  6931. }
  6932. }
  6933. void lb_add_defer_node(lbProcedure *p, isize scope_index, Ast *stmt) {
  6934. Type *pt = base_type(p->type);
  6935. GB_ASSERT(pt->kind == Type_Proc);
  6936. if (pt->Proc.calling_convention == ProcCC_Odin) {
  6937. GB_ASSERT(p->context_stack.count != 0);
  6938. }
  6939. lbDefer *d = array_add_and_get(&p->defer_stmts);
  6940. d->kind = lbDefer_Node;
  6941. d->scope_index = scope_index;
  6942. d->context_stack_count = p->context_stack.count;
  6943. d->block = p->curr_block;
  6944. d->stmt = stmt;
  6945. }
  6946. void lb_add_defer_proc(lbProcedure *p, isize scope_index, lbValue deferred, Array<lbValue> const &result_as_args) {
  6947. Type *pt = base_type(p->type);
  6948. GB_ASSERT(pt->kind == Type_Proc);
  6949. if (pt->Proc.calling_convention == ProcCC_Odin) {
  6950. GB_ASSERT(p->context_stack.count != 0);
  6951. }
  6952. lbDefer *d = array_add_and_get(&p->defer_stmts);
  6953. d->kind = lbDefer_Proc;
  6954. d->scope_index = p->scope_index;
  6955. d->block = p->curr_block;
  6956. d->context_stack_count = p->context_stack.count;
  6957. d->proc.deferred = deferred;
  6958. d->proc.result_as_args = result_as_args;
  6959. }
  6960. Array<lbValue> lb_value_to_array(lbProcedure *p, lbValue value) {
  6961. Array<lbValue> array = {};
  6962. Type *t = base_type(value.type);
  6963. if (t == nullptr) {
  6964. // Do nothing
  6965. } else if (is_type_tuple(t)) {
  6966. GB_ASSERT(t->kind == Type_Tuple);
  6967. auto *rt = &t->Tuple;
  6968. if (rt->variables.count > 0) {
  6969. array = array_make<lbValue>(permanent_allocator(), rt->variables.count);
  6970. for_array(i, rt->variables) {
  6971. lbValue elem = lb_emit_struct_ev(p, value, cast(i32)i);
  6972. array[i] = elem;
  6973. }
  6974. }
  6975. } else {
  6976. array = array_make<lbValue>(permanent_allocator(), 1);
  6977. array[0] = value;
  6978. }
  6979. return array;
  6980. }
  6981. lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, Array<lbValue> const &processed_args, Type *abi_rt, lbAddr context_ptr, ProcInlining inlining) {
  6982. GB_ASSERT(p->module->ctx == LLVMGetTypeContext(LLVMTypeOf(value.value)));
  6983. unsigned arg_count = cast(unsigned)processed_args.count;
  6984. if (return_ptr.value != nullptr) {
  6985. arg_count += 1;
  6986. }
  6987. if (context_ptr.addr.value != nullptr) {
  6988. arg_count += 1;
  6989. }
  6990. LLVMValueRef *args = gb_alloc_array(permanent_allocator(), LLVMValueRef, arg_count);
  6991. isize arg_index = 0;
  6992. if (return_ptr.value != nullptr) {
  6993. args[arg_index++] = return_ptr.value;
  6994. }
  6995. for_array(i, processed_args) {
  6996. lbValue arg = processed_args[i];
  6997. args[arg_index++] = arg.value;
  6998. }
  6999. if (context_ptr.addr.value != nullptr) {
  7000. LLVMValueRef cp = context_ptr.addr.value;
  7001. cp = LLVMBuildPointerCast(p->builder, cp, lb_type(p->module, t_rawptr), "");
  7002. args[arg_index++] = cp;
  7003. }
  7004. LLVMBasicBlockRef curr_block = LLVMGetInsertBlock(p->builder);
  7005. GB_ASSERT(curr_block != p->decl_block->block);
  7006. {
  7007. LLVMTypeRef ftp = lb_type(p->module, value.type);
  7008. LLVMTypeRef ft = LLVMGetElementType(ftp);
  7009. LLVMValueRef fn = value.value;
  7010. if (!lb_is_type_kind(LLVMTypeOf(value.value), LLVMFunctionTypeKind)) {
  7011. fn = LLVMBuildPointerCast(p->builder, fn, ftp, "");
  7012. }
  7013. LLVMTypeRef fnp = LLVMGetElementType(LLVMTypeOf(fn));
  7014. GB_ASSERT_MSG(lb_is_type_kind(fnp, LLVMFunctionTypeKind), "%s", LLVMPrintTypeToString(fnp));
  7015. {
  7016. unsigned param_count = LLVMCountParamTypes(fnp);
  7017. GB_ASSERT(arg_count >= param_count);
  7018. LLVMTypeRef *param_types = gb_alloc_array(temporary_allocator(), LLVMTypeRef, param_count);
  7019. LLVMGetParamTypes(fnp, param_types);
  7020. for (unsigned i = 0; i < param_count; i++) {
  7021. LLVMTypeRef param_type = param_types[i];
  7022. LLVMTypeRef arg_type = LLVMTypeOf(args[i]);
  7023. GB_ASSERT_MSG(
  7024. arg_type == param_type,
  7025. "Parameter types do not match: %s != %s, argument: %s",
  7026. LLVMPrintTypeToString(arg_type),
  7027. LLVMPrintTypeToString(param_type),
  7028. LLVMPrintValueToString(args[i])
  7029. );
  7030. }
  7031. }
  7032. LLVMValueRef ret = LLVMBuildCall2(p->builder, fnp, fn, args, arg_count, "");
  7033. switch (inlining) {
  7034. case ProcInlining_none:
  7035. break;
  7036. case ProcInlining_inline:
  7037. LLVMAddCallSiteAttribute(ret, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(p->module->ctx, "alwaysinline"));
  7038. break;
  7039. case ProcInlining_no_inline:
  7040. LLVMAddCallSiteAttribute(ret, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(p->module->ctx, "noinline"));
  7041. break;
  7042. }
  7043. lbValue res = {};
  7044. res.value = ret;
  7045. res.type = abi_rt;
  7046. return res;
  7047. }
  7048. }
  7049. lbValue lb_lookup_runtime_procedure(lbModule *m, String const &name) {
  7050. AstPackage *pkg = m->info->runtime_package;
  7051. Entity *e = scope_lookup_current(pkg->scope, name);
  7052. return lb_find_procedure_value_from_entity(m, e);
  7053. }
  7054. lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args) {
  7055. String name = make_string_c(c_name);
  7056. lbValue proc = lb_lookup_runtime_procedure(p->module, name);
  7057. return lb_emit_call(p, proc, args);
  7058. }
  7059. lbValue lb_emit_call(lbProcedure *p, lbValue value, Array<lbValue> const &args, ProcInlining inlining, bool use_return_ptr_hint) {
  7060. lbModule *m = p->module;
  7061. Type *pt = base_type(value.type);
  7062. GB_ASSERT(pt->kind == Type_Proc);
  7063. Type *results = pt->Proc.results;
  7064. if (p->entity != nullptr) {
  7065. if (p->entity->flags & EntityFlag_Disabled) {
  7066. return {};
  7067. }
  7068. }
  7069. lbAddr context_ptr = {};
  7070. if (pt->Proc.calling_convention == ProcCC_Odin) {
  7071. context_ptr = lb_find_or_generate_context_ptr(p);
  7072. }
  7073. defer (if (pt->Proc.diverging) {
  7074. LLVMBuildUnreachable(p->builder);
  7075. });
  7076. bool is_c_vararg = pt->Proc.c_vararg;
  7077. isize param_count = pt->Proc.param_count;
  7078. if (is_c_vararg) {
  7079. GB_ASSERT(param_count-1 <= args.count);
  7080. param_count -= 1;
  7081. } else {
  7082. GB_ASSERT_MSG(param_count == args.count, "%td == %td", param_count, args.count);
  7083. }
  7084. lbValue result = {};
  7085. auto processed_args = array_make<lbValue>(permanent_allocator(), 0, args.count);
  7086. {
  7087. lbFunctionType **ft_found = nullptr;
  7088. ft_found = map_get(&m->function_type_map, hash_type(pt));
  7089. if (!ft_found) {
  7090. LLVMTypeRef llvm_proc_type = lb_type(p->module, pt);
  7091. ft_found = map_get(&m->function_type_map, hash_type(pt));
  7092. }
  7093. GB_ASSERT(ft_found != nullptr);
  7094. lbFunctionType *ft = *ft_found;
  7095. bool return_by_pointer = ft->ret.kind == lbArg_Indirect;
  7096. unsigned param_index = 0;
  7097. for (isize i = 0; i < param_count; i++) {
  7098. Entity *e = pt->Proc.params->Tuple.variables[i];
  7099. if (e->kind != Entity_Variable) {
  7100. continue;
  7101. }
  7102. GB_ASSERT(e->flags & EntityFlag_Param);
  7103. Type *original_type = e->type;
  7104. lbArgType *arg = &ft->args[param_index];
  7105. if (arg->kind == lbArg_Ignore) {
  7106. continue;
  7107. }
  7108. lbValue x = lb_emit_conv(p, args[i], original_type);
  7109. LLVMTypeRef xt = lb_type(p->module, x.type);
  7110. if (arg->kind == lbArg_Direct) {
  7111. LLVMTypeRef abi_type = arg->cast_type;
  7112. if (!abi_type) {
  7113. abi_type = arg->type;
  7114. }
  7115. if (xt == abi_type) {
  7116. array_add(&processed_args, x);
  7117. } else {
  7118. x.value = OdinLLVMBuildTransmute(p, x.value, abi_type);
  7119. array_add(&processed_args, x);
  7120. }
  7121. } else if (arg->kind == lbArg_Indirect) {
  7122. lbValue ptr = {};
  7123. if (is_calling_convention_odin(pt->Proc.calling_convention)) {
  7124. // NOTE(bill): Odin parameters are immutable so the original value can be passed if possible
  7125. // i.e. `T const &` in C++
  7126. ptr = lb_address_from_load_or_generate_local(p, x);
  7127. } else {
  7128. ptr = lb_copy_value_to_ptr(p, x, original_type, 16);
  7129. }
  7130. array_add(&processed_args, ptr);
  7131. }
  7132. param_index += 1;
  7133. }
  7134. if (inlining == ProcInlining_none) {
  7135. inlining = p->inlining;
  7136. }
  7137. Type *rt = reduce_tuple_to_single_type(results);
  7138. if (return_by_pointer) {
  7139. lbValue return_ptr = {};
  7140. if (use_return_ptr_hint && p->return_ptr_hint_value.value != nullptr) {
  7141. if (are_types_identical(type_deref(p->return_ptr_hint_value.type), rt)) {
  7142. return_ptr = p->return_ptr_hint_value;
  7143. p->return_ptr_hint_used = true;
  7144. }
  7145. }
  7146. if (return_ptr.value == nullptr) {
  7147. lbAddr r = lb_add_local_generated(p, rt, true);
  7148. return_ptr = r.addr;
  7149. }
  7150. GB_ASSERT(is_type_pointer(return_ptr.type));
  7151. lb_emit_call_internal(p, value, return_ptr, processed_args, nullptr, context_ptr, inlining);
  7152. result = lb_emit_load(p, return_ptr);
  7153. } else if (rt != nullptr) {
  7154. result = lb_emit_call_internal(p, value, {}, processed_args, rt, context_ptr, inlining);
  7155. if (ft->ret.cast_type) {
  7156. result.value = OdinLLVMBuildTransmute(p, result.value, ft->ret.cast_type);
  7157. }
  7158. result.value = OdinLLVMBuildTransmute(p, result.value, ft->ret.type);
  7159. result.type = rt;
  7160. if (LLVMTypeOf(result.value) == LLVMInt1TypeInContext(p->module->ctx)) {
  7161. result.type = t_llvm_bool;
  7162. }
  7163. if (!is_type_tuple(rt)) {
  7164. result = lb_emit_conv(p, result, rt);
  7165. }
  7166. } else {
  7167. lb_emit_call_internal(p, value, {}, processed_args, nullptr, context_ptr, inlining);
  7168. }
  7169. }
  7170. Entity **found = map_get(&p->module->procedure_values, hash_pointer(value.value));
  7171. if (found != nullptr) {
  7172. Entity *e = *found;
  7173. if (e != nullptr && entity_has_deferred_procedure(e)) {
  7174. DeferredProcedureKind kind = e->Procedure.deferred_procedure.kind;
  7175. Entity *deferred_entity = e->Procedure.deferred_procedure.entity;
  7176. lbValue deferred = lb_find_procedure_value_from_entity(p->module, deferred_entity);
  7177. auto in_args = args;
  7178. Array<lbValue> result_as_args = {};
  7179. switch (kind) {
  7180. case DeferredProcedure_none:
  7181. break;
  7182. case DeferredProcedure_in:
  7183. result_as_args = in_args;
  7184. break;
  7185. case DeferredProcedure_out:
  7186. result_as_args = lb_value_to_array(p, result);
  7187. break;
  7188. case DeferredProcedure_in_out:
  7189. {
  7190. auto out_args = lb_value_to_array(p, result);
  7191. array_init(&result_as_args, permanent_allocator(), in_args.count + out_args.count);
  7192. array_copy(&result_as_args, in_args, 0);
  7193. array_copy(&result_as_args, out_args, in_args.count);
  7194. }
  7195. break;
  7196. }
  7197. lb_add_defer_proc(p, p->scope_index, deferred, result_as_args);
  7198. }
  7199. }
  7200. return result;
  7201. }
  7202. lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index) {
  7203. Type *t = s.type;
  7204. GB_ASSERT(is_type_pointer(t));
  7205. Type *st = base_type(type_deref(t));
  7206. GB_ASSERT_MSG(is_type_array(st) || is_type_enumerated_array(st), "%s", type_to_string(st));
  7207. GB_ASSERT_MSG(is_type_integer(core_type(index.type)), "%s", type_to_string(index.type));
  7208. LLVMValueRef indices[2] = {};
  7209. indices[0] = llvm_zero(p->module);
  7210. indices[1] = lb_emit_conv(p, index, t_int).value;
  7211. Type *ptr = base_array_type(st);
  7212. lbValue res = {};
  7213. res.value = LLVMBuildGEP(p->builder, s.value, indices, 2, "");
  7214. res.type = alloc_type_pointer(ptr);
  7215. return res;
  7216. }
  7217. lbValue lb_emit_array_epi(lbProcedure *p, lbValue s, isize index) {
  7218. Type *t = s.type;
  7219. GB_ASSERT(is_type_pointer(t));
  7220. Type *st = base_type(type_deref(t));
  7221. GB_ASSERT_MSG(is_type_array(st) || is_type_enumerated_array(st), "%s", type_to_string(st));
  7222. GB_ASSERT(0 <= index);
  7223. Type *ptr = base_array_type(st);
  7224. LLVMValueRef indices[2] = {
  7225. LLVMConstInt(lb_type(p->module, t_int), 0, false),
  7226. LLVMConstInt(lb_type(p->module, t_int), cast(unsigned)index, false),
  7227. };
  7228. lbValue res = {};
  7229. if (lb_is_const(s)) {
  7230. res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
  7231. } else {
  7232. res.value = LLVMBuildGEP(p->builder, s.value, indices, gb_count_of(indices), "");
  7233. }
  7234. res.type = alloc_type_pointer(ptr);
  7235. return res;
  7236. }
  7237. lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) {
  7238. LLVMValueRef indices[1] = {index.value};
  7239. lbValue res = {};
  7240. res.type = ptr.type;
  7241. if (lb_is_const(ptr) && lb_is_const(index)) {
  7242. res.value = LLVMConstGEP(ptr.value, indices, 1);
  7243. } else {
  7244. res.value = LLVMBuildGEP(p->builder, ptr.value, indices, 1, "");
  7245. }
  7246. return res;
  7247. }
  7248. LLVMValueRef llvm_const_slice(lbModule *m, lbValue data, lbValue len) {
  7249. GB_ASSERT(is_type_pointer(data.type));
  7250. GB_ASSERT(are_types_identical(len.type, t_int));
  7251. LLVMValueRef vals[2] = {
  7252. data.value,
  7253. len.value,
  7254. };
  7255. return LLVMConstStructInContext(m->ctx, vals, gb_count_of(vals), false);
  7256. }
  7257. void lb_fill_slice(lbProcedure *p, lbAddr const &slice, lbValue base_elem, lbValue len) {
  7258. Type *t = lb_addr_type(slice);
  7259. GB_ASSERT(is_type_slice(t));
  7260. lbValue ptr = lb_addr_get_ptr(p, slice);
  7261. lb_emit_store(p, lb_emit_struct_ep(p, ptr, 0), base_elem);
  7262. lb_emit_store(p, lb_emit_struct_ep(p, ptr, 1), len);
  7263. }
  7264. void lb_fill_string(lbProcedure *p, lbAddr const &string, lbValue base_elem, lbValue len) {
  7265. Type *t = lb_addr_type(string);
  7266. GB_ASSERT(is_type_string(t));
  7267. lbValue ptr = lb_addr_get_ptr(p, string);
  7268. lb_emit_store(p, lb_emit_struct_ep(p, ptr, 0), base_elem);
  7269. lb_emit_store(p, lb_emit_struct_ep(p, ptr, 1), len);
  7270. }
  7271. lbValue lb_string_elem(lbProcedure *p, lbValue string) {
  7272. Type *t = base_type(string.type);
  7273. GB_ASSERT(t->kind == Type_Basic && t->Basic.kind == Basic_string);
  7274. return lb_emit_struct_ev(p, string, 0);
  7275. }
  7276. lbValue lb_string_len(lbProcedure *p, lbValue string) {
  7277. Type *t = base_type(string.type);
  7278. GB_ASSERT_MSG(t->kind == Type_Basic && t->Basic.kind == Basic_string, "%s", type_to_string(t));
  7279. return lb_emit_struct_ev(p, string, 1);
  7280. }
  7281. lbValue lb_cstring_len(lbProcedure *p, lbValue value) {
  7282. GB_ASSERT(is_type_cstring(value.type));
  7283. auto args = array_make<lbValue>(permanent_allocator(), 1);
  7284. args[0] = lb_emit_conv(p, value, t_cstring);
  7285. return lb_emit_runtime_call(p, "cstring_len", args);
  7286. }
  7287. lbValue lb_array_elem(lbProcedure *p, lbValue array_ptr) {
  7288. Type *t = type_deref(array_ptr.type);
  7289. GB_ASSERT(is_type_array(t));
  7290. return lb_emit_struct_ep(p, array_ptr, 0);
  7291. }
  7292. lbValue lb_slice_elem(lbProcedure *p, lbValue slice) {
  7293. GB_ASSERT(is_type_slice(slice.type));
  7294. return lb_emit_struct_ev(p, slice, 0);
  7295. }
  7296. lbValue lb_slice_len(lbProcedure *p, lbValue slice) {
  7297. GB_ASSERT(is_type_slice(slice.type));
  7298. return lb_emit_struct_ev(p, slice, 1);
  7299. }
  7300. lbValue lb_dynamic_array_elem(lbProcedure *p, lbValue da) {
  7301. GB_ASSERT(is_type_dynamic_array(da.type));
  7302. return lb_emit_struct_ev(p, da, 0);
  7303. }
  7304. lbValue lb_dynamic_array_len(lbProcedure *p, lbValue da) {
  7305. GB_ASSERT(is_type_dynamic_array(da.type));
  7306. return lb_emit_struct_ev(p, da, 1);
  7307. }
  7308. lbValue lb_dynamic_array_cap(lbProcedure *p, lbValue da) {
  7309. GB_ASSERT(is_type_dynamic_array(da.type));
  7310. return lb_emit_struct_ev(p, da, 2);
  7311. }
  7312. lbValue lb_dynamic_array_allocator(lbProcedure *p, lbValue da) {
  7313. GB_ASSERT(is_type_dynamic_array(da.type));
  7314. return lb_emit_struct_ev(p, da, 3);
  7315. }
  7316. lbValue lb_map_entries(lbProcedure *p, lbValue value) {
  7317. Type *t = base_type(value.type);
  7318. GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t));
  7319. init_map_internal_types(t);
  7320. Type *gst = t->Map.generated_struct_type;
  7321. i32 index = 1;
  7322. lbValue entries = lb_emit_struct_ev(p, value, index);
  7323. return entries;
  7324. }
  7325. lbValue lb_map_entries_ptr(lbProcedure *p, lbValue value) {
  7326. Type *t = base_type(type_deref(value.type));
  7327. GB_ASSERT_MSG(t->kind == Type_Map, "%s", type_to_string(t));
  7328. init_map_internal_types(t);
  7329. Type *gst = t->Map.generated_struct_type;
  7330. i32 index = 1;
  7331. lbValue entries = lb_emit_struct_ep(p, value, index);
  7332. return entries;
  7333. }
  7334. lbValue lb_map_len(lbProcedure *p, lbValue value) {
  7335. lbValue entries = lb_map_entries(p, value);
  7336. return lb_dynamic_array_len(p, entries);
  7337. }
  7338. lbValue lb_map_cap(lbProcedure *p, lbValue value) {
  7339. lbValue entries = lb_map_entries(p, value);
  7340. return lb_dynamic_array_cap(p, entries);
  7341. }
  7342. lbValue lb_soa_struct_len(lbProcedure *p, lbValue value) {
  7343. Type *t = base_type(value.type);
  7344. bool is_ptr = false;
  7345. if (is_type_pointer(t)) {
  7346. is_ptr = true;
  7347. t = base_type(type_deref(t));
  7348. }
  7349. if (t->Struct.soa_kind == StructSoa_Fixed) {
  7350. return lb_const_int(p->module, t_int, t->Struct.soa_count);
  7351. }
  7352. GB_ASSERT(t->Struct.soa_kind == StructSoa_Slice ||
  7353. t->Struct.soa_kind == StructSoa_Dynamic);
  7354. isize n = 0;
  7355. Type *elem = base_type(t->Struct.soa_elem);
  7356. if (elem->kind == Type_Struct) {
  7357. n = elem->Struct.fields.count;
  7358. } else if (elem->kind == Type_Array) {
  7359. n = elem->Array.count;
  7360. } else {
  7361. GB_PANIC("Unreachable");
  7362. }
  7363. if (is_ptr) {
  7364. lbValue v = lb_emit_struct_ep(p, value, cast(i32)n);
  7365. return lb_emit_load(p, v);
  7366. }
  7367. return lb_emit_struct_ev(p, value, cast(i32)n);
  7368. }
  7369. lbValue lb_soa_struct_cap(lbProcedure *p, lbValue value) {
  7370. Type *t = base_type(value.type);
  7371. bool is_ptr = false;
  7372. if (is_type_pointer(t)) {
  7373. is_ptr = true;
  7374. t = base_type(type_deref(t));
  7375. }
  7376. if (t->Struct.soa_kind == StructSoa_Fixed) {
  7377. return lb_const_int(p->module, t_int, t->Struct.soa_count);
  7378. }
  7379. GB_ASSERT(t->Struct.soa_kind == StructSoa_Dynamic);
  7380. isize n = 0;
  7381. Type *elem = base_type(t->Struct.soa_elem);
  7382. if (elem->kind == Type_Struct) {
  7383. n = elem->Struct.fields.count+1;
  7384. } else if (elem->kind == Type_Array) {
  7385. n = elem->Array.count+1;
  7386. } else {
  7387. GB_PANIC("Unreachable");
  7388. }
  7389. if (is_ptr) {
  7390. lbValue v = lb_emit_struct_ep(p, value, cast(i32)n);
  7391. return lb_emit_load(p, v);
  7392. }
  7393. return lb_emit_struct_ev(p, value, cast(i32)n);
  7394. }
  7395. lbValue lb_soa_zip(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) {
  7396. GB_ASSERT(ce->args.count > 0);
  7397. auto slices = slice_make<lbValue>(temporary_allocator(), ce->args.count);
  7398. for_array(i, slices) {
  7399. Ast *arg = ce->args[i];
  7400. if (arg->kind == Ast_FieldValue) {
  7401. arg = arg->FieldValue.value;
  7402. }
  7403. slices[i] = lb_build_expr(p, arg);
  7404. }
  7405. lbValue len = lb_slice_len(p, slices[0]);
  7406. for (isize i = 1; i < slices.count; i++) {
  7407. lbValue other_len = lb_slice_len(p, slices[i]);
  7408. len = lb_emit_min(p, t_int, len, other_len);
  7409. }
  7410. GB_ASSERT(is_type_soa_struct(tv.type));
  7411. lbAddr res = lb_add_local_generated(p, tv.type, true);
  7412. for_array(i, slices) {
  7413. lbValue src = lb_slice_elem(p, slices[i]);
  7414. lbValue dst = lb_emit_struct_ep(p, res.addr, cast(i32)i);
  7415. lb_emit_store(p, dst, src);
  7416. }
  7417. lbValue len_dst = lb_emit_struct_ep(p, res.addr, cast(i32)slices.count);
  7418. lb_emit_store(p, len_dst, len);
  7419. return lb_addr_load(p, res);
  7420. }
  7421. lbValue lb_soa_unzip(lbProcedure *p, AstCallExpr *ce, TypeAndValue const &tv) {
  7422. GB_ASSERT(ce->args.count == 1);
  7423. lbValue arg = lb_build_expr(p, ce->args[0]);
  7424. Type *t = base_type(arg.type);
  7425. GB_ASSERT(is_type_soa_struct(t) && t->Struct.soa_kind == StructSoa_Slice);
  7426. lbValue len = lb_soa_struct_len(p, arg);
  7427. lbAddr res = lb_add_local_generated(p, tv.type, true);
  7428. if (is_type_tuple(tv.type)) {
  7429. lbValue rp = lb_addr_get_ptr(p, res);
  7430. for (i32 i = 0; i < cast(i32)(t->Struct.fields.count-1); i++) {
  7431. lbValue ptr = lb_emit_struct_ev(p, arg, i);
  7432. lbAddr dst = lb_addr(lb_emit_struct_ep(p, rp, i));
  7433. lb_fill_slice(p, dst, ptr, len);
  7434. }
  7435. } else {
  7436. GB_ASSERT(is_type_slice(tv.type));
  7437. lbValue ptr = lb_emit_struct_ev(p, arg, 0);
  7438. lb_fill_slice(p, res, ptr, len);
  7439. }
  7440. return lb_addr_load(p, res);
  7441. }
  7442. lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv, BuiltinProcId id) {
  7443. ast_node(ce, CallExpr, expr);
  7444. switch (id) {
  7445. case BuiltinProc_DIRECTIVE: {
  7446. ast_node(bd, BasicDirective, ce->proc);
  7447. String name = bd->name;
  7448. GB_ASSERT(name == "location");
  7449. String procedure = p->entity->token.string;
  7450. TokenPos pos = ast_token(ce->proc).pos;
  7451. if (ce->args.count > 0) {
  7452. Ast *ident = unselector_expr(ce->args[0]);
  7453. GB_ASSERT(ident->kind == Ast_Ident);
  7454. Entity *e = entity_of_node(ident);
  7455. GB_ASSERT(e != nullptr);
  7456. if (e->parent_proc_decl != nullptr && e->parent_proc_decl->entity != nullptr) {
  7457. procedure = e->parent_proc_decl->entity->token.string;
  7458. } else {
  7459. procedure = str_lit("");
  7460. }
  7461. pos = e->token.pos;
  7462. }
  7463. return lb_emit_source_code_location(p, procedure, pos);
  7464. }
  7465. case BuiltinProc_type_info_of: {
  7466. Ast *arg = ce->args[0];
  7467. TypeAndValue tav = type_and_value_of_expr(arg);
  7468. if (tav.mode == Addressing_Type) {
  7469. Type *t = default_type(type_of_expr(arg));
  7470. return lb_type_info(p->module, t);
  7471. }
  7472. GB_ASSERT(is_type_typeid(tav.type));
  7473. auto args = array_make<lbValue>(permanent_allocator(), 1);
  7474. args[0] = lb_build_expr(p, arg);
  7475. return lb_emit_runtime_call(p, "__type_info_of", args);
  7476. }
  7477. case BuiltinProc_typeid_of: {
  7478. Ast *arg = ce->args[0];
  7479. TypeAndValue tav = type_and_value_of_expr(arg);
  7480. GB_ASSERT(tav.mode == Addressing_Type);
  7481. Type *t = default_type(type_of_expr(arg));
  7482. return lb_typeid(p->module, t);
  7483. }
  7484. case BuiltinProc_len: {
  7485. lbValue v = lb_build_expr(p, ce->args[0]);
  7486. Type *t = base_type(v.type);
  7487. if (is_type_pointer(t)) {
  7488. // IMPORTANT TODO(bill): Should there be a nil pointer check?
  7489. v = lb_emit_load(p, v);
  7490. t = type_deref(t);
  7491. }
  7492. if (is_type_cstring(t)) {
  7493. return lb_cstring_len(p, v);
  7494. } else if (is_type_string(t)) {
  7495. return lb_string_len(p, v);
  7496. } else if (is_type_array(t)) {
  7497. GB_PANIC("Array lengths are constant");
  7498. } else if (is_type_slice(t)) {
  7499. return lb_slice_len(p, v);
  7500. } else if (is_type_dynamic_array(t)) {
  7501. return lb_dynamic_array_len(p, v);
  7502. } else if (is_type_map(t)) {
  7503. return lb_map_len(p, v);
  7504. } else if (is_type_soa_struct(t)) {
  7505. return lb_soa_struct_len(p, v);
  7506. }
  7507. GB_PANIC("Unreachable");
  7508. break;
  7509. }
  7510. case BuiltinProc_cap: {
  7511. lbValue v = lb_build_expr(p, ce->args[0]);
  7512. Type *t = base_type(v.type);
  7513. if (is_type_pointer(t)) {
  7514. // IMPORTANT TODO(bill): Should there be a nil pointer check?
  7515. v = lb_emit_load(p, v);
  7516. t = type_deref(t);
  7517. }
  7518. if (is_type_string(t)) {
  7519. GB_PANIC("Unreachable");
  7520. } else if (is_type_array(t)) {
  7521. GB_PANIC("Array lengths are constant");
  7522. } else if (is_type_slice(t)) {
  7523. return lb_slice_len(p, v);
  7524. } else if (is_type_dynamic_array(t)) {
  7525. return lb_dynamic_array_cap(p, v);
  7526. } else if (is_type_map(t)) {
  7527. return lb_map_cap(p, v);
  7528. } else if (is_type_soa_struct(t)) {
  7529. return lb_soa_struct_cap(p, v);
  7530. }
  7531. GB_PANIC("Unreachable");
  7532. break;
  7533. }
  7534. case BuiltinProc_swizzle: {
  7535. isize index_count = ce->args.count-1;
  7536. if (is_type_simd_vector(tv.type)) {
  7537. lbValue vec = lb_build_expr(p, ce->args[0]);
  7538. if (index_count == 0) {
  7539. return vec;
  7540. }
  7541. unsigned mask_len = cast(unsigned)index_count;
  7542. LLVMValueRef *mask_elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, index_count);
  7543. for (isize i = 1; i < ce->args.count; i++) {
  7544. TypeAndValue tv = type_and_value_of_expr(ce->args[i]);
  7545. GB_ASSERT(is_type_integer(tv.type));
  7546. GB_ASSERT(tv.value.kind == ExactValue_Integer);
  7547. u32 index = cast(u32)big_int_to_i64(&tv.value.value_integer);
  7548. mask_elems[i-1] = LLVMConstInt(lb_type(p->module, t_u32), index, false);
  7549. }
  7550. LLVMValueRef mask = LLVMConstVector(mask_elems, mask_len);
  7551. LLVMValueRef v1 = vec.value;
  7552. LLVMValueRef v2 = vec.value;
  7553. lbValue res = {};
  7554. res.type = tv.type;
  7555. res.value = LLVMBuildShuffleVector(p->builder, v1, v2, mask, "");
  7556. return res;
  7557. }
  7558. lbAddr addr = lb_build_addr(p, ce->args[0]);
  7559. if (index_count == 0) {
  7560. return lb_addr_load(p, addr);
  7561. }
  7562. lbValue src = lb_addr_get_ptr(p, addr);
  7563. // TODO(bill): Should this be zeroed or not?
  7564. lbAddr dst = lb_add_local_generated(p, tv.type, true);
  7565. lbValue dst_ptr = lb_addr_get_ptr(p, dst);
  7566. for (i32 i = 1; i < ce->args.count; i++) {
  7567. TypeAndValue tv = type_and_value_of_expr(ce->args[i]);
  7568. GB_ASSERT(is_type_integer(tv.type));
  7569. GB_ASSERT(tv.value.kind == ExactValue_Integer);
  7570. i32 src_index = cast(i32)big_int_to_i64(&tv.value.value_integer);
  7571. i32 dst_index = i-1;
  7572. lbValue src_elem = lb_emit_array_epi(p, src, src_index);
  7573. lbValue dst_elem = lb_emit_array_epi(p, dst_ptr, dst_index);
  7574. lb_emit_store(p, dst_elem, lb_emit_load(p, src_elem));
  7575. }
  7576. return lb_addr_load(p, dst);
  7577. }
  7578. case BuiltinProc_complex: {
  7579. lbValue real = lb_build_expr(p, ce->args[0]);
  7580. lbValue imag = lb_build_expr(p, ce->args[1]);
  7581. lbAddr dst_addr = lb_add_local_generated(p, tv.type, false);
  7582. lbValue dst = lb_addr_get_ptr(p, dst_addr);
  7583. Type *ft = base_complex_elem_type(tv.type);
  7584. real = lb_emit_conv(p, real, ft);
  7585. imag = lb_emit_conv(p, imag, ft);
  7586. lb_emit_store(p, lb_emit_struct_ep(p, dst, 0), real);
  7587. lb_emit_store(p, lb_emit_struct_ep(p, dst, 1), imag);
  7588. return lb_emit_load(p, dst);
  7589. }
  7590. case BuiltinProc_quaternion: {
  7591. lbValue real = lb_build_expr(p, ce->args[0]);
  7592. lbValue imag = lb_build_expr(p, ce->args[1]);
  7593. lbValue jmag = lb_build_expr(p, ce->args[2]);
  7594. lbValue kmag = lb_build_expr(p, ce->args[3]);
  7595. // @QuaternionLayout
  7596. lbAddr dst_addr = lb_add_local_generated(p, tv.type, false);
  7597. lbValue dst = lb_addr_get_ptr(p, dst_addr);
  7598. Type *ft = base_complex_elem_type(tv.type);
  7599. real = lb_emit_conv(p, real, ft);
  7600. imag = lb_emit_conv(p, imag, ft);
  7601. jmag = lb_emit_conv(p, jmag, ft);
  7602. kmag = lb_emit_conv(p, kmag, ft);
  7603. lb_emit_store(p, lb_emit_struct_ep(p, dst, 3), real);
  7604. lb_emit_store(p, lb_emit_struct_ep(p, dst, 0), imag);
  7605. lb_emit_store(p, lb_emit_struct_ep(p, dst, 1), jmag);
  7606. lb_emit_store(p, lb_emit_struct_ep(p, dst, 2), kmag);
  7607. return lb_emit_load(p, dst);
  7608. }
  7609. case BuiltinProc_real: {
  7610. lbValue val = lb_build_expr(p, ce->args[0]);
  7611. if (is_type_complex(val.type)) {
  7612. lbValue real = lb_emit_struct_ev(p, val, 0);
  7613. return lb_emit_conv(p, real, tv.type);
  7614. } else if (is_type_quaternion(val.type)) {
  7615. // @QuaternionLayout
  7616. lbValue real = lb_emit_struct_ev(p, val, 3);
  7617. return lb_emit_conv(p, real, tv.type);
  7618. }
  7619. GB_PANIC("invalid type for real");
  7620. return {};
  7621. }
  7622. case BuiltinProc_imag: {
  7623. lbValue val = lb_build_expr(p, ce->args[0]);
  7624. if (is_type_complex(val.type)) {
  7625. lbValue imag = lb_emit_struct_ev(p, val, 1);
  7626. return lb_emit_conv(p, imag, tv.type);
  7627. } else if (is_type_quaternion(val.type)) {
  7628. // @QuaternionLayout
  7629. lbValue imag = lb_emit_struct_ev(p, val, 0);
  7630. return lb_emit_conv(p, imag, tv.type);
  7631. }
  7632. GB_PANIC("invalid type for imag");
  7633. return {};
  7634. }
  7635. case BuiltinProc_jmag: {
  7636. lbValue val = lb_build_expr(p, ce->args[0]);
  7637. if (is_type_quaternion(val.type)) {
  7638. // @QuaternionLayout
  7639. lbValue imag = lb_emit_struct_ev(p, val, 1);
  7640. return lb_emit_conv(p, imag, tv.type);
  7641. }
  7642. GB_PANIC("invalid type for jmag");
  7643. return {};
  7644. }
  7645. case BuiltinProc_kmag: {
  7646. lbValue val = lb_build_expr(p, ce->args[0]);
  7647. if (is_type_quaternion(val.type)) {
  7648. // @QuaternionLayout
  7649. lbValue imag = lb_emit_struct_ev(p, val, 2);
  7650. return lb_emit_conv(p, imag, tv.type);
  7651. }
  7652. GB_PANIC("invalid type for kmag");
  7653. return {};
  7654. }
  7655. case BuiltinProc_conj: {
  7656. lbValue val = lb_build_expr(p, ce->args[0]);
  7657. lbValue res = {};
  7658. Type *t = val.type;
  7659. if (is_type_complex(t)) {
  7660. res = lb_addr_get_ptr(p, lb_add_local_generated(p, tv.type, false));
  7661. lbValue real = lb_emit_struct_ev(p, val, 0);
  7662. lbValue imag = lb_emit_struct_ev(p, val, 1);
  7663. imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type);
  7664. lb_emit_store(p, lb_emit_struct_ep(p, res, 0), real);
  7665. lb_emit_store(p, lb_emit_struct_ep(p, res, 1), imag);
  7666. } else if (is_type_quaternion(t)) {
  7667. // @QuaternionLayout
  7668. res = lb_addr_get_ptr(p, lb_add_local_generated(p, tv.type, false));
  7669. lbValue real = lb_emit_struct_ev(p, val, 3);
  7670. lbValue imag = lb_emit_struct_ev(p, val, 0);
  7671. lbValue jmag = lb_emit_struct_ev(p, val, 1);
  7672. lbValue kmag = lb_emit_struct_ev(p, val, 2);
  7673. imag = lb_emit_unary_arith(p, Token_Sub, imag, imag.type);
  7674. jmag = lb_emit_unary_arith(p, Token_Sub, jmag, jmag.type);
  7675. kmag = lb_emit_unary_arith(p, Token_Sub, kmag, kmag.type);
  7676. lb_emit_store(p, lb_emit_struct_ep(p, res, 3), real);
  7677. lb_emit_store(p, lb_emit_struct_ep(p, res, 0), imag);
  7678. lb_emit_store(p, lb_emit_struct_ep(p, res, 1), jmag);
  7679. lb_emit_store(p, lb_emit_struct_ep(p, res, 2), kmag);
  7680. }
  7681. return lb_emit_load(p, res);
  7682. }
  7683. case BuiltinProc_expand_to_tuple: {
  7684. lbValue val = lb_build_expr(p, ce->args[0]);
  7685. Type *t = base_type(val.type);
  7686. if (!is_type_tuple(tv.type)) {
  7687. if (t->kind == Type_Struct) {
  7688. GB_ASSERT(t->Struct.fields.count == 1);
  7689. return lb_emit_struct_ev(p, val, 0);
  7690. } else if (t->kind == Type_Array) {
  7691. GB_ASSERT(t->Array.count == 1);
  7692. return lb_emit_array_epi(p, val, 0);
  7693. } else {
  7694. GB_PANIC("Unknown type of expand_to_tuple");
  7695. }
  7696. }
  7697. GB_ASSERT(is_type_tuple(tv.type));
  7698. // NOTE(bill): Doesn't need to be zero because it will be initialized in the loops
  7699. lbValue tuple = lb_addr_get_ptr(p, lb_add_local_generated(p, tv.type, false));
  7700. if (t->kind == Type_Struct) {
  7701. for_array(src_index, t->Struct.fields) {
  7702. Entity *field = t->Struct.fields[src_index];
  7703. i32 field_index = field->Variable.field_index;
  7704. lbValue f = lb_emit_struct_ev(p, val, field_index);
  7705. lbValue ep = lb_emit_struct_ep(p, tuple, cast(i32)src_index);
  7706. lb_emit_store(p, ep, f);
  7707. }
  7708. } else if (t->kind == Type_Array) {
  7709. // TODO(bill): Clean-up this code
  7710. lbValue ap = lb_address_from_load_or_generate_local(p, val);
  7711. for (i32 i = 0; i < cast(i32)t->Array.count; i++) {
  7712. lbValue f = lb_emit_load(p, lb_emit_array_epi(p, ap, i));
  7713. lbValue ep = lb_emit_struct_ep(p, tuple, i);
  7714. lb_emit_store(p, ep, f);
  7715. }
  7716. } else {
  7717. GB_PANIC("Unknown type of expand_to_tuple");
  7718. }
  7719. return lb_emit_load(p, tuple);
  7720. }
  7721. case BuiltinProc_min: {
  7722. Type *t = type_of_expr(expr);
  7723. if (ce->args.count == 2) {
  7724. return lb_emit_min(p, t, lb_build_expr(p, ce->args[0]), lb_build_expr(p, ce->args[1]));
  7725. } else {
  7726. lbValue x = lb_build_expr(p, ce->args[0]);
  7727. for (isize i = 1; i < ce->args.count; i++) {
  7728. x = lb_emit_min(p, t, x, lb_build_expr(p, ce->args[i]));
  7729. }
  7730. return x;
  7731. }
  7732. }
  7733. case BuiltinProc_max: {
  7734. Type *t = type_of_expr(expr);
  7735. if (ce->args.count == 2) {
  7736. return lb_emit_max(p, t, lb_build_expr(p, ce->args[0]), lb_build_expr(p, ce->args[1]));
  7737. } else {
  7738. lbValue x = lb_build_expr(p, ce->args[0]);
  7739. for (isize i = 1; i < ce->args.count; i++) {
  7740. x = lb_emit_max(p, t, x, lb_build_expr(p, ce->args[i]));
  7741. }
  7742. return x;
  7743. }
  7744. }
  7745. case BuiltinProc_abs: {
  7746. lbValue x = lb_build_expr(p, ce->args[0]);
  7747. Type *t = x.type;
  7748. if (is_type_unsigned(t)) {
  7749. return x;
  7750. }
  7751. if (is_type_quaternion(t)) {
  7752. i64 sz = 8*type_size_of(t);
  7753. auto args = array_make<lbValue>(permanent_allocator(), 1);
  7754. args[0] = x;
  7755. switch (sz) {
  7756. case 64: return lb_emit_runtime_call(p, "abs_quaternion64", args);
  7757. case 128: return lb_emit_runtime_call(p, "abs_quaternion128", args);
  7758. case 256: return lb_emit_runtime_call(p, "abs_quaternion256", args);
  7759. }
  7760. GB_PANIC("Unknown complex type");
  7761. } else if (is_type_complex(t)) {
  7762. i64 sz = 8*type_size_of(t);
  7763. auto args = array_make<lbValue>(permanent_allocator(), 1);
  7764. args[0] = x;
  7765. switch (sz) {
  7766. case 32: return lb_emit_runtime_call(p, "abs_complex32", args);
  7767. case 64: return lb_emit_runtime_call(p, "abs_complex64", args);
  7768. case 128: return lb_emit_runtime_call(p, "abs_complex128", args);
  7769. }
  7770. GB_PANIC("Unknown complex type");
  7771. } else if (is_type_float(t)) {
  7772. i64 sz = 8*type_size_of(t);
  7773. auto args = array_make<lbValue>(permanent_allocator(), 1);
  7774. args[0] = x;
  7775. switch (sz) {
  7776. case 16: return lb_emit_runtime_call(p, "abs_f16", args);
  7777. case 32: return lb_emit_runtime_call(p, "abs_f32", args);
  7778. case 64: return lb_emit_runtime_call(p, "abs_f64", args);
  7779. }
  7780. GB_PANIC("Unknown float type");
  7781. }
  7782. lbValue zero = lb_const_nil(p->module, t);
  7783. lbValue cond = lb_emit_comp(p, Token_Lt, x, zero);
  7784. lbValue neg = lb_emit_unary_arith(p, Token_Sub, x, t);
  7785. return lb_emit_select(p, cond, neg, x);
  7786. }
  7787. case BuiltinProc_clamp:
  7788. return lb_emit_clamp(p, type_of_expr(expr),
  7789. lb_build_expr(p, ce->args[0]),
  7790. lb_build_expr(p, ce->args[1]),
  7791. lb_build_expr(p, ce->args[2]));
  7792. case BuiltinProc_soa_zip:
  7793. return lb_soa_zip(p, ce, tv);
  7794. case BuiltinProc_soa_unzip:
  7795. return lb_soa_unzip(p, ce, tv);
  7796. // "Intrinsics"
  7797. case BuiltinProc_alloca:
  7798. {
  7799. lbValue sz = lb_build_expr(p, ce->args[0]);
  7800. i64 al = exact_value_to_i64(type_and_value_of_expr(ce->args[1]).value);
  7801. lbValue res = {};
  7802. res.type = t_u8_ptr;
  7803. res.value = LLVMBuildArrayAlloca(p->builder, lb_type(p->module, t_u8), sz.value, "");
  7804. LLVMSetAlignment(res.value, cast(unsigned)al);
  7805. return res;
  7806. }
  7807. case BuiltinProc_cpu_relax:
  7808. if (build_context.metrics.arch == TargetArch_386 ||
  7809. build_context.metrics.arch == TargetArch_amd64) {
  7810. LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false);
  7811. LLVMValueRef the_asm = LLVMGetInlineAsm(func_type,
  7812. cast(char *)"pause", 5,
  7813. cast(char *)"", 0,
  7814. /*HasSideEffects*/true, /*IsAlignStack*/false,
  7815. LLVMInlineAsmDialectATT
  7816. );
  7817. GB_ASSERT(the_asm != nullptr);
  7818. LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
  7819. } else if (build_context.metrics.arch == TargetArch_arm64) {
  7820. LLVMTypeRef func_type = LLVMFunctionType(LLVMVoidTypeInContext(p->module->ctx), nullptr, 0, false);
  7821. LLVMValueRef the_asm = LLVMGetInlineAsm(func_type,
  7822. cast(char *)"yield", 5,
  7823. cast(char *)"", 0,
  7824. /*HasSideEffects*/true, /*IsAlignStack*/false,
  7825. LLVMInlineAsmDialectATT
  7826. );
  7827. GB_ASSERT(the_asm != nullptr);
  7828. LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
  7829. }
  7830. return {};
  7831. case BuiltinProc_debug_trap:
  7832. case BuiltinProc_trap:
  7833. {
  7834. char const *name = nullptr;
  7835. switch (id) {
  7836. case BuiltinProc_debug_trap: name = "llvm.debugtrap"; break;
  7837. case BuiltinProc_trap: name = "llvm.trap"; break;
  7838. }
  7839. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  7840. GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
  7841. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0);
  7842. LLVMBuildCall(p->builder, ip, nullptr, 0, "");
  7843. if (id == BuiltinProc_trap) {
  7844. LLVMBuildUnreachable(p->builder);
  7845. }
  7846. return {};
  7847. }
  7848. case BuiltinProc_read_cycle_counter:
  7849. {
  7850. char const *name = "llvm.readcyclecounter";
  7851. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  7852. GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
  7853. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0);
  7854. lbValue res = {};
  7855. res.value = LLVMBuildCall(p->builder, ip, nullptr, 0, "");
  7856. res.type = tv.type;
  7857. return res;
  7858. }
  7859. case BuiltinProc_count_trailing_zeros:
  7860. return lb_emit_count_trailing_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
  7861. case BuiltinProc_count_leading_zeros:
  7862. return lb_emit_count_leading_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
  7863. case BuiltinProc_count_ones:
  7864. return lb_emit_count_ones(p, lb_build_expr(p, ce->args[0]), tv.type);
  7865. case BuiltinProc_count_zeros:
  7866. return lb_emit_count_zeros(p, lb_build_expr(p, ce->args[0]), tv.type);
  7867. case BuiltinProc_reverse_bits:
  7868. return lb_emit_reverse_bits(p, lb_build_expr(p, ce->args[0]), tv.type);
  7869. case BuiltinProc_byte_swap:
  7870. {
  7871. lbValue x = lb_build_expr(p, ce->args[0]);
  7872. x = lb_emit_conv(p, x, tv.type);
  7873. return lb_emit_byte_swap(p, x, tv.type);
  7874. }
  7875. case BuiltinProc_overflow_add:
  7876. case BuiltinProc_overflow_sub:
  7877. case BuiltinProc_overflow_mul:
  7878. {
  7879. Type *main_type = tv.type;
  7880. Type *type = main_type;
  7881. if (is_type_tuple(main_type)) {
  7882. type = main_type->Tuple.variables[0]->type;
  7883. }
  7884. lbValue x = lb_build_expr(p, ce->args[0]);
  7885. lbValue y = lb_build_expr(p, ce->args[1]);
  7886. x = lb_emit_conv(p, x, type);
  7887. y = lb_emit_conv(p, y, type);
  7888. char const *name = nullptr;
  7889. if (is_type_unsigned(type)) {
  7890. switch (id) {
  7891. case BuiltinProc_overflow_add: name = "llvm.uadd.with.overflow"; break;
  7892. case BuiltinProc_overflow_sub: name = "llvm.usub.with.overflow"; break;
  7893. case BuiltinProc_overflow_mul: name = "llvm.umul.with.overflow"; break;
  7894. }
  7895. } else {
  7896. switch (id) {
  7897. case BuiltinProc_overflow_add: name = "llvm.sadd.with.overflow"; break;
  7898. case BuiltinProc_overflow_sub: name = "llvm.ssub.with.overflow"; break;
  7899. case BuiltinProc_overflow_mul: name = "llvm.smul.with.overflow"; break;
  7900. }
  7901. }
  7902. LLVMTypeRef types[1] = {lb_type(p->module, type)};
  7903. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  7904. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  7905. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  7906. LLVMValueRef args[2] = {};
  7907. args[0] = x.value;
  7908. args[1] = y.value;
  7909. lbValue res = {};
  7910. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  7911. if (is_type_tuple(main_type)) {
  7912. Type *res_type = nullptr;
  7913. gbAllocator a = permanent_allocator();
  7914. res_type = alloc_type_tuple();
  7915. array_init(&res_type->Tuple.variables, a, 2);
  7916. res_type->Tuple.variables[0] = alloc_entity_field(nullptr, blank_token, type, false, 0);
  7917. res_type->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1);
  7918. res.type = res_type;
  7919. } else {
  7920. res.value = LLVMBuildExtractValue(p->builder, res.value, 0, "");
  7921. res.type = type;
  7922. }
  7923. return res;
  7924. }
  7925. case BuiltinProc_atomic_fence:
  7926. LLVMBuildFence(p->builder, LLVMAtomicOrderingSequentiallyConsistent, false, "");
  7927. return {};
  7928. case BuiltinProc_atomic_fence_acq:
  7929. LLVMBuildFence(p->builder, LLVMAtomicOrderingAcquire, false, "");
  7930. return {};
  7931. case BuiltinProc_atomic_fence_rel:
  7932. LLVMBuildFence(p->builder, LLVMAtomicOrderingRelease, false, "");
  7933. return {};
  7934. case BuiltinProc_atomic_fence_acqrel:
  7935. LLVMBuildFence(p->builder, LLVMAtomicOrderingAcquireRelease, false, "");
  7936. return {};
  7937. case BuiltinProc_volatile_store:
  7938. case BuiltinProc_atomic_store:
  7939. case BuiltinProc_atomic_store_rel:
  7940. case BuiltinProc_atomic_store_relaxed:
  7941. case BuiltinProc_atomic_store_unordered: {
  7942. lbValue dst = lb_build_expr(p, ce->args[0]);
  7943. lbValue val = lb_build_expr(p, ce->args[1]);
  7944. val = lb_emit_conv(p, val, type_deref(dst.type));
  7945. LLVMValueRef instr = LLVMBuildStore(p->builder, val.value, dst.value);
  7946. switch (id) {
  7947. case BuiltinProc_volatile_store: LLVMSetVolatile(instr, true); break;
  7948. case BuiltinProc_atomic_store: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
  7949. case BuiltinProc_atomic_store_rel: LLVMSetOrdering(instr, LLVMAtomicOrderingRelease); break;
  7950. case BuiltinProc_atomic_store_relaxed: LLVMSetOrdering(instr, LLVMAtomicOrderingMonotonic); break;
  7951. case BuiltinProc_atomic_store_unordered: LLVMSetOrdering(instr, LLVMAtomicOrderingUnordered); break;
  7952. }
  7953. LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type)));
  7954. return {};
  7955. }
  7956. case BuiltinProc_volatile_load:
  7957. case BuiltinProc_atomic_load:
  7958. case BuiltinProc_atomic_load_acq:
  7959. case BuiltinProc_atomic_load_relaxed:
  7960. case BuiltinProc_atomic_load_unordered: {
  7961. lbValue dst = lb_build_expr(p, ce->args[0]);
  7962. LLVMValueRef instr = LLVMBuildLoad(p->builder, dst.value, "");
  7963. switch (id) {
  7964. case BuiltinProc_volatile_load: LLVMSetVolatile(instr, true); break;
  7965. case BuiltinProc_atomic_load: LLVMSetOrdering(instr, LLVMAtomicOrderingSequentiallyConsistent); break;
  7966. case BuiltinProc_atomic_load_acq: LLVMSetOrdering(instr, LLVMAtomicOrderingAcquire); break;
  7967. case BuiltinProc_atomic_load_relaxed: LLVMSetOrdering(instr, LLVMAtomicOrderingMonotonic); break;
  7968. case BuiltinProc_atomic_load_unordered: LLVMSetOrdering(instr, LLVMAtomicOrderingUnordered); break;
  7969. }
  7970. LLVMSetAlignment(instr, cast(unsigned)type_align_of(type_deref(dst.type)));
  7971. lbValue res = {};
  7972. res.value = instr;
  7973. res.type = type_deref(dst.type);
  7974. return res;
  7975. }
  7976. case BuiltinProc_atomic_add:
  7977. case BuiltinProc_atomic_add_acq:
  7978. case BuiltinProc_atomic_add_rel:
  7979. case BuiltinProc_atomic_add_acqrel:
  7980. case BuiltinProc_atomic_add_relaxed:
  7981. case BuiltinProc_atomic_sub:
  7982. case BuiltinProc_atomic_sub_acq:
  7983. case BuiltinProc_atomic_sub_rel:
  7984. case BuiltinProc_atomic_sub_acqrel:
  7985. case BuiltinProc_atomic_sub_relaxed:
  7986. case BuiltinProc_atomic_and:
  7987. case BuiltinProc_atomic_and_acq:
  7988. case BuiltinProc_atomic_and_rel:
  7989. case BuiltinProc_atomic_and_acqrel:
  7990. case BuiltinProc_atomic_and_relaxed:
  7991. case BuiltinProc_atomic_nand:
  7992. case BuiltinProc_atomic_nand_acq:
  7993. case BuiltinProc_atomic_nand_rel:
  7994. case BuiltinProc_atomic_nand_acqrel:
  7995. case BuiltinProc_atomic_nand_relaxed:
  7996. case BuiltinProc_atomic_or:
  7997. case BuiltinProc_atomic_or_acq:
  7998. case BuiltinProc_atomic_or_rel:
  7999. case BuiltinProc_atomic_or_acqrel:
  8000. case BuiltinProc_atomic_or_relaxed:
  8001. case BuiltinProc_atomic_xor:
  8002. case BuiltinProc_atomic_xor_acq:
  8003. case BuiltinProc_atomic_xor_rel:
  8004. case BuiltinProc_atomic_xor_acqrel:
  8005. case BuiltinProc_atomic_xor_relaxed:
  8006. case BuiltinProc_atomic_xchg:
  8007. case BuiltinProc_atomic_xchg_acq:
  8008. case BuiltinProc_atomic_xchg_rel:
  8009. case BuiltinProc_atomic_xchg_acqrel:
  8010. case BuiltinProc_atomic_xchg_relaxed: {
  8011. lbValue dst = lb_build_expr(p, ce->args[0]);
  8012. lbValue val = lb_build_expr(p, ce->args[1]);
  8013. val = lb_emit_conv(p, val, type_deref(dst.type));
  8014. LLVMAtomicRMWBinOp op = {};
  8015. LLVMAtomicOrdering ordering = {};
  8016. switch (id) {
  8017. case BuiltinProc_atomic_add: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  8018. case BuiltinProc_atomic_add_acq: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingAcquire; break;
  8019. case BuiltinProc_atomic_add_rel: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingRelease; break;
  8020. case BuiltinProc_atomic_add_acqrel: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingAcquireRelease; break;
  8021. case BuiltinProc_atomic_add_relaxed: op = LLVMAtomicRMWBinOpAdd; ordering = LLVMAtomicOrderingMonotonic; break;
  8022. case BuiltinProc_atomic_sub: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  8023. case BuiltinProc_atomic_sub_acq: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingAcquire; break;
  8024. case BuiltinProc_atomic_sub_rel: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingRelease; break;
  8025. case BuiltinProc_atomic_sub_acqrel: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingAcquireRelease; break;
  8026. case BuiltinProc_atomic_sub_relaxed: op = LLVMAtomicRMWBinOpSub; ordering = LLVMAtomicOrderingMonotonic; break;
  8027. case BuiltinProc_atomic_and: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  8028. case BuiltinProc_atomic_and_acq: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingAcquire; break;
  8029. case BuiltinProc_atomic_and_rel: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingRelease; break;
  8030. case BuiltinProc_atomic_and_acqrel: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingAcquireRelease; break;
  8031. case BuiltinProc_atomic_and_relaxed: op = LLVMAtomicRMWBinOpAnd; ordering = LLVMAtomicOrderingMonotonic; break;
  8032. case BuiltinProc_atomic_nand: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  8033. case BuiltinProc_atomic_nand_acq: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingAcquire; break;
  8034. case BuiltinProc_atomic_nand_rel: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingRelease; break;
  8035. case BuiltinProc_atomic_nand_acqrel: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingAcquireRelease; break;
  8036. case BuiltinProc_atomic_nand_relaxed: op = LLVMAtomicRMWBinOpNand; ordering = LLVMAtomicOrderingMonotonic; break;
  8037. case BuiltinProc_atomic_or: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  8038. case BuiltinProc_atomic_or_acq: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingAcquire; break;
  8039. case BuiltinProc_atomic_or_rel: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingRelease; break;
  8040. case BuiltinProc_atomic_or_acqrel: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingAcquireRelease; break;
  8041. case BuiltinProc_atomic_or_relaxed: op = LLVMAtomicRMWBinOpOr; ordering = LLVMAtomicOrderingMonotonic; break;
  8042. case BuiltinProc_atomic_xor: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  8043. case BuiltinProc_atomic_xor_acq: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingAcquire; break;
  8044. case BuiltinProc_atomic_xor_rel: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingRelease; break;
  8045. case BuiltinProc_atomic_xor_acqrel: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingAcquireRelease; break;
  8046. case BuiltinProc_atomic_xor_relaxed: op = LLVMAtomicRMWBinOpXor; ordering = LLVMAtomicOrderingMonotonic; break;
  8047. case BuiltinProc_atomic_xchg: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingSequentiallyConsistent; break;
  8048. case BuiltinProc_atomic_xchg_acq: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingAcquire; break;
  8049. case BuiltinProc_atomic_xchg_rel: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingRelease; break;
  8050. case BuiltinProc_atomic_xchg_acqrel: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingAcquireRelease; break;
  8051. case BuiltinProc_atomic_xchg_relaxed: op = LLVMAtomicRMWBinOpXchg; ordering = LLVMAtomicOrderingMonotonic; break;
  8052. }
  8053. lbValue res = {};
  8054. res.value = LLVMBuildAtomicRMW(p->builder, op, dst.value, val.value, ordering, false);
  8055. res.type = tv.type;
  8056. return res;
  8057. }
  8058. case BuiltinProc_atomic_cxchg:
  8059. case BuiltinProc_atomic_cxchg_acq:
  8060. case BuiltinProc_atomic_cxchg_rel:
  8061. case BuiltinProc_atomic_cxchg_acqrel:
  8062. case BuiltinProc_atomic_cxchg_relaxed:
  8063. case BuiltinProc_atomic_cxchg_failrelaxed:
  8064. case BuiltinProc_atomic_cxchg_failacq:
  8065. case BuiltinProc_atomic_cxchg_acq_failrelaxed:
  8066. case BuiltinProc_atomic_cxchg_acqrel_failrelaxed:
  8067. case BuiltinProc_atomic_cxchgweak:
  8068. case BuiltinProc_atomic_cxchgweak_acq:
  8069. case BuiltinProc_atomic_cxchgweak_rel:
  8070. case BuiltinProc_atomic_cxchgweak_acqrel:
  8071. case BuiltinProc_atomic_cxchgweak_relaxed:
  8072. case BuiltinProc_atomic_cxchgweak_failrelaxed:
  8073. case BuiltinProc_atomic_cxchgweak_failacq:
  8074. case BuiltinProc_atomic_cxchgweak_acq_failrelaxed:
  8075. case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: {
  8076. Type *type = expr->tav.type;
  8077. lbValue address = lb_build_expr(p, ce->args[0]);
  8078. Type *elem = type_deref(address.type);
  8079. lbValue old_value = lb_build_expr(p, ce->args[1]);
  8080. lbValue new_value = lb_build_expr(p, ce->args[2]);
  8081. old_value = lb_emit_conv(p, old_value, elem);
  8082. new_value = lb_emit_conv(p, new_value, elem);
  8083. LLVMAtomicOrdering success_ordering = {};
  8084. LLVMAtomicOrdering failure_ordering = {};
  8085. LLVMBool weak = false;
  8086. switch (id) {
  8087. case BuiltinProc_atomic_cxchg: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  8088. case BuiltinProc_atomic_cxchg_acq: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  8089. case BuiltinProc_atomic_cxchg_rel: success_ordering = LLVMAtomicOrderingRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  8090. case BuiltinProc_atomic_cxchg_acqrel: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  8091. case BuiltinProc_atomic_cxchg_relaxed: success_ordering = LLVMAtomicOrderingMonotonic; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
  8092. case BuiltinProc_atomic_cxchg_failrelaxed: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
  8093. case BuiltinProc_atomic_cxchg_failacq: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingAcquire; weak = false; break;
  8094. case BuiltinProc_atomic_cxchg_acq_failrelaxed: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
  8095. case BuiltinProc_atomic_cxchg_acqrel_failrelaxed: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = false; break;
  8096. case BuiltinProc_atomic_cxchgweak: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = false; break;
  8097. case BuiltinProc_atomic_cxchgweak_acq: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break;
  8098. case BuiltinProc_atomic_cxchgweak_rel: success_ordering = LLVMAtomicOrderingRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break;
  8099. case BuiltinProc_atomic_cxchgweak_acqrel: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingSequentiallyConsistent; weak = true; break;
  8100. case BuiltinProc_atomic_cxchgweak_relaxed: success_ordering = LLVMAtomicOrderingMonotonic; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
  8101. case BuiltinProc_atomic_cxchgweak_failrelaxed: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
  8102. case BuiltinProc_atomic_cxchgweak_failacq: success_ordering = LLVMAtomicOrderingSequentiallyConsistent; failure_ordering = LLVMAtomicOrderingAcquire; weak = true; break;
  8103. case BuiltinProc_atomic_cxchgweak_acq_failrelaxed: success_ordering = LLVMAtomicOrderingAcquire; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
  8104. case BuiltinProc_atomic_cxchgweak_acqrel_failrelaxed: success_ordering = LLVMAtomicOrderingAcquireRelease; failure_ordering = LLVMAtomicOrderingMonotonic; weak = true; break;
  8105. }
  8106. // TODO(bill): Figure out how to make it weak
  8107. LLVMBool single_threaded = weak;
  8108. LLVMValueRef value = LLVMBuildAtomicCmpXchg(
  8109. p->builder, address.value,
  8110. old_value.value, new_value.value,
  8111. success_ordering,
  8112. failure_ordering,
  8113. single_threaded
  8114. );
  8115. if (tv.type->kind == Type_Tuple) {
  8116. Type *fix_typed = alloc_type_tuple();
  8117. array_init(&fix_typed->Tuple.variables, permanent_allocator(), 2);
  8118. fix_typed->Tuple.variables[0] = tv.type->Tuple.variables[0];
  8119. fix_typed->Tuple.variables[1] = alloc_entity_field(nullptr, blank_token, t_llvm_bool, false, 1);
  8120. lbValue res = {};
  8121. res.value = value;
  8122. res.type = fix_typed;
  8123. return res;
  8124. } else {
  8125. lbValue res = {};
  8126. res.value = LLVMBuildExtractValue(p->builder, value, 0, "");
  8127. res.type = tv.type;
  8128. return res;
  8129. }
  8130. }
  8131. case BuiltinProc_type_equal_proc:
  8132. return lb_get_equal_proc_for_type(p->module, ce->args[0]->tav.type);
  8133. case BuiltinProc_type_hasher_proc:
  8134. return lb_get_hasher_proc_for_type(p->module, ce->args[0]->tav.type);
  8135. case BuiltinProc_fixed_point_mul:
  8136. case BuiltinProc_fixed_point_div:
  8137. case BuiltinProc_fixed_point_mul_sat:
  8138. case BuiltinProc_fixed_point_div_sat:
  8139. {
  8140. bool do_bswap = is_type_different_to_arch_endianness(tv.type);
  8141. Type *platform_type = integer_endian_type_to_platform_type(tv.type);
  8142. lbValue x = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), platform_type);
  8143. lbValue y = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), platform_type);
  8144. lbValue scale = lb_emit_conv(p, lb_build_expr(p, ce->args[2]), platform_type);
  8145. char const *name = nullptr;
  8146. if (is_type_unsigned(tv.type)) {
  8147. switch (id) {
  8148. case BuiltinProc_fixed_point_mul: name = "llvm.umul.fix"; break;
  8149. case BuiltinProc_fixed_point_div: name = "llvm.udiv.fix"; break;
  8150. case BuiltinProc_fixed_point_mul_sat: name = "llvm.umul.fix.sat"; break;
  8151. case BuiltinProc_fixed_point_div_sat: name = "llvm.udiv.fix.sat"; break;
  8152. }
  8153. } else {
  8154. switch (id) {
  8155. case BuiltinProc_fixed_point_mul: name = "llvm.smul.fix"; break;
  8156. case BuiltinProc_fixed_point_div: name = "llvm.sdiv.fix"; break;
  8157. case BuiltinProc_fixed_point_mul_sat: name = "llvm.smul.fix.sat"; break;
  8158. case BuiltinProc_fixed_point_div_sat: name = "llvm.sdiv.fix.sat"; break;
  8159. }
  8160. }
  8161. GB_ASSERT(name != nullptr);
  8162. LLVMTypeRef types[1] = {lb_type(p->module, platform_type)};
  8163. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  8164. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  8165. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  8166. lbValue res = {};
  8167. LLVMValueRef args[3] = {};
  8168. args[0] = x.value;
  8169. args[1] = y.value;
  8170. args[2] = scale.value;
  8171. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  8172. res.type = platform_type;
  8173. return lb_emit_conv(p, res, tv.type);
  8174. }
  8175. case BuiltinProc_expect:
  8176. {
  8177. Type *t = default_type(tv.type);
  8178. lbValue x = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t);
  8179. lbValue y = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t);
  8180. char const *name = "llvm.expect";
  8181. LLVMTypeRef types[1] = {lb_type(p->module, t)};
  8182. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  8183. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  8184. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  8185. lbValue res = {};
  8186. LLVMValueRef args[2] = {};
  8187. args[0] = x.value;
  8188. args[1] = y.value;
  8189. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  8190. res.type = t;
  8191. return lb_emit_conv(p, res, t);
  8192. }
  8193. }
  8194. GB_PANIC("Unhandled built-in procedure %.*s", LIT(builtin_procs[id].name));
  8195. return {};
  8196. }
  8197. lbValue lb_handle_param_value(lbProcedure *p, Type *parameter_type, ParameterValue const &param_value, TokenPos const &pos) {
  8198. switch (param_value.kind) {
  8199. case ParameterValue_Constant:
  8200. if (is_type_constant_type(parameter_type)) {
  8201. auto res = lb_const_value(p->module, parameter_type, param_value.value);
  8202. return res;
  8203. } else {
  8204. ExactValue ev = param_value.value;
  8205. lbValue arg = {};
  8206. Type *type = type_of_expr(param_value.original_ast_expr);
  8207. if (type != nullptr) {
  8208. arg = lb_const_value(p->module, type, ev);
  8209. } else {
  8210. arg = lb_const_value(p->module, parameter_type, param_value.value);
  8211. }
  8212. return lb_emit_conv(p, arg, parameter_type);
  8213. }
  8214. case ParameterValue_Nil:
  8215. return lb_const_nil(p->module, parameter_type);
  8216. case ParameterValue_Location:
  8217. {
  8218. String proc_name = {};
  8219. if (p->entity != nullptr) {
  8220. proc_name = p->entity->token.string;
  8221. }
  8222. return lb_emit_source_code_location(p, proc_name, pos);
  8223. }
  8224. case ParameterValue_Value:
  8225. return lb_build_expr(p, param_value.ast_value);
  8226. }
  8227. return lb_const_nil(p->module, parameter_type);
  8228. }
  8229. lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) {
  8230. lbModule *m = p->module;
  8231. TypeAndValue tv = type_and_value_of_expr(expr);
  8232. ast_node(ce, CallExpr, expr);
  8233. TypeAndValue proc_tv = type_and_value_of_expr(ce->proc);
  8234. AddressingMode proc_mode = proc_tv.mode;
  8235. if (proc_mode == Addressing_Type) {
  8236. GB_ASSERT(ce->args.count == 1);
  8237. lbValue x = lb_build_expr(p, ce->args[0]);
  8238. lbValue y = lb_emit_conv(p, x, tv.type);
  8239. return y;
  8240. }
  8241. Ast *pexpr = unparen_expr(ce->proc);
  8242. if (proc_mode == Addressing_Builtin) {
  8243. Entity *e = entity_of_node(pexpr);
  8244. BuiltinProcId id = BuiltinProc_Invalid;
  8245. if (e != nullptr) {
  8246. id = cast(BuiltinProcId)e->Builtin.id;
  8247. } else {
  8248. id = BuiltinProc_DIRECTIVE;
  8249. }
  8250. return lb_build_builtin_proc(p, expr, tv, id);
  8251. }
  8252. // NOTE(bill): Regular call
  8253. lbValue value = {};
  8254. Ast *proc_expr = unparen_expr(ce->proc);
  8255. if (proc_expr->tav.mode == Addressing_Constant) {
  8256. ExactValue v = proc_expr->tav.value;
  8257. switch (v.kind) {
  8258. case ExactValue_Integer:
  8259. {
  8260. u64 u = big_int_to_u64(&v.value_integer);
  8261. lbValue x = {};
  8262. x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false);
  8263. x.type = t_uintptr;
  8264. x = lb_emit_conv(p, x, t_rawptr);
  8265. value = lb_emit_conv(p, x, proc_expr->tav.type);
  8266. break;
  8267. }
  8268. case ExactValue_Pointer:
  8269. {
  8270. u64 u = cast(u64)v.value_pointer;
  8271. lbValue x = {};
  8272. x.value = LLVMConstInt(lb_type(m, t_uintptr), u, false);
  8273. x.type = t_uintptr;
  8274. x = lb_emit_conv(p, x, t_rawptr);
  8275. value = lb_emit_conv(p, x, proc_expr->tav.type);
  8276. break;
  8277. }
  8278. }
  8279. }
  8280. Entity *proc_entity = entity_of_node(proc_expr);
  8281. if (proc_entity != nullptr) {
  8282. if (proc_entity->flags & EntityFlag_Disabled) {
  8283. return {};
  8284. }
  8285. }
  8286. if (value.value == nullptr) {
  8287. value = lb_build_expr(p, proc_expr);
  8288. }
  8289. GB_ASSERT(value.value != nullptr);
  8290. Type *proc_type_ = base_type(value.type);
  8291. GB_ASSERT(proc_type_->kind == Type_Proc);
  8292. TypeProc *pt = &proc_type_->Proc;
  8293. if (is_call_expr_field_value(ce)) {
  8294. auto args = array_make<lbValue>(permanent_allocator(), pt->param_count);
  8295. for_array(arg_index, ce->args) {
  8296. Ast *arg = ce->args[arg_index];
  8297. ast_node(fv, FieldValue, arg);
  8298. GB_ASSERT(fv->field->kind == Ast_Ident);
  8299. String name = fv->field->Ident.token.string;
  8300. isize index = lookup_procedure_parameter(pt, name);
  8301. GB_ASSERT(index >= 0);
  8302. TypeAndValue tav = type_and_value_of_expr(fv->value);
  8303. if (tav.mode == Addressing_Type) {
  8304. args[index] = lb_const_nil(m, tav.type);
  8305. } else {
  8306. args[index] = lb_build_expr(p, fv->value);
  8307. }
  8308. }
  8309. TypeTuple *params = &pt->params->Tuple;
  8310. for (isize i = 0; i < args.count; i++) {
  8311. Entity *e = params->variables[i];
  8312. if (e->kind == Entity_TypeName) {
  8313. args[i] = lb_const_nil(m, e->type);
  8314. } else if (e->kind == Entity_Constant) {
  8315. continue;
  8316. } else {
  8317. GB_ASSERT(e->kind == Entity_Variable);
  8318. if (args[i].value == nullptr) {
  8319. args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
  8320. } else {
  8321. args[i] = lb_emit_conv(p, args[i], e->type);
  8322. }
  8323. }
  8324. }
  8325. for (isize i = 0; i < args.count; i++) {
  8326. Entity *e = params->variables[i];
  8327. if (args[i].type == nullptr) {
  8328. continue;
  8329. } else if (is_type_untyped_nil(args[i].type)) {
  8330. args[i] = lb_const_nil(m, e->type);
  8331. } else if (is_type_untyped_undef(args[i].type)) {
  8332. args[i] = lb_const_undef(m, e->type);
  8333. }
  8334. }
  8335. return lb_emit_call(p, value, args, ce->inlining, p->return_ptr_hint_ast == expr);
  8336. }
  8337. isize arg_index = 0;
  8338. isize arg_count = 0;
  8339. for_array(i, ce->args) {
  8340. Ast *arg = ce->args[i];
  8341. TypeAndValue tav = type_and_value_of_expr(arg);
  8342. GB_ASSERT_MSG(tav.mode != Addressing_Invalid, "%s %s", expr_to_string(arg), expr_to_string(expr));
  8343. GB_ASSERT_MSG(tav.mode != Addressing_ProcGroup, "%s", expr_to_string(arg));
  8344. Type *at = tav.type;
  8345. if (at->kind == Type_Tuple) {
  8346. arg_count += at->Tuple.variables.count;
  8347. } else {
  8348. arg_count++;
  8349. }
  8350. }
  8351. isize param_count = 0;
  8352. if (pt->params) {
  8353. GB_ASSERT(pt->params->kind == Type_Tuple);
  8354. param_count = pt->params->Tuple.variables.count;
  8355. }
  8356. auto args = array_make<lbValue>(permanent_allocator(), cast(isize)gb_max(param_count, arg_count));
  8357. isize variadic_index = pt->variadic_index;
  8358. bool variadic = pt->variadic && variadic_index >= 0;
  8359. bool vari_expand = ce->ellipsis.pos.line != 0;
  8360. bool is_c_vararg = pt->c_vararg;
  8361. String proc_name = {};
  8362. if (p->entity != nullptr) {
  8363. proc_name = p->entity->token.string;
  8364. }
  8365. TokenPos pos = ast_token(ce->proc).pos;
  8366. TypeTuple *param_tuple = nullptr;
  8367. if (pt->params) {
  8368. GB_ASSERT(pt->params->kind == Type_Tuple);
  8369. param_tuple = &pt->params->Tuple;
  8370. }
  8371. for_array(i, ce->args) {
  8372. Ast *arg = ce->args[i];
  8373. TypeAndValue arg_tv = type_and_value_of_expr(arg);
  8374. if (arg_tv.mode == Addressing_Type) {
  8375. args[arg_index++] = lb_const_nil(m, arg_tv.type);
  8376. } else {
  8377. lbValue a = lb_build_expr(p, arg);
  8378. Type *at = a.type;
  8379. if (at->kind == Type_Tuple) {
  8380. for_array(i, at->Tuple.variables) {
  8381. Entity *e = at->Tuple.variables[i];
  8382. lbValue v = lb_emit_struct_ev(p, a, cast(i32)i);
  8383. args[arg_index++] = v;
  8384. }
  8385. } else {
  8386. args[arg_index++] = a;
  8387. }
  8388. }
  8389. }
  8390. if (param_count > 0) {
  8391. GB_ASSERT_MSG(pt->params != nullptr, "%s %td", expr_to_string(expr), pt->param_count);
  8392. GB_ASSERT(param_count < 1000000);
  8393. if (arg_count < param_count) {
  8394. isize end = cast(isize)param_count;
  8395. if (variadic) {
  8396. end = variadic_index;
  8397. }
  8398. while (arg_index < end) {
  8399. Entity *e = param_tuple->variables[arg_index];
  8400. GB_ASSERT(e->kind == Entity_Variable);
  8401. args[arg_index++] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
  8402. }
  8403. }
  8404. if (is_c_vararg) {
  8405. GB_ASSERT(variadic);
  8406. GB_ASSERT(!vari_expand);
  8407. isize i = 0;
  8408. for (; i < variadic_index; i++) {
  8409. Entity *e = param_tuple->variables[i];
  8410. if (e->kind == Entity_Variable) {
  8411. args[i] = lb_emit_conv(p, args[i], e->type);
  8412. }
  8413. }
  8414. Type *variadic_type = param_tuple->variables[i]->type;
  8415. GB_ASSERT(is_type_slice(variadic_type));
  8416. variadic_type = base_type(variadic_type)->Slice.elem;
  8417. if (!is_type_any(variadic_type)) {
  8418. for (; i < arg_count; i++) {
  8419. args[i] = lb_emit_conv(p, args[i], variadic_type);
  8420. }
  8421. } else {
  8422. for (; i < arg_count; i++) {
  8423. args[i] = lb_emit_conv(p, args[i], default_type(args[i].type));
  8424. }
  8425. }
  8426. } else if (variadic) {
  8427. isize i = 0;
  8428. for (; i < variadic_index; i++) {
  8429. Entity *e = param_tuple->variables[i];
  8430. if (e->kind == Entity_Variable) {
  8431. args[i] = lb_emit_conv(p, args[i], e->type);
  8432. }
  8433. }
  8434. if (!vari_expand) {
  8435. Type *variadic_type = param_tuple->variables[i]->type;
  8436. GB_ASSERT(is_type_slice(variadic_type));
  8437. variadic_type = base_type(variadic_type)->Slice.elem;
  8438. for (; i < arg_count; i++) {
  8439. args[i] = lb_emit_conv(p, args[i], variadic_type);
  8440. }
  8441. }
  8442. } else {
  8443. for (isize i = 0; i < param_count; i++) {
  8444. Entity *e = param_tuple->variables[i];
  8445. if (e->kind == Entity_Variable) {
  8446. if (args[i].value == nullptr) {
  8447. continue;
  8448. }
  8449. GB_ASSERT_MSG(args[i].value != nullptr, "%.*s", LIT(e->token.string));
  8450. args[i] = lb_emit_conv(p, args[i], e->type);
  8451. }
  8452. }
  8453. }
  8454. if (variadic && !vari_expand && !is_c_vararg) {
  8455. // variadic call argument generation
  8456. Type *slice_type = param_tuple->variables[variadic_index]->type;
  8457. Type *elem_type = base_type(slice_type)->Slice.elem;
  8458. lbAddr slice = lb_add_local_generated(p, slice_type, true);
  8459. isize slice_len = arg_count+1 - (variadic_index+1);
  8460. if (slice_len > 0) {
  8461. lbAddr base_array = lb_add_local_generated(p, alloc_type_array(elem_type, slice_len), true);
  8462. for (isize i = variadic_index, j = 0; i < arg_count; i++, j++) {
  8463. lbValue addr = lb_emit_array_epi(p, base_array.addr, cast(i32)j);
  8464. lb_emit_store(p, addr, args[i]);
  8465. }
  8466. lbValue base_elem = lb_emit_array_epi(p, base_array.addr, 0);
  8467. lbValue len = lb_const_int(m, t_int, slice_len);
  8468. lb_fill_slice(p, slice, base_elem, len);
  8469. }
  8470. arg_count = param_count;
  8471. args[variadic_index] = lb_addr_load(p, slice);
  8472. }
  8473. }
  8474. if (variadic && variadic_index+1 < param_count) {
  8475. for (isize i = variadic_index+1; i < param_count; i++) {
  8476. Entity *e = param_tuple->variables[i];
  8477. args[i] = lb_handle_param_value(p, e->type, e->Variable.param_value, ast_token(expr).pos);
  8478. }
  8479. }
  8480. isize final_count = param_count;
  8481. if (is_c_vararg) {
  8482. final_count = arg_count;
  8483. }
  8484. if (param_tuple != nullptr) {
  8485. for (isize i = 0; i < gb_min(args.count, param_tuple->variables.count); i++) {
  8486. Entity *e = param_tuple->variables[i];
  8487. if (args[i].type == nullptr) {
  8488. continue;
  8489. } else if (is_type_untyped_nil(args[i].type)) {
  8490. args[i] = lb_const_nil(m, e->type);
  8491. } else if (is_type_untyped_undef(args[i].type)) {
  8492. args[i] = lb_const_undef(m, e->type);
  8493. }
  8494. }
  8495. }
  8496. auto call_args = array_slice(args, 0, final_count);
  8497. return lb_emit_call(p, value, call_args, ce->inlining, p->return_ptr_hint_ast == expr);
  8498. }
  8499. bool lb_is_const(lbValue value) {
  8500. LLVMValueRef v = value.value;
  8501. if (is_type_untyped_nil(value.type) || is_type_untyped_undef(value.type)) {
  8502. // TODO(bill): Is this correct behaviour?
  8503. return true;
  8504. }
  8505. if (LLVMIsConstant(v)) {
  8506. return true;
  8507. }
  8508. return false;
  8509. }
  8510. bool lb_is_const_or_global(lbValue value) {
  8511. if (lb_is_const(value)) {
  8512. return true;
  8513. }
  8514. if (LLVMGetValueKind(value.value) == LLVMGlobalVariableValueKind) {
  8515. LLVMTypeRef t = LLVMGetElementType(LLVMTypeOf(value.value));
  8516. if (!lb_is_type_kind(t, LLVMPointerTypeKind)) {
  8517. return false;
  8518. }
  8519. LLVMTypeRef elem = LLVMGetElementType(t);
  8520. return lb_is_type_kind(elem, LLVMFunctionTypeKind);
  8521. }
  8522. return false;
  8523. }
  8524. bool lb_is_const_nil(lbValue value) {
  8525. LLVMValueRef v = value.value;
  8526. if (LLVMIsConstant(v)) {
  8527. if (LLVMIsAConstantAggregateZero(v)) {
  8528. return true;
  8529. } else if (LLVMIsAConstantPointerNull(v)) {
  8530. return true;
  8531. }
  8532. }
  8533. return false;
  8534. }
  8535. String lb_get_const_string(lbModule *m, lbValue value) {
  8536. GB_ASSERT(lb_is_const(value));
  8537. GB_ASSERT(LLVMIsConstant(value.value));
  8538. Type *t = base_type(value.type);
  8539. GB_ASSERT(are_types_identical(t, t_string));
  8540. unsigned ptr_indices[1] = {0};
  8541. unsigned len_indices[1] = {1};
  8542. LLVMValueRef underlying_ptr = LLVMConstExtractValue(value.value, ptr_indices, gb_count_of(ptr_indices));
  8543. LLVMValueRef underlying_len = LLVMConstExtractValue(value.value, len_indices, gb_count_of(len_indices));
  8544. GB_ASSERT(LLVMGetConstOpcode(underlying_ptr) == LLVMGetElementPtr);
  8545. underlying_ptr = LLVMGetOperand(underlying_ptr, 0);
  8546. GB_ASSERT(LLVMIsAGlobalVariable(underlying_ptr));
  8547. underlying_ptr = LLVMGetInitializer(underlying_ptr);
  8548. size_t length = 0;
  8549. char const *text = LLVMGetAsString(underlying_ptr, &length);
  8550. isize real_length = cast(isize)LLVMConstIntGetSExtValue(underlying_len);
  8551. return make_string(cast(u8 const *)text, real_length);
  8552. }
  8553. void lb_emit_increment(lbProcedure *p, lbValue addr) {
  8554. GB_ASSERT(is_type_pointer(addr.type));
  8555. Type *type = type_deref(addr.type);
  8556. lbValue v_one = lb_const_value(p->module, type, exact_value_i64(1));
  8557. lb_emit_store(p, addr, lb_emit_arith(p, Token_Add, lb_emit_load(p, addr), v_one, type));
  8558. }
  8559. lbValue lb_emit_byte_swap(lbProcedure *p, lbValue value, Type *end_type) {
  8560. GB_ASSERT(type_size_of(value.type) == type_size_of(end_type));
  8561. if (type_size_of(value.type) < 2) {
  8562. return value;
  8563. }
  8564. Type *original_type = value.type;
  8565. if (is_type_float(original_type)) {
  8566. i64 sz = type_size_of(original_type);
  8567. Type *integer_type = nullptr;
  8568. switch (sz) {
  8569. case 2: integer_type = t_u16; break;
  8570. case 4: integer_type = t_u32; break;
  8571. case 8: integer_type = t_u64; break;
  8572. }
  8573. GB_ASSERT(integer_type != nullptr);
  8574. value = lb_emit_transmute(p, value, integer_type);
  8575. }
  8576. char const *name = "llvm.bswap";
  8577. LLVMTypeRef types[1] = {lb_type(p->module, value.type)};
  8578. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  8579. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  8580. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  8581. LLVMValueRef args[1] = {};
  8582. args[0] = value.value;
  8583. lbValue res = {};
  8584. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  8585. res.type = value.type;
  8586. if (is_type_float(original_type)) {
  8587. res = lb_emit_transmute(p, res, original_type);
  8588. }
  8589. res.type = end_type;
  8590. return res;
  8591. }
  8592. lbValue lb_emit_count_ones(lbProcedure *p, lbValue x, Type *type) {
  8593. x = lb_emit_conv(p, x, type);
  8594. char const *name = "llvm.ctpop";
  8595. LLVMTypeRef types[1] = {lb_type(p->module, type)};
  8596. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  8597. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  8598. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  8599. LLVMValueRef args[1] = {};
  8600. args[0] = x.value;
  8601. lbValue res = {};
  8602. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  8603. res.type = type;
  8604. return res;
  8605. }
  8606. lbValue lb_emit_count_zeros(lbProcedure *p, lbValue x, Type *type) {
  8607. i64 sz = 8*type_size_of(type);
  8608. lbValue size = lb_const_int(p->module, type, cast(u64)sz);
  8609. lbValue count = lb_emit_count_ones(p, x, type);
  8610. return lb_emit_arith(p, Token_Sub, size, count, type);
  8611. }
  8612. lbValue lb_emit_count_trailing_zeros(lbProcedure *p, lbValue x, Type *type) {
  8613. x = lb_emit_conv(p, x, type);
  8614. char const *name = "llvm.cttz";
  8615. LLVMTypeRef types[1] = {lb_type(p->module, type)};
  8616. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  8617. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  8618. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  8619. LLVMValueRef args[2] = {};
  8620. args[0] = x.value;
  8621. args[1] = LLVMConstNull(LLVMInt1TypeInContext(p->module->ctx));
  8622. lbValue res = {};
  8623. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  8624. res.type = type;
  8625. return res;
  8626. }
  8627. lbValue lb_emit_count_leading_zeros(lbProcedure *p, lbValue x, Type *type) {
  8628. x = lb_emit_conv(p, x, type);
  8629. char const *name = "llvm.ctlz";
  8630. LLVMTypeRef types[1] = {lb_type(p->module, type)};
  8631. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  8632. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  8633. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  8634. LLVMValueRef args[2] = {};
  8635. args[0] = x.value;
  8636. args[1] = LLVMConstNull(LLVMInt1TypeInContext(p->module->ctx));
  8637. lbValue res = {};
  8638. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  8639. res.type = type;
  8640. return res;
  8641. }
  8642. lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type) {
  8643. x = lb_emit_conv(p, x, type);
  8644. char const *name = "llvm.bitreverse";
  8645. LLVMTypeRef types[1] = {lb_type(p->module, type)};
  8646. unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
  8647. GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
  8648. LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
  8649. LLVMValueRef args[1] = {};
  8650. args[0] = x.value;
  8651. lbValue res = {};
  8652. res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
  8653. res.type = type;
  8654. return res;
  8655. }
  8656. lbValue lb_emit_bit_set_card(lbProcedure *p, lbValue x) {
  8657. GB_ASSERT(is_type_bit_set(x.type));
  8658. Type *underlying = bit_set_to_int(x.type);
  8659. lbValue card = lb_emit_count_ones(p, x, underlying);
  8660. return lb_emit_conv(p, card, t_int);
  8661. }
  8662. lbLoopData lb_loop_start(lbProcedure *p, isize count, Type *index_type) {
  8663. lbLoopData data = {};
  8664. lbValue max = lb_const_int(p->module, t_int, count);
  8665. data.idx_addr = lb_add_local_generated(p, index_type, true);
  8666. data.body = lb_create_block(p, "loop.body");
  8667. data.done = lb_create_block(p, "loop.done");
  8668. data.loop = lb_create_block(p, "loop.loop");
  8669. lb_emit_jump(p, data.loop);
  8670. lb_start_block(p, data.loop);
  8671. data.idx = lb_addr_load(p, data.idx_addr);
  8672. lbValue cond = lb_emit_comp(p, Token_Lt, data.idx, max);
  8673. lb_emit_if(p, cond, data.body, data.done);
  8674. lb_start_block(p, data.body);
  8675. return data;
  8676. }
  8677. void lb_loop_end(lbProcedure *p, lbLoopData const &data) {
  8678. if (data.idx_addr.addr.value != nullptr) {
  8679. lb_emit_increment(p, data.idx_addr.addr);
  8680. lb_emit_jump(p, data.loop);
  8681. lb_start_block(p, data.done);
  8682. }
  8683. }
  8684. lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) {
  8685. lbValue res = {};
  8686. res.type = t_llvm_bool;
  8687. Type *t = x.type;
  8688. if (is_type_pointer(t)) {
  8689. if (op_kind == Token_CmpEq) {
  8690. res.value = LLVMBuildIsNull(p->builder, x.value, "");
  8691. } else if (op_kind == Token_NotEq) {
  8692. res.value = LLVMBuildIsNotNull(p->builder, x.value, "");
  8693. }
  8694. return res;
  8695. } else if (is_type_cstring(t)) {
  8696. lbValue ptr = lb_emit_conv(p, x, t_u8_ptr);
  8697. if (op_kind == Token_CmpEq) {
  8698. res.value = LLVMBuildIsNull(p->builder, ptr.value, "");
  8699. } else if (op_kind == Token_NotEq) {
  8700. res.value = LLVMBuildIsNotNull(p->builder, ptr.value, "");
  8701. }
  8702. return res;
  8703. } else if (is_type_proc(t)) {
  8704. if (op_kind == Token_CmpEq) {
  8705. res.value = LLVMBuildIsNull(p->builder, x.value, "");
  8706. } else if (op_kind == Token_NotEq) {
  8707. res.value = LLVMBuildIsNotNull(p->builder, x.value, "");
  8708. }
  8709. return res;
  8710. } else if (is_type_any(t)) {
  8711. // TODO(bill): is this correct behaviour for nil comparison for any?
  8712. lbValue data = lb_emit_struct_ev(p, x, 0);
  8713. lbValue ti = lb_emit_struct_ev(p, x, 1);
  8714. if (op_kind == Token_CmpEq) {
  8715. LLVMValueRef a = LLVMBuildIsNull(p->builder, data.value, "");
  8716. LLVMValueRef b = LLVMBuildIsNull(p->builder, ti.value, "");
  8717. res.value = LLVMBuildOr(p->builder, a, b, "");
  8718. return res;
  8719. } else if (op_kind == Token_NotEq) {
  8720. LLVMValueRef a = LLVMBuildIsNotNull(p->builder, data.value, "");
  8721. LLVMValueRef b = LLVMBuildIsNotNull(p->builder, ti.value, "");
  8722. res.value = LLVMBuildAnd(p->builder, a, b, "");
  8723. return res;
  8724. }
  8725. } else if (is_type_slice(t)) {
  8726. lbValue len = lb_emit_struct_ev(p, x, 1);
  8727. if (op_kind == Token_CmpEq) {
  8728. res.value = LLVMBuildIsNull(p->builder, len.value, "");
  8729. return res;
  8730. } else if (op_kind == Token_NotEq) {
  8731. res.value = LLVMBuildIsNotNull(p->builder, len.value, "");
  8732. return res;
  8733. }
  8734. } else if (is_type_dynamic_array(t)) {
  8735. lbValue cap = lb_emit_struct_ev(p, x, 2);
  8736. if (op_kind == Token_CmpEq) {
  8737. res.value = LLVMBuildIsNull(p->builder, cap.value, "");
  8738. return res;
  8739. } else if (op_kind == Token_NotEq) {
  8740. res.value = LLVMBuildIsNotNull(p->builder, cap.value, "");
  8741. return res;
  8742. }
  8743. } else if (is_type_map(t)) {
  8744. lbValue cap = lb_map_cap(p, x);
  8745. return lb_emit_comp(p, op_kind, cap, lb_zero(p->module, cap.type));
  8746. } else if (is_type_union(t)) {
  8747. if (type_size_of(t) == 0) {
  8748. if (op_kind == Token_CmpEq) {
  8749. return lb_const_bool(p->module, t_llvm_bool, true);
  8750. } else if (op_kind == Token_NotEq) {
  8751. return lb_const_bool(p->module, t_llvm_bool, false);
  8752. }
  8753. } else if (is_type_union_maybe_pointer(t)) {
  8754. lbValue tag = lb_emit_transmute(p, x, t_rawptr);
  8755. return lb_emit_comp_against_nil(p, op_kind, tag);
  8756. } else {
  8757. lbValue tag = lb_emit_union_tag_value(p, x);
  8758. return lb_emit_comp(p, op_kind, tag, lb_zero(p->module, tag.type));
  8759. }
  8760. } else if (is_type_typeid(t)) {
  8761. lbValue invalid_typeid = lb_const_value(p->module, t_typeid, exact_value_i64(0));
  8762. return lb_emit_comp(p, op_kind, x, invalid_typeid);
  8763. } else if (is_type_soa_struct(t)) {
  8764. Type *bt = base_type(t);
  8765. if (bt->Struct.soa_kind == StructSoa_Slice) {
  8766. lbValue len = lb_soa_struct_len(p, x);
  8767. if (op_kind == Token_CmpEq) {
  8768. res.value = LLVMBuildIsNull(p->builder, len.value, "");
  8769. return res;
  8770. } else if (op_kind == Token_NotEq) {
  8771. res.value = LLVMBuildIsNotNull(p->builder, len.value, "");
  8772. return res;
  8773. }
  8774. } else if (bt->Struct.soa_kind == StructSoa_Dynamic) {
  8775. lbValue cap = lb_soa_struct_cap(p, x);
  8776. if (op_kind == Token_CmpEq) {
  8777. res.value = LLVMBuildIsNull(p->builder, cap.value, "");
  8778. return res;
  8779. } else if (op_kind == Token_NotEq) {
  8780. res.value = LLVMBuildIsNotNull(p->builder, cap.value, "");
  8781. return res;
  8782. }
  8783. }
  8784. } else if (is_type_struct(t) && type_has_nil(t)) {
  8785. auto args = array_make<lbValue>(permanent_allocator(), 2);
  8786. lbValue lhs = lb_address_from_load_or_generate_local(p, x);
  8787. args[0] = lb_emit_conv(p, lhs, t_rawptr);
  8788. args[1] = lb_const_int(p->module, t_int, type_size_of(t));
  8789. lbValue val = lb_emit_runtime_call(p, "memory_compare_zero", args);
  8790. lbValue res = lb_emit_comp(p, op_kind, val, lb_const_int(p->module, t_int, 0));
  8791. return res;
  8792. }
  8793. return {};
  8794. }
  8795. lbValue lb_get_equal_proc_for_type(lbModule *m, Type *type) {
  8796. Type *original_type = type;
  8797. type = base_type(type);
  8798. GB_ASSERT(is_type_comparable(type));
  8799. Type *pt = alloc_type_pointer(type);
  8800. LLVMTypeRef ptr_type = lb_type(m, pt);
  8801. auto key = hash_type(type);
  8802. lbProcedure **found = map_get(&m->equal_procs, key);
  8803. lbProcedure *compare_proc = nullptr;
  8804. if (found) {
  8805. compare_proc = *found;
  8806. GB_ASSERT(compare_proc != nullptr);
  8807. return {compare_proc->value, compare_proc->type};
  8808. }
  8809. static u32 proc_index = 0;
  8810. char buf[16] = {};
  8811. isize n = gb_snprintf(buf, 16, "__$equal%u", ++proc_index);
  8812. char *str = gb_alloc_str_len(permanent_allocator(), buf, n-1);
  8813. String proc_name = make_string_c(str);
  8814. lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_equal_proc);
  8815. map_set(&m->equal_procs, key, p);
  8816. lb_begin_procedure_body(p);
  8817. LLVMValueRef x = LLVMGetParam(p->value, 0);
  8818. LLVMValueRef y = LLVMGetParam(p->value, 1);
  8819. x = LLVMBuildPointerCast(p->builder, x, ptr_type, "");
  8820. y = LLVMBuildPointerCast(p->builder, y, ptr_type, "");
  8821. lbValue lhs = {x, pt};
  8822. lbValue rhs = {y, pt};
  8823. lbBlock *block_same_ptr = lb_create_block(p, "same_ptr");
  8824. lbBlock *block_diff_ptr = lb_create_block(p, "diff_ptr");
  8825. lbValue same_ptr = lb_emit_comp(p, Token_CmpEq, lhs, rhs);
  8826. lb_emit_if(p, same_ptr, block_same_ptr, block_diff_ptr);
  8827. lb_start_block(p, block_same_ptr);
  8828. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_bool), 1, false));
  8829. lb_start_block(p, block_diff_ptr);
  8830. if (type->kind == Type_Struct) {
  8831. type_set_offsets(type);
  8832. lbBlock *block_false = lb_create_block(p, "bfalse");
  8833. lbValue res = lb_const_bool(m, t_bool, true);
  8834. for_array(i, type->Struct.fields) {
  8835. lbBlock *next_block = lb_create_block(p, "btrue");
  8836. lbValue pleft = lb_emit_struct_ep(p, lhs, cast(i32)i);
  8837. lbValue pright = lb_emit_struct_ep(p, rhs, cast(i32)i);
  8838. lbValue left = lb_emit_load(p, pleft);
  8839. lbValue right = lb_emit_load(p, pright);
  8840. lbValue ok = lb_emit_comp(p, Token_CmpEq, left, right);
  8841. lb_emit_if(p, ok, next_block, block_false);
  8842. lb_emit_jump(p, next_block);
  8843. lb_start_block(p, next_block);
  8844. }
  8845. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_bool), 1, false));
  8846. lb_start_block(p, block_false);
  8847. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_bool), 0, false));
  8848. } else if (type->kind == Type_Union) {
  8849. if (is_type_union_maybe_pointer(type)) {
  8850. Type *v = type->Union.variants[0];
  8851. Type *pv = alloc_type_pointer(v);
  8852. lbValue left = lb_emit_load(p, lb_emit_conv(p, lhs, pv));
  8853. lbValue right = lb_emit_load(p, lb_emit_conv(p, rhs, pv));
  8854. lbValue ok = lb_emit_comp(p, Token_CmpEq, left, right);
  8855. ok = lb_emit_conv(p, ok, t_bool);
  8856. LLVMBuildRet(p->builder, ok.value);
  8857. } else {
  8858. lbBlock *block_false = lb_create_block(p, "bfalse");
  8859. lbBlock *block_switch = lb_create_block(p, "bswitch");
  8860. lbValue left_tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, lhs));
  8861. lbValue right_tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, rhs));
  8862. lbValue tag_eq = lb_emit_comp(p, Token_CmpEq, left_tag, right_tag);
  8863. lb_emit_if(p, tag_eq, block_switch, block_false);
  8864. lb_start_block(p, block_switch);
  8865. LLVMValueRef v_switch = LLVMBuildSwitch(p->builder, left_tag.value, block_false->block, cast(unsigned)type->Union.variants.count);
  8866. for_array(i, type->Union.variants) {
  8867. lbBlock *case_block = lb_create_block(p, "bcase");
  8868. lb_start_block(p, case_block);
  8869. Type *v = type->Union.variants[i];
  8870. lbValue case_tag = lb_const_union_tag(p->module, type, v);
  8871. Type *vp = alloc_type_pointer(v);
  8872. lbValue left = lb_emit_load(p, lb_emit_conv(p, lhs, vp));
  8873. lbValue right = lb_emit_load(p, lb_emit_conv(p, rhs, vp));
  8874. lbValue ok = lb_emit_comp(p, Token_CmpEq, left, right);
  8875. ok = lb_emit_conv(p, ok, t_bool);
  8876. LLVMBuildRet(p->builder, ok.value);
  8877. LLVMAddCase(v_switch, case_tag.value, case_block->block);
  8878. }
  8879. lb_start_block(p, block_false);
  8880. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_bool), 0, false));
  8881. }
  8882. } else {
  8883. lbValue left = lb_emit_load(p, lhs);
  8884. lbValue right = lb_emit_load(p, rhs);
  8885. lbValue ok = lb_emit_comp(p, Token_CmpEq, left, right);
  8886. ok = lb_emit_conv(p, ok, t_bool);
  8887. LLVMBuildRet(p->builder, ok.value);
  8888. }
  8889. lb_end_procedure_body(p);
  8890. compare_proc = p;
  8891. return {compare_proc->value, compare_proc->type};
  8892. }
  8893. lbValue lb_simple_compare_hash(lbProcedure *p, Type *type, lbValue data, lbValue seed) {
  8894. GB_ASSERT_MSG(is_type_simple_compare(type), "%s", type_to_string(type));
  8895. i64 sz = type_size_of(type);
  8896. if (1 <= sz && sz <= 16) {
  8897. char name[20] = {};
  8898. gb_snprintf(name, 20, "default_hasher%d", cast(i32)sz);
  8899. auto args = array_make<lbValue>(permanent_allocator(), 2);
  8900. args[0] = data;
  8901. args[1] = seed;
  8902. return lb_emit_runtime_call(p, name, args);
  8903. }
  8904. auto args = array_make<lbValue>(permanent_allocator(), 3);
  8905. args[0] = data;
  8906. args[1] = seed;
  8907. args[2] = lb_const_int(p->module, t_int, type_size_of(type));
  8908. return lb_emit_runtime_call(p, "default_hasher_n", args);
  8909. }
  8910. lbValue lb_get_hasher_proc_for_type(lbModule *m, Type *type) {
  8911. Type *original_type = type;
  8912. type = core_type(type);
  8913. GB_ASSERT(is_type_valid_for_keys(type));
  8914. Type *pt = alloc_type_pointer(type);
  8915. LLVMTypeRef ptr_type = lb_type(m, pt);
  8916. auto key = hash_type(type);
  8917. lbProcedure **found = map_get(&m->hasher_procs, key);
  8918. if (found) {
  8919. GB_ASSERT(*found != nullptr);
  8920. return {(*found)->value, (*found)->type};
  8921. }
  8922. static u32 proc_index = 0;
  8923. char buf[16] = {};
  8924. isize n = gb_snprintf(buf, 16, "__$hasher%u", ++proc_index);
  8925. char *str = gb_alloc_str_len(permanent_allocator(), buf, n-1);
  8926. String proc_name = make_string_c(str);
  8927. lbProcedure *p = lb_create_dummy_procedure(m, proc_name, t_hasher_proc);
  8928. map_set(&m->hasher_procs, key, p);
  8929. lb_begin_procedure_body(p);
  8930. defer (lb_end_procedure_body(p));
  8931. LLVMValueRef x = LLVMGetParam(p->value, 0);
  8932. LLVMValueRef y = LLVMGetParam(p->value, 1);
  8933. lbValue data = {x, t_rawptr};
  8934. lbValue seed = {y, t_uintptr};
  8935. LLVMAttributeRef nonnull_attr = lb_create_enum_attribute(m->ctx, "nonnull");
  8936. LLVMAddAttributeAtIndex(p->value, 1+0, nonnull_attr);
  8937. if (is_type_simple_compare(type)) {
  8938. lbValue res = lb_simple_compare_hash(p, type, data, seed);
  8939. LLVMBuildRet(p->builder, res.value);
  8940. return {p->value, p->type};
  8941. }
  8942. if (type->kind == Type_Struct) {
  8943. type_set_offsets(type);
  8944. data = lb_emit_conv(p, data, t_u8_ptr);
  8945. auto args = array_make<lbValue>(permanent_allocator(), 2);
  8946. for_array(i, type->Struct.fields) {
  8947. i64 offset = type->Struct.offsets[i];
  8948. Entity *field = type->Struct.fields[i];
  8949. lbValue field_hasher = lb_get_hasher_proc_for_type(m, field->type);
  8950. lbValue ptr = lb_emit_ptr_offset(p, data, lb_const_int(m, t_uintptr, offset));
  8951. args[0] = ptr;
  8952. args[1] = seed;
  8953. seed = lb_emit_call(p, field_hasher, args);
  8954. }
  8955. LLVMBuildRet(p->builder, seed.value);
  8956. } else if (type->kind == Type_Union) {
  8957. auto args = array_make<lbValue>(permanent_allocator(), 2);
  8958. if (is_type_union_maybe_pointer(type)) {
  8959. Type *v = type->Union.variants[0];
  8960. lbValue variant_hasher = lb_get_hasher_proc_for_type(m, v);
  8961. args[0] = data;
  8962. args[1] = seed;
  8963. lbValue res = lb_emit_call(p, variant_hasher, args);
  8964. LLVMBuildRet(p->builder, res.value);
  8965. }
  8966. lbBlock *end_block = lb_create_block(p, "bend");
  8967. data = lb_emit_conv(p, data, pt);
  8968. lbValue tag_ptr = lb_emit_union_tag_ptr(p, data);
  8969. lbValue tag = lb_emit_load(p, tag_ptr);
  8970. LLVMValueRef v_switch = LLVMBuildSwitch(p->builder, tag.value, end_block->block, cast(unsigned)type->Union.variants.count);
  8971. for_array(i, type->Union.variants) {
  8972. lbBlock *case_block = lb_create_block(p, "bcase");
  8973. lb_start_block(p, case_block);
  8974. Type *v = type->Union.variants[i];
  8975. Type *vp = alloc_type_pointer(v);
  8976. lbValue case_tag = lb_const_union_tag(p->module, type, v);
  8977. lbValue variant_hasher = lb_get_hasher_proc_for_type(m, v);
  8978. args[0] = data;
  8979. args[1] = seed;
  8980. lbValue res = lb_emit_call(p, variant_hasher, args);
  8981. LLVMBuildRet(p->builder, res.value);
  8982. LLVMAddCase(v_switch, case_tag.value, case_block->block);
  8983. }
  8984. lb_start_block(p, end_block);
  8985. LLVMBuildRet(p->builder, seed.value);
  8986. } else if (type->kind == Type_Array) {
  8987. lbAddr pres = lb_add_local_generated(p, t_uintptr, false);
  8988. lb_addr_store(p, pres, seed);
  8989. auto args = array_make<lbValue>(permanent_allocator(), 2);
  8990. lbValue elem_hasher = lb_get_hasher_proc_for_type(m, type->Array.elem);
  8991. auto loop_data = lb_loop_start(p, type->Array.count, t_i32);
  8992. data = lb_emit_conv(p, data, pt);
  8993. lbValue ptr = lb_emit_array_ep(p, data, loop_data.idx);
  8994. args[0] = ptr;
  8995. args[1] = lb_addr_load(p, pres);
  8996. lbValue new_seed = lb_emit_call(p, elem_hasher, args);
  8997. lb_addr_store(p, pres, new_seed);
  8998. lb_loop_end(p, loop_data);
  8999. lbValue res = lb_addr_load(p, pres);
  9000. LLVMBuildRet(p->builder, res.value);
  9001. } else if (type->kind == Type_EnumeratedArray) {
  9002. lbAddr res = lb_add_local_generated(p, t_uintptr, false);
  9003. lb_addr_store(p, res, seed);
  9004. auto args = array_make<lbValue>(permanent_allocator(), 2);
  9005. lbValue elem_hasher = lb_get_hasher_proc_for_type(m, type->EnumeratedArray.elem);
  9006. auto loop_data = lb_loop_start(p, type->EnumeratedArray.count, t_i32);
  9007. data = lb_emit_conv(p, data, pt);
  9008. lbValue ptr = lb_emit_array_ep(p, data, loop_data.idx);
  9009. args[0] = ptr;
  9010. args[1] = lb_addr_load(p, res);
  9011. lbValue new_seed = lb_emit_call(p, elem_hasher, args);
  9012. lb_addr_store(p, res, new_seed);
  9013. lb_loop_end(p, loop_data);
  9014. lbValue vres = lb_addr_load(p, res);
  9015. LLVMBuildRet(p->builder, vres.value);
  9016. } else if (is_type_cstring(type)) {
  9017. auto args = array_make<lbValue>(permanent_allocator(), 2);
  9018. args[0] = data;
  9019. args[1] = seed;
  9020. lbValue res = lb_emit_runtime_call(p, "default_hasher_cstring", args);
  9021. LLVMBuildRet(p->builder, res.value);
  9022. } else if (is_type_string(type)) {
  9023. auto args = array_make<lbValue>(permanent_allocator(), 2);
  9024. args[0] = data;
  9025. args[1] = seed;
  9026. lbValue res = lb_emit_runtime_call(p, "default_hasher_string", args);
  9027. LLVMBuildRet(p->builder, res.value);
  9028. } else {
  9029. GB_PANIC("Unhandled type for hasher: %s", type_to_string(type));
  9030. }
  9031. return {p->value, p->type};
  9032. }
  9033. lbValue lb_compare_records(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue right, Type *type) {
  9034. GB_ASSERT((is_type_struct(type) || is_type_union(type)) && is_type_comparable(type));
  9035. lbValue left_ptr = lb_address_from_load_or_generate_local(p, left);
  9036. lbValue right_ptr = lb_address_from_load_or_generate_local(p, right);
  9037. lbValue res = {};
  9038. if (is_type_simple_compare(type)) {
  9039. // TODO(bill): Test to see if this is actually faster!!!!
  9040. auto args = array_make<lbValue>(permanent_allocator(), 3);
  9041. args[0] = lb_emit_conv(p, left_ptr, t_rawptr);
  9042. args[1] = lb_emit_conv(p, right_ptr, t_rawptr);
  9043. args[2] = lb_const_int(p->module, t_int, type_size_of(type));
  9044. res = lb_emit_runtime_call(p, "memory_equal", args);
  9045. } else {
  9046. lbValue value = lb_get_equal_proc_for_type(p->module, type);
  9047. auto args = array_make<lbValue>(permanent_allocator(), 2);
  9048. args[0] = lb_emit_conv(p, left_ptr, t_rawptr);
  9049. args[1] = lb_emit_conv(p, right_ptr, t_rawptr);
  9050. res = lb_emit_call(p, value, args);
  9051. }
  9052. if (op_kind == Token_NotEq) {
  9053. res = lb_emit_unary_arith(p, Token_Not, res, res.type);
  9054. }
  9055. return res;
  9056. }
  9057. lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue right) {
  9058. Type *a = core_type(left.type);
  9059. Type *b = core_type(right.type);
  9060. GB_ASSERT(gb_is_between(op_kind, Token__ComparisonBegin+1, Token__ComparisonEnd-1));
  9061. lbValue nil_check = {};
  9062. if (is_type_untyped_nil(left.type)) {
  9063. nil_check = lb_emit_comp_against_nil(p, op_kind, right);
  9064. } else if (is_type_untyped_nil(right.type)) {
  9065. nil_check = lb_emit_comp_against_nil(p, op_kind, left);
  9066. }
  9067. if (nil_check.value != nullptr) {
  9068. return nil_check;
  9069. }
  9070. if (are_types_identical(a, b)) {
  9071. // NOTE(bill): No need for a conversion
  9072. } else if (lb_is_const(left) || lb_is_const_nil(left)) {
  9073. left = lb_emit_conv(p, left, right.type);
  9074. } else if (lb_is_const(right) || lb_is_const_nil(right)) {
  9075. right = lb_emit_conv(p, right, left.type);
  9076. } else {
  9077. Type *lt = left.type;
  9078. Type *rt = right.type;
  9079. lt = left.type;
  9080. rt = right.type;
  9081. i64 ls = type_size_of(lt);
  9082. i64 rs = type_size_of(rt);
  9083. // NOTE(bill): Quick heuristic, larger types are usually the target type
  9084. if (ls < rs) {
  9085. left = lb_emit_conv(p, left, rt);
  9086. } else if (ls > rs) {
  9087. right = lb_emit_conv(p, right, lt);
  9088. } else {
  9089. if (is_type_union(rt)) {
  9090. left = lb_emit_conv(p, left, rt);
  9091. } else {
  9092. right = lb_emit_conv(p, right, lt);
  9093. }
  9094. }
  9095. }
  9096. if (is_type_array(a)) {
  9097. Type *tl = base_type(a);
  9098. lbValue lhs = lb_address_from_load_or_generate_local(p, left);
  9099. lbValue rhs = lb_address_from_load_or_generate_local(p, right);
  9100. TokenKind cmp_op = Token_And;
  9101. lbValue res = lb_const_bool(p->module, t_llvm_bool, true);
  9102. if (op_kind == Token_NotEq) {
  9103. res = lb_const_bool(p->module, t_llvm_bool, false);
  9104. cmp_op = Token_Or;
  9105. } else if (op_kind == Token_CmpEq) {
  9106. res = lb_const_bool(p->module, t_llvm_bool, true);
  9107. cmp_op = Token_And;
  9108. }
  9109. bool inline_array_arith = type_size_of(tl) <= build_context.max_align;
  9110. i32 count = cast(i32)tl->Array.count;
  9111. if (inline_array_arith) {
  9112. // inline
  9113. lbAddr val = lb_add_local_generated(p, t_bool, false);
  9114. lb_addr_store(p, val, res);
  9115. for (i32 i = 0; i < count; i++) {
  9116. lbValue x = lb_emit_load(p, lb_emit_array_epi(p, lhs, i));
  9117. lbValue y = lb_emit_load(p, lb_emit_array_epi(p, rhs, i));
  9118. lbValue cmp = lb_emit_comp(p, op_kind, x, y);
  9119. lbValue new_res = lb_emit_arith(p, cmp_op, lb_addr_load(p, val), cmp, t_bool);
  9120. lb_addr_store(p, val, lb_emit_conv(p, new_res, t_bool));
  9121. }
  9122. return lb_addr_load(p, val);
  9123. } else {
  9124. if (is_type_simple_compare(tl) && (op_kind == Token_CmpEq || op_kind == Token_NotEq)) {
  9125. // TODO(bill): Test to see if this is actually faster!!!!
  9126. auto args = array_make<lbValue>(permanent_allocator(), 3);
  9127. args[0] = lb_emit_conv(p, lhs, t_rawptr);
  9128. args[1] = lb_emit_conv(p, rhs, t_rawptr);
  9129. args[2] = lb_const_int(p->module, t_int, type_size_of(tl));
  9130. lbValue val = lb_emit_runtime_call(p, "memory_compare", args);
  9131. lbValue res = lb_emit_comp(p, op_kind, val, lb_const_nil(p->module, val.type));
  9132. return lb_emit_conv(p, res, t_bool);
  9133. } else {
  9134. lbAddr val = lb_add_local_generated(p, t_bool, false);
  9135. lb_addr_store(p, val, res);
  9136. auto loop_data = lb_loop_start(p, count, t_i32);
  9137. {
  9138. lbValue i = loop_data.idx;
  9139. lbValue x = lb_emit_load(p, lb_emit_array_ep(p, lhs, i));
  9140. lbValue y = lb_emit_load(p, lb_emit_array_ep(p, rhs, i));
  9141. lbValue cmp = lb_emit_comp(p, op_kind, x, y);
  9142. lbValue new_res = lb_emit_arith(p, cmp_op, lb_addr_load(p, val), cmp, t_bool);
  9143. lb_addr_store(p, val, lb_emit_conv(p, new_res, t_bool));
  9144. }
  9145. lb_loop_end(p, loop_data);
  9146. return lb_addr_load(p, val);
  9147. }
  9148. }
  9149. }
  9150. if ((is_type_struct(a) || is_type_union(a)) && is_type_comparable(a)) {
  9151. return lb_compare_records(p, op_kind, left, right, a);
  9152. }
  9153. if ((is_type_struct(b) || is_type_union(b)) && is_type_comparable(b)) {
  9154. return lb_compare_records(p, op_kind, left, right, b);
  9155. }
  9156. if (is_type_string(a)) {
  9157. if (is_type_cstring(a)) {
  9158. left = lb_emit_conv(p, left, t_string);
  9159. right = lb_emit_conv(p, right, t_string);
  9160. }
  9161. char const *runtime_procedure = nullptr;
  9162. switch (op_kind) {
  9163. case Token_CmpEq: runtime_procedure = "string_eq"; break;
  9164. case Token_NotEq: runtime_procedure = "string_ne"; break;
  9165. case Token_Lt: runtime_procedure = "string_lt"; break;
  9166. case Token_Gt: runtime_procedure = "string_gt"; break;
  9167. case Token_LtEq: runtime_procedure = "string_le"; break;
  9168. case Token_GtEq: runtime_procedure = "string_gt"; break;
  9169. }
  9170. GB_ASSERT(runtime_procedure != nullptr);
  9171. auto args = array_make<lbValue>(permanent_allocator(), 2);
  9172. args[0] = left;
  9173. args[1] = right;
  9174. return lb_emit_runtime_call(p, runtime_procedure, args);
  9175. }
  9176. if (is_type_complex(a)) {
  9177. char const *runtime_procedure = "";
  9178. i64 sz = 8*type_size_of(a);
  9179. switch (sz) {
  9180. case 64:
  9181. switch (op_kind) {
  9182. case Token_CmpEq: runtime_procedure = "complex64_eq"; break;
  9183. case Token_NotEq: runtime_procedure = "complex64_ne"; break;
  9184. }
  9185. break;
  9186. case 128:
  9187. switch (op_kind) {
  9188. case Token_CmpEq: runtime_procedure = "complex128_eq"; break;
  9189. case Token_NotEq: runtime_procedure = "complex128_ne"; break;
  9190. }
  9191. break;
  9192. }
  9193. GB_ASSERT(runtime_procedure != nullptr);
  9194. auto args = array_make<lbValue>(permanent_allocator(), 2);
  9195. args[0] = left;
  9196. args[1] = right;
  9197. return lb_emit_runtime_call(p, runtime_procedure, args);
  9198. }
  9199. if (is_type_quaternion(a)) {
  9200. char const *runtime_procedure = "";
  9201. i64 sz = 8*type_size_of(a);
  9202. switch (sz) {
  9203. case 128:
  9204. switch (op_kind) {
  9205. case Token_CmpEq: runtime_procedure = "quaternion128_eq"; break;
  9206. case Token_NotEq: runtime_procedure = "quaternion128_ne"; break;
  9207. }
  9208. break;
  9209. case 256:
  9210. switch (op_kind) {
  9211. case Token_CmpEq: runtime_procedure = "quaternion256_eq"; break;
  9212. case Token_NotEq: runtime_procedure = "quaternion256_ne"; break;
  9213. }
  9214. break;
  9215. }
  9216. GB_ASSERT(runtime_procedure != nullptr);
  9217. auto args = array_make<lbValue>(permanent_allocator(), 2);
  9218. args[0] = left;
  9219. args[1] = right;
  9220. return lb_emit_runtime_call(p, runtime_procedure, args);
  9221. }
  9222. if (is_type_bit_set(a)) {
  9223. switch (op_kind) {
  9224. case Token_Lt:
  9225. case Token_LtEq:
  9226. case Token_Gt:
  9227. case Token_GtEq:
  9228. {
  9229. Type *it = bit_set_to_int(a);
  9230. lbValue lhs = lb_emit_transmute(p, left, it);
  9231. lbValue rhs = lb_emit_transmute(p, right, it);
  9232. lbValue res = lb_emit_arith(p, Token_And, lhs, rhs, it);
  9233. if (op_kind == Token_Lt || op_kind == Token_LtEq) {
  9234. // (lhs & rhs) == lhs
  9235. res.value = LLVMBuildICmp(p->builder, LLVMIntEQ, res.value, lhs.value, "");
  9236. res.type = t_llvm_bool;
  9237. } else if (op_kind == Token_Gt || op_kind == Token_GtEq) {
  9238. // (lhs & rhs) == rhs
  9239. res.value = LLVMBuildICmp(p->builder, LLVMIntEQ, res.value, rhs.value, "");
  9240. res.type = t_llvm_bool;
  9241. }
  9242. // NOTE(bill): Strict subsets
  9243. if (op_kind == Token_Lt || op_kind == Token_Gt) {
  9244. // res &~ (lhs == rhs)
  9245. lbValue eq = {};
  9246. eq.value = LLVMBuildICmp(p->builder, LLVMIntEQ, lhs.value, rhs.value, "");
  9247. eq.type = t_llvm_bool;
  9248. res = lb_emit_arith(p, Token_AndNot, res, eq, t_llvm_bool);
  9249. }
  9250. return res;
  9251. }
  9252. case Token_CmpEq:
  9253. case Token_NotEq:
  9254. {
  9255. LLVMIntPredicate pred = {};
  9256. switch (op_kind) {
  9257. case Token_CmpEq: pred = LLVMIntEQ; break;
  9258. case Token_NotEq: pred = LLVMIntNE; break;
  9259. }
  9260. lbValue res = {};
  9261. res.type = t_llvm_bool;
  9262. res.value = LLVMBuildICmp(p->builder, pred, left.value, right.value, "");
  9263. return res;
  9264. }
  9265. }
  9266. }
  9267. if (op_kind != Token_CmpEq && op_kind != Token_NotEq) {
  9268. Type *t = left.type;
  9269. if (is_type_integer(t) && is_type_different_to_arch_endianness(t)) {
  9270. Type *platform_type = integer_endian_type_to_platform_type(t);
  9271. lbValue x = lb_emit_byte_swap(p, left, platform_type);
  9272. lbValue y = lb_emit_byte_swap(p, right, platform_type);
  9273. left = x;
  9274. right = y;
  9275. } else if (is_type_float(t) && is_type_different_to_arch_endianness(t)) {
  9276. Type *platform_type = integer_endian_type_to_platform_type(t);
  9277. lbValue x = lb_emit_conv(p, left, platform_type);
  9278. lbValue y = lb_emit_conv(p, right, platform_type);
  9279. left = x;
  9280. right = y;
  9281. }
  9282. }
  9283. a = core_type(left.type);
  9284. b = core_type(right.type);
  9285. lbValue res = {};
  9286. res.type = t_llvm_bool;
  9287. if (is_type_integer(a) ||
  9288. is_type_boolean(a) ||
  9289. is_type_pointer(a) ||
  9290. is_type_proc(a) ||
  9291. is_type_enum(a)) {
  9292. LLVMIntPredicate pred = {};
  9293. if (is_type_unsigned(left.type)) {
  9294. switch (op_kind) {
  9295. case Token_Gt: pred = LLVMIntUGT; break;
  9296. case Token_GtEq: pred = LLVMIntUGE; break;
  9297. case Token_Lt: pred = LLVMIntULT; break;
  9298. case Token_LtEq: pred = LLVMIntULE; break;
  9299. }
  9300. } else {
  9301. switch (op_kind) {
  9302. case Token_Gt: pred = LLVMIntSGT; break;
  9303. case Token_GtEq: pred = LLVMIntSGE; break;
  9304. case Token_Lt: pred = LLVMIntSLT; break;
  9305. case Token_LtEq: pred = LLVMIntSLE; break;
  9306. }
  9307. }
  9308. switch (op_kind) {
  9309. case Token_CmpEq: pred = LLVMIntEQ; break;
  9310. case Token_NotEq: pred = LLVMIntNE; break;
  9311. }
  9312. LLVMValueRef lhs = left.value;
  9313. LLVMValueRef rhs = right.value;
  9314. if (LLVMTypeOf(lhs) != LLVMTypeOf(rhs)) {
  9315. if (lb_is_type_kind(LLVMTypeOf(lhs), LLVMPointerTypeKind)) {
  9316. rhs = LLVMBuildPointerCast(p->builder, rhs, LLVMTypeOf(lhs), "");
  9317. }
  9318. }
  9319. res.value = LLVMBuildICmp(p->builder, pred, lhs, rhs, "");
  9320. } else if (is_type_float(a)) {
  9321. LLVMRealPredicate pred = {};
  9322. switch (op_kind) {
  9323. case Token_CmpEq: pred = LLVMRealOEQ; break;
  9324. case Token_Gt: pred = LLVMRealOGT; break;
  9325. case Token_GtEq: pred = LLVMRealOGE; break;
  9326. case Token_Lt: pred = LLVMRealOLT; break;
  9327. case Token_LtEq: pred = LLVMRealOLE; break;
  9328. case Token_NotEq: pred = LLVMRealONE; break;
  9329. }
  9330. res.value = LLVMBuildFCmp(p->builder, pred, left.value, right.value, "");
  9331. } else if (is_type_typeid(a)) {
  9332. LLVMIntPredicate pred = {};
  9333. switch (op_kind) {
  9334. case Token_Gt: pred = LLVMIntUGT; break;
  9335. case Token_GtEq: pred = LLVMIntUGE; break;
  9336. case Token_Lt: pred = LLVMIntULT; break;
  9337. case Token_LtEq: pred = LLVMIntULE; break;
  9338. case Token_CmpEq: pred = LLVMIntEQ; break;
  9339. case Token_NotEq: pred = LLVMIntNE; break;
  9340. }
  9341. res.value = LLVMBuildICmp(p->builder, pred, left.value, right.value, "");
  9342. } else {
  9343. GB_PANIC("Unhandled comparison kind %s (%s) %.*s %s (%s)", type_to_string(left.type), type_to_string(base_type(left.type)), LIT(token_strings[op_kind]), type_to_string(right.type), type_to_string(base_type(right.type)));
  9344. }
  9345. return res;
  9346. }
  9347. lbValue lb_generate_anonymous_proc_lit(lbModule *m, String const &prefix_name, Ast *expr, lbProcedure *parent) {
  9348. lbProcedure **found = map_get(&m->gen->anonymous_proc_lits, hash_pointer(expr));
  9349. if (found) {
  9350. return lb_find_procedure_value_from_entity(m, (*found)->entity);
  9351. }
  9352. ast_node(pl, ProcLit, expr);
  9353. // NOTE(bill): Generate a new name
  9354. // parent$count
  9355. isize name_len = prefix_name.len + 1 + 8 + 1;
  9356. char *name_text = gb_alloc_array(permanent_allocator(), char, name_len);
  9357. i32 name_id = cast(i32)m->gen->anonymous_proc_lits.entries.count;
  9358. name_len = gb_snprintf(name_text, name_len, "%.*s$anon-%d", LIT(prefix_name), name_id);
  9359. String name = make_string((u8 *)name_text, name_len-1);
  9360. Type *type = type_of_expr(expr);
  9361. Token token = {};
  9362. token.pos = ast_token(expr).pos;
  9363. token.kind = Token_Ident;
  9364. token.string = name;
  9365. Entity *e = alloc_entity_procedure(nullptr, token, type, pl->tags);
  9366. e->file = expr->file;
  9367. e->decl_info = pl->decl;
  9368. e->code_gen_module = m;
  9369. lbProcedure *p = lb_create_procedure(m, e);
  9370. lbValue value = {};
  9371. value.value = p->value;
  9372. value.type = p->type;
  9373. array_add(&m->procedures_to_generate, p);
  9374. if (parent != nullptr) {
  9375. array_add(&parent->children, p);
  9376. } else {
  9377. string_map_set(&m->members, name, value);
  9378. }
  9379. map_set(&m->anonymous_proc_lits, hash_pointer(expr), p);
  9380. map_set(&m->gen->anonymous_proc_lits, hash_pointer(expr), p);
  9381. return value;
  9382. }
  9383. lbValue lb_emit_union_cast_only_ok_check(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
  9384. GB_ASSERT(is_type_tuple(type));
  9385. lbModule *m = p->module;
  9386. Type *src_type = value.type;
  9387. bool is_ptr = is_type_pointer(src_type);
  9388. // IMPORTANT NOTE(bill): This assumes that the value is completely ignored
  9389. // so when it does an assignment, it complete ignores the value.
  9390. // Just make it two booleans and ignore the first one
  9391. //
  9392. // _, ok := x.(T);
  9393. //
  9394. Type *ok_type = type->Tuple.variables[1]->type;
  9395. Type *gen_tuple_types[2] = {};
  9396. gen_tuple_types[0] = ok_type;
  9397. gen_tuple_types[1] = ok_type;
  9398. Type *gen_tuple = alloc_type_tuple_from_field_types(gen_tuple_types, gb_count_of(gen_tuple_types), false, true);
  9399. lbAddr v = lb_add_local_generated(p, gen_tuple, false);
  9400. if (is_ptr) {
  9401. value = lb_emit_load(p, value);
  9402. }
  9403. Type *src = base_type(type_deref(src_type));
  9404. GB_ASSERT_MSG(is_type_union(src), "%s", type_to_string(src_type));
  9405. Type *dst = type->Tuple.variables[0]->type;
  9406. lbValue cond = {};
  9407. if (is_type_union_maybe_pointer(src)) {
  9408. lbValue data = lb_emit_transmute(p, value, dst);
  9409. cond = lb_emit_comp_against_nil(p, Token_NotEq, data);
  9410. } else {
  9411. lbValue tag = lb_emit_union_tag_value(p, value);
  9412. lbValue dst_tag = lb_const_union_tag(m, src, dst);
  9413. cond = lb_emit_comp(p, Token_CmpEq, tag, dst_tag);
  9414. }
  9415. lbValue gep1 = lb_emit_struct_ep(p, v.addr, 1);
  9416. lb_emit_store(p, gep1, cond);
  9417. return lb_addr_load(p, v);
  9418. }
  9419. lbValue lb_emit_union_cast(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
  9420. lbModule *m = p->module;
  9421. Type *src_type = value.type;
  9422. bool is_ptr = is_type_pointer(src_type);
  9423. bool is_tuple = true;
  9424. Type *tuple = type;
  9425. if (type->kind != Type_Tuple) {
  9426. is_tuple = false;
  9427. tuple = make_optional_ok_type(type);
  9428. }
  9429. lbAddr v = lb_add_local_generated(p, tuple, true);
  9430. if (is_ptr) {
  9431. value = lb_emit_load(p, value);
  9432. }
  9433. Type *src = base_type(type_deref(src_type));
  9434. GB_ASSERT_MSG(is_type_union(src), "%s", type_to_string(src_type));
  9435. Type *dst = tuple->Tuple.variables[0]->type;
  9436. lbValue value_ = lb_address_from_load_or_generate_local(p, value);
  9437. lbValue tag = {};
  9438. lbValue dst_tag = {};
  9439. lbValue cond = {};
  9440. lbValue data = {};
  9441. lbValue gep0 = lb_emit_struct_ep(p, v.addr, 0);
  9442. lbValue gep1 = lb_emit_struct_ep(p, v.addr, 1);
  9443. if (is_type_union_maybe_pointer(src)) {
  9444. data = lb_emit_load(p, lb_emit_conv(p, value_, gep0.type));
  9445. } else {
  9446. tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, value_));
  9447. dst_tag = lb_const_union_tag(m, src, dst);
  9448. }
  9449. lbBlock *ok_block = lb_create_block(p, "union_cast.ok");
  9450. lbBlock *end_block = lb_create_block(p, "union_cast.end");
  9451. if (data.value != nullptr) {
  9452. GB_ASSERT(is_type_union_maybe_pointer(src));
  9453. cond = lb_emit_comp_against_nil(p, Token_NotEq, data);
  9454. } else {
  9455. cond = lb_emit_comp(p, Token_CmpEq, tag, dst_tag);
  9456. }
  9457. lb_emit_if(p, cond, ok_block, end_block);
  9458. lb_start_block(p, ok_block);
  9459. if (data.value == nullptr) {
  9460. data = lb_emit_load(p, lb_emit_conv(p, value_, gep0.type));
  9461. }
  9462. lb_emit_store(p, gep0, data);
  9463. lb_emit_store(p, gep1, lb_const_bool(m, t_bool, true));
  9464. lb_emit_jump(p, end_block);
  9465. lb_start_block(p, end_block);
  9466. if (!is_tuple) {
  9467. {
  9468. // NOTE(bill): Panic on invalid conversion
  9469. Type *dst_type = tuple->Tuple.variables[0]->type;
  9470. lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1));
  9471. auto args = array_make<lbValue>(permanent_allocator(), 7);
  9472. args[0] = ok;
  9473. args[1] = lb_const_string(m, get_file_path_string(pos.file_id));
  9474. args[2] = lb_const_int(m, t_i32, pos.line);
  9475. args[3] = lb_const_int(m, t_i32, pos.column);
  9476. args[4] = lb_typeid(m, src_type);
  9477. args[5] = lb_typeid(m, dst_type);
  9478. args[6] = lb_emit_conv(p, value_, t_rawptr);
  9479. lb_emit_runtime_call(p, "type_assertion_check2", args);
  9480. }
  9481. return lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 0));
  9482. }
  9483. return lb_addr_load(p, v);
  9484. }
  9485. lbAddr lb_emit_any_cast_addr(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
  9486. lbModule *m = p->module;
  9487. Type *src_type = value.type;
  9488. if (is_type_pointer(src_type)) {
  9489. value = lb_emit_load(p, value);
  9490. }
  9491. bool is_tuple = true;
  9492. Type *tuple = type;
  9493. if (type->kind != Type_Tuple) {
  9494. is_tuple = false;
  9495. tuple = make_optional_ok_type(type);
  9496. }
  9497. Type *dst_type = tuple->Tuple.variables[0]->type;
  9498. lbAddr v = lb_add_local_generated(p, tuple, true);
  9499. lbValue dst_typeid = lb_typeid(m, dst_type);
  9500. lbValue any_typeid = lb_emit_struct_ev(p, value, 1);
  9501. lbBlock *ok_block = lb_create_block(p, "any_cast.ok");
  9502. lbBlock *end_block = lb_create_block(p, "any_cast.end");
  9503. lbValue cond = lb_emit_comp(p, Token_CmpEq, any_typeid, dst_typeid);
  9504. lb_emit_if(p, cond, ok_block, end_block);
  9505. lb_start_block(p, ok_block);
  9506. lbValue gep0 = lb_emit_struct_ep(p, v.addr, 0);
  9507. lbValue gep1 = lb_emit_struct_ep(p, v.addr, 1);
  9508. lbValue any_data = lb_emit_struct_ev(p, value, 0);
  9509. lbValue ptr = lb_emit_conv(p, any_data, alloc_type_pointer(dst_type));
  9510. lb_emit_store(p, gep0, lb_emit_load(p, ptr));
  9511. lb_emit_store(p, gep1, lb_const_bool(m, t_bool, true));
  9512. lb_emit_jump(p, end_block);
  9513. lb_start_block(p, end_block);
  9514. if (!is_tuple) {
  9515. // NOTE(bill): Panic on invalid conversion
  9516. lbValue ok = lb_emit_load(p, lb_emit_struct_ep(p, v.addr, 1));
  9517. auto args = array_make<lbValue>(permanent_allocator(), 7);
  9518. args[0] = ok;
  9519. args[1] = lb_const_string(m, get_file_path_string(pos.file_id));
  9520. args[2] = lb_const_int(m, t_i32, pos.line);
  9521. args[3] = lb_const_int(m, t_i32, pos.column);
  9522. args[4] = any_typeid;
  9523. args[5] = dst_typeid;
  9524. args[6] = lb_emit_struct_ev(p, value, 0);;
  9525. lb_emit_runtime_call(p, "type_assertion_check2", args);
  9526. return lb_addr(lb_emit_struct_ep(p, v.addr, 0));
  9527. }
  9528. return v;
  9529. }
  9530. lbValue lb_emit_any_cast(lbProcedure *p, lbValue value, Type *type, TokenPos pos) {
  9531. return lb_addr_load(p, lb_emit_any_cast_addr(p, value, type, pos));
  9532. }
  9533. lbValue lb_find_ident(lbProcedure *p, lbModule *m, Entity *e, Ast *expr) {
  9534. auto *found = map_get(&m->values, hash_entity(e));
  9535. if (found) {
  9536. auto v = *found;
  9537. // NOTE(bill): This is because pointers are already pointers in LLVM
  9538. if (is_type_proc(v.type)) {
  9539. return v;
  9540. }
  9541. return lb_emit_load(p, v);
  9542. } else if (e != nullptr && e->kind == Entity_Variable) {
  9543. return lb_addr_load(p, lb_build_addr(p, expr));
  9544. }
  9545. if (e->kind == Entity_Procedure) {
  9546. return lb_find_procedure_value_from_entity(m, e);
  9547. }
  9548. if (USE_SEPARTE_MODULES) {
  9549. lbModule *other_module = lb_pkg_module(m->gen, e->pkg);
  9550. if (other_module != m) {
  9551. String name = lb_get_entity_name(other_module, e);
  9552. lbValue g = {};
  9553. g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name));
  9554. g.type = alloc_type_pointer(e->type);
  9555. LLVMSetLinkage(g.value, LLVMExternalLinkage);
  9556. lb_add_entity(m, e, g);
  9557. lb_add_member(m, name, g);
  9558. return lb_emit_load(p, g);
  9559. }
  9560. }
  9561. String pkg = {};
  9562. if (e->pkg) {
  9563. pkg = e->pkg->name;
  9564. }
  9565. gb_printf_err("Error in: %s\n", token_pos_to_string(ast_token(expr).pos));
  9566. GB_PANIC("nullptr value for expression from identifier: %.*s.%.*s (%p) : %s @ %p", LIT(pkg), LIT(e->token.string), e, type_to_string(e->type), expr);
  9567. return {};
  9568. }
  9569. bool lb_is_expr_constant_zero(Ast *expr) {
  9570. GB_ASSERT(expr != nullptr);
  9571. auto v = exact_value_to_integer(expr->tav.value);
  9572. if (v.kind == ExactValue_Integer) {
  9573. return big_int_cmp_zero(&v.value_integer) == 0;
  9574. }
  9575. return false;
  9576. }
  9577. lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
  9578. lbModule *m = p->module;
  9579. u16 prev_state_flags = p->state_flags;
  9580. defer (p->state_flags = prev_state_flags);
  9581. if (expr->state_flags != 0) {
  9582. u16 in = expr->state_flags;
  9583. u16 out = p->state_flags;
  9584. if (in & StateFlag_bounds_check) {
  9585. out |= StateFlag_bounds_check;
  9586. out &= ~StateFlag_no_bounds_check;
  9587. } else if (in & StateFlag_no_bounds_check) {
  9588. out |= StateFlag_no_bounds_check;
  9589. out &= ~StateFlag_bounds_check;
  9590. }
  9591. p->state_flags = out;
  9592. }
  9593. expr = unparen_expr(expr);
  9594. TokenPos expr_pos = ast_token(expr).pos;
  9595. TypeAndValue tv = type_and_value_of_expr(expr);
  9596. GB_ASSERT_MSG(tv.mode != Addressing_Invalid, "invalid expression '%s' (tv.mode = %d, tv.type = %s) @ %s\n Current Proc: %.*s : %s", expr_to_string(expr), tv.mode, type_to_string(tv.type), token_pos_to_string(expr_pos), LIT(p->name), type_to_string(p->type));
  9597. if (tv.value.kind != ExactValue_Invalid) {
  9598. // NOTE(bill): Short on constant values
  9599. // GB_ASSERT_MSG(!is_type_untyped(tv.type), "%s @ %s", type_to_string(tv.type), token_pos_to_string(expr_pos));
  9600. return lb_const_value(p->module, tv.type, tv.value);
  9601. }
  9602. #if 0
  9603. LLVMMetadataRef prev_debug_location = nullptr;
  9604. if (p->debug_info != nullptr) {
  9605. prev_debug_location = LLVMGetCurrentDebugLocation2(p->builder);
  9606. LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, expr));
  9607. }
  9608. defer (if (prev_debug_location != nullptr) {
  9609. LLVMSetCurrentDebugLocation2(p->builder, prev_debug_location);
  9610. });
  9611. #endif
  9612. switch (expr->kind) {
  9613. case_ast_node(bl, BasicLit, expr);
  9614. TokenPos pos = bl->token.pos;
  9615. GB_PANIC("Non-constant basic literal %s - %.*s", token_pos_to_string(pos), LIT(token_strings[bl->token.kind]));
  9616. case_end;
  9617. case_ast_node(bd, BasicDirective, expr);
  9618. TokenPos pos = bd->token.pos;
  9619. GB_PANIC("Non-constant basic literal %s - %.*s", token_pos_to_string(pos), LIT(bd->name));
  9620. case_end;
  9621. case_ast_node(i, Implicit, expr);
  9622. return lb_addr_load(p, lb_build_addr(p, expr));
  9623. case_end;
  9624. case_ast_node(u, Undef, expr)
  9625. lbValue res = {};
  9626. if (is_type_untyped(tv.type)) {
  9627. res.value = nullptr;
  9628. res.type = t_untyped_undef;
  9629. } else {
  9630. res.value = LLVMGetUndef(lb_type(m, tv.type));
  9631. res.type = tv.type;
  9632. }
  9633. return res;
  9634. case_end;
  9635. case_ast_node(i, Ident, expr);
  9636. Entity *e = entity_from_expr(expr);
  9637. e = strip_entity_wrapping(e);
  9638. GB_ASSERT_MSG(e != nullptr, "%s", expr_to_string(expr));
  9639. if (e->kind == Entity_Builtin) {
  9640. Token token = ast_token(expr);
  9641. GB_PANIC("TODO(bill): lb_build_expr Entity_Builtin '%.*s'\n"
  9642. "\t at %s", LIT(builtin_procs[e->Builtin.id].name),
  9643. token_pos_to_string(token.pos));
  9644. return {};
  9645. } else if (e->kind == Entity_Nil) {
  9646. lbValue res = {};
  9647. res.value = nullptr;
  9648. res.type = e->type;
  9649. return res;
  9650. }
  9651. GB_ASSERT(e->kind != Entity_ProcGroup);
  9652. return lb_find_ident(p, m, e, expr);
  9653. case_end;
  9654. case_ast_node(de, DerefExpr, expr);
  9655. return lb_addr_load(p, lb_build_addr(p, expr));
  9656. case_end;
  9657. case_ast_node(se, SelectorExpr, expr);
  9658. TypeAndValue tav = type_and_value_of_expr(expr);
  9659. GB_ASSERT(tav.mode != Addressing_Invalid);
  9660. return lb_addr_load(p, lb_build_addr(p, expr));
  9661. case_end;
  9662. case_ast_node(ise, ImplicitSelectorExpr, expr);
  9663. TypeAndValue tav = type_and_value_of_expr(expr);
  9664. GB_ASSERT(tav.mode == Addressing_Constant);
  9665. return lb_const_value(p->module, tv.type, tv.value);
  9666. case_end;
  9667. case_ast_node(se, SelectorCallExpr, expr);
  9668. GB_ASSERT(se->modified_call);
  9669. TypeAndValue tav = type_and_value_of_expr(expr);
  9670. GB_ASSERT(tav.mode != Addressing_Invalid);
  9671. return lb_build_expr(p, se->call);
  9672. case_end;
  9673. case_ast_node(te, TernaryIfExpr, expr);
  9674. LLVMValueRef incoming_values[2] = {};
  9675. LLVMBasicBlockRef incoming_blocks[2] = {};
  9676. GB_ASSERT(te->y != nullptr);
  9677. lbBlock *then = lb_create_block(p, "if.then");
  9678. lbBlock *done = lb_create_block(p, "if.done"); // NOTE(bill): Append later
  9679. lbBlock *else_ = lb_create_block(p, "if.else");
  9680. lbValue cond = lb_build_cond(p, te->cond, then, else_);
  9681. lb_start_block(p, then);
  9682. Type *type = default_type(type_of_expr(expr));
  9683. lb_open_scope(p, nullptr);
  9684. incoming_values[0] = lb_emit_conv(p, lb_build_expr(p, te->x), type).value;
  9685. lb_close_scope(p, lbDeferExit_Default, nullptr);
  9686. lb_emit_jump(p, done);
  9687. lb_start_block(p, else_);
  9688. lb_open_scope(p, nullptr);
  9689. incoming_values[1] = lb_emit_conv(p, lb_build_expr(p, te->y), type).value;
  9690. lb_close_scope(p, lbDeferExit_Default, nullptr);
  9691. lb_emit_jump(p, done);
  9692. lb_start_block(p, done);
  9693. lbValue res = {};
  9694. res.value = LLVMBuildPhi(p->builder, lb_type(p->module, type), "");
  9695. res.type = type;
  9696. GB_ASSERT(p->curr_block->preds.count >= 2);
  9697. incoming_blocks[0] = p->curr_block->preds[0]->block;
  9698. incoming_blocks[1] = p->curr_block->preds[1]->block;
  9699. LLVMAddIncoming(res.value, incoming_values, incoming_blocks, 2);
  9700. return res;
  9701. case_end;
  9702. case_ast_node(te, TernaryWhenExpr, expr);
  9703. TypeAndValue tav = type_and_value_of_expr(te->cond);
  9704. GB_ASSERT(tav.mode == Addressing_Constant);
  9705. GB_ASSERT(tav.value.kind == ExactValue_Bool);
  9706. if (tav.value.value_bool) {
  9707. return lb_build_expr(p, te->x);
  9708. } else {
  9709. return lb_build_expr(p, te->y);
  9710. }
  9711. case_end;
  9712. case_ast_node(ta, TypeAssertion, expr);
  9713. TokenPos pos = ast_token(expr).pos;
  9714. Type *type = tv.type;
  9715. lbValue e = lb_build_expr(p, ta->expr);
  9716. Type *t = type_deref(e.type);
  9717. if (is_type_union(t)) {
  9718. if (ta->ignores[0]) {
  9719. // NOTE(bill): This is not needed for optimization levels other than 0
  9720. return lb_emit_union_cast_only_ok_check(p, e, type, pos);
  9721. }
  9722. return lb_emit_union_cast(p, e, type, pos);
  9723. } else if (is_type_any(t)) {
  9724. return lb_emit_any_cast(p, e, type, pos);
  9725. } else {
  9726. GB_PANIC("TODO(bill): type assertion %s", type_to_string(e.type));
  9727. }
  9728. case_end;
  9729. case_ast_node(tc, TypeCast, expr);
  9730. lbValue e = lb_build_expr(p, tc->expr);
  9731. switch (tc->token.kind) {
  9732. case Token_cast:
  9733. return lb_emit_conv(p, e, tv.type);
  9734. case Token_transmute:
  9735. return lb_emit_transmute(p, e, tv.type);
  9736. }
  9737. GB_PANIC("Invalid AST TypeCast");
  9738. case_end;
  9739. case_ast_node(ac, AutoCast, expr);
  9740. lbValue value = lb_build_expr(p, ac->expr);
  9741. return lb_emit_conv(p, value, tv.type);
  9742. case_end;
  9743. case_ast_node(ue, UnaryExpr, expr);
  9744. switch (ue->op.kind) {
  9745. case Token_And: {
  9746. Ast *ue_expr = unparen_expr(ue->expr);
  9747. if (ue_expr->kind == Ast_CompoundLit) {
  9748. lbValue v = lb_build_expr(p, ue->expr);
  9749. Type *type = v.type;
  9750. lbAddr addr = {};
  9751. if (p->is_startup) {
  9752. addr = lb_add_global_generated(p->module, type, v);
  9753. } else {
  9754. addr = lb_add_local_generated(p, type, false);
  9755. }
  9756. lb_addr_store(p, addr, v);
  9757. return addr.addr;
  9758. } else if (ue_expr->kind == Ast_TypeAssertion) {
  9759. GB_ASSERT(is_type_pointer(tv.type));
  9760. ast_node(ta, TypeAssertion, ue_expr);
  9761. TokenPos pos = ast_token(expr).pos;
  9762. Type *type = type_of_expr(ue_expr);
  9763. GB_ASSERT(!is_type_tuple(type));
  9764. lbValue e = lb_build_expr(p, ta->expr);
  9765. Type *t = type_deref(e.type);
  9766. if (is_type_union(t)) {
  9767. lbValue v = e;
  9768. if (!is_type_pointer(v.type)) {
  9769. v = lb_address_from_load_or_generate_local(p, v);
  9770. }
  9771. Type *src_type = type_deref(v.type);
  9772. Type *dst_type = type;
  9773. lbValue src_tag = {};
  9774. lbValue dst_tag = {};
  9775. if (is_type_union_maybe_pointer(src_type)) {
  9776. src_tag = lb_emit_comp_against_nil(p, Token_NotEq, v);
  9777. dst_tag = lb_const_bool(p->module, t_bool, true);
  9778. } else {
  9779. src_tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, v));
  9780. dst_tag = lb_const_union_tag(p->module, src_type, dst_type);
  9781. }
  9782. lbValue ok = lb_emit_comp(p, Token_CmpEq, src_tag, dst_tag);
  9783. auto args = array_make<lbValue>(permanent_allocator(), 6);
  9784. args[0] = ok;
  9785. args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id));
  9786. args[2] = lb_const_int(p->module, t_i32, pos.line);
  9787. args[3] = lb_const_int(p->module, t_i32, pos.column);
  9788. args[4] = lb_typeid(p->module, src_type);
  9789. args[5] = lb_typeid(p->module, dst_type);
  9790. lb_emit_runtime_call(p, "type_assertion_check", args);
  9791. lbValue data_ptr = v;
  9792. return lb_emit_conv(p, data_ptr, tv.type);
  9793. } else if (is_type_any(t)) {
  9794. lbValue v = e;
  9795. if (is_type_pointer(v.type)) {
  9796. v = lb_emit_load(p, v);
  9797. }
  9798. lbValue data_ptr = lb_emit_struct_ev(p, v, 0);
  9799. lbValue any_id = lb_emit_struct_ev(p, v, 1);
  9800. lbValue id = lb_typeid(p->module, type);
  9801. lbValue ok = lb_emit_comp(p, Token_CmpEq, any_id, id);
  9802. auto args = array_make<lbValue>(permanent_allocator(), 6);
  9803. args[0] = ok;
  9804. args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id));
  9805. args[2] = lb_const_int(p->module, t_i32, pos.line);
  9806. args[3] = lb_const_int(p->module, t_i32, pos.column);
  9807. args[4] = any_id;
  9808. args[5] = id;
  9809. lb_emit_runtime_call(p, "type_assertion_check", args);
  9810. return lb_emit_conv(p, data_ptr, tv.type);
  9811. } else {
  9812. GB_PANIC("TODO(bill): type assertion %s", type_to_string(type));
  9813. }
  9814. }
  9815. return lb_build_addr_ptr(p, ue->expr);
  9816. }
  9817. default:
  9818. {
  9819. lbValue v = lb_build_expr(p, ue->expr);
  9820. return lb_emit_unary_arith(p, ue->op.kind, v, tv.type);
  9821. }
  9822. }
  9823. case_end;
  9824. case_ast_node(be, BinaryExpr, expr);
  9825. return lb_build_binary_expr(p, expr);
  9826. case_end;
  9827. case_ast_node(pl, ProcLit, expr);
  9828. return lb_generate_anonymous_proc_lit(p->module, p->name, expr, p);
  9829. case_end;
  9830. case_ast_node(cl, CompoundLit, expr);
  9831. return lb_addr_load(p, lb_build_addr(p, expr));
  9832. case_end;
  9833. case_ast_node(ce, CallExpr, expr);
  9834. lbValue res = lb_build_call_expr(p, expr);
  9835. if (ce->optional_ok_one) { // TODO(bill): Minor hack for #optional_ok procedures
  9836. GB_ASSERT(is_type_tuple(res.type));
  9837. GB_ASSERT(res.type->Tuple.variables.count == 2);
  9838. return lb_emit_struct_ev(p, res, 0);
  9839. }
  9840. return res;
  9841. case_end;
  9842. case_ast_node(se, SliceExpr, expr);
  9843. if (is_type_slice(type_of_expr(se->expr))) {
  9844. // NOTE(bill): Quick optimization
  9845. if (se->high == nullptr &&
  9846. (se->low == nullptr || lb_is_expr_constant_zero(se->low))) {
  9847. return lb_build_expr(p, se->expr);
  9848. }
  9849. }
  9850. return lb_addr_load(p, lb_build_addr(p, expr));
  9851. case_end;
  9852. case_ast_node(ie, IndexExpr, expr);
  9853. return lb_addr_load(p, lb_build_addr(p, expr));
  9854. case_end;
  9855. case_ast_node(ia, InlineAsmExpr, expr);
  9856. Type *t = type_of_expr(expr);
  9857. GB_ASSERT(is_type_asm_proc(t));
  9858. String asm_string = {};
  9859. String constraints_string = {};
  9860. TypeAndValue tav;
  9861. tav = type_and_value_of_expr(ia->asm_string);
  9862. GB_ASSERT(is_type_string(tav.type));
  9863. GB_ASSERT(tav.value.kind == ExactValue_String);
  9864. asm_string = tav.value.value_string;
  9865. tav = type_and_value_of_expr(ia->constraints_string);
  9866. GB_ASSERT(is_type_string(tav.type));
  9867. GB_ASSERT(tav.value.kind == ExactValue_String);
  9868. constraints_string = tav.value.value_string;
  9869. LLVMInlineAsmDialect dialect = LLVMInlineAsmDialectATT;
  9870. switch (ia->dialect) {
  9871. case InlineAsmDialect_Default: dialect = LLVMInlineAsmDialectATT; break;
  9872. case InlineAsmDialect_ATT: dialect = LLVMInlineAsmDialectATT; break;
  9873. case InlineAsmDialect_Intel: dialect = LLVMInlineAsmDialectIntel; break;
  9874. default: GB_PANIC("Unhandled inline asm dialect"); break;
  9875. }
  9876. LLVMTypeRef func_type = LLVMGetElementType(lb_type(p->module, t));
  9877. LLVMValueRef the_asm = LLVMGetInlineAsm(func_type,
  9878. cast(char *)asm_string.text, cast(size_t)asm_string.len,
  9879. cast(char *)constraints_string.text, cast(size_t)constraints_string.len,
  9880. ia->has_side_effects, ia->is_align_stack, dialect
  9881. );
  9882. GB_ASSERT(the_asm != nullptr);
  9883. return {the_asm, t};
  9884. case_end;
  9885. }
  9886. GB_PANIC("lb_build_expr: %.*s", LIT(ast_strings[expr->kind]));
  9887. return {};
  9888. }
  9889. lbAddr lb_get_soa_variable_addr(lbProcedure *p, Entity *e) {
  9890. lbAddr *found = map_get(&p->module->soa_values, hash_entity(e));
  9891. GB_ASSERT(found != nullptr);
  9892. return *found;
  9893. }
  9894. lbValue lb_get_using_variable(lbProcedure *p, Entity *e) {
  9895. GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Using);
  9896. String name = e->token.string;
  9897. Entity *parent = e->using_parent;
  9898. Selection sel = lookup_field(parent->type, name, false);
  9899. GB_ASSERT(sel.entity != nullptr);
  9900. lbValue *pv = map_get(&p->module->values, hash_entity(parent));
  9901. lbValue v = {};
  9902. if (pv == nullptr && parent->flags & EntityFlag_SoaPtrField) {
  9903. // NOTE(bill): using SOA value (probably from for-in statement)
  9904. lbAddr parent_addr = lb_get_soa_variable_addr(p, parent);
  9905. v = lb_addr_get_ptr(p, parent_addr);
  9906. } else if (pv != nullptr) {
  9907. v = *pv;
  9908. } else {
  9909. GB_ASSERT_MSG(e->using_expr != nullptr, "%.*s", LIT(name));
  9910. v = lb_build_addr_ptr(p, e->using_expr);
  9911. }
  9912. GB_ASSERT(v.value != nullptr);
  9913. GB_ASSERT_MSG(parent->type == type_deref(v.type), "%s %s", type_to_string(parent->type), type_to_string(v.type));
  9914. lbValue ptr = lb_emit_deep_field_gep(p, v, sel);
  9915. if (parent->scope) {
  9916. if ((parent->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) {
  9917. lb_add_debug_local_variable(p, ptr.value, e->type, e->token);
  9918. }
  9919. } else {
  9920. lb_add_debug_local_variable(p, ptr.value, e->type, e->token);
  9921. }
  9922. return ptr;
  9923. }
  9924. lbAddr lb_build_addr_from_entity(lbProcedure *p, Entity *e, Ast *expr) {
  9925. GB_ASSERT(e != nullptr);
  9926. if (e->kind == Entity_Constant) {
  9927. Type *t = default_type(type_of_expr(expr));
  9928. lbValue v = lb_const_value(p->module, t, e->Constant.value);
  9929. lbAddr g = lb_add_global_generated(p->module, t, v);
  9930. return g;
  9931. }
  9932. lbValue v = {};
  9933. lbValue *found = map_get(&p->module->values, hash_entity(e));
  9934. if (found) {
  9935. v = *found;
  9936. } else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
  9937. // NOTE(bill): Calculate the using variable every time
  9938. v = lb_get_using_variable(p, e);
  9939. } else if (e->flags & EntityFlag_SoaPtrField) {
  9940. return lb_get_soa_variable_addr(p, e);
  9941. }
  9942. if (v.value == nullptr) {
  9943. return lb_addr(lb_find_value_from_entity(p->module, e));
  9944. // error(expr, "%.*s Unknown value: %.*s, entity: %p %.*s",
  9945. // LIT(p->name),
  9946. // LIT(e->token.string), e, LIT(entity_strings[e->kind]));
  9947. // GB_PANIC("Unknown value");
  9948. }
  9949. return lb_addr(v);
  9950. }
  9951. lbValue lb_gen_map_header(lbProcedure *p, lbValue map_val_ptr, Type *map_type) {
  9952. GB_ASSERT_MSG(is_type_pointer(map_val_ptr.type), "%s", type_to_string(map_val_ptr.type));
  9953. lbAddr h = lb_add_local_generated(p, t_map_header, false); // all the values will be initialzed later
  9954. map_type = base_type(map_type);
  9955. GB_ASSERT(map_type->kind == Type_Map);
  9956. Type *key_type = map_type->Map.key;
  9957. Type *val_type = map_type->Map.value;
  9958. // NOTE(bill): Removes unnecessary allocation if split gep
  9959. lbValue gep0 = lb_emit_struct_ep(p, h.addr, 0);
  9960. lbValue m = lb_emit_conv(p, map_val_ptr, type_deref(gep0.type));
  9961. lb_emit_store(p, gep0, m);
  9962. i64 entry_size = type_size_of (map_type->Map.entry_type);
  9963. i64 entry_align = type_align_of (map_type->Map.entry_type);
  9964. i64 key_offset = type_offset_of(map_type->Map.entry_type, 2);
  9965. i64 key_size = type_size_of (map_type->Map.key);
  9966. i64 value_offset = type_offset_of(map_type->Map.entry_type, 3);
  9967. i64 value_size = type_size_of (map_type->Map.value);
  9968. lb_emit_store(p, lb_emit_struct_ep(p, h.addr, 1), lb_get_equal_proc_for_type(p->module, key_type));
  9969. lb_emit_store(p, lb_emit_struct_ep(p, h.addr, 2), lb_const_int(p->module, t_int, entry_size));
  9970. lb_emit_store(p, lb_emit_struct_ep(p, h.addr, 3), lb_const_int(p->module, t_int, entry_align));
  9971. lb_emit_store(p, lb_emit_struct_ep(p, h.addr, 4), lb_const_int(p->module, t_uintptr, key_offset));
  9972. lb_emit_store(p, lb_emit_struct_ep(p, h.addr, 5), lb_const_int(p->module, t_int, key_size));
  9973. lb_emit_store(p, lb_emit_struct_ep(p, h.addr, 6), lb_const_int(p->module, t_uintptr, value_offset));
  9974. lb_emit_store(p, lb_emit_struct_ep(p, h.addr, 7), lb_const_int(p->module, t_int, value_size));
  9975. return lb_addr_load(p, h);
  9976. }
  9977. lbValue lb_const_hash(lbModule *m, lbValue key, Type *key_type) {
  9978. if (true) {
  9979. return {};
  9980. }
  9981. lbValue hashed_key = {};
  9982. if (lb_is_const(key)) {
  9983. u64 hash = 0xcbf29ce484222325;
  9984. if (is_type_cstring(key_type)) {
  9985. size_t length = 0;
  9986. char const *text = LLVMGetAsString(key.value, &length);
  9987. hash = fnv64a(text, cast(isize)length);
  9988. } else if (is_type_string(key_type)) {
  9989. unsigned data_indices[] = {0};
  9990. unsigned len_indices[] = {1};
  9991. LLVMValueRef data = LLVMConstExtractValue(key.value, data_indices, gb_count_of(data_indices));
  9992. LLVMValueRef len = LLVMConstExtractValue(key.value, len_indices, gb_count_of(len_indices));
  9993. isize length = LLVMConstIntGetSExtValue(len);
  9994. char const *text = nullptr;
  9995. if (false && length != 0) {
  9996. if (LLVMGetConstOpcode(data) != LLVMGetElementPtr) {
  9997. return {};
  9998. }
  9999. // TODO(bill): THIS IS BROKEN! THIS NEEDS FIXING :P
  10000. size_t ulength = 0;
  10001. text = LLVMGetAsString(data, &ulength);
  10002. gb_printf_err("%td %td %s\n", length, ulength, text);
  10003. length = gb_min(length, cast(isize)ulength);
  10004. }
  10005. hash = fnv64a(text, cast(isize)length);
  10006. } else {
  10007. return {};
  10008. }
  10009. // TODO(bill): other const hash types
  10010. if (build_context.word_size == 4) {
  10011. hash &= 0xffffffffull;
  10012. }
  10013. hashed_key = lb_const_int(m, t_uintptr, hash);
  10014. }
  10015. return hashed_key;
  10016. }
  10017. lbValue lb_gen_map_hash(lbProcedure *p, lbValue key, Type *key_type) {
  10018. Type *hash_type = t_u64;
  10019. lbAddr v = lb_add_local_generated(p, t_map_hash, true);
  10020. lbValue vp = lb_addr_get_ptr(p, v);
  10021. Type *t = base_type(key.type);
  10022. key = lb_emit_conv(p, key, key_type);
  10023. lbValue key_ptr = lb_address_from_load_or_generate_local(p, key);
  10024. key_ptr = lb_emit_conv(p, key_ptr, t_rawptr);
  10025. lbValue hashed_key = lb_const_hash(p->module, key, key_type);
  10026. if (hashed_key.value == nullptr) {
  10027. lbValue hasher = lb_get_hasher_proc_for_type(p->module, key_type);
  10028. auto args = array_make<lbValue>(permanent_allocator(), 2);
  10029. args[0] = key_ptr;
  10030. args[1] = lb_const_int(p->module, t_uintptr, 0);
  10031. hashed_key = lb_emit_call(p, hasher, args);
  10032. }
  10033. lb_emit_store(p, lb_emit_struct_ep(p, vp, 0), hashed_key);
  10034. lb_emit_store(p, lb_emit_struct_ep(p, vp, 1), key_ptr);
  10035. return lb_addr_load(p, v);
  10036. }
  10037. void lb_insert_dynamic_map_key_and_value(lbProcedure *p, lbAddr addr, Type *map_type,
  10038. lbValue map_key, lbValue map_value, Ast *node) {
  10039. map_type = base_type(map_type);
  10040. GB_ASSERT(map_type->kind == Type_Map);
  10041. lbValue h = lb_gen_map_header(p, addr.addr, map_type);
  10042. lbValue key = lb_gen_map_hash(p, map_key, map_type->Map.key);
  10043. lbValue v = lb_emit_conv(p, map_value, map_type->Map.value);
  10044. lbAddr value_addr = lb_add_local_generated(p, v.type, false);
  10045. lb_addr_store(p, value_addr, v);
  10046. auto args = array_make<lbValue>(permanent_allocator(), 4);
  10047. args[0] = h;
  10048. args[1] = key;
  10049. args[2] = lb_emit_conv(p, value_addr.addr, t_rawptr);
  10050. args[3] = lb_emit_source_code_location(p, node);
  10051. lb_emit_runtime_call(p, "__dynamic_map_set", args);
  10052. }
  10053. lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
  10054. expr = unparen_expr(expr);
  10055. switch (expr->kind) {
  10056. case_ast_node(i, Implicit, expr);
  10057. lbAddr v = {};
  10058. switch (i->kind) {
  10059. case Token_context:
  10060. v = lb_find_or_generate_context_ptr(p);
  10061. break;
  10062. }
  10063. GB_ASSERT(v.addr.value != nullptr);
  10064. return v;
  10065. case_end;
  10066. case_ast_node(i, Ident, expr);
  10067. if (is_blank_ident(expr)) {
  10068. lbAddr val = {};
  10069. return val;
  10070. }
  10071. String name = i->token.string;
  10072. Entity *e = entity_of_node(expr);
  10073. return lb_build_addr_from_entity(p, e, expr);
  10074. case_end;
  10075. case_ast_node(se, SelectorExpr, expr);
  10076. Ast *sel = unparen_expr(se->selector);
  10077. if (sel->kind == Ast_Ident) {
  10078. String selector = sel->Ident.token.string;
  10079. TypeAndValue tav = type_and_value_of_expr(se->expr);
  10080. if (tav.mode == Addressing_Invalid) {
  10081. // NOTE(bill): Imports
  10082. Entity *imp = entity_of_node(se->expr);
  10083. if (imp != nullptr) {
  10084. GB_ASSERT(imp->kind == Entity_ImportName);
  10085. }
  10086. return lb_build_addr(p, unparen_expr(se->selector));
  10087. }
  10088. Type *type = base_type(tav.type);
  10089. if (tav.mode == Addressing_Type) { // Addressing_Type
  10090. Selection sel = lookup_field(type, selector, true);
  10091. Entity *e = sel.entity;
  10092. GB_ASSERT_MSG(e->kind == Entity_Variable, "Entity_%.*s", LIT(entity_strings[e->kind]));
  10093. GB_ASSERT(e->flags & EntityFlag_TypeField);
  10094. String name = e->token.string;
  10095. /*if (name == "names") {
  10096. lbValue ti_ptr = lb_type_info(m, type);
  10097. lbValue variant = lb_emit_struct_ep(p, ti_ptr, 2);
  10098. lbValue names_ptr = nullptr;
  10099. if (is_type_enum(type)) {
  10100. lbValue enum_info = lb_emit_conv(p, variant, t_type_info_enum_ptr);
  10101. names_ptr = lb_emit_struct_ep(p, enum_info, 1);
  10102. } else if (type->kind == Type_Struct) {
  10103. lbValue struct_info = lb_emit_conv(p, variant, t_type_info_struct_ptr);
  10104. names_ptr = lb_emit_struct_ep(p, struct_info, 1);
  10105. }
  10106. return ir_addr(names_ptr);
  10107. } else */{
  10108. GB_PANIC("Unhandled TypeField %.*s", LIT(name));
  10109. }
  10110. GB_PANIC("Unreachable");
  10111. }
  10112. Selection sel = lookup_field(type, selector, false);
  10113. GB_ASSERT(sel.entity != nullptr);
  10114. {
  10115. lbAddr addr = lb_build_addr(p, se->expr);
  10116. if (addr.kind == lbAddr_Map) {
  10117. lbValue v = lb_addr_load(p, addr);
  10118. lbValue a = lb_address_from_load_or_generate_local(p, v);
  10119. a = lb_emit_deep_field_gep(p, a, sel);
  10120. return lb_addr(a);
  10121. } else if (addr.kind == lbAddr_Context) {
  10122. GB_ASSERT(sel.index.count > 0);
  10123. if (addr.ctx.sel.index.count >= 0) {
  10124. sel = selection_combine(addr.ctx.sel, sel);
  10125. }
  10126. addr.ctx.sel = sel;
  10127. addr.kind = lbAddr_Context;
  10128. return addr;
  10129. } else if (addr.kind == lbAddr_SoaVariable) {
  10130. lbValue index = addr.soa.index;
  10131. i32 first_index = sel.index[0];
  10132. Selection sub_sel = sel;
  10133. sub_sel.index.data += 1;
  10134. sub_sel.index.count -= 1;
  10135. lbValue arr = lb_emit_struct_ep(p, addr.addr, first_index);
  10136. Type *t = base_type(type_deref(addr.addr.type));
  10137. GB_ASSERT(is_type_soa_struct(t));
  10138. // TODO(bill): Bounds check
  10139. if (addr.soa.index_expr != nullptr && (!lb_is_const(addr.soa.index) || t->Struct.soa_kind != StructSoa_Fixed)) {
  10140. lbValue len = lb_soa_struct_len(p, addr.addr);
  10141. lb_emit_bounds_check(p, ast_token(addr.soa.index_expr), addr.soa.index, len);
  10142. }
  10143. lbValue item = {};
  10144. if (t->Struct.soa_kind == StructSoa_Fixed) {
  10145. item = lb_emit_array_ep(p, arr, index);
  10146. } else {
  10147. item = lb_emit_ptr_offset(p, lb_emit_load(p, arr), index);
  10148. }
  10149. if (sub_sel.index.count > 0) {
  10150. item = lb_emit_deep_field_gep(p, item, sub_sel);
  10151. }
  10152. return lb_addr(item);
  10153. }
  10154. lbValue a = lb_addr_get_ptr(p, addr);
  10155. a = lb_emit_deep_field_gep(p, a, sel);
  10156. return lb_addr(a);
  10157. }
  10158. } else {
  10159. GB_PANIC("Unsupported selector expression");
  10160. }
  10161. case_end;
  10162. case_ast_node(se, SelectorCallExpr, expr);
  10163. GB_ASSERT(se->modified_call);
  10164. TypeAndValue tav = type_and_value_of_expr(expr);
  10165. GB_ASSERT(tav.mode != Addressing_Invalid);
  10166. return lb_build_addr(p, se->call);
  10167. case_end;
  10168. case_ast_node(ta, TypeAssertion, expr);
  10169. TokenPos pos = ast_token(expr).pos;
  10170. lbValue e = lb_build_expr(p, ta->expr);
  10171. Type *t = type_deref(e.type);
  10172. if (is_type_union(t)) {
  10173. Type *type = type_of_expr(expr);
  10174. lbAddr v = lb_add_local_generated(p, type, false);
  10175. lb_addr_store(p, v, lb_emit_union_cast(p, lb_build_expr(p, ta->expr), type, pos));
  10176. return v;
  10177. } else if (is_type_any(t)) {
  10178. Type *type = type_of_expr(expr);
  10179. return lb_emit_any_cast_addr(p, lb_build_expr(p, ta->expr), type, pos);
  10180. } else {
  10181. GB_PANIC("TODO(bill): type assertion %s", type_to_string(e.type));
  10182. }
  10183. case_end;
  10184. case_ast_node(ue, UnaryExpr, expr);
  10185. switch (ue->op.kind) {
  10186. case Token_And: {
  10187. return lb_build_addr(p, ue->expr);
  10188. }
  10189. default:
  10190. GB_PANIC("Invalid unary expression for lb_build_addr");
  10191. }
  10192. case_end;
  10193. case_ast_node(be, BinaryExpr, expr);
  10194. lbValue v = lb_build_expr(p, expr);
  10195. Type *t = v.type;
  10196. if (is_type_pointer(t)) {
  10197. return lb_addr(v);
  10198. }
  10199. return lb_addr(lb_address_from_load_or_generate_local(p, v));
  10200. case_end;
  10201. case_ast_node(ie, IndexExpr, expr);
  10202. Type *t = base_type(type_of_expr(ie->expr));
  10203. bool deref = is_type_pointer(t);
  10204. t = base_type(type_deref(t));
  10205. if (is_type_soa_struct(t)) {
  10206. // SOA STRUCTURES!!!!
  10207. lbValue val = lb_build_addr_ptr(p, ie->expr);
  10208. if (deref) {
  10209. val = lb_emit_load(p, val);
  10210. }
  10211. lbValue index = lb_build_expr(p, ie->index);
  10212. return lb_addr_soa_variable(val, index, ie->index);
  10213. }
  10214. if (ie->expr->tav.mode == Addressing_SoaVariable) {
  10215. // SOA Structures for slices/dynamic arrays
  10216. GB_ASSERT(is_type_pointer(type_of_expr(ie->expr)));
  10217. lbValue field = lb_build_expr(p, ie->expr);
  10218. lbValue index = lb_build_expr(p, ie->index);
  10219. if (!build_context.no_bounds_check) {
  10220. // TODO HACK(bill): Clean up this hack to get the length for bounds checking
  10221. // GB_ASSERT(LLVMIsALoadInst(field.value));
  10222. // lbValue a = {};
  10223. // a.value = LLVMGetOperand(field.value, 0);
  10224. // a.type = alloc_type_pointer(field.type);
  10225. // irInstr *b = &a->Instr;
  10226. // GB_ASSERT(b->kind == irInstr_StructElementPtr);
  10227. // lbValue base_struct = b->StructElementPtr.address;
  10228. // GB_ASSERT(is_type_soa_struct(type_deref(ir_type(base_struct))));
  10229. // lbValue len = ir_soa_struct_len(p, base_struct);
  10230. // lb_emit_bounds_check(p, ast_token(ie->index), index, len);
  10231. }
  10232. lbValue val = lb_emit_ptr_offset(p, field, index);
  10233. return lb_addr(val);
  10234. }
  10235. GB_ASSERT_MSG(is_type_indexable(t), "%s %s", type_to_string(t), expr_to_string(expr));
  10236. if (is_type_map(t)) {
  10237. lbValue map_val = lb_build_addr_ptr(p, ie->expr);
  10238. if (deref) {
  10239. map_val = lb_emit_load(p, map_val);
  10240. }
  10241. lbValue key = lb_build_expr(p, ie->index);
  10242. key = lb_emit_conv(p, key, t->Map.key);
  10243. Type *result_type = type_of_expr(expr);
  10244. return lb_addr_map(map_val, key, t, result_type);
  10245. }
  10246. switch (t->kind) {
  10247. case Type_Array: {
  10248. lbValue array = {};
  10249. array = lb_build_addr_ptr(p, ie->expr);
  10250. if (deref) {
  10251. array = lb_emit_load(p, array);
  10252. }
  10253. lbValue index = lb_build_expr(p, ie->index);
  10254. index = lb_emit_conv(p, index, t_int);
  10255. lbValue elem = lb_emit_array_ep(p, array, index);
  10256. auto index_tv = type_and_value_of_expr(ie->index);
  10257. if (index_tv.mode != Addressing_Constant) {
  10258. lbValue len = lb_const_int(p->module, t_int, t->Array.count);
  10259. lb_emit_bounds_check(p, ast_token(ie->index), index, len);
  10260. }
  10261. return lb_addr(elem);
  10262. }
  10263. case Type_EnumeratedArray: {
  10264. lbValue array = {};
  10265. array = lb_build_addr_ptr(p, ie->expr);
  10266. if (deref) {
  10267. array = lb_emit_load(p, array);
  10268. }
  10269. Type *index_type = t->EnumeratedArray.index;
  10270. auto index_tv = type_and_value_of_expr(ie->index);
  10271. lbValue index = {};
  10272. if (compare_exact_values(Token_NotEq, t->EnumeratedArray.min_value, exact_value_i64(0))) {
  10273. if (index_tv.mode == Addressing_Constant) {
  10274. ExactValue idx = exact_value_sub(index_tv.value, t->EnumeratedArray.min_value);
  10275. index = lb_const_value(p->module, index_type, idx);
  10276. } else {
  10277. index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int);
  10278. index = lb_emit_arith(p, Token_Sub, index, lb_const_value(p->module, index_type, t->EnumeratedArray.min_value), index_type);
  10279. }
  10280. } else {
  10281. index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int);
  10282. }
  10283. lbValue elem = lb_emit_array_ep(p, array, index);
  10284. if (index_tv.mode != Addressing_Constant) {
  10285. lbValue len = lb_const_int(p->module, t_int, t->EnumeratedArray.count);
  10286. lb_emit_bounds_check(p, ast_token(ie->index), index, len);
  10287. }
  10288. return lb_addr(elem);
  10289. }
  10290. case Type_Slice: {
  10291. lbValue slice = {};
  10292. slice = lb_build_expr(p, ie->expr);
  10293. if (deref) {
  10294. slice = lb_emit_load(p, slice);
  10295. }
  10296. lbValue elem = lb_slice_elem(p, slice);
  10297. lbValue index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int);
  10298. lbValue len = lb_slice_len(p, slice);
  10299. lb_emit_bounds_check(p, ast_token(ie->index), index, len);
  10300. lbValue v = lb_emit_ptr_offset(p, elem, index);
  10301. return lb_addr(v);
  10302. }
  10303. case Type_RelativeSlice: {
  10304. lbAddr slice_addr = {};
  10305. if (deref) {
  10306. slice_addr = lb_addr(lb_build_expr(p, ie->expr));
  10307. } else {
  10308. slice_addr = lb_build_addr(p, ie->expr);
  10309. }
  10310. lbValue slice = lb_addr_load(p, slice_addr);
  10311. lbValue elem = lb_slice_elem(p, slice);
  10312. lbValue index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int);
  10313. lbValue len = lb_slice_len(p, slice);
  10314. lb_emit_bounds_check(p, ast_token(ie->index), index, len);
  10315. lbValue v = lb_emit_ptr_offset(p, elem, index);
  10316. return lb_addr(v);
  10317. }
  10318. case Type_DynamicArray: {
  10319. lbValue dynamic_array = {};
  10320. dynamic_array = lb_build_expr(p, ie->expr);
  10321. if (deref) {
  10322. dynamic_array = lb_emit_load(p, dynamic_array);
  10323. }
  10324. lbValue elem = lb_dynamic_array_elem(p, dynamic_array);
  10325. lbValue len = lb_dynamic_array_len(p, dynamic_array);
  10326. lbValue index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int);
  10327. lb_emit_bounds_check(p, ast_token(ie->index), index, len);
  10328. lbValue v = lb_emit_ptr_offset(p, elem, index);
  10329. return lb_addr(v);
  10330. }
  10331. case Type_Basic: { // Basic_string
  10332. lbValue str;
  10333. lbValue elem;
  10334. lbValue len;
  10335. lbValue index;
  10336. str = lb_build_expr(p, ie->expr);
  10337. if (deref) {
  10338. str = lb_emit_load(p, str);
  10339. }
  10340. elem = lb_string_elem(p, str);
  10341. len = lb_string_len(p, str);
  10342. index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int);
  10343. lb_emit_bounds_check(p, ast_token(ie->index), index, len);
  10344. return lb_addr(lb_emit_ptr_offset(p, elem, index));
  10345. }
  10346. }
  10347. case_end;
  10348. case_ast_node(se, SliceExpr, expr);
  10349. lbValue low = lb_const_int(p->module, t_int, 0);
  10350. lbValue high = {};
  10351. if (se->low != nullptr) low = lb_build_expr(p, se->low);
  10352. if (se->high != nullptr) high = lb_build_expr(p, se->high);
  10353. bool no_indices = se->low == nullptr && se->high == nullptr;
  10354. lbAddr addr = lb_build_addr(p, se->expr);
  10355. lbValue base = lb_addr_load(p, addr);
  10356. Type *type = base_type(base.type);
  10357. if (is_type_pointer(type)) {
  10358. type = base_type(type_deref(type));
  10359. addr = lb_addr(base);
  10360. base = lb_addr_load(p, addr);
  10361. }
  10362. switch (type->kind) {
  10363. case Type_Slice: {
  10364. Type *slice_type = type;
  10365. lbValue len = lb_slice_len(p, base);
  10366. if (high.value == nullptr) high = len;
  10367. if (!no_indices) {
  10368. lb_emit_slice_bounds_check(p, se->open, low, high, len, se->low != nullptr);
  10369. }
  10370. lbValue elem = lb_emit_ptr_offset(p, lb_slice_elem(p, base), low);
  10371. lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int);
  10372. lbAddr slice = lb_add_local_generated(p, slice_type, false);
  10373. lb_fill_slice(p, slice, elem, new_len);
  10374. return slice;
  10375. }
  10376. case Type_RelativeSlice:
  10377. GB_PANIC("TODO(bill): Type_RelativeSlice should be handled above already on the lb_addr_load");
  10378. break;
  10379. case Type_DynamicArray: {
  10380. Type *elem_type = type->DynamicArray.elem;
  10381. Type *slice_type = alloc_type_slice(elem_type);
  10382. lbValue len = lb_dynamic_array_len(p, base);
  10383. if (high.value == nullptr) high = len;
  10384. if (!no_indices) {
  10385. lb_emit_slice_bounds_check(p, se->open, low, high, len, se->low != nullptr);
  10386. }
  10387. lbValue elem = lb_emit_ptr_offset(p, lb_dynamic_array_elem(p, base), low);
  10388. lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int);
  10389. lbAddr slice = lb_add_local_generated(p, slice_type, false);
  10390. lb_fill_slice(p, slice, elem, new_len);
  10391. return slice;
  10392. }
  10393. case Type_Array: {
  10394. Type *slice_type = alloc_type_slice(type->Array.elem);
  10395. lbValue len = lb_const_int(p->module, t_int, type->Array.count);
  10396. if (high.value == nullptr) high = len;
  10397. bool low_const = type_and_value_of_expr(se->low).mode == Addressing_Constant;
  10398. bool high_const = type_and_value_of_expr(se->high).mode == Addressing_Constant;
  10399. if (!low_const || !high_const) {
  10400. if (!no_indices) {
  10401. lb_emit_slice_bounds_check(p, se->open, low, high, len, se->low != nullptr);
  10402. }
  10403. }
  10404. lbValue elem = lb_emit_ptr_offset(p, lb_array_elem(p, lb_addr_get_ptr(p, addr)), low);
  10405. lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int);
  10406. lbAddr slice = lb_add_local_generated(p, slice_type, false);
  10407. lb_fill_slice(p, slice, elem, new_len);
  10408. return slice;
  10409. }
  10410. case Type_Basic: {
  10411. GB_ASSERT(type == t_string);
  10412. lbValue len = lb_string_len(p, base);
  10413. if (high.value == nullptr) high = len;
  10414. if (!no_indices) {
  10415. lb_emit_slice_bounds_check(p, se->open, low, high, len, se->low != nullptr);
  10416. }
  10417. lbValue elem = lb_emit_ptr_offset(p, lb_string_elem(p, base), low);
  10418. lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int);
  10419. lbAddr str = lb_add_local_generated(p, t_string, false);
  10420. lb_fill_string(p, str, elem, new_len);
  10421. return str;
  10422. }
  10423. case Type_Struct:
  10424. if (is_type_soa_struct(type)) {
  10425. lbValue len = lb_soa_struct_len(p, lb_addr_get_ptr(p, addr));
  10426. if (high.value == nullptr) high = len;
  10427. if (!no_indices) {
  10428. lb_emit_slice_bounds_check(p, se->open, low, high, len, se->low != nullptr);
  10429. }
  10430. #if 1
  10431. lbAddr dst = lb_add_local_generated(p, type_of_expr(expr), true);
  10432. if (type->Struct.soa_kind == StructSoa_Fixed) {
  10433. i32 field_count = cast(i32)type->Struct.fields.count;
  10434. for (i32 i = 0; i < field_count; i++) {
  10435. lbValue field_dst = lb_emit_struct_ep(p, dst.addr, i);
  10436. lbValue field_src = lb_emit_struct_ep(p, lb_addr_get_ptr(p, addr), i);
  10437. field_src = lb_emit_array_ep(p, field_src, low);
  10438. lb_emit_store(p, field_dst, field_src);
  10439. }
  10440. lbValue len_dst = lb_emit_struct_ep(p, dst.addr, field_count);
  10441. lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int);
  10442. lb_emit_store(p, len_dst, new_len);
  10443. } else if (type->Struct.soa_kind == StructSoa_Slice) {
  10444. if (no_indices) {
  10445. lb_addr_store(p, dst, base);
  10446. } else {
  10447. i32 field_count = cast(i32)type->Struct.fields.count - 1;
  10448. for (i32 i = 0; i < field_count; i++) {
  10449. lbValue field_dst = lb_emit_struct_ep(p, dst.addr, i);
  10450. lbValue field_src = lb_emit_struct_ev(p, base, i);
  10451. field_src = lb_emit_ptr_offset(p, field_src, low);
  10452. lb_emit_store(p, field_dst, field_src);
  10453. }
  10454. lbValue len_dst = lb_emit_struct_ep(p, dst.addr, field_count);
  10455. lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int);
  10456. lb_emit_store(p, len_dst, new_len);
  10457. }
  10458. } else if (type->Struct.soa_kind == StructSoa_Dynamic) {
  10459. i32 field_count = cast(i32)type->Struct.fields.count - 3;
  10460. for (i32 i = 0; i < field_count; i++) {
  10461. lbValue field_dst = lb_emit_struct_ep(p, dst.addr, i);
  10462. lbValue field_src = lb_emit_struct_ev(p, base, i);
  10463. field_src = lb_emit_ptr_offset(p, field_src, low);
  10464. lb_emit_store(p, field_dst, field_src);
  10465. }
  10466. lbValue len_dst = lb_emit_struct_ep(p, dst.addr, field_count);
  10467. lbValue new_len = lb_emit_arith(p, Token_Sub, high, low, t_int);
  10468. lb_emit_store(p, len_dst, new_len);
  10469. }
  10470. return dst;
  10471. #endif
  10472. }
  10473. break;
  10474. }
  10475. GB_PANIC("Unknown slicable type");
  10476. case_end;
  10477. case_ast_node(de, DerefExpr, expr);
  10478. if (is_type_relative_pointer(type_of_expr(de->expr))) {
  10479. lbAddr addr = lb_build_addr(p, de->expr);
  10480. addr.relative.deref = true;
  10481. return addr;
  10482. }
  10483. lbValue addr = lb_build_expr(p, de->expr);
  10484. return lb_addr(addr);
  10485. case_end;
  10486. case_ast_node(ce, CallExpr, expr);
  10487. // NOTE(bill): This is make sure you never need to have an 'array_ev'
  10488. lbValue e = lb_build_expr(p, expr);
  10489. lbAddr v = lb_add_local_generated(p, e.type, false);
  10490. lb_addr_store(p, v, e);
  10491. return v;
  10492. case_end;
  10493. case_ast_node(cl, CompoundLit, expr);
  10494. Type *type = type_of_expr(expr);
  10495. Type *bt = base_type(type);
  10496. lbAddr v = lb_add_local_generated(p, type, true);
  10497. Type *et = nullptr;
  10498. switch (bt->kind) {
  10499. case Type_Array: et = bt->Array.elem; break;
  10500. case Type_EnumeratedArray: et = bt->EnumeratedArray.elem; break;
  10501. case Type_Slice: et = bt->Slice.elem; break;
  10502. case Type_BitSet: et = bt->BitSet.elem; break;
  10503. case Type_SimdVector: et = bt->SimdVector.elem; break;
  10504. }
  10505. String proc_name = {};
  10506. if (p->entity) {
  10507. proc_name = p->entity->token.string;
  10508. }
  10509. TokenPos pos = ast_token(expr).pos;
  10510. switch (bt->kind) {
  10511. default: GB_PANIC("Unknown CompoundLit type: %s", type_to_string(type)); break;
  10512. case Type_Struct: {
  10513. // TODO(bill): "constant" '#raw_union's are not initialized constantly at the moment.
  10514. // NOTE(bill): This is due to the layout of the unions when printed to LLVM-IR
  10515. bool is_raw_union = is_type_raw_union(bt);
  10516. GB_ASSERT(is_type_struct(bt) || is_raw_union);
  10517. TypeStruct *st = &bt->Struct;
  10518. if (cl->elems.count > 0) {
  10519. lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr)));
  10520. for_array(field_index, cl->elems) {
  10521. Ast *elem = cl->elems[field_index];
  10522. lbValue field_expr = {};
  10523. Entity *field = nullptr;
  10524. isize index = field_index;
  10525. if (elem->kind == Ast_FieldValue) {
  10526. ast_node(fv, FieldValue, elem);
  10527. String name = fv->field->Ident.token.string;
  10528. Selection sel = lookup_field(bt, name, false);
  10529. index = sel.index[0];
  10530. elem = fv->value;
  10531. TypeAndValue tav = type_and_value_of_expr(elem);
  10532. } else {
  10533. TypeAndValue tav = type_and_value_of_expr(elem);
  10534. Selection sel = lookup_field_from_index(bt, st->fields[field_index]->Variable.field_src_index);
  10535. index = sel.index[0];
  10536. }
  10537. field = st->fields[index];
  10538. Type *ft = field->type;
  10539. if (!is_raw_union && !is_type_typeid(ft) && lb_is_elem_const(elem, ft)) {
  10540. continue;
  10541. }
  10542. field_expr = lb_build_expr(p, elem);
  10543. Type *fet = field_expr.type;
  10544. GB_ASSERT(fet->kind != Type_Tuple);
  10545. // HACK TODO(bill): THIS IS A MASSIVE HACK!!!!
  10546. if (is_type_union(ft) && !are_types_identical(fet, ft) && !is_type_untyped(fet)) {
  10547. GB_ASSERT_MSG(union_variant_index(ft, fet) > 0, "%s", type_to_string(fet));
  10548. lbValue gep = lb_emit_struct_ep(p, lb_addr_get_ptr(p, v), cast(i32)index);
  10549. lb_emit_store_union_variant(p, gep, field_expr, fet);
  10550. } else {
  10551. lbValue fv = lb_emit_conv(p, field_expr, ft);
  10552. lbValue gep = lb_emit_struct_ep(p, lb_addr_get_ptr(p, v), cast(i32)index);
  10553. lb_emit_store(p, gep, fv);
  10554. }
  10555. }
  10556. }
  10557. break;
  10558. }
  10559. case Type_Map: {
  10560. if (cl->elems.count == 0) {
  10561. break;
  10562. }
  10563. {
  10564. auto args = array_make<lbValue>(permanent_allocator(), 3);
  10565. args[0] = lb_gen_map_header(p, v.addr, type);
  10566. args[1] = lb_const_int(p->module, t_int, 2*cl->elems.count);
  10567. args[2] = lb_emit_source_code_location(p, proc_name, pos);
  10568. lb_emit_runtime_call(p, "__dynamic_map_reserve", args);
  10569. }
  10570. for_array(field_index, cl->elems) {
  10571. Ast *elem = cl->elems[field_index];
  10572. ast_node(fv, FieldValue, elem);
  10573. lbValue key = lb_build_expr(p, fv->field);
  10574. lbValue value = lb_build_expr(p, fv->value);
  10575. lb_insert_dynamic_map_key_and_value(p, v, type, key, value, elem);
  10576. }
  10577. break;
  10578. }
  10579. case Type_Array: {
  10580. if (cl->elems.count > 0) {
  10581. lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr)));
  10582. auto temp_data = array_make<lbCompoundLitElemTempData>(temporary_allocator(), 0, cl->elems.count);
  10583. // NOTE(bill): Separate value, gep, store into their own chunks
  10584. for_array(i, cl->elems) {
  10585. Ast *elem = cl->elems[i];
  10586. if (elem->kind == Ast_FieldValue) {
  10587. ast_node(fv, FieldValue, elem);
  10588. if (lb_is_elem_const(fv->value, et)) {
  10589. continue;
  10590. }
  10591. if (is_ast_range(fv->field)) {
  10592. ast_node(ie, BinaryExpr, fv->field);
  10593. TypeAndValue lo_tav = ie->left->tav;
  10594. TypeAndValue hi_tav = ie->right->tav;
  10595. GB_ASSERT(lo_tav.mode == Addressing_Constant);
  10596. GB_ASSERT(hi_tav.mode == Addressing_Constant);
  10597. TokenKind op = ie->op.kind;
  10598. i64 lo = exact_value_to_i64(lo_tav.value);
  10599. i64 hi = exact_value_to_i64(hi_tav.value);
  10600. if (op == Token_Ellipsis) {
  10601. hi += 1;
  10602. }
  10603. lbValue value = lb_build_expr(p, fv->value);
  10604. for (i64 k = lo; k < hi; k++) {
  10605. lbCompoundLitElemTempData data = {};
  10606. data.value = value;
  10607. data.elem_index = cast(i32)k;
  10608. array_add(&temp_data, data);
  10609. }
  10610. } else {
  10611. auto tav = fv->field->tav;
  10612. GB_ASSERT(tav.mode == Addressing_Constant);
  10613. i64 index = exact_value_to_i64(tav.value);
  10614. lbValue value = lb_build_expr(p, fv->value);
  10615. lbCompoundLitElemTempData data = {};
  10616. data.value = lb_emit_conv(p, value, et);
  10617. data.expr = fv->value;
  10618. data.elem_index = cast(i32)index;
  10619. array_add(&temp_data, data);
  10620. }
  10621. } else {
  10622. if (lb_is_elem_const(elem, et)) {
  10623. continue;
  10624. }
  10625. lbCompoundLitElemTempData data = {};
  10626. data.expr = elem;
  10627. data.elem_index = cast(i32)i;
  10628. array_add(&temp_data, data);
  10629. }
  10630. }
  10631. for_array(i, temp_data) {
  10632. temp_data[i].gep = lb_emit_array_epi(p, lb_addr_get_ptr(p, v), temp_data[i].elem_index);
  10633. }
  10634. for_array(i, temp_data) {
  10635. auto return_ptr_hint_ast = p->return_ptr_hint_ast;
  10636. auto return_ptr_hint_value = p->return_ptr_hint_value;
  10637. auto return_ptr_hint_used = p->return_ptr_hint_used;
  10638. defer (p->return_ptr_hint_ast = return_ptr_hint_ast);
  10639. defer (p->return_ptr_hint_value = return_ptr_hint_value);
  10640. defer (p->return_ptr_hint_used = return_ptr_hint_used);
  10641. lbValue field_expr = temp_data[i].value;
  10642. Ast *expr = temp_data[i].expr;
  10643. p->return_ptr_hint_value = temp_data[i].gep;
  10644. p->return_ptr_hint_ast = unparen_expr(expr);
  10645. if (field_expr.value == nullptr) {
  10646. field_expr = lb_build_expr(p, expr);
  10647. }
  10648. Type *t = field_expr.type;
  10649. GB_ASSERT(t->kind != Type_Tuple);
  10650. lbValue ev = lb_emit_conv(p, field_expr, et);
  10651. if (!p->return_ptr_hint_used) {
  10652. temp_data[i].value = ev;
  10653. }
  10654. }
  10655. for_array(i, temp_data) {
  10656. if (temp_data[i].value.value != nullptr) {
  10657. lb_emit_store(p, temp_data[i].gep, temp_data[i].value);
  10658. }
  10659. }
  10660. }
  10661. break;
  10662. }
  10663. case Type_EnumeratedArray: {
  10664. if (cl->elems.count > 0) {
  10665. lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr)));
  10666. auto temp_data = array_make<lbCompoundLitElemTempData>(temporary_allocator(), 0, cl->elems.count);
  10667. // NOTE(bill): Separate value, gep, store into their own chunks
  10668. for_array(i, cl->elems) {
  10669. Ast *elem = cl->elems[i];
  10670. if (elem->kind == Ast_FieldValue) {
  10671. ast_node(fv, FieldValue, elem);
  10672. if (lb_is_elem_const(fv->value, et)) {
  10673. continue;
  10674. }
  10675. if (is_ast_range(fv->field)) {
  10676. ast_node(ie, BinaryExpr, fv->field);
  10677. TypeAndValue lo_tav = ie->left->tav;
  10678. TypeAndValue hi_tav = ie->right->tav;
  10679. GB_ASSERT(lo_tav.mode == Addressing_Constant);
  10680. GB_ASSERT(hi_tav.mode == Addressing_Constant);
  10681. TokenKind op = ie->op.kind;
  10682. i64 lo = exact_value_to_i64(lo_tav.value);
  10683. i64 hi = exact_value_to_i64(hi_tav.value);
  10684. if (op == Token_Ellipsis) {
  10685. hi += 1;
  10686. }
  10687. lbValue value = lb_build_expr(p, fv->value);
  10688. for (i64 k = lo; k < hi; k++) {
  10689. lbCompoundLitElemTempData data = {};
  10690. data.value = value;
  10691. data.elem_index = cast(i32)k;
  10692. array_add(&temp_data, data);
  10693. }
  10694. } else {
  10695. auto tav = fv->field->tav;
  10696. GB_ASSERT(tav.mode == Addressing_Constant);
  10697. i64 index = exact_value_to_i64(tav.value);
  10698. lbValue value = lb_build_expr(p, fv->value);
  10699. lbCompoundLitElemTempData data = {};
  10700. data.value = lb_emit_conv(p, value, et);
  10701. data.expr = fv->value;
  10702. data.elem_index = cast(i32)index;
  10703. array_add(&temp_data, data);
  10704. }
  10705. } else {
  10706. if (lb_is_elem_const(elem, et)) {
  10707. continue;
  10708. }
  10709. lbCompoundLitElemTempData data = {};
  10710. data.expr = elem;
  10711. data.elem_index = cast(i32)i;
  10712. array_add(&temp_data, data);
  10713. }
  10714. }
  10715. i32 index_offset = cast(i32)exact_value_to_i64(bt->EnumeratedArray.min_value);
  10716. for_array(i, temp_data) {
  10717. i32 index = temp_data[i].elem_index - index_offset;
  10718. temp_data[i].gep = lb_emit_array_epi(p, lb_addr_get_ptr(p, v), index);
  10719. }
  10720. for_array(i, temp_data) {
  10721. auto return_ptr_hint_ast = p->return_ptr_hint_ast;
  10722. auto return_ptr_hint_value = p->return_ptr_hint_value;
  10723. auto return_ptr_hint_used = p->return_ptr_hint_used;
  10724. defer (p->return_ptr_hint_ast = return_ptr_hint_ast);
  10725. defer (p->return_ptr_hint_value = return_ptr_hint_value);
  10726. defer (p->return_ptr_hint_used = return_ptr_hint_used);
  10727. lbValue field_expr = temp_data[i].value;
  10728. Ast *expr = temp_data[i].expr;
  10729. p->return_ptr_hint_value = temp_data[i].gep;
  10730. p->return_ptr_hint_ast = unparen_expr(expr);
  10731. if (field_expr.value == nullptr) {
  10732. field_expr = lb_build_expr(p, expr);
  10733. }
  10734. Type *t = field_expr.type;
  10735. GB_ASSERT(t->kind != Type_Tuple);
  10736. lbValue ev = lb_emit_conv(p, field_expr, et);
  10737. if (!p->return_ptr_hint_used) {
  10738. temp_data[i].value = ev;
  10739. }
  10740. }
  10741. for_array(i, temp_data) {
  10742. if (temp_data[i].value.value != nullptr) {
  10743. lb_emit_store(p, temp_data[i].gep, temp_data[i].value);
  10744. }
  10745. }
  10746. }
  10747. break;
  10748. }
  10749. case Type_Slice: {
  10750. if (cl->elems.count > 0) {
  10751. Type *elem_type = bt->Slice.elem;
  10752. Type *elem_ptr_type = alloc_type_pointer(elem_type);
  10753. Type *elem_ptr_ptr_type = alloc_type_pointer(elem_ptr_type);
  10754. lbValue slice = lb_const_value(p->module, type, exact_value_compound(expr));
  10755. lbValue data = lb_slice_elem(p, slice);
  10756. auto temp_data = array_make<lbCompoundLitElemTempData>(temporary_allocator(), 0, cl->elems.count);
  10757. for_array(i, cl->elems) {
  10758. Ast *elem = cl->elems[i];
  10759. if (elem->kind == Ast_FieldValue) {
  10760. ast_node(fv, FieldValue, elem);
  10761. if (lb_is_elem_const(fv->value, et)) {
  10762. continue;
  10763. }
  10764. if (is_ast_range(fv->field)) {
  10765. ast_node(ie, BinaryExpr, fv->field);
  10766. TypeAndValue lo_tav = ie->left->tav;
  10767. TypeAndValue hi_tav = ie->right->tav;
  10768. GB_ASSERT(lo_tav.mode == Addressing_Constant);
  10769. GB_ASSERT(hi_tav.mode == Addressing_Constant);
  10770. TokenKind op = ie->op.kind;
  10771. i64 lo = exact_value_to_i64(lo_tav.value);
  10772. i64 hi = exact_value_to_i64(hi_tav.value);
  10773. if (op == Token_Ellipsis) {
  10774. hi += 1;
  10775. }
  10776. lbValue value = lb_emit_conv(p, lb_build_expr(p, fv->value), et);
  10777. for (i64 k = lo; k < hi; k++) {
  10778. lbCompoundLitElemTempData data = {};
  10779. data.value = value;
  10780. data.elem_index = cast(i32)k;
  10781. array_add(&temp_data, data);
  10782. }
  10783. } else {
  10784. GB_ASSERT(fv->field->tav.mode == Addressing_Constant);
  10785. i64 index = exact_value_to_i64(fv->field->tav.value);
  10786. lbValue field_expr = lb_build_expr(p, fv->value);
  10787. GB_ASSERT(!is_type_tuple(field_expr.type));
  10788. lbValue ev = lb_emit_conv(p, field_expr, et);
  10789. lbCompoundLitElemTempData data = {};
  10790. data.value = ev;
  10791. data.elem_index = cast(i32)index;
  10792. array_add(&temp_data, data);
  10793. }
  10794. } else {
  10795. if (lb_is_elem_const(elem, et)) {
  10796. continue;
  10797. }
  10798. lbValue field_expr = lb_build_expr(p, elem);
  10799. GB_ASSERT(!is_type_tuple(field_expr.type));
  10800. lbValue ev = lb_emit_conv(p, field_expr, et);
  10801. lbCompoundLitElemTempData data = {};
  10802. data.value = ev;
  10803. data.elem_index = cast(i32)i;
  10804. array_add(&temp_data, data);
  10805. }
  10806. }
  10807. for_array(i, temp_data) {
  10808. temp_data[i].gep = lb_emit_ptr_offset(p, data, lb_const_int(p->module, t_int, temp_data[i].elem_index));
  10809. }
  10810. for_array(i, temp_data) {
  10811. lb_emit_store(p, temp_data[i].gep, temp_data[i].value);
  10812. }
  10813. {
  10814. lbValue count = {};
  10815. count.type = t_int;
  10816. if (lb_is_const(slice)) {
  10817. unsigned indices[1] = {1};
  10818. count.value = LLVMConstExtractValue(slice.value, indices, gb_count_of(indices));
  10819. } else {
  10820. count.value = LLVMBuildExtractValue(p->builder, slice.value, 1, "");
  10821. }
  10822. lb_fill_slice(p, v, data, count);
  10823. }
  10824. }
  10825. break;
  10826. }
  10827. case Type_DynamicArray: {
  10828. if (cl->elems.count == 0) {
  10829. break;
  10830. }
  10831. Type *et = bt->DynamicArray.elem;
  10832. lbValue size = lb_const_int(p->module, t_int, type_size_of(et));
  10833. lbValue align = lb_const_int(p->module, t_int, type_align_of(et));
  10834. i64 item_count = gb_max(cl->max_count, cl->elems.count);
  10835. {
  10836. auto args = array_make<lbValue>(permanent_allocator(), 5);
  10837. args[0] = lb_emit_conv(p, lb_addr_get_ptr(p, v), t_rawptr);
  10838. args[1] = size;
  10839. args[2] = align;
  10840. args[3] = lb_const_int(p->module, t_int, 2*item_count); // TODO(bill): Is this too much waste?
  10841. args[4] = lb_emit_source_code_location(p, proc_name, pos);
  10842. lb_emit_runtime_call(p, "__dynamic_array_reserve", args);
  10843. }
  10844. lbValue items = lb_generate_local_array(p, et, item_count);
  10845. // lbValue items = lb_generate_global_array(p->module, et, item_count, str_lit("dacl$"), cast(i64)cast(intptr)expr);
  10846. for_array(i, cl->elems) {
  10847. Ast *elem = cl->elems[i];
  10848. if (elem->kind == Ast_FieldValue) {
  10849. ast_node(fv, FieldValue, elem);
  10850. if (is_ast_range(fv->field)) {
  10851. ast_node(ie, BinaryExpr, fv->field);
  10852. TypeAndValue lo_tav = ie->left->tav;
  10853. TypeAndValue hi_tav = ie->right->tav;
  10854. GB_ASSERT(lo_tav.mode == Addressing_Constant);
  10855. GB_ASSERT(hi_tav.mode == Addressing_Constant);
  10856. TokenKind op = ie->op.kind;
  10857. i64 lo = exact_value_to_i64(lo_tav.value);
  10858. i64 hi = exact_value_to_i64(hi_tav.value);
  10859. if (op == Token_Ellipsis) {
  10860. hi += 1;
  10861. }
  10862. lbValue value = lb_emit_conv(p, lb_build_expr(p, fv->value), et);
  10863. for (i64 k = lo; k < hi; k++) {
  10864. lbValue ep = lb_emit_array_epi(p, items, cast(i32)k);
  10865. lb_emit_store(p, ep, value);
  10866. }
  10867. } else {
  10868. GB_ASSERT(fv->field->tav.mode == Addressing_Constant);
  10869. i64 field_index = exact_value_to_i64(fv->field->tav.value);
  10870. lbValue ev = lb_build_expr(p, fv->value);
  10871. lbValue value = lb_emit_conv(p, ev, et);
  10872. lbValue ep = lb_emit_array_epi(p, items, cast(i32)field_index);
  10873. lb_emit_store(p, ep, value);
  10874. }
  10875. } else {
  10876. lbValue value = lb_emit_conv(p, lb_build_expr(p, elem), et);
  10877. lbValue ep = lb_emit_array_epi(p, items, cast(i32)i);
  10878. lb_emit_store(p, ep, value);
  10879. }
  10880. }
  10881. {
  10882. auto args = array_make<lbValue>(permanent_allocator(), 6);
  10883. args[0] = lb_emit_conv(p, v.addr, t_rawptr);
  10884. args[1] = size;
  10885. args[2] = align;
  10886. args[3] = lb_emit_conv(p, items, t_rawptr);
  10887. args[4] = lb_const_int(p->module, t_int, item_count);
  10888. args[5] = lb_emit_source_code_location(p, proc_name, pos);
  10889. lb_emit_runtime_call(p, "__dynamic_array_append", args);
  10890. }
  10891. break;
  10892. }
  10893. case Type_Basic: {
  10894. GB_ASSERT(is_type_any(bt));
  10895. if (cl->elems.count > 0) {
  10896. lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr)));
  10897. String field_names[2] = {
  10898. str_lit("data"),
  10899. str_lit("id"),
  10900. };
  10901. Type *field_types[2] = {
  10902. t_rawptr,
  10903. t_typeid,
  10904. };
  10905. for_array(field_index, cl->elems) {
  10906. Ast *elem = cl->elems[field_index];
  10907. lbValue field_expr = {};
  10908. isize index = field_index;
  10909. if (elem->kind == Ast_FieldValue) {
  10910. ast_node(fv, FieldValue, elem);
  10911. Selection sel = lookup_field(bt, fv->field->Ident.token.string, false);
  10912. index = sel.index[0];
  10913. elem = fv->value;
  10914. } else {
  10915. TypeAndValue tav = type_and_value_of_expr(elem);
  10916. Selection sel = lookup_field(bt, field_names[field_index], false);
  10917. index = sel.index[0];
  10918. }
  10919. field_expr = lb_build_expr(p, elem);
  10920. GB_ASSERT(field_expr.type->kind != Type_Tuple);
  10921. Type *ft = field_types[index];
  10922. lbValue fv = lb_emit_conv(p, field_expr, ft);
  10923. lbValue gep = lb_emit_struct_ep(p, lb_addr_get_ptr(p, v), cast(i32)index);
  10924. lb_emit_store(p, gep, fv);
  10925. }
  10926. }
  10927. break;
  10928. }
  10929. case Type_BitSet: {
  10930. i64 sz = type_size_of(type);
  10931. if (cl->elems.count > 0 && sz > 0) {
  10932. lb_addr_store(p, v, lb_const_value(p->module, type, exact_value_compound(expr)));
  10933. lbValue lower = lb_const_value(p->module, t_int, exact_value_i64(bt->BitSet.lower));
  10934. for_array(i, cl->elems) {
  10935. Ast *elem = cl->elems[i];
  10936. GB_ASSERT(elem->kind != Ast_FieldValue);
  10937. if (lb_is_elem_const(elem, et)) {
  10938. continue;
  10939. }
  10940. lbValue expr = lb_build_expr(p, elem);
  10941. GB_ASSERT(expr.type->kind != Type_Tuple);
  10942. Type *it = bit_set_to_int(bt);
  10943. lbValue one = lb_const_value(p->module, it, exact_value_i64(1));
  10944. lbValue e = lb_emit_conv(p, expr, it);
  10945. e = lb_emit_arith(p, Token_Sub, e, lower, it);
  10946. e = lb_emit_arith(p, Token_Shl, one, e, it);
  10947. lbValue old_value = lb_emit_transmute(p, lb_addr_load(p, v), it);
  10948. lbValue new_value = lb_emit_arith(p, Token_Or, old_value, e, it);
  10949. new_value = lb_emit_transmute(p, new_value, type);
  10950. lb_addr_store(p, v, new_value);
  10951. }
  10952. }
  10953. break;
  10954. }
  10955. }
  10956. return v;
  10957. case_end;
  10958. case_ast_node(tc, TypeCast, expr);
  10959. Type *type = type_of_expr(expr);
  10960. lbValue x = lb_build_expr(p, tc->expr);
  10961. lbValue e = {};
  10962. switch (tc->token.kind) {
  10963. case Token_cast:
  10964. e = lb_emit_conv(p, x, type);
  10965. break;
  10966. case Token_transmute:
  10967. e = lb_emit_transmute(p, x, type);
  10968. break;
  10969. default:
  10970. GB_PANIC("Invalid AST TypeCast");
  10971. }
  10972. lbAddr v = lb_add_local_generated(p, type, false);
  10973. lb_addr_store(p, v, e);
  10974. return v;
  10975. case_end;
  10976. case_ast_node(ac, AutoCast, expr);
  10977. return lb_build_addr(p, ac->expr);
  10978. case_end;
  10979. }
  10980. TokenPos token_pos = ast_token(expr).pos;
  10981. GB_PANIC("Unexpected address expression\n"
  10982. "\tAst: %.*s @ "
  10983. "%s\n",
  10984. LIT(ast_strings[expr->kind]),
  10985. token_pos_to_string(token_pos));
  10986. return {};
  10987. }
  10988. void lb_init_module(lbModule *m, Checker *c) {
  10989. m->info = &c->info;
  10990. gbString module_name = gb_string_make(heap_allocator(), "odin_package");
  10991. if (m->pkg) {
  10992. module_name = gb_string_appendc(module_name, "-");
  10993. module_name = gb_string_append_length(module_name, m->pkg->name.text, m->pkg->name.len);
  10994. } else if (USE_SEPARTE_MODULES) {
  10995. module_name = gb_string_appendc(module_name, "-builtin");
  10996. }
  10997. m->ctx = LLVMContextCreate();
  10998. m->mod = LLVMModuleCreateWithNameInContext(module_name ? module_name : "odin_package", m->ctx);
  10999. // m->debug_builder = nullptr;
  11000. if (build_context.ODIN_DEBUG) {
  11001. enum {DEBUG_METADATA_VERSION = 3};
  11002. LLVMMetadataRef debug_ref = LLVMValueAsMetadata(LLVMConstInt(LLVMInt32TypeInContext(m->ctx), DEBUG_METADATA_VERSION, true));
  11003. LLVMAddModuleFlag(m->mod, LLVMModuleFlagBehaviorWarning, "Debug Info Version", 18, debug_ref);
  11004. switch (build_context.metrics.os) {
  11005. case TargetOs_windows:
  11006. LLVMAddModuleFlag(m->mod,
  11007. LLVMModuleFlagBehaviorWarning,
  11008. "CodeView", 8,
  11009. LLVMValueAsMetadata(LLVMConstInt(LLVMInt32TypeInContext(m->ctx), 1, true)));
  11010. break;
  11011. case TargetOs_darwin:
  11012. // NOTE(bill): Darwin only supports DWARF2 (that I know of)
  11013. LLVMAddModuleFlag(m->mod,
  11014. LLVMModuleFlagBehaviorWarning,
  11015. "Dwarf Version", 13,
  11016. LLVMValueAsMetadata(LLVMConstInt(LLVMInt32TypeInContext(m->ctx), 2, true)));
  11017. break;
  11018. }
  11019. m->debug_builder = LLVMCreateDIBuilder(m->mod);
  11020. }
  11021. gbAllocator a = heap_allocator();
  11022. map_init(&m->types, a);
  11023. map_init(&m->llvm_types, a);
  11024. map_init(&m->values, a);
  11025. map_init(&m->soa_values, a);
  11026. string_map_init(&m->members, a);
  11027. map_init(&m->procedure_values, a);
  11028. string_map_init(&m->procedures, a);
  11029. string_map_init(&m->const_strings, a);
  11030. map_init(&m->anonymous_proc_lits, a);
  11031. map_init(&m->function_type_map, a);
  11032. map_init(&m->equal_procs, a);
  11033. map_init(&m->hasher_procs, a);
  11034. array_init(&m->procedures_to_generate, a, 0, 1024);
  11035. array_init(&m->foreign_library_paths, a, 0, 1024);
  11036. map_init(&m->debug_values, a);
  11037. array_init(&m->debug_incomplete_types, a, 0, 1024);
  11038. }
  11039. bool lb_init_generator(lbGenerator *gen, Checker *c) {
  11040. if (global_error_collector.count != 0) {
  11041. return false;
  11042. }
  11043. isize tc = c->parser->total_token_count;
  11044. if (tc < 2) {
  11045. return false;
  11046. }
  11047. String init_fullpath = c->parser->init_fullpath;
  11048. if (build_context.out_filepath.len == 0) {
  11049. gen->output_name = remove_directory_from_path(init_fullpath);
  11050. gen->output_name = remove_extension_from_path(gen->output_name);
  11051. gen->output_name = string_trim_whitespace(gen->output_name);
  11052. if (gen->output_name.len == 0) {
  11053. gen->output_name = c->info.init_scope->pkg->name;
  11054. }
  11055. gen->output_base = gen->output_name;
  11056. } else {
  11057. gen->output_name = build_context.out_filepath;
  11058. gen->output_name = string_trim_whitespace(gen->output_name);
  11059. if (gen->output_name.len == 0) {
  11060. gen->output_name = c->info.init_scope->pkg->name;
  11061. }
  11062. isize pos = string_extension_position(gen->output_name);
  11063. if (pos < 0) {
  11064. gen->output_base = gen->output_name;
  11065. } else {
  11066. gen->output_base = substring(gen->output_name, 0, pos);
  11067. }
  11068. }
  11069. gbAllocator ha = heap_allocator();
  11070. array_init(&gen->output_object_paths, ha);
  11071. array_init(&gen->output_temp_paths, ha);
  11072. gen->output_base = path_to_full_path(ha, gen->output_base);
  11073. gbString output_file_path = gb_string_make_length(ha, gen->output_base.text, gen->output_base.len);
  11074. output_file_path = gb_string_appendc(output_file_path, ".obj");
  11075. defer (gb_string_free(output_file_path));
  11076. gen->info = &c->info;
  11077. map_init(&gen->modules, permanent_allocator(), gen->info->packages.entries.count*2);
  11078. map_init(&gen->modules_through_ctx, permanent_allocator(), gen->info->packages.entries.count*2);
  11079. map_init(&gen->anonymous_proc_lits, heap_allocator(), 1024);
  11080. gb_mutex_init(&gen->mutex);
  11081. if (USE_SEPARTE_MODULES) {
  11082. for_array(i, gen->info->packages.entries) {
  11083. AstPackage *pkg = gen->info->packages.entries[i].value;
  11084. auto m = gb_alloc_item(permanent_allocator(), lbModule);
  11085. m->pkg = pkg;
  11086. m->gen = gen;
  11087. map_set(&gen->modules, hash_pointer(pkg), m);
  11088. lb_init_module(m, c);
  11089. }
  11090. }
  11091. gen->default_module.gen = gen;
  11092. map_set(&gen->modules, hash_pointer(nullptr), &gen->default_module);
  11093. lb_init_module(&gen->default_module, c);
  11094. for_array(i, gen->modules.entries) {
  11095. lbModule *m = gen->modules.entries[i].value;
  11096. LLVMContextRef ctx = LLVMGetModuleContext(m->mod);
  11097. map_set(&gen->modules_through_ctx, hash_pointer(ctx), m);
  11098. }
  11099. return true;
  11100. }
  11101. lbAddr lb_add_global_generated(lbModule *m, Type *type, lbValue value) {
  11102. GB_ASSERT(type != nullptr);
  11103. type = default_type(type);
  11104. isize max_len = 7+8+1;
  11105. u8 *str = cast(u8 *)gb_alloc_array(permanent_allocator(), u8, max_len);
  11106. u32 id = cast(u32)gb_atomic32_fetch_add(&m->gen->global_generated_index, 1);
  11107. isize len = gb_snprintf(cast(char *)str, max_len, "ggv$%x", id);
  11108. String name = make_string(str, len-1);
  11109. Scope *scope = nullptr;
  11110. Entity *e = alloc_entity_variable(scope, make_token_ident(name), type);
  11111. lbValue g = {};
  11112. g.type = alloc_type_pointer(type);
  11113. g.value = LLVMAddGlobal(m->mod, lb_type(m, type), cast(char const *)str);
  11114. if (value.value != nullptr) {
  11115. GB_ASSERT_MSG(LLVMIsConstant(value.value), LLVMPrintValueToString(value.value));
  11116. LLVMSetInitializer(g.value, value.value);
  11117. } else {
  11118. LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, type)));
  11119. }
  11120. lb_add_entity(m, e, g);
  11121. lb_add_member(m, name, g);
  11122. return lb_addr(g);
  11123. }
  11124. lbValue lb_find_runtime_value(lbModule *m, String const &name) {
  11125. AstPackage *p = m->info->runtime_package;
  11126. Entity *e = scope_lookup_current(p->scope, name);
  11127. return lb_find_value_from_entity(m, e);
  11128. }
  11129. lbValue lb_find_package_value(lbModule *m, String const &pkg, String const &name) {
  11130. Entity *e = find_entity_in_pkg(m->info, pkg, name);
  11131. lbValue *found = map_get(&m->values, hash_entity(e));
  11132. return lb_find_value_from_entity(m, e);
  11133. }
  11134. lbValue lb_get_type_info_ptr(lbModule *m, Type *type) {
  11135. i32 index = cast(i32)lb_type_info_index(m->info, type);
  11136. GB_ASSERT(index >= 0);
  11137. // gb_printf_err("%d %s\n", index, type_to_string(type));
  11138. LLVMValueRef indices[2] = {
  11139. LLVMConstInt(lb_type(m, t_int), 0, false),
  11140. LLVMConstInt(lb_type(m, t_int), index, false),
  11141. };
  11142. lbValue res = {};
  11143. res.type = t_type_info_ptr;
  11144. res.value = LLVMConstGEP(lb_global_type_info_data_ptr(m).value, indices, cast(unsigned)gb_count_of(indices));
  11145. return res;
  11146. }
  11147. lbValue lb_type_info_member_types_offset(lbProcedure *p, isize count) {
  11148. lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_types.addr, lb_global_type_info_member_types_index);
  11149. lb_global_type_info_member_types_index += cast(i32)count;
  11150. return offset;
  11151. }
  11152. lbValue lb_type_info_member_names_offset(lbProcedure *p, isize count) {
  11153. lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_names.addr, lb_global_type_info_member_names_index);
  11154. lb_global_type_info_member_names_index += cast(i32)count;
  11155. return offset;
  11156. }
  11157. lbValue lb_type_info_member_offsets_offset(lbProcedure *p, isize count) {
  11158. lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_offsets.addr, lb_global_type_info_member_offsets_index);
  11159. lb_global_type_info_member_offsets_index += cast(i32)count;
  11160. return offset;
  11161. }
  11162. lbValue lb_type_info_member_usings_offset(lbProcedure *p, isize count) {
  11163. lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_usings.addr, lb_global_type_info_member_usings_index);
  11164. lb_global_type_info_member_usings_index += cast(i32)count;
  11165. return offset;
  11166. }
  11167. lbValue lb_type_info_member_tags_offset(lbProcedure *p, isize count) {
  11168. lbValue offset = lb_emit_array_epi(p, lb_global_type_info_member_tags.addr, lb_global_type_info_member_tags_index);
  11169. lb_global_type_info_member_tags_index += cast(i32)count;
  11170. return offset;
  11171. }
  11172. lbValue lb_generate_local_array(lbProcedure *p, Type *elem_type, i64 count, bool zero_init) {
  11173. lbAddr addr = lb_add_local_generated(p, alloc_type_array(elem_type, count), zero_init);
  11174. return lb_addr_get_ptr(p, addr);
  11175. }
  11176. lbValue lb_generate_global_array(lbModule *m, Type *elem_type, i64 count, String prefix, i64 id) {
  11177. Token token = {Token_Ident};
  11178. isize name_len = prefix.len + 1 + 20;
  11179. auto suffix_id = cast(unsigned long long)id;
  11180. char *text = gb_alloc_array(permanent_allocator(), char, name_len+1);
  11181. gb_snprintf(text, name_len,
  11182. "%.*s-%llu", LIT(prefix), suffix_id);
  11183. text[name_len] = 0;
  11184. String s = make_string_c(text);
  11185. Type *t = alloc_type_array(elem_type, count);
  11186. lbValue g = {};
  11187. g.value = LLVMAddGlobal(m->mod, lb_type(m, t), text);
  11188. g.type = alloc_type_pointer(t);
  11189. LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, t)));
  11190. LLVMSetLinkage(g.value, LLVMInternalLinkage);
  11191. string_map_set(&m->members, s, g);
  11192. return g;
  11193. }
  11194. void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info data
  11195. lbModule *m = p->module;
  11196. LLVMContextRef ctx = m->ctx;
  11197. CheckerInfo *info = m->info;
  11198. {
  11199. // NOTE(bill): Set the type_table slice with the global backing array
  11200. lbValue global_type_table = lb_find_runtime_value(m, str_lit("type_table"));
  11201. Type *type = base_type(lb_global_type_info_data_entity->type);
  11202. GB_ASSERT(is_type_array(type));
  11203. LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
  11204. LLVMValueRef values[2] = {
  11205. LLVMConstInBoundsGEP(lb_global_type_info_data_ptr(m).value, indices, gb_count_of(indices)),
  11206. LLVMConstInt(lb_type(m, t_int), type->Array.count, true),
  11207. };
  11208. LLVMValueRef slice = llvm_const_named_struct(llvm_addr_type(global_type_table), values, gb_count_of(values));
  11209. LLVMSetInitializer(global_type_table.value, slice);
  11210. }
  11211. // Useful types
  11212. Type *t_i64_slice_ptr = alloc_type_pointer(alloc_type_slice(t_i64));
  11213. Type *t_string_slice_ptr = alloc_type_pointer(alloc_type_slice(t_string));
  11214. Entity *type_info_flags_entity = find_core_entity(info->checker, str_lit("Type_Info_Flags"));
  11215. Type *t_type_info_flags = type_info_flags_entity->type;
  11216. i32 type_info_member_types_index = 0;
  11217. i32 type_info_member_names_index = 0;
  11218. i32 type_info_member_offsets_index = 0;
  11219. for_array(type_info_type_index, info->type_info_types) {
  11220. Type *t = info->type_info_types[type_info_type_index];
  11221. if (t == nullptr || t == t_invalid) {
  11222. continue;
  11223. }
  11224. isize entry_index = lb_type_info_index(info, t, false);
  11225. if (entry_index <= 0) {
  11226. continue;
  11227. }
  11228. lbValue tag = {};
  11229. lbValue ti_ptr = lb_emit_array_epi(p, lb_global_type_info_data_ptr(m), cast(i32)entry_index);
  11230. lbValue variant_ptr = lb_emit_struct_ep(p, ti_ptr, 4);
  11231. lbValue type_info_flags = lb_const_int(p->module, t_type_info_flags, type_info_flags_of_type(t));
  11232. lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 0), lb_const_int(m, t_int, type_size_of(t)));
  11233. lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 1), lb_const_int(m, t_int, type_align_of(t)));
  11234. lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 2), type_info_flags);
  11235. lb_emit_store(p, lb_emit_struct_ep(p, ti_ptr, 3), lb_typeid(m, t));
  11236. switch (t->kind) {
  11237. case Type_Named: {
  11238. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_named_ptr);
  11239. LLVMValueRef pkg_name = nullptr;
  11240. if (t->Named.type_name->pkg) {
  11241. pkg_name = lb_const_string(m, t->Named.type_name->pkg->name).value;
  11242. } else {
  11243. pkg_name = LLVMConstNull(lb_type(m, t_string));
  11244. }
  11245. String proc_name = {};
  11246. if (t->Named.type_name->parent_proc_decl) {
  11247. DeclInfo *decl = t->Named.type_name->parent_proc_decl;
  11248. if (decl->entity && decl->entity->kind == Entity_Procedure) {
  11249. proc_name = decl->entity->token.string;
  11250. }
  11251. }
  11252. TokenPos pos = t->Named.type_name->token.pos;
  11253. lbValue loc = lb_emit_source_code_location(p, proc_name, pos);
  11254. LLVMValueRef vals[4] = {
  11255. lb_const_string(p->module, t->Named.type_name->token.string).value,
  11256. lb_get_type_info_ptr(m, t->Named.base).value,
  11257. pkg_name,
  11258. loc.value
  11259. };
  11260. lbValue res = {};
  11261. res.type = type_deref(tag.type);
  11262. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11263. lb_emit_store(p, tag, res);
  11264. break;
  11265. }
  11266. case Type_Basic:
  11267. switch (t->Basic.kind) {
  11268. case Basic_bool:
  11269. case Basic_b8:
  11270. case Basic_b16:
  11271. case Basic_b32:
  11272. case Basic_b64:
  11273. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_boolean_ptr);
  11274. break;
  11275. case Basic_i8:
  11276. case Basic_u8:
  11277. case Basic_i16:
  11278. case Basic_u16:
  11279. case Basic_i32:
  11280. case Basic_u32:
  11281. case Basic_i64:
  11282. case Basic_u64:
  11283. case Basic_i128:
  11284. case Basic_u128:
  11285. case Basic_i16le:
  11286. case Basic_u16le:
  11287. case Basic_i32le:
  11288. case Basic_u32le:
  11289. case Basic_i64le:
  11290. case Basic_u64le:
  11291. case Basic_i128le:
  11292. case Basic_u128le:
  11293. case Basic_i16be:
  11294. case Basic_u16be:
  11295. case Basic_i32be:
  11296. case Basic_u32be:
  11297. case Basic_i64be:
  11298. case Basic_u64be:
  11299. case Basic_i128be:
  11300. case Basic_u128be:
  11301. case Basic_int:
  11302. case Basic_uint:
  11303. case Basic_uintptr: {
  11304. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_integer_ptr);
  11305. lbValue is_signed = lb_const_bool(m, t_bool, (t->Basic.flags & BasicFlag_Unsigned) == 0);
  11306. // NOTE(bill): This is matches the runtime layout
  11307. u8 endianness_value = 0;
  11308. if (t->Basic.flags & BasicFlag_EndianLittle) {
  11309. endianness_value = 1;
  11310. } else if (t->Basic.flags & BasicFlag_EndianBig) {
  11311. endianness_value = 2;
  11312. }
  11313. lbValue endianness = lb_const_int(m, t_u8, endianness_value);
  11314. LLVMValueRef vals[2] = {
  11315. is_signed.value,
  11316. endianness.value,
  11317. };
  11318. lbValue res = {};
  11319. res.type = type_deref(tag.type);
  11320. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11321. lb_emit_store(p, tag, res);
  11322. break;
  11323. }
  11324. case Basic_rune:
  11325. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_rune_ptr);
  11326. break;
  11327. case Basic_f16:
  11328. case Basic_f32:
  11329. case Basic_f64:
  11330. case Basic_f16le:
  11331. case Basic_f32le:
  11332. case Basic_f64le:
  11333. case Basic_f16be:
  11334. case Basic_f32be:
  11335. case Basic_f64be:
  11336. {
  11337. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_float_ptr);
  11338. // NOTE(bill): This is matches the runtime layout
  11339. u8 endianness_value = 0;
  11340. if (t->Basic.flags & BasicFlag_EndianLittle) {
  11341. endianness_value = 1;
  11342. } else if (t->Basic.flags & BasicFlag_EndianBig) {
  11343. endianness_value = 2;
  11344. }
  11345. lbValue endianness = lb_const_int(m, t_u8, endianness_value);
  11346. LLVMValueRef vals[1] = {
  11347. endianness.value,
  11348. };
  11349. lbValue res = {};
  11350. res.type = type_deref(tag.type);
  11351. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11352. lb_emit_store(p, tag, res);
  11353. }
  11354. break;
  11355. case Basic_complex32:
  11356. case Basic_complex64:
  11357. case Basic_complex128:
  11358. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_complex_ptr);
  11359. break;
  11360. case Basic_quaternion64:
  11361. case Basic_quaternion128:
  11362. case Basic_quaternion256:
  11363. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_quaternion_ptr);
  11364. break;
  11365. case Basic_rawptr:
  11366. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_pointer_ptr);
  11367. break;
  11368. case Basic_string:
  11369. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_string_ptr);
  11370. break;
  11371. case Basic_cstring:
  11372. {
  11373. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_string_ptr);
  11374. LLVMValueRef vals[1] = {
  11375. lb_const_bool(m, t_bool, true).value,
  11376. };
  11377. lbValue res = {};
  11378. res.type = type_deref(tag.type);
  11379. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11380. lb_emit_store(p, tag, res);
  11381. }
  11382. break;
  11383. case Basic_any:
  11384. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_any_ptr);
  11385. break;
  11386. case Basic_typeid:
  11387. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_typeid_ptr);
  11388. break;
  11389. }
  11390. break;
  11391. case Type_Pointer: {
  11392. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_pointer_ptr);
  11393. lbValue gep = lb_get_type_info_ptr(m, t->Pointer.elem);
  11394. LLVMValueRef vals[1] = {
  11395. gep.value,
  11396. };
  11397. lbValue res = {};
  11398. res.type = type_deref(tag.type);
  11399. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11400. lb_emit_store(p, tag, res);
  11401. break;
  11402. }
  11403. case Type_Array: {
  11404. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_array_ptr);
  11405. i64 ez = type_size_of(t->Array.elem);
  11406. LLVMValueRef vals[3] = {
  11407. lb_get_type_info_ptr(m, t->Array.elem).value,
  11408. lb_const_int(m, t_int, ez).value,
  11409. lb_const_int(m, t_int, t->Array.count).value,
  11410. };
  11411. lbValue res = {};
  11412. res.type = type_deref(tag.type);
  11413. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11414. lb_emit_store(p, tag, res);
  11415. break;
  11416. }
  11417. case Type_EnumeratedArray: {
  11418. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_enumerated_array_ptr);
  11419. LLVMValueRef vals[6] = {
  11420. lb_get_type_info_ptr(m, t->EnumeratedArray.elem).value,
  11421. lb_get_type_info_ptr(m, t->EnumeratedArray.index).value,
  11422. lb_const_int(m, t_int, type_size_of(t->EnumeratedArray.elem)).value,
  11423. lb_const_int(m, t_int, t->EnumeratedArray.count).value,
  11424. // Unions
  11425. LLVMConstNull(lb_type(m, t_type_info_enum_value)),
  11426. LLVMConstNull(lb_type(m, t_type_info_enum_value)),
  11427. };
  11428. lbValue res = {};
  11429. res.type = type_deref(tag.type);
  11430. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11431. lb_emit_store(p, tag, res);
  11432. // NOTE(bill): Union assignment
  11433. lbValue min_value = lb_emit_struct_ep(p, tag, 4);
  11434. lbValue max_value = lb_emit_struct_ep(p, tag, 5);
  11435. lbValue min_v = lb_const_value(m, t_i64, t->EnumeratedArray.min_value);
  11436. lbValue max_v = lb_const_value(m, t_i64, t->EnumeratedArray.max_value);
  11437. lb_emit_store(p, min_value, min_v);
  11438. lb_emit_store(p, max_value, max_v);
  11439. break;
  11440. }
  11441. case Type_DynamicArray: {
  11442. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_dynamic_array_ptr);
  11443. LLVMValueRef vals[2] = {
  11444. lb_get_type_info_ptr(m, t->DynamicArray.elem).value,
  11445. lb_const_int(m, t_int, type_size_of(t->DynamicArray.elem)).value,
  11446. };
  11447. lbValue res = {};
  11448. res.type = type_deref(tag.type);
  11449. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11450. lb_emit_store(p, tag, res);
  11451. break;
  11452. }
  11453. case Type_Slice: {
  11454. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_slice_ptr);
  11455. LLVMValueRef vals[2] = {
  11456. lb_get_type_info_ptr(m, t->Slice.elem).value,
  11457. lb_const_int(m, t_int, type_size_of(t->Slice.elem)).value,
  11458. };
  11459. lbValue res = {};
  11460. res.type = type_deref(tag.type);
  11461. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11462. lb_emit_store(p, tag, res);
  11463. break;
  11464. }
  11465. case Type_Proc: {
  11466. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_procedure_ptr);
  11467. LLVMValueRef params = LLVMConstNull(lb_type(m, t_type_info_ptr));
  11468. LLVMValueRef results = LLVMConstNull(lb_type(m, t_type_info_ptr));
  11469. if (t->Proc.params != nullptr) {
  11470. params = lb_get_type_info_ptr(m, t->Proc.params).value;
  11471. }
  11472. if (t->Proc.results != nullptr) {
  11473. results = lb_get_type_info_ptr(m, t->Proc.results).value;
  11474. }
  11475. LLVMValueRef vals[4] = {
  11476. params,
  11477. results,
  11478. lb_const_bool(m, t_bool, t->Proc.variadic).value,
  11479. lb_const_int(m, t_u8, t->Proc.calling_convention).value,
  11480. };
  11481. lbValue res = {};
  11482. res.type = type_deref(tag.type);
  11483. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11484. lb_emit_store(p, tag, res);
  11485. break;
  11486. }
  11487. case Type_Tuple: {
  11488. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_tuple_ptr);
  11489. lbValue memory_types = lb_type_info_member_types_offset(p, t->Tuple.variables.count);
  11490. lbValue memory_names = lb_type_info_member_names_offset(p, t->Tuple.variables.count);
  11491. for_array(i, t->Tuple.variables) {
  11492. // NOTE(bill): offset is not used for tuples
  11493. Entity *f = t->Tuple.variables[i];
  11494. lbValue index = lb_const_int(m, t_int, i);
  11495. lbValue type_info = lb_emit_ptr_offset(p, memory_types, index);
  11496. // TODO(bill): Make this constant if possible, 'lb_const_store' does not work
  11497. lb_emit_store(p, type_info, lb_type_info(m, f->type));
  11498. if (f->token.string.len > 0) {
  11499. lbValue name = lb_emit_ptr_offset(p, memory_names, index);
  11500. lb_emit_store(p, name, lb_const_string(m, f->token.string));
  11501. }
  11502. }
  11503. lbValue count = lb_const_int(m, t_int, t->Tuple.variables.count);
  11504. LLVMValueRef types_slice = llvm_const_slice(m, memory_types, count);
  11505. LLVMValueRef names_slice = llvm_const_slice(m, memory_names, count);
  11506. LLVMValueRef vals[2] = {
  11507. types_slice,
  11508. names_slice,
  11509. };
  11510. lbValue res = {};
  11511. res.type = type_deref(tag.type);
  11512. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11513. lb_emit_store(p, tag, res);
  11514. break;
  11515. }
  11516. case Type_Enum:
  11517. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_enum_ptr);
  11518. {
  11519. GB_ASSERT(t->Enum.base_type != nullptr);
  11520. // GB_ASSERT_MSG(type_size_of(t_type_info_enum_value) == 16, "%lld == 16", cast(long long)type_size_of(t_type_info_enum_value));
  11521. LLVMValueRef vals[3] = {};
  11522. vals[0] = lb_type_info(m, t->Enum.base_type).value;
  11523. if (t->Enum.fields.count > 0) {
  11524. auto fields = t->Enum.fields;
  11525. lbValue name_array = lb_generate_global_array(m, t_string, fields.count,
  11526. str_lit("$enum_names"), cast(i64)entry_index);
  11527. lbValue value_array = lb_generate_global_array(m, t_type_info_enum_value, fields.count,
  11528. str_lit("$enum_values"), cast(i64)entry_index);
  11529. LLVMValueRef *name_values = gb_alloc_array(temporary_allocator(), LLVMValueRef, fields.count);
  11530. LLVMValueRef *value_values = gb_alloc_array(temporary_allocator(), LLVMValueRef, fields.count);
  11531. GB_ASSERT(is_type_integer(t->Enum.base_type));
  11532. LLVMTypeRef align_type = lb_alignment_prefix_type_hack(m, type_align_of(t));
  11533. LLVMTypeRef array_type = LLVMArrayType(lb_type(m, t_u8), 8);
  11534. for_array(i, fields) {
  11535. name_values[i] = lb_const_string(m, fields[i]->token.string).value;
  11536. value_values[i] = lb_const_value(m, t_i64, fields[i]->Constant.value).value;
  11537. }
  11538. LLVMValueRef name_init = llvm_const_array(lb_type(m, t_string), name_values, cast(unsigned)fields.count);
  11539. LLVMValueRef value_init = llvm_const_array(lb_type(m, t_type_info_enum_value), value_values, cast(unsigned)fields.count);
  11540. LLVMSetInitializer(name_array.value, name_init);
  11541. LLVMSetInitializer(value_array.value, value_init);
  11542. lbValue v_count = lb_const_int(m, t_int, fields.count);
  11543. vals[1] = llvm_const_slice(m, lb_array_elem(p, name_array), v_count);
  11544. vals[2] = llvm_const_slice(m, lb_array_elem(p, value_array), v_count);
  11545. } else {
  11546. vals[1] = LLVMConstNull(lb_type(m, base_type(t_type_info_enum)->Struct.fields[1]->type));
  11547. vals[2] = LLVMConstNull(lb_type(m, base_type(t_type_info_enum)->Struct.fields[2]->type));
  11548. }
  11549. lbValue res = {};
  11550. res.type = type_deref(tag.type);
  11551. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11552. lb_emit_store(p, tag, res);
  11553. }
  11554. break;
  11555. case Type_Union: {
  11556. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_union_ptr);
  11557. {
  11558. LLVMValueRef vals[7] = {};
  11559. isize variant_count = gb_max(0, t->Union.variants.count);
  11560. lbValue memory_types = lb_type_info_member_types_offset(p, variant_count);
  11561. // NOTE(bill): Zeroth is nil so ignore it
  11562. for (isize variant_index = 0; variant_index < variant_count; variant_index++) {
  11563. Type *vt = t->Union.variants[variant_index];
  11564. lbValue tip = lb_get_type_info_ptr(m, vt);
  11565. lbValue index = lb_const_int(m, t_int, variant_index);
  11566. lbValue type_info = lb_emit_ptr_offset(p, memory_types, index);
  11567. lb_emit_store(p, type_info, lb_type_info(m, vt));
  11568. }
  11569. lbValue count = lb_const_int(m, t_int, variant_count);
  11570. vals[0] = llvm_const_slice(m, memory_types, count);
  11571. i64 tag_size = union_tag_size(t);
  11572. i64 tag_offset = align_formula(t->Union.variant_block_size, tag_size);
  11573. if (tag_size > 0) {
  11574. vals[1] = lb_const_int(m, t_uintptr, tag_offset).value;
  11575. vals[2] = lb_type_info(m, union_tag_type(t)).value;
  11576. } else {
  11577. vals[1] = lb_const_int(m, t_uintptr, 0).value;
  11578. vals[2] = LLVMConstNull(lb_type(m, t_type_info_ptr));
  11579. }
  11580. if (is_type_comparable(t) && !is_type_simple_compare(t)) {
  11581. vals[3] = lb_get_equal_proc_for_type(m, t).value;
  11582. }
  11583. vals[4] = lb_const_bool(m, t_bool, t->Union.custom_align != 0).value;
  11584. vals[5] = lb_const_bool(m, t_bool, t->Union.no_nil).value;
  11585. vals[6] = lb_const_bool(m, t_bool, t->Union.maybe).value;
  11586. for (isize i = 0; i < gb_count_of(vals); i++) {
  11587. if (vals[i] == nullptr) {
  11588. vals[i] = LLVMConstNull(lb_type(m, get_struct_field_type(tag.type, i)));
  11589. }
  11590. }
  11591. lbValue res = {};
  11592. res.type = type_deref(tag.type);
  11593. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11594. lb_emit_store(p, tag, res);
  11595. }
  11596. break;
  11597. }
  11598. case Type_Struct: {
  11599. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_struct_ptr);
  11600. LLVMValueRef vals[12] = {};
  11601. {
  11602. lbValue is_packed = lb_const_bool(m, t_bool, t->Struct.is_packed);
  11603. lbValue is_raw_union = lb_const_bool(m, t_bool, t->Struct.is_raw_union);
  11604. lbValue is_custom_align = lb_const_bool(m, t_bool, t->Struct.custom_align != 0);
  11605. vals[5] = is_packed.value;
  11606. vals[6] = is_raw_union.value;
  11607. vals[7] = is_custom_align.value;
  11608. if (is_type_comparable(t) && !is_type_simple_compare(t)) {
  11609. vals[8] = lb_get_equal_proc_for_type(m, t).value;
  11610. }
  11611. if (t->Struct.soa_kind != StructSoa_None) {
  11612. lbValue kind = lb_emit_struct_ep(p, tag, 9);
  11613. Type *kind_type = type_deref(kind.type);
  11614. lbValue soa_kind = lb_const_value(m, kind_type, exact_value_i64(t->Struct.soa_kind));
  11615. lbValue soa_type = lb_type_info(m, t->Struct.soa_elem);
  11616. lbValue soa_len = lb_const_int(m, t_int, t->Struct.soa_count);
  11617. vals[9] = soa_kind.value;
  11618. vals[10] = soa_type.value;
  11619. vals[11] = soa_len.value;
  11620. }
  11621. }
  11622. isize count = t->Struct.fields.count;
  11623. if (count > 0) {
  11624. lbValue memory_types = lb_type_info_member_types_offset (p, count);
  11625. lbValue memory_names = lb_type_info_member_names_offset (p, count);
  11626. lbValue memory_offsets = lb_type_info_member_offsets_offset(p, count);
  11627. lbValue memory_usings = lb_type_info_member_usings_offset (p, count);
  11628. lbValue memory_tags = lb_type_info_member_tags_offset (p, count);
  11629. type_set_offsets(t); // NOTE(bill): Just incase the offsets have not been set yet
  11630. for (isize source_index = 0; source_index < count; source_index++) {
  11631. // TODO(bill): Order fields in source order not layout order
  11632. Entity *f = t->Struct.fields[source_index];
  11633. lbValue tip = lb_get_type_info_ptr(m, f->type);
  11634. i64 foffset = 0;
  11635. if (!t->Struct.is_raw_union) {
  11636. foffset = t->Struct.offsets[f->Variable.field_index];
  11637. }
  11638. GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
  11639. lbValue index = lb_const_int(m, t_int, source_index);
  11640. lbValue type_info = lb_emit_ptr_offset(p, memory_types, index);
  11641. lbValue offset = lb_emit_ptr_offset(p, memory_offsets, index);
  11642. lbValue is_using = lb_emit_ptr_offset(p, memory_usings, index);
  11643. lb_emit_store(p, type_info, lb_type_info(m, f->type));
  11644. if (f->token.string.len > 0) {
  11645. lbValue name = lb_emit_ptr_offset(p, memory_names, index);
  11646. lb_emit_store(p, name, lb_const_string(m, f->token.string));
  11647. }
  11648. lb_emit_store(p, offset, lb_const_int(m, t_uintptr, foffset));
  11649. lb_emit_store(p, is_using, lb_const_bool(m, t_bool, (f->flags&EntityFlag_Using) != 0));
  11650. if (t->Struct.tags.count > 0) {
  11651. String tag_string = t->Struct.tags[source_index];
  11652. if (tag_string.len > 0) {
  11653. lbValue tag_ptr = lb_emit_ptr_offset(p, memory_tags, index);
  11654. lb_emit_store(p, tag_ptr, lb_const_string(m, tag_string));
  11655. }
  11656. }
  11657. }
  11658. lbValue cv = lb_const_int(m, t_int, count);
  11659. vals[0] = llvm_const_slice(m, memory_types, cv);
  11660. vals[1] = llvm_const_slice(m, memory_names, cv);
  11661. vals[2] = llvm_const_slice(m, memory_offsets, cv);
  11662. vals[3] = llvm_const_slice(m, memory_usings, cv);
  11663. vals[4] = llvm_const_slice(m, memory_tags, cv);
  11664. }
  11665. for (isize i = 0; i < gb_count_of(vals); i++) {
  11666. if (vals[i] == nullptr) {
  11667. vals[i] = LLVMConstNull(lb_type(m, get_struct_field_type(tag.type, i)));
  11668. }
  11669. }
  11670. lbValue res = {};
  11671. res.type = type_deref(tag.type);
  11672. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11673. lb_emit_store(p, tag, res);
  11674. break;
  11675. }
  11676. case Type_Map: {
  11677. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_map_ptr);
  11678. init_map_internal_types(t);
  11679. LLVMValueRef vals[5] = {
  11680. lb_get_type_info_ptr(m, t->Map.key).value,
  11681. lb_get_type_info_ptr(m, t->Map.value).value,
  11682. lb_get_type_info_ptr(m, t->Map.generated_struct_type).value,
  11683. lb_get_equal_proc_for_type(m, t->Map.key).value,
  11684. lb_get_hasher_proc_for_type(m, t->Map.key).value
  11685. };
  11686. lbValue res = {};
  11687. res.type = type_deref(tag.type);
  11688. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11689. lb_emit_store(p, tag, res);
  11690. break;
  11691. }
  11692. case Type_BitSet:
  11693. {
  11694. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_bit_set_ptr);
  11695. GB_ASSERT(is_type_typed(t->BitSet.elem));
  11696. LLVMValueRef vals[4] = {
  11697. lb_get_type_info_ptr(m, t->BitSet.elem).value,
  11698. LLVMConstNull(lb_type(m, t_type_info_ptr)),
  11699. lb_const_int(m, t_i64, t->BitSet.lower).value,
  11700. lb_const_int(m, t_i64, t->BitSet.upper).value,
  11701. };
  11702. if (t->BitSet.underlying != nullptr) {
  11703. vals[1] =lb_get_type_info_ptr(m, t->BitSet.underlying).value;
  11704. }
  11705. lbValue res = {};
  11706. res.type = type_deref(tag.type);
  11707. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11708. lb_emit_store(p, tag, res);
  11709. }
  11710. break;
  11711. case Type_SimdVector:
  11712. {
  11713. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_simd_vector_ptr);
  11714. LLVMValueRef vals[3] = {};
  11715. vals[0] = lb_get_type_info_ptr(m, t->SimdVector.elem).value;
  11716. vals[1] = lb_const_int(m, t_int, type_size_of(t->SimdVector.elem)).value;
  11717. vals[2] = lb_const_int(m, t_int, t->SimdVector.count).value;
  11718. lbValue res = {};
  11719. res.type = type_deref(tag.type);
  11720. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11721. lb_emit_store(p, tag, res);
  11722. }
  11723. break;
  11724. case Type_RelativePointer:
  11725. {
  11726. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_relative_pointer_ptr);
  11727. LLVMValueRef vals[2] = {
  11728. lb_get_type_info_ptr(m, t->RelativePointer.pointer_type).value,
  11729. lb_get_type_info_ptr(m, t->RelativePointer.base_integer).value,
  11730. };
  11731. lbValue res = {};
  11732. res.type = type_deref(tag.type);
  11733. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11734. lb_emit_store(p, tag, res);
  11735. }
  11736. break;
  11737. case Type_RelativeSlice:
  11738. {
  11739. tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_relative_slice_ptr);
  11740. LLVMValueRef vals[2] = {
  11741. lb_get_type_info_ptr(m, t->RelativeSlice.slice_type).value,
  11742. lb_get_type_info_ptr(m, t->RelativeSlice.base_integer).value,
  11743. };
  11744. lbValue res = {};
  11745. res.type = type_deref(tag.type);
  11746. res.value = llvm_const_named_struct(lb_type(m, res.type), vals, gb_count_of(vals));
  11747. lb_emit_store(p, tag, res);
  11748. }
  11749. break;
  11750. }
  11751. if (tag.value != nullptr) {
  11752. Type *tag_type = type_deref(tag.type);
  11753. GB_ASSERT(is_type_named(tag_type));
  11754. // lb_emit_store_union_variant(p, variant_ptr, lb_emit_load(p, tag), tag_type);
  11755. lb_emit_store_union_variant_tag(p, variant_ptr, tag_type);
  11756. } else {
  11757. if (t != t_llvm_bool) {
  11758. GB_PANIC("Unhandled Type_Info variant: %s", type_to_string(t));
  11759. }
  11760. }
  11761. }
  11762. }
  11763. struct lbGlobalVariable {
  11764. lbValue var;
  11765. lbValue init;
  11766. DeclInfo *decl;
  11767. bool is_initialized;
  11768. };
  11769. lbProcedure *lb_create_startup_type_info(lbModule *m) {
  11770. LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod);
  11771. lb_populate_function_pass_manager(m, default_function_pass_manager, false, build_context.optimization_level);
  11772. LLVMFinalizeFunctionPassManager(default_function_pass_manager);
  11773. Type *params = alloc_type_tuple();
  11774. Type *results = alloc_type_tuple();
  11775. Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_CDecl);
  11776. lbProcedure *p = lb_create_dummy_procedure(m, str_lit(LB_STARTUP_TYPE_INFO_PROC_NAME), proc_type);
  11777. p->is_startup = true;
  11778. lb_begin_procedure_body(p);
  11779. lb_setup_type_info_data(p);
  11780. lb_end_procedure_body(p);
  11781. if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
  11782. gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %s\n", "main");
  11783. LLVMDumpValue(p->value);
  11784. gb_printf_err("\n\n\n\n");
  11785. LLVMVerifyFunction(p->value, LLVMAbortProcessAction);
  11786. }
  11787. lb_run_function_pass_manager(default_function_pass_manager, p);
  11788. return p;
  11789. }
  11790. lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *startup_type_info, Array<lbGlobalVariable> &global_variables) { // Startup Runtime
  11791. LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(main_module->mod);
  11792. lb_populate_function_pass_manager(main_module, default_function_pass_manager, false, build_context.optimization_level);
  11793. LLVMFinalizeFunctionPassManager(default_function_pass_manager);
  11794. Type *params = alloc_type_tuple();
  11795. Type *results = alloc_type_tuple();
  11796. Type *proc_type = alloc_type_proc(nullptr, nullptr, 0, nullptr, 0, false, ProcCC_CDecl);
  11797. lbProcedure *p = lb_create_dummy_procedure(main_module, str_lit(LB_STARTUP_RUNTIME_PROC_NAME), proc_type);
  11798. p->is_startup = true;
  11799. lb_begin_procedure_body(p);
  11800. LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(main_module, startup_type_info->type)), startup_type_info->value, nullptr, 0, "");
  11801. for_array(i, global_variables) {
  11802. auto *var = &global_variables[i];
  11803. if (var->is_initialized) {
  11804. continue;
  11805. }
  11806. lbModule *entity_module = main_module;
  11807. Entity *e = var->decl->entity;
  11808. GB_ASSERT(e->kind == Entity_Variable);
  11809. e->code_gen_module = entity_module;
  11810. if (var->decl->init_expr != nullptr) {
  11811. // gb_printf_err("%s\n", expr_to_string(var->decl->init_expr));
  11812. lbValue init = lb_build_expr(p, var->decl->init_expr);
  11813. LLVMValueKind value_kind = LLVMGetValueKind(init.value);
  11814. // gb_printf_err("%s %d\n", LLVMPrintValueToString(init.value));
  11815. if (lb_is_const_or_global(init)) {
  11816. if (!var->is_initialized) {
  11817. LLVMSetInitializer(var->var.value, init.value);
  11818. var->is_initialized = true;
  11819. continue;
  11820. }
  11821. } else {
  11822. var->init = init;
  11823. }
  11824. }
  11825. if (var->init.value != nullptr) {
  11826. GB_ASSERT(!var->is_initialized);
  11827. Type *t = type_deref(var->var.type);
  11828. if (is_type_any(t)) {
  11829. // NOTE(bill): Edge case for 'any' type
  11830. Type *var_type = default_type(var->init.type);
  11831. lbAddr g = lb_add_global_generated(main_module, var_type, var->init);
  11832. lb_addr_store(p, g, var->init);
  11833. lbValue gp = lb_addr_get_ptr(p, g);
  11834. lbValue data = lb_emit_struct_ep(p, var->var, 0);
  11835. lbValue ti = lb_emit_struct_ep(p, var->var, 1);
  11836. lb_emit_store(p, data, lb_emit_conv(p, gp, t_rawptr));
  11837. lb_emit_store(p, ti, lb_type_info(main_module, var_type));
  11838. } else {
  11839. LLVMTypeRef pvt = LLVMTypeOf(var->var.value);
  11840. LLVMTypeRef vt = LLVMGetElementType(pvt);
  11841. lbValue src0 = lb_emit_conv(p, var->init, t);
  11842. LLVMValueRef src = OdinLLVMBuildTransmute(p, src0.value, vt);
  11843. LLVMValueRef dst = var->var.value;
  11844. LLVMBuildStore(p->builder, src, dst);
  11845. }
  11846. var->is_initialized = true;
  11847. }
  11848. }
  11849. lb_end_procedure_body(p);
  11850. if (!main_module->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
  11851. gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %s\n", "main");
  11852. LLVMDumpValue(p->value);
  11853. gb_printf_err("\n\n\n\n");
  11854. LLVMVerifyFunction(p->value, LLVMAbortProcessAction);
  11855. }
  11856. lb_run_function_pass_manager(default_function_pass_manager, p);
  11857. return p;
  11858. }
  11859. lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime) {
  11860. LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod);
  11861. lb_populate_function_pass_manager(m, default_function_pass_manager, false, build_context.optimization_level);
  11862. LLVMFinalizeFunctionPassManager(default_function_pass_manager);
  11863. Type *params = alloc_type_tuple();
  11864. Type *results = alloc_type_tuple();
  11865. Type *t_ptr_cstring = alloc_type_pointer(t_cstring);
  11866. String name = str_lit("main");
  11867. if (build_context.metrics.os == TargetOs_windows && build_context.metrics.arch == TargetArch_386) {
  11868. name = str_lit("mainCRTStartup");
  11869. } else {
  11870. array_init(&params->Tuple.variables, permanent_allocator(), 2);
  11871. params->Tuple.variables[0] = alloc_entity_param(nullptr, make_token_ident("argc"), t_i32, false, true);
  11872. params->Tuple.variables[1] = alloc_entity_param(nullptr, make_token_ident("argv"), t_ptr_cstring, false, true);
  11873. }
  11874. array_init(&results->Tuple.variables, permanent_allocator(), 1);
  11875. results->Tuple.variables[0] = alloc_entity_param(nullptr, blank_token, t_i32, false, true);
  11876. Type *proc_type = alloc_type_proc(nullptr,
  11877. params, params->Tuple.variables.count,
  11878. results, results->Tuple.variables.count, false, ProcCC_CDecl);
  11879. lbProcedure *p = lb_create_dummy_procedure(m, name, proc_type);
  11880. p->is_startup = true;
  11881. lb_begin_procedure_body(p);
  11882. { // initialize `runtime.args__`
  11883. lbValue argc = {LLVMGetParam(p->value, 0), t_i32};
  11884. lbValue argv = {LLVMGetParam(p->value, 1), t_ptr_cstring};
  11885. LLVMSetValueName2(argc.value, "argc", 4);
  11886. LLVMSetValueName2(argv.value, "argv", 4);
  11887. argc = lb_emit_conv(p, argc, t_int);
  11888. lbAddr args = lb_addr(lb_find_runtime_value(p->module, str_lit("args__")));
  11889. lb_fill_slice(p, args, argv, argc);
  11890. }
  11891. LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(m, startup_runtime->type)), startup_runtime->value, nullptr, 0, "");
  11892. if (build_context.command_kind == Command_test) {
  11893. Type *t_Internal_Test = find_type_in_pkg(m->info, str_lit("testing"), str_lit("Internal_Test"));
  11894. Type *array_type = alloc_type_array(t_Internal_Test, m->info->testing_procedures.count);
  11895. Type *slice_type = alloc_type_slice(t_Internal_Test);
  11896. lbAddr all_tests_array_addr = lb_add_global_generated(p->module, array_type, {});
  11897. lbValue all_tests_array = lb_addr_get_ptr(p, all_tests_array_addr);
  11898. LLVMTypeRef lbt_Internal_Test = lb_type(m, t_Internal_Test);
  11899. LLVMValueRef indices[2] = {};
  11900. indices[0] = LLVMConstInt(lb_type(m, t_i32), 0, false);
  11901. for_array(i, m->info->testing_procedures) {
  11902. Entity *testing_proc = m->info->testing_procedures[i];
  11903. String name = testing_proc->token.string;
  11904. String pkg_name = {};
  11905. if (testing_proc->pkg != nullptr) {
  11906. pkg_name = testing_proc->pkg->name;
  11907. }
  11908. lbValue v_pkg = lb_find_or_add_entity_string(m, pkg_name);
  11909. lbValue v_name = lb_find_or_add_entity_string(m, name);
  11910. lbValue v_proc = lb_find_procedure_value_from_entity(m, testing_proc);
  11911. indices[1] = LLVMConstInt(lb_type(m, t_int), i, false);
  11912. LLVMValueRef vals[3] = {};
  11913. vals[0] = v_pkg.value;
  11914. vals[1] = v_name.value;
  11915. vals[2] = v_proc.value;
  11916. GB_ASSERT(LLVMIsConstant(vals[0]));
  11917. GB_ASSERT(LLVMIsConstant(vals[1]));
  11918. GB_ASSERT(LLVMIsConstant(vals[2]));
  11919. LLVMValueRef dst = LLVMConstInBoundsGEP(all_tests_array.value, indices, gb_count_of(indices));
  11920. LLVMValueRef src = llvm_const_named_struct(lbt_Internal_Test, vals, gb_count_of(vals));
  11921. LLVMBuildStore(p->builder, src, dst);
  11922. }
  11923. lbAddr all_tests_slice = lb_add_local_generated(p, slice_type, true);
  11924. lb_fill_slice(p, all_tests_slice,
  11925. lb_array_elem(p, all_tests_array),
  11926. lb_const_int(m, t_int, m->info->testing_procedures.count));
  11927. lbValue runner = lb_find_package_value(m, str_lit("testing"), str_lit("runner"));
  11928. auto args = array_make<lbValue>(heap_allocator(), 1);
  11929. args[0] = lb_addr_load(p, all_tests_slice);
  11930. lb_emit_call(p, runner, args);
  11931. } else {
  11932. lbValue entry_point = lb_find_procedure_value_from_entity(m, m->info->entry_point);
  11933. lb_emit_call(p, entry_point, {});
  11934. }
  11935. LLVMBuildRet(p->builder, LLVMConstInt(lb_type(m, t_i32), 0, false));
  11936. lb_end_procedure_body(p);
  11937. if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
  11938. gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %s\n", "main");
  11939. LLVMDumpValue(p->value);
  11940. gb_printf_err("\n\n\n\n");
  11941. LLVMVerifyFunction(p->value, LLVMAbortProcessAction);
  11942. }
  11943. lb_run_function_pass_manager(default_function_pass_manager, p);
  11944. return p;
  11945. }
  11946. String lb_filepath_ll_for_module(lbModule *m) {
  11947. String path = m->gen->output_base;
  11948. if (m->pkg) {
  11949. path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name);
  11950. } else if (USE_SEPARTE_MODULES) {
  11951. path = concatenate_strings(permanent_allocator(), path, STR_LIT("-builtin"));
  11952. }
  11953. path = concatenate_strings(permanent_allocator(), path, STR_LIT(".ll"));
  11954. return path;
  11955. }
  11956. String lb_filepath_obj_for_module(lbModule *m) {
  11957. String path = m->gen->output_base;
  11958. if (m->pkg) {
  11959. path = concatenate3_strings(permanent_allocator(), path, STR_LIT("-"), m->pkg->name);
  11960. }
  11961. String ext = {};
  11962. if (build_context.build_mode == BuildMode_Assembly) {
  11963. ext = STR_LIT(".S");
  11964. } else {
  11965. switch (build_context.metrics.os) {
  11966. case TargetOs_windows:
  11967. ext = STR_LIT(".obj");
  11968. break;
  11969. case TargetOs_darwin:
  11970. case TargetOs_linux:
  11971. case TargetOs_essence:
  11972. ext = STR_LIT(".o");
  11973. break;
  11974. case TargetOs_js:
  11975. ext = STR_LIT(".wasm-obj");
  11976. break;
  11977. }
  11978. }
  11979. return concatenate_strings(permanent_allocator(), path, ext);
  11980. }
  11981. bool lb_is_module_empty(lbModule *m) {
  11982. if (LLVMGetFirstFunction(m->mod) == nullptr &&
  11983. LLVMGetFirstGlobal(m->mod) == nullptr) {
  11984. return true;
  11985. }
  11986. for (auto fn = LLVMGetFirstFunction(m->mod); fn != nullptr; fn = LLVMGetNextFunction(fn)) {
  11987. if (LLVMGetFirstBasicBlock(fn) != nullptr) {
  11988. return false;
  11989. }
  11990. }
  11991. for (auto g = LLVMGetFirstGlobal(m->mod); g != nullptr; g = LLVMGetNextGlobal(g)) {
  11992. if (LLVMGetLinkage(g) == LLVMExternalLinkage) {
  11993. continue;
  11994. }
  11995. if (!LLVMIsExternallyInitialized(g)) {
  11996. return false;
  11997. }
  11998. }
  11999. return true;
  12000. }
  12001. struct lbLLVMEmitWorker {
  12002. LLVMTargetMachineRef target_machine;
  12003. LLVMCodeGenFileType code_gen_file_type;
  12004. String filepath_obj;
  12005. lbModule *m;
  12006. };
  12007. WORKER_TASK_PROC(lb_llvm_emit_worker_proc) {
  12008. GB_ASSERT(MULTITHREAD_OBJECT_GENERATION);
  12009. char *llvm_error = nullptr;
  12010. auto wd = cast(lbLLVMEmitWorker *)data;
  12011. if (LLVMTargetMachineEmitToFile(wd->target_machine, wd->m->mod, cast(char *)wd->filepath_obj.text, wd->code_gen_file_type, &llvm_error)) {
  12012. gb_printf_err("LLVM Error: %s\n", llvm_error);
  12013. gb_exit(1);
  12014. }
  12015. return 0;
  12016. }
  12017. WORKER_TASK_PROC(lb_llvm_function_pass_worker_proc) {
  12018. GB_ASSERT(MULTITHREAD_OBJECT_GENERATION);
  12019. auto m = cast(lbModule *)data;
  12020. LLVMPassManagerRef default_function_pass_manager = LLVMCreateFunctionPassManagerForModule(m->mod);
  12021. LLVMPassManagerRef function_pass_manager_minimal = LLVMCreateFunctionPassManagerForModule(m->mod);
  12022. LLVMPassManagerRef function_pass_manager_size = LLVMCreateFunctionPassManagerForModule(m->mod);
  12023. LLVMPassManagerRef function_pass_manager_speed = LLVMCreateFunctionPassManagerForModule(m->mod);
  12024. LLVMInitializeFunctionPassManager(default_function_pass_manager);
  12025. LLVMInitializeFunctionPassManager(function_pass_manager_minimal);
  12026. LLVMInitializeFunctionPassManager(function_pass_manager_size);
  12027. LLVMInitializeFunctionPassManager(function_pass_manager_speed);
  12028. lb_populate_function_pass_manager(m, default_function_pass_manager, false, build_context.optimization_level);
  12029. lb_populate_function_pass_manager_specific(m, function_pass_manager_minimal, 0);
  12030. lb_populate_function_pass_manager_specific(m, function_pass_manager_size, 1);
  12031. lb_populate_function_pass_manager_specific(m, function_pass_manager_speed, 2);
  12032. LLVMFinalizeFunctionPassManager(default_function_pass_manager);
  12033. LLVMFinalizeFunctionPassManager(function_pass_manager_minimal);
  12034. LLVMFinalizeFunctionPassManager(function_pass_manager_size);
  12035. LLVMFinalizeFunctionPassManager(function_pass_manager_speed);
  12036. LLVMPassManagerRef default_function_pass_manager_without_memcpy = LLVMCreateFunctionPassManagerForModule(m->mod);
  12037. LLVMInitializeFunctionPassManager(default_function_pass_manager_without_memcpy);
  12038. lb_populate_function_pass_manager(m, default_function_pass_manager_without_memcpy, true, build_context.optimization_level);
  12039. LLVMFinalizeFunctionPassManager(default_function_pass_manager_without_memcpy);
  12040. for_array(i, m->procedures_to_generate) {
  12041. lbProcedure *p = m->procedures_to_generate[i];
  12042. if (p->body != nullptr) { // Build Procedure
  12043. if (p->flags & lbProcedureFlag_WithoutMemcpyPass) {
  12044. lb_run_function_pass_manager(default_function_pass_manager_without_memcpy, p);
  12045. } else {
  12046. if (p->entity && p->entity->kind == Entity_Procedure) {
  12047. switch (p->entity->Procedure.optimization_mode) {
  12048. case ProcedureOptimizationMode_None:
  12049. case ProcedureOptimizationMode_Minimal:
  12050. lb_run_function_pass_manager(function_pass_manager_minimal, p);
  12051. break;
  12052. case ProcedureOptimizationMode_Size:
  12053. lb_run_function_pass_manager(function_pass_manager_size, p);
  12054. break;
  12055. case ProcedureOptimizationMode_Speed:
  12056. lb_run_function_pass_manager(function_pass_manager_speed, p);
  12057. break;
  12058. default:
  12059. lb_run_function_pass_manager(default_function_pass_manager, p);
  12060. break;
  12061. }
  12062. } else {
  12063. lb_run_function_pass_manager(default_function_pass_manager, p);
  12064. }
  12065. }
  12066. }
  12067. }
  12068. for_array(i, m->equal_procs.entries) {
  12069. lbProcedure *p = m->equal_procs.entries[i].value;
  12070. lb_run_function_pass_manager(default_function_pass_manager, p);
  12071. }
  12072. for_array(i, m->hasher_procs.entries) {
  12073. lbProcedure *p = m->hasher_procs.entries[i].value;
  12074. lb_run_function_pass_manager(default_function_pass_manager, p);
  12075. }
  12076. return 0;
  12077. }
  12078. struct lbLLVMModulePassWorkerData {
  12079. lbModule *m;
  12080. LLVMTargetMachineRef target_machine;
  12081. };
  12082. WORKER_TASK_PROC(lb_llvm_module_pass_worker_proc) {
  12083. GB_ASSERT(MULTITHREAD_OBJECT_GENERATION);
  12084. auto wd = cast(lbLLVMModulePassWorkerData *)data;
  12085. LLVMPassManagerRef module_pass_manager = LLVMCreatePassManager();
  12086. lb_populate_module_pass_manager(wd->target_machine, module_pass_manager, build_context.optimization_level);
  12087. LLVMRunPassManager(module_pass_manager, wd->m->mod);
  12088. return 0;
  12089. }
  12090. void lb_generate_code(lbGenerator *gen) {
  12091. #define TIME_SECTION(str) do { if (build_context.show_more_timings) timings_start_section(&global_timings, str_lit(str)); } while (0)
  12092. #define TIME_SECTION_WITH_LEN(str, len) do { if (build_context.show_more_timings) timings_start_section(&global_timings, make_string((u8 *)str, len)); } while (0)
  12093. TIME_SECTION("LLVM Initializtion");
  12094. isize thread_count = gb_max(build_context.thread_count, 1);
  12095. isize worker_count = thread_count-1;
  12096. LLVMBool do_threading = (LLVMIsMultithreaded() && USE_SEPARTE_MODULES && MULTITHREAD_OBJECT_GENERATION && worker_count > 0);
  12097. thread_pool_init(&lb_thread_pool, heap_allocator(), worker_count, "LLVMBackend");
  12098. defer (thread_pool_destroy(&lb_thread_pool));
  12099. lbModule *default_module = &gen->default_module;
  12100. CheckerInfo *info = gen->info;
  12101. auto *min_dep_set = &info->minimum_dependency_set;
  12102. LLVMInitializeAllTargetInfos();
  12103. LLVMInitializeAllTargets();
  12104. LLVMInitializeAllTargetMCs();
  12105. LLVMInitializeAllAsmPrinters();
  12106. LLVMInitializeAllAsmParsers();
  12107. LLVMInitializeAllDisassemblers();
  12108. LLVMInitializeNativeTarget();
  12109. char const *target_triple = alloc_cstring(permanent_allocator(), build_context.metrics.target_triplet);
  12110. char const *target_data_layout = alloc_cstring(permanent_allocator(), build_context.metrics.target_data_layout);
  12111. for_array(i, gen->modules.entries) {
  12112. LLVMSetTarget(gen->modules.entries[i].value->mod, target_triple);
  12113. }
  12114. LLVMTargetRef target = {};
  12115. char *llvm_error = nullptr;
  12116. LLVMGetTargetFromTriple(target_triple, &target, &llvm_error);
  12117. GB_ASSERT(target != nullptr);
  12118. TIME_SECTION("LLVM Create Target Machine");
  12119. LLVMCodeModel code_mode = LLVMCodeModelDefault;
  12120. if (build_context.metrics.arch == TargetArch_wasm32) {
  12121. code_mode = LLVMCodeModelJITDefault;
  12122. }
  12123. char const *host_cpu_name = LLVMGetHostCPUName();
  12124. char const *llvm_cpu = "generic";
  12125. char const *llvm_features = "";
  12126. if (build_context.microarch.len != 0) {
  12127. if (build_context.microarch == "native") {
  12128. llvm_cpu = host_cpu_name;
  12129. } else {
  12130. llvm_cpu = alloc_cstring(permanent_allocator(), build_context.microarch);
  12131. }
  12132. if (gb_strcmp(llvm_cpu, host_cpu_name) == 0) {
  12133. llvm_features = LLVMGetHostCPUFeatures();
  12134. }
  12135. }
  12136. // GB_ASSERT_MSG(LLVMTargetHasAsmBackend(target));
  12137. LLVMCodeGenOptLevel code_gen_level = LLVMCodeGenLevelNone;
  12138. switch (build_context.optimization_level) {
  12139. case 0: code_gen_level = LLVMCodeGenLevelNone; break;
  12140. case 1: code_gen_level = LLVMCodeGenLevelLess; break;
  12141. case 2: code_gen_level = LLVMCodeGenLevelDefault; break;
  12142. case 3: code_gen_level = LLVMCodeGenLevelDefault; break; // NOTE(bill): force -opt:3 to be the same as -opt:2
  12143. // case 3: code_gen_level = LLVMCodeGenLevelAggressive; break;
  12144. }
  12145. // NOTE(bill): Target Machine Creation
  12146. // NOTE(bill, 2021-05-04): Target machines must be unique to each module because they are not thread safe
  12147. auto target_machines = array_make<LLVMTargetMachineRef>(permanent_allocator(), gen->modules.entries.count);
  12148. for_array(i, gen->modules.entries) {
  12149. target_machines[i] = LLVMCreateTargetMachine(
  12150. target, target_triple, llvm_cpu,
  12151. llvm_features,
  12152. code_gen_level,
  12153. LLVMRelocDefault,
  12154. code_mode);
  12155. LLVMSetModuleDataLayout(gen->modules.entries[i].value->mod, LLVMCreateTargetDataLayout(target_machines[i]));
  12156. }
  12157. for_array(i, gen->modules.entries) {
  12158. lbModule *m = gen->modules.entries[i].value;
  12159. if (m->debug_builder) { // Debug Info
  12160. for_array(i, info->files.entries) {
  12161. AstFile *f = info->files.entries[i].value;
  12162. String fullpath = f->fullpath;
  12163. String filename = remove_directory_from_path(fullpath);
  12164. String directory = directory_from_path(fullpath);
  12165. LLVMMetadataRef res = LLVMDIBuilderCreateFile(m->debug_builder,
  12166. cast(char const *)filename.text, filename.len,
  12167. cast(char const *)directory.text, directory.len);
  12168. lb_set_llvm_metadata(m, f, res);
  12169. }
  12170. gbString producer = gb_string_make(heap_allocator(), "odin");
  12171. // producer = gb_string_append_fmt(producer, " version %.*s", LIT(ODIN_VERSION));
  12172. // #ifdef NIGHTLY
  12173. // producer = gb_string_appendc(producer, "-nightly");
  12174. // #endif
  12175. // #ifdef GIT_SHA
  12176. // producer = gb_string_append_fmt(producer, "-%s", GIT_SHA);
  12177. // #endif
  12178. gbString split_name = gb_string_make(heap_allocator(), "");
  12179. LLVMBool is_optimized = build_context.optimization_level > 0;
  12180. AstFile *init_file = m->info->init_package->files[0];
  12181. if (m->info->entry_point && m->info->entry_point->identifier && m->info->entry_point->identifier->file) {
  12182. init_file = m->info->entry_point->identifier->file;
  12183. }
  12184. LLVMBool split_debug_inlining = false;
  12185. LLVMBool debug_info_for_profiling = false;
  12186. m->debug_compile_unit = LLVMDIBuilderCreateCompileUnit(m->debug_builder, LLVMDWARFSourceLanguageC99,
  12187. lb_get_llvm_metadata(m, init_file),
  12188. producer, gb_string_length(producer),
  12189. is_optimized, "", 0,
  12190. 1, split_name, gb_string_length(split_name),
  12191. LLVMDWARFEmissionFull,
  12192. 0, split_debug_inlining,
  12193. debug_info_for_profiling,
  12194. "", 0, // sys_root
  12195. "", 0 // SDK
  12196. );
  12197. GB_ASSERT(m->debug_compile_unit != nullptr);
  12198. }
  12199. }
  12200. TIME_SECTION("LLVM Global Variables");
  12201. {
  12202. lbModule *m = default_module;
  12203. { // Add type info data
  12204. isize max_type_info_count = info->minimum_dependency_type_info_set.entries.count+1;
  12205. // gb_printf_err("max_type_info_count: %td\n", max_type_info_count);
  12206. Type *t = alloc_type_array(t_type_info, max_type_info_count);
  12207. LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), LB_TYPE_INFO_DATA_NAME);
  12208. LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
  12209. // LLVMSetLinkage(g, LLVMInternalLinkage);
  12210. lbValue value = {};
  12211. value.value = g;
  12212. value.type = alloc_type_pointer(t);
  12213. lb_global_type_info_data_entity = alloc_entity_variable(nullptr, make_token_ident(LB_TYPE_INFO_DATA_NAME), t, EntityState_Resolved);
  12214. lb_add_entity(m, lb_global_type_info_data_entity, value);
  12215. }
  12216. { // Type info member buffer
  12217. // NOTE(bill): Removes need for heap allocation by making it global memory
  12218. isize count = 0;
  12219. for_array(entry_index, m->info->type_info_types) {
  12220. Type *t = m->info->type_info_types[entry_index];
  12221. isize index = lb_type_info_index(m->info, t, false);
  12222. if (index < 0) {
  12223. continue;
  12224. }
  12225. switch (t->kind) {
  12226. case Type_Union:
  12227. count += t->Union.variants.count;
  12228. break;
  12229. case Type_Struct:
  12230. count += t->Struct.fields.count;
  12231. break;
  12232. case Type_Tuple:
  12233. count += t->Tuple.variables.count;
  12234. break;
  12235. }
  12236. }
  12237. if (count > 0) {
  12238. {
  12239. char const *name = LB_TYPE_INFO_TYPES_NAME;
  12240. Type *t = alloc_type_array(t_type_info_ptr, count);
  12241. LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
  12242. LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
  12243. // LLVMSetLinkage(g, LLVMInternalLinkage);
  12244. lb_global_type_info_member_types = lb_addr({g, alloc_type_pointer(t)});
  12245. }
  12246. {
  12247. char const *name = LB_TYPE_INFO_NAMES_NAME;
  12248. Type *t = alloc_type_array(t_string, count);
  12249. LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
  12250. LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
  12251. // LLVMSetLinkage(g, LLVMInternalLinkage);
  12252. lb_global_type_info_member_names = lb_addr({g, alloc_type_pointer(t)});
  12253. }
  12254. {
  12255. char const *name = LB_TYPE_INFO_OFFSETS_NAME;
  12256. Type *t = alloc_type_array(t_uintptr, count);
  12257. LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
  12258. LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
  12259. // LLVMSetLinkage(g, LLVMInternalLinkage);
  12260. lb_global_type_info_member_offsets = lb_addr({g, alloc_type_pointer(t)});
  12261. }
  12262. {
  12263. char const *name = LB_TYPE_INFO_USINGS_NAME;
  12264. Type *t = alloc_type_array(t_bool, count);
  12265. LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
  12266. LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
  12267. // LLVMSetLinkage(g, LLVMInternalLinkage);
  12268. lb_global_type_info_member_usings = lb_addr({g, alloc_type_pointer(t)});
  12269. }
  12270. {
  12271. char const *name = LB_TYPE_INFO_TAGS_NAME;
  12272. Type *t = alloc_type_array(t_string, count);
  12273. LLVMValueRef g = LLVMAddGlobal(m->mod, lb_type(m, t), name);
  12274. LLVMSetInitializer(g, LLVMConstNull(lb_type(m, t)));
  12275. // LLVMSetLinkage(g, LLVMInternalLinkage);
  12276. lb_global_type_info_member_tags = lb_addr({g, alloc_type_pointer(t)});
  12277. }
  12278. }
  12279. }
  12280. }
  12281. isize global_variable_max_count = 0;
  12282. Entity *entry_point = info->entry_point;
  12283. bool has_dll_main = false;
  12284. bool has_win_main = false;
  12285. for_array(i, info->entities) {
  12286. Entity *e = info->entities[i];
  12287. String name = e->token.string;
  12288. bool is_global = e->pkg != nullptr;
  12289. if (e->kind == Entity_Variable) {
  12290. global_variable_max_count++;
  12291. } else if (e->kind == Entity_Procedure && !is_global) {
  12292. if ((e->scope->flags&ScopeFlag_Init) && name == "main") {
  12293. GB_ASSERT(e == entry_point);
  12294. // entry_point = e;
  12295. }
  12296. if (e->Procedure.is_export ||
  12297. (e->Procedure.link_name.len > 0) ||
  12298. ((e->scope->flags&ScopeFlag_File) && e->Procedure.link_name.len > 0)) {
  12299. if (!has_dll_main && name == "DllMain") {
  12300. has_dll_main = true;
  12301. } else if (!has_win_main && name == "WinMain") {
  12302. has_win_main = true;
  12303. }
  12304. }
  12305. }
  12306. }
  12307. auto global_variables = array_make<lbGlobalVariable>(permanent_allocator(), 0, global_variable_max_count);
  12308. for_array(i, info->variable_init_order) {
  12309. DeclInfo *d = info->variable_init_order[i];
  12310. Entity *e = d->entity;
  12311. if ((e->scope->flags & ScopeFlag_File) == 0) {
  12312. continue;
  12313. }
  12314. if (!ptr_set_exists(min_dep_set, e)) {
  12315. continue;
  12316. }
  12317. DeclInfo *decl = decl_info_of_entity(e);
  12318. if (decl == nullptr) {
  12319. continue;
  12320. }
  12321. GB_ASSERT(e->kind == Entity_Variable);
  12322. bool is_foreign = e->Variable.is_foreign;
  12323. bool is_export = e->Variable.is_export;
  12324. lbModule *m = &gen->default_module;
  12325. String name = lb_get_entity_name(m, e);
  12326. lbValue g = {};
  12327. g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name));
  12328. g.type = alloc_type_pointer(e->type);
  12329. if (e->Variable.thread_local_model != "") {
  12330. LLVMSetThreadLocal(g.value, true);
  12331. String m = e->Variable.thread_local_model;
  12332. LLVMThreadLocalMode mode = LLVMGeneralDynamicTLSModel;
  12333. if (m == "default") {
  12334. mode = LLVMGeneralDynamicTLSModel;
  12335. } else if (m == "localdynamic") {
  12336. mode = LLVMLocalDynamicTLSModel;
  12337. } else if (m == "initialexec") {
  12338. mode = LLVMInitialExecTLSModel;
  12339. } else if (m == "localexec") {
  12340. mode = LLVMLocalExecTLSModel;
  12341. } else {
  12342. GB_PANIC("Unhandled thread local mode %.*s", LIT(m));
  12343. }
  12344. LLVMSetThreadLocalMode(g.value, mode);
  12345. }
  12346. if (is_foreign) {
  12347. LLVMSetLinkage(g.value, LLVMExternalLinkage);
  12348. LLVMSetExternallyInitialized(g.value, true);
  12349. lb_add_foreign_library_path(m, e->Variable.foreign_library);
  12350. } else {
  12351. LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, e->type)));
  12352. }
  12353. if (is_export) {
  12354. LLVMSetLinkage(g.value, LLVMDLLExportLinkage);
  12355. LLVMSetDLLStorageClass(g.value, LLVMDLLExportStorageClass);
  12356. } else {
  12357. // LLVMSetLinkage(g.value, LLVMInternalLinkage);
  12358. }
  12359. lbGlobalVariable var = {};
  12360. var.var = g;
  12361. var.decl = decl;
  12362. if (decl->init_expr != nullptr) {
  12363. TypeAndValue tav = type_and_value_of_expr(decl->init_expr);
  12364. if (!is_type_any(e->type)) {
  12365. if (tav.mode != Addressing_Invalid) {
  12366. if (tav.value.kind != ExactValue_Invalid) {
  12367. ExactValue v = tav.value;
  12368. lbValue init = lb_const_value(m, tav.type, v);
  12369. LLVMSetInitializer(g.value, init.value);
  12370. var.is_initialized = true;
  12371. }
  12372. }
  12373. }
  12374. if (!var.is_initialized &&
  12375. (is_type_untyped_nil(tav.type) || is_type_untyped_undef(tav.type))) {
  12376. var.is_initialized = true;
  12377. }
  12378. }
  12379. array_add(&global_variables, var);
  12380. lb_add_entity(m, e, g);
  12381. lb_add_member(m, name, g);
  12382. if (m->debug_builder) {
  12383. String global_name = e->token.string;
  12384. if (global_name.len != 0 && global_name != "_") {
  12385. LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, e->file);
  12386. LLVMMetadataRef llvm_scope = llvm_file;
  12387. LLVMBool local_to_unit = e->flags & EntityFlag_Static;
  12388. LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0);
  12389. LLVMMetadataRef llvm_decl = nullptr;
  12390. u32 align_in_bits = cast(u32)(8*type_align_of(e->type));
  12391. LLVMMetadataRef global_variable_metadata = LLVMDIBuilderCreateGlobalVariableExpression(
  12392. m->debug_builder, llvm_scope,
  12393. cast(char const *)global_name.text, global_name.len,
  12394. "", 0, // linkage
  12395. llvm_file, e->token.pos.line,
  12396. lb_debug_type(m, e->type),
  12397. local_to_unit,
  12398. llvm_expr,
  12399. llvm_decl,
  12400. align_in_bits
  12401. );
  12402. lb_set_llvm_metadata(m, g.value, global_variable_metadata);
  12403. LLVMGlobalSetMetadata(g.value, 0, global_variable_metadata);
  12404. }
  12405. }
  12406. }
  12407. TIME_SECTION("LLVM Global Procedures and Types");
  12408. for_array(i, info->entities) {
  12409. Entity *e = info->entities[i];
  12410. String name = e->token.string;
  12411. DeclInfo *decl = e->decl_info;
  12412. Scope * scope = e->scope;
  12413. if ((scope->flags & ScopeFlag_File) == 0) {
  12414. continue;
  12415. }
  12416. Scope *package_scope = scope->parent;
  12417. GB_ASSERT(package_scope->flags & ScopeFlag_Pkg);
  12418. switch (e->kind) {
  12419. case Entity_Variable:
  12420. // NOTE(bill): Handled above as it requires a specific load order
  12421. continue;
  12422. case Entity_ProcGroup:
  12423. continue;
  12424. case Entity_TypeName:
  12425. case Entity_Procedure:
  12426. break;
  12427. }
  12428. bool polymorphic_struct = false;
  12429. if (e->type != nullptr && e->kind == Entity_TypeName) {
  12430. Type *bt = base_type(e->type);
  12431. if (bt->kind == Type_Struct) {
  12432. polymorphic_struct = is_type_polymorphic(bt);
  12433. }
  12434. }
  12435. if (!polymorphic_struct && !ptr_set_exists(min_dep_set, e)) {
  12436. // NOTE(bill): Nothing depends upon it so doesn't need to be built
  12437. continue;
  12438. }
  12439. lbModule *m = &gen->default_module;
  12440. if (USE_SEPARTE_MODULES) {
  12441. m = lb_pkg_module(gen, e->pkg);
  12442. }
  12443. String mangled_name = lb_get_entity_name(m, e);
  12444. switch (e->kind) {
  12445. case Entity_TypeName:
  12446. lb_type(m, e->type);
  12447. break;
  12448. case Entity_Procedure:
  12449. {
  12450. lbProcedure *p = lb_create_procedure(m, e);
  12451. array_add(&m->procedures_to_generate, p);
  12452. }
  12453. break;
  12454. }
  12455. }
  12456. TIME_SECTION("LLVM Runtime Type Information Creation");
  12457. lbProcedure *startup_type_info = lb_create_startup_type_info(default_module);
  12458. TIME_SECTION("LLVM Runtime Startup Creation (Global Variables)");
  12459. lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, global_variables);
  12460. TIME_SECTION("LLVM Procedure Generation");
  12461. for_array(j, gen->modules.entries) {
  12462. lbModule *m = gen->modules.entries[j].value;
  12463. for_array(i, m->procedures_to_generate) {
  12464. lbProcedure *p = m->procedures_to_generate[i];
  12465. if (p->is_done) {
  12466. continue;
  12467. }
  12468. if (p->body != nullptr) { // Build Procedure
  12469. m->curr_procedure = p;
  12470. lb_begin_procedure_body(p);
  12471. lb_build_stmt(p, p->body);
  12472. lb_end_procedure_body(p);
  12473. p->is_done = true;
  12474. m->curr_procedure = nullptr;
  12475. }
  12476. lb_end_procedure(p);
  12477. // Add Flags
  12478. if (p->body != nullptr) {
  12479. if (p->name == "memcpy" || p->name == "memmove" ||
  12480. p->name == "runtime.mem_copy" || p->name == "mem_copy_non_overlapping" ||
  12481. string_starts_with(p->name, str_lit("llvm.memcpy")) ||
  12482. string_starts_with(p->name, str_lit("llvm.memmove"))) {
  12483. p->flags |= lbProcedureFlag_WithoutMemcpyPass;
  12484. }
  12485. }
  12486. if (!m->debug_builder && LLVMVerifyFunction(p->value, LLVMReturnStatusAction)) {
  12487. gb_printf_err("LLVM CODE GEN FAILED FOR PROCEDURE: %.*s\n", LIT(p->name));
  12488. LLVMDumpValue(p->value);
  12489. gb_printf_err("\n\n\n\n");
  12490. String filepath_ll = lb_filepath_ll_for_module(m);
  12491. if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
  12492. gb_printf_err("LLVM Error: %s\n", llvm_error);
  12493. }
  12494. LLVMVerifyFunction(p->value, LLVMPrintMessageAction);
  12495. gb_exit(1);
  12496. }
  12497. }
  12498. }
  12499. if (!(build_context.build_mode == BuildMode_DynamicLibrary && !has_dll_main)) {
  12500. TIME_SECTION("LLVM main");
  12501. lb_create_main_procedure(default_module, startup_runtime);
  12502. }
  12503. if (build_context.ODIN_DEBUG) {
  12504. TIME_SECTION("LLVM Debug Info Complete Types and Finalize");
  12505. for_array(j, gen->modules.entries) {
  12506. lbModule *m = gen->modules.entries[j].value;
  12507. if (m->debug_builder != nullptr) {
  12508. lb_debug_complete_types(m);
  12509. LLVMDIBuilderFinalize(m->debug_builder);
  12510. }
  12511. }
  12512. }
  12513. TIME_SECTION("LLVM Function Pass");
  12514. for_array(i, gen->modules.entries) {
  12515. lbModule *m = gen->modules.entries[i].value;
  12516. lb_llvm_function_pass_worker_proc(m);
  12517. }
  12518. TIME_SECTION("LLVM Module Pass");
  12519. for_array(i, gen->modules.entries) {
  12520. lbModule *m = gen->modules.entries[i].value;
  12521. auto wd = gb_alloc_item(permanent_allocator(), lbLLVMModulePassWorkerData);
  12522. wd->m = m;
  12523. wd->target_machine = target_machines[i];
  12524. lb_llvm_module_pass_worker_proc(wd);
  12525. }
  12526. llvm_error = nullptr;
  12527. defer (LLVMDisposeMessage(llvm_error));
  12528. LLVMCodeGenFileType code_gen_file_type = LLVMObjectFile;
  12529. if (build_context.build_mode == BuildMode_Assembly) {
  12530. code_gen_file_type = LLVMAssemblyFile;
  12531. }
  12532. for_array(j, gen->modules.entries) {
  12533. lbModule *m = gen->modules.entries[j].value;
  12534. if (LLVMVerifyModule(m->mod, LLVMReturnStatusAction, &llvm_error)) {
  12535. gb_printf_err("LLVM Error:\n%s\n", llvm_error);
  12536. if (build_context.keep_temp_files) {
  12537. TIME_SECTION("LLVM Print Module to File");
  12538. String filepath_ll = lb_filepath_ll_for_module(m);
  12539. if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
  12540. gb_printf_err("LLVM Error: %s\n", llvm_error);
  12541. gb_exit(1);
  12542. return;
  12543. }
  12544. }
  12545. gb_exit(1);
  12546. return;
  12547. }
  12548. }
  12549. llvm_error = nullptr;
  12550. if (build_context.keep_temp_files ||
  12551. build_context.build_mode == BuildMode_LLVM_IR) {
  12552. TIME_SECTION("LLVM Print Module to File");
  12553. for_array(j, gen->modules.entries) {
  12554. lbModule *m = gen->modules.entries[j].value;
  12555. if (lb_is_module_empty(m)) {
  12556. continue;
  12557. }
  12558. String filepath_ll = lb_filepath_ll_for_module(m);
  12559. if (LLVMPrintModuleToFile(m->mod, cast(char const *)filepath_ll.text, &llvm_error)) {
  12560. gb_printf_err("LLVM Error: %s\n", llvm_error);
  12561. gb_exit(1);
  12562. return;
  12563. }
  12564. array_add(&gen->output_temp_paths, filepath_ll);
  12565. }
  12566. if (build_context.build_mode == BuildMode_LLVM_IR) {
  12567. gb_exit(0);
  12568. return;
  12569. }
  12570. }
  12571. TIME_SECTION("LLVM Add Foreign Library Paths");
  12572. for_array(j, gen->modules.entries) {
  12573. lbModule *m = gen->modules.entries[j].value;
  12574. for_array(i, m->info->required_foreign_imports_through_force) {
  12575. Entity *e = m->info->required_foreign_imports_through_force[i];
  12576. lb_add_foreign_library_path(m, e);
  12577. }
  12578. if (lb_is_module_empty(m)) {
  12579. continue;
  12580. }
  12581. }
  12582. TIME_SECTION("LLVM Object Generation");
  12583. if (do_threading) {
  12584. for_array(j, gen->modules.entries) {
  12585. lbModule *m = gen->modules.entries[j].value;
  12586. if (lb_is_module_empty(m)) {
  12587. continue;
  12588. }
  12589. String filepath_ll = lb_filepath_ll_for_module(m);
  12590. String filepath_obj = lb_filepath_obj_for_module(m);
  12591. array_add(&gen->output_object_paths, filepath_obj);
  12592. array_add(&gen->output_temp_paths, filepath_ll);
  12593. auto *wd = gb_alloc_item(heap_allocator(), lbLLVMEmitWorker);
  12594. wd->target_machine = target_machines[j];
  12595. wd->code_gen_file_type = code_gen_file_type;
  12596. wd->filepath_obj = filepath_obj;
  12597. wd->m = m;
  12598. thread_pool_add_task(&lb_thread_pool, lb_llvm_emit_worker_proc, wd);
  12599. }
  12600. thread_pool_start(&lb_thread_pool);
  12601. thread_pool_wait_to_process(&lb_thread_pool);
  12602. } else {
  12603. for_array(j, gen->modules.entries) {
  12604. lbModule *m = gen->modules.entries[j].value;
  12605. if (lb_is_module_empty(m)) {
  12606. continue;
  12607. }
  12608. String filepath_obj = lb_filepath_obj_for_module(m);
  12609. array_add(&gen->output_object_paths, filepath_obj);
  12610. String short_name = remove_directory_from_path(filepath_obj);
  12611. gbString section_name = gb_string_make(heap_allocator(), "LLVM Generate Object: ");
  12612. section_name = gb_string_append_length(section_name, short_name.text, short_name.len);
  12613. TIME_SECTION_WITH_LEN(section_name, gb_string_length(section_name));
  12614. if (LLVMTargetMachineEmitToFile(target_machines[j], m->mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error)) {
  12615. gb_printf_err("LLVM Error: %s\n", llvm_error);
  12616. gb_exit(1);
  12617. return;
  12618. }
  12619. }
  12620. }
  12621. #undef TIME_SECTION
  12622. }