12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353 |
- #include "BfIRCodeGen.h"
- #include "BfModule.h"
- #include "BeefySysLib/util/BeefPerf.h"
- #include "BeefySysLib/util/Hash.h"
- #ifdef BF_PLATFORM_WINDOWS
- #include <io.h>
- #endif
- #pragma warning(push)
- #pragma warning(disable:4141)
- #pragma warning(disable:4146)
- #pragma warning(disable:4291)
- #pragma warning(disable:4244)
- #pragma warning(disable:4267)
- #pragma warning(disable:4624)
- #pragma warning(disable:4800)
- #pragma warning(disable:4996)
- #include "llvm/IR/Module.h"
- #include "llvm/IR/Constants.h"
- #include "llvm/IR/GlobalValue.h"
- #include "llvm/IR/GlobalVariable.h"
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/IR/InlineAsm.h"
- #include "llvm/IR/Attributes.h"
- #include "llvm/Support/FileSystem.h"
- #include "llvm/TargetParser/Host.h"
- //#include "llvm/Support/Dwarf.h"
- #include "llvm/IR/DIBuilder.h"
- //#include "llvm/ADT/Triple.h"
- //#include "llvm/CodeGen/CommandFlags.h"
- #include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
- #include "llvm/CodeGen/LinkAllCodegenComponents.h"
- #include "llvm/IR/DataLayout.h"
- #include "llvm/IR/IRPrintingPasses.h"
- #include "llvm/IR/LLVMContext.h"
- #include "llvm/IR/Module.h"
- #include "llvm/IRReader/IRReader.h"
- //#include "llvm/MC/SubtargetFeature.h"
- #include "llvm/MC/MCObjectWriter.h"
- #include "llvm/Pass.h"
- //#include "llvm/Transforms/IPO/PassManagerBuilder.h"
- #include "llvm/Transforms/Utils.h"
- #include "llvm/Transforms/Scalar/InstSimplifyPass.h"
- #include "llvm/IR/LegacyPassManager.h"
- #include "llvm/Support/CommandLine.h"
- #include "llvm/Support/Debug.h"
- #include "llvm/Support/FileSystem.h"
- #include "llvm/Support/FormattedStream.h"
- //#include "llvm/Support/Host.h"
- #include "llvm/Support/ManagedStatic.h"
- #include "llvm/Support/CodeGen.h"
- #include "llvm/Support/PluginLoader.h"
- #include "llvm/Support/PrettyStackTrace.h"
- #include "llvm/Support/Signals.h"
- #include "llvm/Support/SourceMgr.h"
- //#include "llvm/Support/TargetRegistry.h"
- #include "llvm/Support/TargetSelect.h"
- #include "llvm/Support/ToolOutputFile.h"
- //#include "llvm/Target/TargetLibraryInfo.h"
- #include "llvm/Target/TargetMachine.h"
- //#include "llvm/Target/TargetSubtargetInfo.h"
- //#include "llvm/Transforms/IPO/PassManagerBuilder.h"
- //#include "llvm-c/Transforms/PassManagerBuilder.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/Analysis/Passes.h"
- #include "llvm/IR/DataLayout.h"
- #include "llvm/IR/Verifier.h"
- #include "llvm/IR/LegacyPassManager.h"
- #include "llvm/IR/PassManager.h"
- #include "llvm/Support/CommandLine.h"
- #include "llvm/Support/ManagedStatic.h"
- #include "llvm/Analysis/BasicAliasAnalysis.h"
- //#include "llvm/Analysis/CFLAliasAnalysis.h"
- //#include "llvm/Analysis/CFLAndersAliasAnalysis.h"
- //#include "llvm/Analysis/CFLSteensAliasAnalysis.h"
- #include "llvm/Analysis/GlobalsModRef.h"
- #include "llvm/Analysis/ScopedNoAliasAA.h"
- #include "llvm/Analysis/TargetLibraryInfo.h"
- #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
- #include "llvm/Target/TargetMachine.h"
- #include "llvm/Transforms/IPO.h"
- #include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
- #include "llvm/Transforms/IPO/FunctionAttrs.h"
- #include "llvm/Transforms/IPO/InferFunctionAttrs.h"
- #include "llvm/Transforms/IPO/AlwaysInliner.h"
- #include "llvm/Transforms/Instrumentation.h"
- #include "llvm/Transforms/Scalar.h"
- #include "llvm/Transforms/Scalar/GVN.h"
- //#include "llvm/Transforms/Vectorize.h"
- #include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"
- #include "llvm/Transforms/InstCombine/InstCombine.h"
- #include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
- #include "llvm/Passes/PassBuilder.h"
- //#include "llvm/Bitcode/ReaderWriter.h"
- #include "llvm/Analysis/Passes.h"
- #include "llvm/Transforms/IPO.h"
- #include "llvm/Transforms/Scalar.h"
- //#include "llvm/Transforms/Vectorize.h"
- #include "llvm/Pass.h"
- #include "llvm/CodeGen/MachineFunctionPass.h"
- #include "llvm/Support/raw_ostream.h"
- #include "llvm/MC/MCAsmBackend.h"
- #include "llvm/MC/MCCodeEmitter.h"
- #include "llvm/MC/TargetRegistry.h"
- #include "llvm/LTO/LTOBackend.h"
- #include "llvm/Bitcode/BitcodeWriter.h"
- #include "llvm/Bitcode/BitcodeReader.h"
- #include "llvm/Bitcode/BitcodeWriterPass.h"
- #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
- #include "llvm/Transforms/IPO/AlwaysInliner.h"
- #include "llvm/Transforms/IPO.h"
- #include "../LLVMUtils.h"
- #pragma warning(pop)
- void pm(llvm::Module* module);
- USING_NS_BF;
- #pragma warning(disable:4146)
- #pragma warning(disable:4996)
- struct BuiltinEntry
- {
- const char* mName;
- bool operator<(const StringImpl& rhs) const
- {
- return strcmp(mName, rhs.c_str()) < 0;
- }
- };
- static const BuiltinEntry gIntrinEntries[] =
- {
- {":PLATFORM"},
- {"abs"},
- {"add"},
- {"and"},
- {"atomic_add"},
- {"atomic_and"},
- {"atomic_cmpstore"},
- {"atomic_cmpstore_weak"},
- {"atomic_cmpxchg"},
- {"atomic_fence"},
- {"atomic_load"},
- {"atomic_max"},
- {"atomic_min"},
- {"atomic_nand"},
- {"atomic_or"},
- {"atomic_store"},
- {"atomic_sub"},
- {"atomic_umax"},
- {"atomic_umin"},
- {"atomic_xchg"},
- {"atomic_xor"},
- {"bswap"},
- {"cast"},
- {"cos"},
- {"cpuid"},
- {"debugtrap"},
- {"div"},
- {"eq"},
- {"floor"},
- {"free"},
- {"gt"},
- {"gte"},
- ("index"),
- {"log"},
- {"log10"},
- {"log2"},
- {"lt"},
- {"lte"},
- {"malloc"},
- {"max"},
- {"memcpy"},
- {"memmove"},
- {"memset"},
- {"min"},
- {"mod"},
- {"mul"},
- {"neq"},
- {"not"},
- {"or"},
- {"pow"},
- {"powi"},
- {"returnaddress"},
- {"round"},
- {"sar"},
- {"shl"},
- {"shr"},
- {"shuffle"},
- {"sin"},
- {"sqrt"},
- {"sub"},
- {"va_arg"},
- {"va_end"},
- {"va_start"},
- {"xgetbv"},
- {"xor"},
- };
- #define CMD_PARAM(ty, name) ty name; Read(name);
- #define CMD_PARAM_NOTRANS(ty, name) ty name; Read(name, NULL, BfIRSizeAlignKind_NoTransform);
- BF_STATIC_ASSERT(BF_ARRAY_COUNT(gIntrinEntries) == BfIRIntrinsic_COUNT);
- template <typename T>
- class CmdParamVec : public llvm::SmallVector<T, 8>
- {};
- static int GetLLVMCallingConv(BfIRCallingConv callingConv, BfTargetTriple& targetTriple)
- {
- int llvmCallingConv = llvm::CallingConv::C;
- if (targetTriple.GetMachineType() == BfMachineType_AArch64)
- {
- if (callingConv == BfIRCallingConv_CDecl)
- llvmCallingConv = llvm::CallingConv::C;
- else
- llvmCallingConv = llvm::CallingConv::PreserveMost;
- }
- else
- {
- if (callingConv == BfIRCallingConv_ThisCall)
- llvmCallingConv = llvm::CallingConv::X86_ThisCall;
- else if (callingConv == BfIRCallingConv_StdCall)
- llvmCallingConv = llvm::CallingConv::X86_StdCall;
- else if (callingConv == BfIRCallingConv_FastCall)
- llvmCallingConv = llvm::CallingConv::X86_FastCall;
- else if (callingConv == BfIRCallingConv_CDecl)
- llvmCallingConv = llvm::CallingConv::C;
- }
- return llvmCallingConv;
- }
- static llvm::GlobalValue::LinkageTypes LLVMMapLinkageType(BfIRLinkageType linkageType)
- {
- llvm::GlobalValue::LinkageTypes llvmLinkageType;
- if (linkageType == BfIRLinkageType_Internal)
- llvmLinkageType = llvm::GlobalValue::InternalLinkage;
- else
- llvmLinkageType = llvm::GlobalValue::ExternalLinkage;
- return llvmLinkageType;
- }
- static llvm::Attribute::AttrKind LLVMMapAttribute(BfIRAttribute attr)
- {
- switch (attr)
- {
- case BfIRAttribute_NoReturn: return llvm::Attribute::NoReturn;
- case BfIRAttribute_NoAlias: return llvm::Attribute::NoAlias;
- case BfIRAttribute_NoCapture: return llvm::Attribute::NoCapture;
- case BfIRAttribute_StructRet: return llvm::Attribute::StructRet;
- case BfIRAttribute_ZExt: return llvm::Attribute::ZExt;
- case BFIRAttribute_NoUnwind: return llvm::Attribute::NoUnwind;
- case BFIRAttribute_UWTable: return llvm::Attribute::UWTable;
- case BFIRAttribute_AlwaysInline: return llvm::Attribute::AlwaysInline;
- case BFIRAttribute_NoRecurse: return llvm::Attribute::NoRecurse;
- default: break;
- }
- return llvm::Attribute::None;
- }
- #ifdef BF_PLATFORM_WINDOWS
- struct BfTempFile
- {
- String mContents;
- String mFilePath;
- CritSect mCritSect;
- FILE* mFP;
- BfTempFile()
- {
- mFP = NULL;
- }
- ~BfTempFile()
- {
- if (mFP != NULL)
- fclose(mFP);
- if (!mFilePath.IsEmpty())
- ::DeleteFileW(UTF8Decode(mFilePath).c_str());
- }
- bool Create()
- {
- AutoCrit autoCrit(mCritSect);
- if (mFP != NULL)
- return false;
- WCHAR wPath[4096];
- wPath[0] = 0;
- ::GetTempPathW(4096, wPath);
- WCHAR wFilePath[4096];
- wFilePath[0] = 0;
- GetTempFileNameW(wPath, L"bftmp", 0, wFilePath);
- mFilePath = UTF8Encode(wFilePath);
- mFP = _wfopen(wFilePath, L"w+D");
- return mFP != NULL;
- }
- String GetContents()
- {
- AutoCrit autoCrit(mCritSect);
- if (mFP != NULL)
- {
- fseek(mFP, 0, SEEK_END);
- int size = (int)ftell(mFP);
- fseek(mFP, 0, SEEK_SET);
- char* str = new char[size];
- int readSize = (int)fread(str, 1, size, mFP);
- mContents.Append(str, readSize);
- delete [] str;
- fclose(mFP);
- mFP = NULL;
- ::DeleteFileW(UTF8Decode(mFilePath).c_str());
- }
- return mContents;
- }
- };
- static BfTempFile gTempFile;
- static void AddStdErrCrashInfo()
- {
- String tempContents = gTempFile.GetContents();
- if (!tempContents.IsEmpty())
- BfpSystem_AddCrashInfo(tempContents.c_str());
- }
- #endif
- ///
- BfIRCodeGen::BfIRCodeGen()
- {
- mStream = NULL;
- mBfIRBuilder = NULL;
- mLLVMTargetMachine = NULL;
- mNopInlineAsm = NULL;
- mObjectCheckAsm = NULL;
- mOverflowCheckAsm = NULL;
- mHasDebugLoc = false;
- mAttrSet = NULL;
- mIRBuilder = NULL;
- mDIBuilder = NULL;
- mDICompileUnit = NULL;
- mActiveFunction = NULL;
- mActiveFunctionType = NULL;
- mLLVMContext = new llvm::LLVMContext();
- mLLVMModule = NULL;
- mIsCodeView = false;
- mHadDLLExport = false;
- mConstValIdx = 0;
- mCmdCount = 0;
- mCurLine = -1;
- #ifdef BF_PLATFORM_WINDOWS
- if (::GetStdHandle(STD_ERROR_HANDLE) == 0)
- {
- if (gTempFile.Create())
- {
- _dup2(fileno(gTempFile.mFP), 2);
- BfpSystem_AddCrashInfoFunc(AddStdErrCrashInfo);
- }
- }
- #endif
- }
- BfIRCodeGen::~BfIRCodeGen()
- {
- mDebugLoc = llvm::DebugLoc();
- mSavedDebugLocs.Clear();
-
- for (auto typeEx : mIRTypeExs)
- delete typeEx;
- for (auto kv : mTypeCodeTypeExMap)
- delete kv.mValue;
- delete mStream;
- delete mIRBuilder;
- delete mDIBuilder;
- delete mLLVMTargetMachine;
- delete mLLVMModule;
- delete mLLVMContext;
- }
- void BfIRCodeGen::FatalError(const StringImpl &err)
- {
- String failStr = "Fatal Error in Module: ";
- failStr += mModuleName;
- failStr += "\n";
- if (mLLVMModule != NULL)
- {
- if (mActiveFunction != NULL)
- {
- failStr += "Function: ";
- failStr += mActiveFunction->getName().str();
- failStr += "\n";
- }
- auto loc = mIRBuilder->getCurrentDebugLocation();
- auto dbgLoc = loc.getAsMDNode();
- if (dbgLoc != NULL)
- {
- std::string str;
- llvm::raw_string_ostream os(str);
- dbgLoc->print(os);
- failStr += "DbgLoc: ";
- failStr += str;
- failStr += "\n";
- llvm::MDNode* scope = loc.getScope();
- if (scope != NULL)
- {
- std::string str;
- llvm::raw_string_ostream os(str);
- scope->print(os);
- failStr += "Scope: ";
- failStr += str;
- failStr += "\n";
- }
- }
- }
- failStr += err;
- BF_FATAL(failStr);
- }
- void BfIRCodeGen::Fail(const StringImpl& error)
- {
- if (mFailed)
- return;
- if (mHasDebugLoc)
- {
- auto dbgLoc = mIRBuilder->getCurrentDebugLocation();
- if (dbgLoc)
- {
- llvm::DIFile* file = NULL;
- if (llvm::DIScope* scope = llvm::dyn_cast<llvm::DIScope>(dbgLoc.getScope()))
- {
- BfIRCodeGenBase::Fail(StrFormat("%s at line %d:%d in %s/%s", error.c_str(), dbgLoc.getLine(), dbgLoc.getCol(), scope->getDirectory().data(), scope->getFilename().data()));
- return;
- }
- }
- }
- BfIRCodeGenBase::Fail(error);
- }
- void BfIRCodeGen::PrintModule()
- {
- Beefy::debug_ostream os;
- mLLVMModule->print(os, NULL, false, true);
- os << "\n";
- os.flush();
- }
- void BfIRCodeGen::PrintFunction()
- {
- Beefy::debug_ostream os;
- mActiveFunction->print(os);
- os << "\n";
- os.flush();
- }
- void pte(BfIRTypeEx* typeEx, int indent)
- {
- Beefy::debug_ostream os;
- typeEx->mLLVMType->print(os);
- os << "\n";
- os.flush();
- for (int i = 0; i < typeEx->mMembers.mSize; i++)
- {
- for (int i = 0; i < indent; i++)
- os << " ";
- os << i << ". ";
- os.flush();
- pte(typeEx->mMembers[i], indent + 1);
- }
- }
- void pte(BfIRTypeEx* typeEx)
- {
- if (typeEx == NULL)
- return;
- pte(typeEx, 0);
- }
- void pve(const BfIRTypedValue& typedValue)
- {
- Beefy::debug_ostream os;
- os << "Value: ";
- typedValue.mValue->print(os);
- os << "\nType: ";
- os.flush();
- pte(typedValue.mTypeEx);
- }
- void pirb(llvm::IRBuilder<>* irBuilder)
- {
- Beefy::debug_ostream os;
- os << "Debug loc: ";
- auto debugLoc = irBuilder->getCurrentDebugLocation();
- if (debugLoc.get() == NULL)
- os << "NULL";
- else
- debugLoc->print(os);
- os << "\n";
- os.flush();
- }
- void BfIRCodeGen::FixValues(llvm::StructType* structType, llvm::SmallVector<llvm::Value*, 8>& values)
- {
- if (values.size() >= structType->getNumElements())
- return;
- int readIdx = (int)values.size() - 1;
- values.resize(structType->getNumElements());
- for (int i = (int)values.size() - 1; i >= 0; i--)
- {
- if (values[readIdx]->getType() == structType->getElementType(i))
- {
- values[i] = values[readIdx];
- readIdx--;
- }
- else if (structType->getElementType(i)->isArrayTy())
- {
- values[i] = llvm::ConstantAggregateZero::get(structType->getElementType(i));
- }
- else
- {
- BF_FATAL("Malformed structure values");
- }
- }
- }
- void BfIRCodeGen::FixIndexer(llvm::Value*& val)
- {
- if ((int)val->getType()->getScalarSizeInBits() > mPtrSize * 8)
- val = mIRBuilder->CreateIntCast(val, llvm::Type::getInt32Ty(*mLLVMContext), false);
- }
- BfTypeCode BfIRCodeGen::GetTypeCode(llvm::Type* type, bool isSigned)
- {
- if (type->isIntegerTy())
- {
- switch (type->getIntegerBitWidth())
- {
- case 1:
- return BfTypeCode_Boolean;
- case 8:
- return isSigned ? BfTypeCode_Int8 : BfTypeCode_UInt8;
- case 16:
- return isSigned ? BfTypeCode_Int16 : BfTypeCode_UInt16;
- case 32:
- return isSigned ? BfTypeCode_Int32 : BfTypeCode_UInt32;
- case 64:
- return isSigned ? BfTypeCode_Int64 : BfTypeCode_UInt64;
- }
- }
- if (type->isFloatingPointTy())
- return BfTypeCode_Float;
- if (type->isDoubleTy())
- return BfTypeCode_Double;
- return BfTypeCode_None;
- }
- llvm::Type* BfIRCodeGen::GetLLVMType(BfTypeCode typeCode, bool& isSigned)
- {
- if ((typeCode == BfTypeCode_IntPtr) || (typeCode == BfTypeCode_UIntPtr))
- {
- /*isSigned = typeCode == BfTypeCode_IntPtr;
- if (mModule->mSystem->mPtrSize == 4)
- return llvm::Type::getInt32Ty(*mLLVMContext);
- else
- return llvm::Type::getInt64Ty(*mLLVMContext);*/
- BF_FATAL("Unsupported");
- }
- isSigned = false;
- switch (typeCode)
- {
- case BfTypeCode_None:
- return llvm::Type::getVoidTy(*mLLVMContext);
- case BfTypeCode_NullPtr:
- return llvm::PointerType::get(*mLLVMContext, 0);
- case BfTypeCode_Boolean:
- return llvm::Type::getInt1Ty(*mLLVMContext);
- case BfTypeCode_Int8:
- isSigned = true;
- return llvm::Type::getInt8Ty(*mLLVMContext);
- case BfTypeCode_UInt8:
- case BfTypeCode_Char8:
- return llvm::Type::getInt8Ty(*mLLVMContext);
- case BfTypeCode_Int16:
- isSigned = true;
- return llvm::Type::getInt16Ty(*mLLVMContext);
- case BfTypeCode_UInt16:
- case BfTypeCode_Char16:
- return llvm::Type::getInt16Ty(*mLLVMContext);
- case BfTypeCode_Int24:
- isSigned = true;
- return llvm::Type::getIntNTy(*mLLVMContext, 24);
- case BfTypeCode_UInt24:
- return llvm::Type::getIntNTy(*mLLVMContext, 24);
- case BfTypeCode_Int32:
- isSigned = true;
- return llvm::Type::getInt32Ty(*mLLVMContext);
- case BfTypeCode_UInt32:
- case BfTypeCode_Char32:
- return llvm::Type::getInt32Ty(*mLLVMContext);
- case BfTypeCode_Int40:
- isSigned = true;
- return llvm::Type::getIntNTy(*mLLVMContext, 40);
- case BfTypeCode_UInt40:
- return llvm::Type::getIntNTy(*mLLVMContext, 40);
- case BfTypeCode_Int48:
- isSigned = true;
- return llvm::Type::getIntNTy(*mLLVMContext, 48);
- case BfTypeCode_UInt48:
- return llvm::Type::getIntNTy(*mLLVMContext, 48);
- case BfTypeCode_Int56:
- isSigned = true;
- return llvm::Type::getIntNTy(*mLLVMContext, 56);
- case BfTypeCode_UInt56:
- return llvm::Type::getIntNTy(*mLLVMContext, 56);
- case BfTypeCode_Int64:
- isSigned = true;
- return llvm::Type::getInt64Ty(*mLLVMContext);
- case BfTypeCode_UInt64:
- return llvm::Type::getInt64Ty(*mLLVMContext);
- case BfTypeCode_Int128:
- isSigned = true;
- return llvm::Type::getInt128Ty(*mLLVMContext);
- case BfTypeCode_UInt128:
- return llvm::Type::getInt128Ty(*mLLVMContext);
- case BfTypeCode_IntPtr:
- BF_FATAL("Illegal");
- /*isSigned = true;
- if (mModule->mSystem->mPtrSize == 4)
- return llvm::Type::getInt32Ty(*mLLVMContext);
- else
- return llvm::Type::getInt64Ty(*mLLVMContext);*/
- case BfTypeCode_UIntPtr:
- BF_FATAL("Illegal");
- /*if (mModule->mSystem->mPtrSize == 4)
- return llvm::Type::getInt32Ty(*mLLVMContext);
- else
- return llvm::Type::getInt64Ty(*mLLVMContext);*/
- case BfTypeCode_Float:
- return llvm::Type::getFloatTy(*mLLVMContext);
- case BfTypeCode_Double:
- return llvm::Type::getDoubleTy(*mLLVMContext);
- case BfTypeCode_Float2:
- return llvm::FixedVectorType::get(llvm::Type::getFloatTy(*mLLVMContext), 2);
- case BfTypeCode_FloatX2:
- return llvm::ArrayType::get(llvm::Type::getFloatTy(*mLLVMContext), 2);
- case BfTypeCode_FloatX3:
- return llvm::ArrayType::get(llvm::Type::getFloatTy(*mLLVMContext), 3);
- case BfTypeCode_FloatX4:
- return llvm::ArrayType::get(llvm::Type::getFloatTy(*mLLVMContext), 4);
- case BfTypeCode_DoubleX2:
- return llvm::ArrayType::get(llvm::Type::getDoubleTy(*mLLVMContext), 2);
- case BfTypeCode_DoubleX3:
- return llvm::ArrayType::get(llvm::Type::getDoubleTy(*mLLVMContext), 3);
- case BfTypeCode_DoubleX4:
- return llvm::ArrayType::get(llvm::Type::getDoubleTy(*mLLVMContext), 4);
- case BfTypeCode_Int64X2:
- return llvm::ArrayType::get(llvm::Type::getInt64Ty(*mLLVMContext), 2);
- case BfTypeCode_Int64X3:
- return llvm::ArrayType::get(llvm::Type::getInt64Ty(*mLLVMContext), 3);
- case BfTypeCode_Int64X4:
- return llvm::ArrayType::get(llvm::Type::getInt64Ty(*mLLVMContext), 4);
- default: break;
- }
- return NULL;
- }
- BfIRTypeEx* BfIRCodeGen::GetTypeEx(BfTypeCode typeCode, bool& isSigned)
- {
- BfIRTypeEx** valuePtr = NULL;
- if (mTypeCodeTypeExMap.TryAdd(typeCode, NULL, &valuePtr))
- {
- BfIRTypeEx* typeEx = new BfIRTypeEx();
- typeEx->mLLVMType = GetLLVMType(typeCode, isSigned);
- if (typeEx->mLLVMType->isPointerTy())
- {
- // Make void* actually be an i8*
- typeEx->mMembers.Add(GetTypeEx(llvm::Type::getInt8Ty(*mLLVMContext)));
- }
- if (auto arrType = llvm::dyn_cast<llvm::ArrayType>(typeEx->mLLVMType))
- {
- typeEx->mMembers.Add(GetTypeEx(arrType->getElementType()));
- }
- if (auto vectorType = llvm::dyn_cast<llvm::VectorType>(typeEx->mLLVMType))
- {
- typeEx->mMembers.Add(GetTypeEx(vectorType->getElementType()));
- }
- *valuePtr = typeEx;
- }
- else
- {
- isSigned = false;
- switch (typeCode)
- {
- case BfTypeCode_Int8:
- case BfTypeCode_Int16:
- case BfTypeCode_Int24:
- case BfTypeCode_Int32:
- case BfTypeCode_Int40:
- case BfTypeCode_Int48:
- case BfTypeCode_Int56:
- case BfTypeCode_Int64:
- case BfTypeCode_Int128:
- isSigned = true;
- }
- }
- return *valuePtr;
- }
- BfIRTypeEx* BfIRCodeGen::GetTypeEx(llvm::Type* llvmType)
- {
- BfIRTypeEx** valuePtr = NULL;
- if (mLLVMTypeExMap.TryAdd(llvmType, NULL, &valuePtr))
- {
- BfIRTypeEx* typeEx = new BfIRTypeEx();
- mIRTypeExs.Add(typeEx);
- typeEx->mLLVMType = llvmType;
- *valuePtr = typeEx;
- }
- return *valuePtr;
- }
- BfIRTypeEx* BfIRCodeGen::CreateTypeEx(llvm::Type* llvmType)
- {
- BfIRTypeEx* typeEx = new BfIRTypeEx();
- mIRTypeExs.Add(typeEx);
- typeEx->mLLVMType = llvmType;
- return typeEx;
- }
- BfIRTypeEx* BfIRCodeGen::GetPointerTypeEx(BfIRTypeEx* elementType)
- {
- BF_ASSERT(elementType != NULL);
- BfIRTypeEx** valuePtr = NULL;
- if (mPointerTypeExMap.TryAdd(elementType, NULL, &valuePtr))
- {
- BfIRTypeEx* typeEx = new BfIRTypeEx();
- mIRTypeExs.Add(typeEx);
- typeEx->mLLVMType = llvm::PointerType::get(*mLLVMContext, 0);
- typeEx->mMembers.Add(elementType);
- *valuePtr = typeEx;
- }
- return *valuePtr;
- }
- BfIRTypeEx* BfIRCodeGen::GetTypeMember(BfIRTypeEx* typeEx, int idx)
- {
- if ((idx < 0) || (idx >= typeEx->mMembers.mSize))
- {
- Fail("BfIRTypeEx GetTypeMember OOB");
- bool isSigned;
- return GetTypeEx(BfTypeCode_Int8, isSigned);
- }
- return typeEx->mMembers[idx];
- }
- BfIRTypeEntry& BfIRCodeGen::GetTypeEntry(int typeId)
- {
- BfIRTypeEntry& typeEntry = mTypes[typeId];
- if (typeEntry.mTypeId == -1)
- typeEntry.mTypeId = typeId;
- return typeEntry;
- }
- BfIRTypeEntry* BfIRCodeGen::GetTypeEntry(BfIRTypeEx* type)
- {
- int typeId = 0;
- if (!mTypeToTypeIdMap.TryGetValue(type, &typeId))
- return NULL;
- return &GetTypeEntry(typeId);
- }
- void BfIRCodeGen::SetResult(int id, llvm::Value* value)
- {
- BF_ASSERT(!value->getType()->isAggregateType());
- BF_ASSERT(!value->getType()->isPointerTy());
- BfIRCodeGenEntry entry;
- entry.mKind = BfIRCodeGenEntryKind_LLVMValue;
- entry.mLLVMValue = value;
- mResults.TryAdd(id, entry);
- }
- void BfIRCodeGen::SetResult(int id, const BfIRTypedValue& value)
- {
- BfIRCodeGenEntry entry;
- entry.mKind = BfIRCodeGenEntryKind_TypedValue;
- entry.mTypedValue = value;
- mResults.TryAdd(id, entry);
- }
- void BfIRCodeGen::SetResultAligned(int id, llvm::Value* value)
- {
- BfIRCodeGenEntry entry;
- entry.mKind = BfIRCodeGenEntryKind_LLVMValue_Aligned;
- entry.mLLVMValue = value;
- mResults.TryAdd(id, entry);
- }
- void BfIRCodeGen::SetResultAligned(int id, const BfIRTypedValue& value)
- {
- BfIRCodeGenEntry entry;
- entry.mKind = BfIRCodeGenEntryKind_TypedValue_Aligned;
- entry.mTypedValue = value;
- mResults.TryAdd(id, entry);
- }
- void BfIRCodeGen::SetResult(int id, llvm::Type* type)
- {
- BfIRCodeGenEntry entry;
- entry.mKind = BfIRCodeGenEntryKind_LLVMType;
- entry.mLLVMType = type;
- mResults.TryAdd(id, entry);
- }
- void BfIRCodeGen::SetResult(int id, BfIRTypeEx* typeEx)
- {
- BfIRCodeGenEntry entry;
- entry.mKind = BfIRCodeGenEntryKind_TypeEx;
- entry.mTypeEx = typeEx;
- mResults.TryAdd(id, entry);
- }
- void BfIRCodeGen::SetResult(int id, llvm::BasicBlock* value)
- {
- BfIRCodeGenEntry entry;
- entry.mKind = BfIRCodeGenEntryKind_LLVMBasicBlock;
- entry.mLLVMBlock = value;
- mResults.TryAdd(id, entry);
- }
- void BfIRCodeGen::SetResult(int id, llvm::MDNode* md)
- {
- BfIRCodeGenEntry entry;
- entry.mKind = BfIRCodeGenEntryKind_LLVMMetadata;
- entry.mLLVMMetadata = md;
- mResults.TryAdd(id, entry);
- }
- void BfIRCodeGen::ProcessBfIRData(const BfSizedArray<uint8>& buffer)
- {
- // Diagnostic handlers were unified in LLVM change 5de2d189e6ad, so starting
- // with LLVM 13 this function is gone.
- /*struct InlineAsmErrorHook
- {
- static void StaticHandler(const llvm::SMDiagnostic& diag, void *context, unsigned locCookie)
- {
- if (diag.getKind() == llvm::SourceMgr::DK_Error)
- {
- BfIRCodeGen* irCodeGen = (BfIRCodeGen*)context;
- if (!irCodeGen->mErrorMsg.empty())
- irCodeGen->mErrorMsg += "\n";
- irCodeGen->mErrorMsg += StrFormat("Inline assembly error: \"%s\" : %s", diag.getMessage().data(), diag.getLineContents().data());
- }
- }
- };
- mLLVMContext->setInlineAsmDiagnosticHandler(InlineAsmErrorHook::StaticHandler, this);*/
- BF_ASSERT(mStream == NULL);
- mStream = new ChunkedDataBuffer();
- mStream->InitFlatRef(buffer.mVals, buffer.mSize);
- while (mStream->GetReadPos() < buffer.mSize)
- {
- if (mFailed)
- break;
- HandleNextCmd();
- }
- BF_ASSERT((mFailed) || (mStream->GetReadPos() == buffer.mSize));
- }
- int64 BfIRCodeGen::ReadSLEB128()
- {
- int64 val = 0;
- int64 shift = 0;
- uint8 byteVal;
- do
- {
- byteVal = mStream->Read();
- val |= ((int64)(byteVal & 0x7f)) << shift;
- shift += 7;
- } while (byteVal >= 128);
- // Sign extend negative numbers.
- if ((byteVal & 0x40) && (shift < 64))
- val |= (-1ULL) << shift;
- return val;
- }
- void BfIRCodeGen::Read(StringImpl& str)
- {
- int len = (int)ReadSLEB128();
- str.Append('?', len);
- mStream->Read((void*)str.c_str(), len);
- }
- void BfIRCodeGen::Read(int& i)
- {
- i = (int)ReadSLEB128();
- }
- void BfIRCodeGen::Read(int64& i)
- {
- i = ReadSLEB128();
- }
- void BfIRCodeGen::Read(Val128& i)
- {
- i.mLow = (uint64)ReadSLEB128();
- i.mHigh = (uint64)ReadSLEB128();
- }
- void BfIRCodeGen::Read(bool& val)
- {
- val = mStream->Read() != 0;
- }
- void BfIRCodeGen::Read(int8& val)
- {
- val = mStream->Read();
- }
- void BfIRCodeGen::Read(BfIRTypeEntry*& type)
- {
- int typeId = (int)ReadSLEB128();
- type = &GetTypeEntry(typeId);
- }
- void BfIRCodeGen::Read(BfIRTypeEx*& typeEx, BfIRTypeEntry** outTypeEntry)
- {
- typeEx = NULL;
- BfIRType::TypeKind typeKind = (BfIRType::TypeKind)mStream->Read();
- if (typeKind == BfIRType::TypeKind::TypeKind_None)
- return;
- if (typeKind == BfIRType::TypeKind::TypeKind_Stream)
- {
- int streamId = (int)ReadSLEB128();
- if (streamId == -1)
- {
- typeEx = NULL;
- return;
- }
- auto& result = mResults[streamId];
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_TypeEx);
- typeEx = result.mTypeEx;
- return;
- }
- if (typeKind == BfIRType::TypeKind::TypeKind_SizedArray)
- {
- CMD_PARAM(BfIRTypeEx*, elementType);
- CMD_PARAM(int, length);
- typeEx = new BfIRTypeEx();
- typeEx->mLLVMType = llvm::ArrayType::get(elementType->mLLVMType, length);
- BF_ASSERT(elementType != NULL);
- typeEx->mMembers.Add(elementType);
- mIRTypeExs.Add(typeEx);
- return;
- }
- int typeId = (int)ReadSLEB128();
- if (typeKind == BfIRType::TypeKind::TypeKind_TypeCode)
- {
- bool isSigned = false;
- typeEx = GetTypeEx((BfTypeCode)typeId, isSigned);
- return;
- }
- auto& typeEntry = GetTypeEntry(typeId);
- if (typeKind == BfIRType::TypeKind::TypeKind_TypeId)
- typeEx = typeEntry.mType;
- else if (typeKind == BfIRType::TypeKind::TypeKind_TypeInstId)
- typeEx = typeEntry.mInstType;
- else if (typeKind == BfIRType::TypeKind::TypeKind_TypeInstPtrId)
- typeEx = GetPointerTypeEx(typeEntry.mInstType);
- if (outTypeEntry != NULL)
- *outTypeEntry = &typeEntry;
- }
- void BfIRCodeGen::Read(llvm::Type*& llvmType, BfIRTypeEntry** outTypeEntry)
- {
- BfIRTypeEx* typeEx = NULL;
- Read(typeEx, outTypeEntry);
- if (typeEx != NULL)
- {
- llvmType = typeEx->mLLVMType;
- }
- else
- llvmType = NULL;
- }
- void BfIRCodeGen::Read(llvm::FunctionType*& llvmType)
- {
- int streamId = (int)ReadSLEB128();
- auto& result = mResults[streamId];
- if (result.mKind == BfIRCodeGenEntryKind_TypeEx)
- {
- llvmType = (llvm::FunctionType*)result.mTypeEx->mLLVMType;
- return;
- }
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMType);
- llvmType = (llvm::FunctionType*)result.mLLVMType;
- }
- void BfIRCodeGen::ReadFunctionType(BfIRTypeEx*& typeEx)
- {
- int streamId = (int)ReadSLEB128();
- auto& result = mResults[streamId];
- if (result.mKind == BfIRCodeGenEntryKind_TypeEx)
- {
- typeEx = result.mTypeEx;
- return;
- }
- BF_FATAL("Invalid path in ReadFunctionType");
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMType);
- typeEx = GetTypeEx(result.mLLVMType);
- }
- void BfIRCodeGen::FixTypedValue(BfIRTypedValue& typedValue)
- {
- if ((typedValue.mValue != NULL) && (typedValue.mTypeEx == NULL))
- {
- typedValue.mTypeEx = GetTypeEx(typedValue.mValue->getType());
- BF_ASSERT(!typedValue.mValue->getType()->isStructTy());
- BF_ASSERT(!typedValue.mValue->getType()->isFunctionTy());
- }
- }
- void BfIRCodeGen::Read(BfIRTypedValue& typedValue, BfIRCodeGenEntry** codeGenEntry, BfIRSizeAlignKind sizeAlignKind)
- {
- typedValue.mValue = NULL;
- typedValue.mTypeEx = NULL;
- BfIRParamType paramType = (BfIRParamType)mStream->Read();
- if (paramType == BfIRParamType_None)
- {
- //
- }
- else if (paramType == BfIRParamType_Const)
- {
- BfTypeCode typeCode = (BfTypeCode)mStream->Read();
- BfConstType constType = (BfConstType)typeCode;
- if (constType == BfConstType_GlobalVar)
- {
- CMD_PARAM(int, streamId);
- if (streamId == -1)
- {
- int streamId = mCmdCount++;
- CMD_PARAM(BfIRTypeEx*, varType);
- CMD_PARAM(bool, isConstant);
- BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
- CMD_PARAM(llvm::Constant*, initializer);
- CMD_PARAM(String, name);
- CMD_PARAM(bool, isTLS);
- llvm::GlobalVariable* globalVariable = mLLVMModule->getGlobalVariable(name.c_str(), true);
- if (globalVariable == NULL)
- {
- globalVariable = mLLVMModule->getGlobalVariable(name.c_str());
- if (globalVariable == NULL)
- {
- globalVariable = new llvm::GlobalVariable(
- *mLLVMModule,
- varType->mLLVMType,
- isConstant,
- LLVMMapLinkageType(linkageType),
- initializer,
- name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
- }
- }
- typedValue.mTypeEx = GetPointerTypeEx(varType);
- typedValue.mValue = globalVariable;
- SetResult(streamId, typedValue);
- }
- else
- typedValue = GetTypedValue(streamId);
- FixTypedValue(typedValue);
- return;
- }
- /*else if (constType == BfConstType_GlobalVar_TypeInst)
- {
- CMD_PARAM(int, streamId);
- if (streamId == -1)
- {
- int streamId = mStream->GetReadPos();
- CMD_PARAM(int, varTypeId);
- auto& typeEntry = GetTypeEntry(varTypeId);
- auto varType = typeEntry.mInstLLVMType;
- CMD_PARAM(bool, isConstant);
- BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
- CMD_PARAM(llvm::Constant*, initializer);
- CMD_PARAM(String, name);
- CMD_PARAM(bool, isTLS);
- auto globalVariable = new llvm::GlobalVariable(
- *mLLVMModule,
- varType,
- isConstant,
- LLVMMapLinkageType(linkageType),
- initializer,
- name, NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
- llvmValue = globalVariable;
- SetResult(streamId, globalVariable);
- }
- else
- llvmValue = GetLLVMValue(streamId);
- return;
- }*/
- else if ((constType == BfConstType_BitCast) || (constType == BfConstType_BitCastNull))
- {
- CMD_PARAM(llvm::Constant*, target);
- CMD_PARAM(BfIRTypeEx*, toType);
- typedValue.mTypeEx = toType;
- if ((constType == BfConstType_BitCastNull) && (toType->mLLVMType->isIntegerTy()))
- {
- typedValue.mValue = llvm::ConstantInt::getNullValue(toType->mLLVMType);
- }
- else if (target->getType()->isIntegerTy())
- typedValue.mValue = llvm::ConstantExpr::getIntToPtr(target, toType->mLLVMType);
- else
- typedValue.mValue = llvm::ConstantExpr::getBitCast(target, toType->mLLVMType);
- FixTypedValue(typedValue);
- return;
- }
- else if (constType == BfConstType_GEP32_1)
- {
- CMD_PARAM(BfIRTypedValue, target);
- CMD_PARAM(int, idx0);
- llvm::Value* gepArgs[] = {
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), idx0)};
-
- auto compositeType = GetTypeMember(target.mTypeEx, 0);
- auto constant = llvm::dyn_cast<llvm::Constant>(target.mValue);
- typedValue.mTypeEx = target.mTypeEx;
- typedValue.mValue = llvm::ConstantExpr::getInBoundsGetElementPtr(compositeType->mLLVMType, constant, gepArgs);
- FixTypedValue(typedValue);
- return;
- }
- else if (constType == BfConstType_GEP32_2)
- {
- CMD_PARAM(BfIRTypedValue, target);
- CMD_PARAM(int, idx0);
- CMD_PARAM(int, idx1);
- llvm::Value* gepArgs[] = {
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), idx0),
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), idx1)};
- auto compositeType = GetTypeMember(target.mTypeEx, 0);
- int elemIdx = BF_MAX(BF_MIN(idx1, (int)compositeType->mMembers.mSize - 1), 0);
- auto elemType = GetTypeMember(compositeType, elemIdx);
- auto constant = llvm::dyn_cast<llvm::Constant>(target.mValue);
- typedValue.mValue = llvm::ConstantExpr::getInBoundsGetElementPtr(compositeType->mLLVMType, constant, gepArgs);
- typedValue.mTypeEx = GetPointerTypeEx(elemType);
- return;
- }
- else if (constType == BfConstType_ExtractValue)
- {
- CMD_PARAM(BfIRTypedValue, target);
- CMD_PARAM(int, idx0);
-
- auto compositeType = target.mTypeEx;
- int elemIdx = BF_MIN(idx0, (int)compositeType->mMembers.mSize - 1);
- auto elemType = GetTypeMember(compositeType, elemIdx);
- typedValue.mTypeEx = elemType;
- if (auto constant = llvm::dyn_cast<llvm::Constant>(target.mValue))
- typedValue.mValue = constant->getAggregateElement(llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), idx0));
- FixTypedValue(typedValue);
- return;
- }
- else if (constType == BfConstType_PtrToInt)
- {
- CMD_PARAM(llvm::Constant*, target);
- BfTypeCode toTypeCode = (BfTypeCode)mStream->Read();
- bool isSigned;
- BfIRTypeEx* toType = GetTypeEx(toTypeCode, isSigned);
- typedValue.mTypeEx = toType;
- typedValue.mValue = llvm::ConstantExpr::getPtrToInt(target, toType->mLLVMType);
- FixTypedValue(typedValue);
- return;
- }
- else if (constType == BfConstType_IntToPtr)
- {
- CMD_PARAM(llvm::Constant*, target);
- CMD_PARAM(BfIRTypeEx*, toType);
- typedValue.mTypeEx = toType;
- typedValue.mValue = llvm::ConstantExpr::getIntToPtr(target, toType->mLLVMType);
- FixTypedValue(typedValue);
- return;
- }
- else if (constType == BfConstType_AggZero)
- {
- BfIRTypeEntry* typeEntry = NULL;
- BfIRTypeEx* type = NULL;
- Read(type, &typeEntry);
- typedValue.mTypeEx = type;
- if ((sizeAlignKind == BfIRSizeAlignKind_Aligned) && (typeEntry != NULL))
- typedValue.mValue = llvm::ConstantAggregateZero::get(GetSizeAlignedType(typeEntry)->mLLVMType);
- else
- typedValue.mValue = llvm::ConstantAggregateZero::get(type->mLLVMType);
- FixTypedValue(typedValue);
- return;
- }
- else if (constType == BfConstType_ArrayZero8)
- {
- CMD_PARAM(int, count);
- auto arrType = llvm::ArrayType::get(llvm::Type::getInt8Ty(*mLLVMContext), count);
- typedValue.mValue = llvm::ConstantAggregateZero::get(arrType);
- FixTypedValue(typedValue);
- return;
- }
- else if (constType == BfConstType_Agg)
- {
- BfIRTypeEntry* typeEntry = NULL;
- BfIRTypeEx* type = NULL;
- Read(type, &typeEntry);
- CmdParamVec<llvm::Constant*> values;
- Read(values, type->mLLVMType->isArrayTy() ? BfIRSizeAlignKind_Aligned : BfIRSizeAlignKind_Original);
- typedValue.mTypeEx = type;
- if (auto arrayType = llvm::dyn_cast<llvm::ArrayType>(type->mLLVMType))
- {
- int fillCount = (int)(arrayType->getNumElements() - values.size());
- if (fillCount > 0)
- {
- auto lastValue = values.back();
- for (int i = 0; i < fillCount; i++)
- values.push_back(lastValue);
- }
- typedValue.mValue = llvm::ConstantArray::get(arrayType, values);
- }
- else if (auto structType = llvm::dyn_cast<llvm::StructType>(type->mLLVMType))
- {
- for (int i = 0; i < (int)values.size(); i++)
- {
- if (values[i]->getType() != structType->getElementType(i))
- {
- auto valArrayType = llvm::dyn_cast<llvm::ArrayType>(values[i]->getType());
- if (valArrayType != NULL)
- {
- if (valArrayType->getNumElements() == 0)
- {
- values[i] = llvm::ConstantAggregateZero::get(structType->getElementType(i));
- }
- }
- }
- }
- if ((sizeAlignKind == BfIRSizeAlignKind_Aligned) && (typeEntry != NULL))
- {
- auto alignedTypeEx = GetSizeAlignedType(typeEntry);
- auto alignedType = llvm::dyn_cast<llvm::StructType>(alignedTypeEx->mLLVMType);
- if (type != alignedTypeEx)
- values.push_back(llvm::ConstantAggregateZero::get(alignedType->getElementType(alignedType->getNumElements() - 1)));
- typedValue.mTypeEx = alignedTypeEx;
- typedValue.mValue = llvm::ConstantStruct::get(alignedType, values);
- }
- else
- {
- typedValue.mValue = llvm::ConstantStruct::get(structType, values);
- }
- }
- else if (auto vecType = llvm::dyn_cast<llvm::VectorType>(type->mLLVMType))
- {
- typedValue.mValue = llvm::ConstantVector::get(values);
- }
- else
- {
- typedValue.mValue = NULL;
- Fail("Bad type");
- }
- FixTypedValue(typedValue);
- return;
- }
- else if (constType == BfConstType_Undef)
- {
- CMD_PARAM(BfIRTypeEx*, type);
- typedValue.mTypeEx = type;
- typedValue.mValue = llvm::UndefValue::get(type->mLLVMType);
- return;
- }
- else if (constType == BfConstType_TypeOf)
- {
- CMD_PARAM(BfIRTypeEx*, type);
- typedValue = mReflectDataMap[type];
- BF_ASSERT(typedValue.mValue != NULL);
- return;
- }
- else if (constType == BfConstType_TypeOf_WithData)
- {
- CMD_PARAM(BfIRTypeEx*, type);
- CMD_PARAM(BfIRTypedValue, value);
- mReflectDataMap[type] = value;
- typedValue = value;
- return;
- }
- bool isSigned;
- llvm::Type* llvmConstType = GetLLVMType(typeCode, isSigned);
- if (typeCode == BfTypeCode_Float)
- {
- float f;
- mStream->Read(&f, sizeof(float));
- typedValue.mValue = llvm::ConstantFP::get(llvmConstType, f);
- }
- else if (typeCode == BfTypeCode_Double)
- {
- double d;
- mStream->Read(&d, sizeof(double));
- typedValue.mValue = llvm::ConstantFP::get(llvmConstType, d);
- }
- else if (typeCode == BfTypeCode_Boolean)
- {
- CMD_PARAM(bool, boolVal);
- typedValue.mValue = llvm::ConstantInt::get(llvmConstType, boolVal ? 1 : 0);
- }
- else if (typeCode == BfTypeCode_None)
- {
- typedValue.mValue = NULL;
- }
- else if (typeCode == BfTypeCode_NullPtr)
- {
- CMD_PARAM(llvm::Type*, nullType);
- if (nullType != NULL)
- typedValue.mValue = llvm::ConstantPointerNull::get((llvm::PointerType*)nullType);
- else
- typedValue.mValue = llvm::ConstantPointerNull::get((llvm::PointerType*)llvmConstType);
- }
- else if (BfIRBuilder::IsInt(typeCode))
- {
- int64 intVal = ReadSLEB128();
- auto constVal = llvm::ConstantInt::get(llvmConstType, intVal);
- auto constInt = (llvm::ConstantInt*)constVal;
- typedValue.mValue = constInt;
- }
- else
- {
- BF_FATAL("Unhandled");
- }
- }
- else if (paramType == BfIRParamType_Arg)
- {
- int argIdx = mStream->Read();
- if (argIdx >= mActiveFunction->arg_size())
- {
- FatalError(StrFormat("ARG out of bounds %d", argIdx));
- }
- auto typeEx = mActiveFunctionType;
- BF_ASSERT(argIdx < mActiveFunction->arg_size());
- auto argItr = mActiveFunction->arg_begin();
- for (int i = 0; i < argIdx; i++)
- argItr++;
- typedValue.mValue = &(*argItr);
- typedValue.mTypeEx = GetTypeMember(typeEx, argIdx + 1);
- }
- else
- {
- int cmdId = -1;
- if (paramType == BfIRParamType_StreamId_Abs8)
- {
- cmdId = mStream->Read();
- }
- else if (paramType == BfIRParamType_StreamId_Rel)
- {
- cmdId = mCmdCount - (int)ReadSLEB128();
- }
- else
- {
- cmdId = mCmdCount - (paramType - BfIRParamType_StreamId_Back1) - 1;
- }
- auto& result = mResults[cmdId];
- if ((codeGenEntry != NULL) && (result.mKind != BfIRCodeGenEntryKind_None))
- *codeGenEntry = &result;
- if (result.mKind == BfIRCodeGenEntryKind_TypedValue_Aligned)
- {
- typedValue = result.mTypedValue;
- BfIRTypeEx* normalType = NULL;
- if (mAlignedTypeToNormalType.TryGetValue(typedValue.mTypeEx, &normalType))
- typedValue.mTypeEx = normalType;
- return;
- }
- if (result.mKind == BfIRCodeGenEntryKind_TypedValue)
- {
- typedValue = result.mTypedValue;
- return;
- }
- if (result.mKind != BfIRCodeGenEntryKind_LLVMValue)
- {
- if ((codeGenEntry != NULL) && (result.mKind != BfIRCodeGenEntryKind_None))
- {
- *codeGenEntry = &result;
- return;
- }
- }
- if (result.mKind == BfIRCodeGenEntryKind_LLVMValue_Aligned)
- {
- typedValue.mValue = result.mLLVMValue;
- if (sizeAlignKind != BfIRSizeAlignKind_Original)
- return;
- llvm::Type* normalType = NULL;
- //TODO: if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(llvmValue->getType()))
- {
-
- // if (mAlignedTypeToNormalType.TryGetValue(ptrType->getElementType(), &normalType))
- // {
- // llvmValue = mIRBuilder->CreateBitCast(llvmValue, normalType->getPointerTo());
- // return;
- // }
- }
- }
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue);
- typedValue.mValue = result.mLLVMValue;
- }
- FixTypedValue(typedValue);
- }
- void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry, BfIRSizeAlignKind sizeAlignKind)
- {
- BfIRTypedValue typedValue;
- Read(typedValue, codeGenEntry, sizeAlignKind);
- llvmValue = typedValue.mValue;
- }
- void BfIRCodeGen::Read(llvm::Constant*& llvmConstant, BfIRSizeAlignKind sizeAlignKind)
- {
- llvm::Value* value;
- Read(value, NULL, sizeAlignKind);
- if (value == NULL)
- {
- llvmConstant = NULL;
- }
- else
- {
- BF_ASSERT(llvm::isa<llvm::Constant>(value));
- llvmConstant = (llvm::Constant*)value;
- }
- }
- void BfIRCodeGen::Read(llvm::Function*& llvmFunc)
- {
- int streamId = (int)ReadSLEB128();
- if (streamId == -1)
- {
- llvmFunc = NULL;
- return;
- }
- auto& result = mResults[streamId];
- if (result.mKind == BfIRCodeGenEntryKind_TypedValue)
- {
- llvmFunc = (llvm::Function*)result.mTypedValue.mValue;
- return;
- }
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue);
- BF_ASSERT(llvm::isa<llvm::Function>(result.mLLVMValue));
- llvmFunc = (llvm::Function*)result.mLLVMValue;
- }
- void BfIRCodeGen::ReadFunction(BfIRTypedValue& typedValue)
- {
- int streamId = (int)ReadSLEB128();
- if (streamId == -1)
- {
- typedValue.mValue = NULL;
- typedValue.mTypeEx = NULL;
- return;
- }
- auto& result = mResults[streamId];
- if (result.mKind == BfIRCodeGenEntryKind_TypedValue)
- {
- typedValue = result.mTypedValue;
- return;
- }
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue);
- BF_ASSERT(llvm::isa<llvm::Function>(result.mLLVMValue));
- typedValue.mValue = result.mLLVMValue;
- FixTypedValue(typedValue);
- }
- void BfIRCodeGen::Read(llvm::BasicBlock*& llvmBlock)
- {
- int streamId = (int)ReadSLEB128();
- auto& result = mResults[streamId];
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMBasicBlock);
- llvmBlock = (llvm::BasicBlock*)result.mLLVMType;
- }
- void BfIRCodeGen::Read(llvm::MDNode*& llvmMD)
- {
- int streamId = (int)ReadSLEB128();
- if (streamId == -1)
- {
- llvmMD = NULL;
- return;
- }
- auto& result = mResults[streamId];
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMMetadata);
- llvmMD = result.mLLVMMetadata;
- }
- void BfIRCodeGen::Read(llvm::Metadata*& llvmMD)
- {
- int streamId = (int)ReadSLEB128();
- if (streamId == -1)
- {
- llvmMD = NULL;
- return;
- }
- auto& result = mResults[streamId];
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMMetadata);
- llvmMD = result.mLLVMMetadata;
- }
- void BfIRCodeGen::AddNop()
- {
- if ((mTargetTriple.GetMachineType() != BfMachineType_x86) && (mTargetTriple.GetMachineType() != BfMachineType_x64))
- return;
- if (mNopInlineAsm == NULL)
- {
- llvm::SmallVector<llvm::Type*, 8> paramTypes;
- llvm::FunctionType* funcType = llvm::FunctionType::get(llvm::Type::getVoidTy(*mLLVMContext), paramTypes, false);
- mNopInlineAsm = llvm::InlineAsm::get(funcType,
- "nop", "", true, false, llvm::InlineAsm::AD_ATT);
- }
- llvm::CallInst* callInst = mIRBuilder->CreateCall(mNopInlineAsm);
-
- callInst->addFnAttr(llvm::Attribute::NoUnwind);
- }
- llvm::Value* BfIRCodeGen::TryToVector(const BfIRTypedValue& value)
- {
- auto valueType = value.mTypeEx->mLLVMType;
- if (llvm::isa<llvm::VectorType>(valueType))
- return value.mValue;
-
- if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(valueType))
- {
- auto ptrElemType = GetTypeMember(value.mTypeEx, 0);
- if (auto arrType = llvm::dyn_cast<llvm::ArrayType>(ptrElemType->mLLVMType))
- {
- auto vecType = llvm::FixedVectorType::get(arrType->getArrayElementType(), (uint)arrType->getArrayNumElements());
- auto vecPtrType = vecType->getPointerTo();
-
- auto ptrVal0 = mIRBuilder->CreateBitCast(value.mValue, vecPtrType);
- return mIRBuilder->CreateAlignedLoad(vecType, ptrVal0, llvm::MaybeAlign(1));
- }
-
- if (auto vecType = llvm::dyn_cast<llvm::VectorType>(ptrElemType->mLLVMType))
- {
- return mIRBuilder->CreateAlignedLoad(vecType, value.mValue, llvm::MaybeAlign(1));
- }
- }
- return NULL;
- }
- bool BfIRCodeGen::TryMemCpy(const BfIRTypedValue& ptr, llvm::Value* val)
- {
- auto valType = val->getType();
- auto dataLayout = llvm::DataLayout(mLLVMModule);
- int arrayBytes = (int)dataLayout.getTypeSizeInBits(valType) / 8;
- // LLVM has perf issues with large aggregates - it treats each element as a unique value,
- // which is great for optimizing small data but is a perf killer for large data.
- if (arrayBytes < 256)
- return false;
- auto int8Ty = llvm::Type::getInt8Ty(*mLLVMContext);
- auto int32Ty = llvm::Type::getInt32Ty(*mLLVMContext);
- auto int8PtrTy = int8Ty->getPointerTo();
- if (auto loadInst = llvm::dyn_cast<llvm::LoadInst>(val))
- {
- mIRBuilder->CreateMemCpy(
- mIRBuilder->CreateBitCast(ptr.mValue, int8PtrTy),
- llvm::MaybeAlign(1),
- mIRBuilder->CreateBitCast(loadInst->getPointerOperand(), int8PtrTy),
- llvm::MaybeAlign(1),
- llvm::ConstantInt::get(int32Ty, arrayBytes));
- return true;
- }
- auto constVal = llvm::dyn_cast<llvm::Constant>(val);
- if (constVal == NULL)
- return false;
- if (llvm::isa<llvm::ConstantAggregateZero>(constVal))
- {
- mIRBuilder->CreateMemSet(
- mIRBuilder->CreateBitCast(ptr.mValue, int8PtrTy),
- llvm::ConstantInt::get(int8Ty, 0),
- llvm::ConstantInt::get(int32Ty, arrayBytes),
- llvm::MaybeAlign(1));
- return true;
- }
- auto globalVariable = new llvm::GlobalVariable(
- *mLLVMModule,
- valType,
- true,
- llvm::GlobalValue::InternalLinkage,
- constVal,
- StrFormat("__ConstVal__%d", mConstValIdx++).c_str(),
- NULL,
- llvm::GlobalValue::NotThreadLocal);
- mIRBuilder->CreateMemCpy(
- mIRBuilder->CreateBitCast(ptr.mValue, int8PtrTy),
- llvm::MaybeAlign(1),
- mIRBuilder->CreateBitCast(globalVariable, int8PtrTy),
- llvm::MaybeAlign(1),
- llvm::ConstantInt::get(int32Ty, arrayBytes));
- return true;
- }
- bool BfIRCodeGen::TryVectorCpy(const BfIRTypedValue& ptr, llvm::Value* val)
- {
- if (GetTypeMember(ptr.mTypeEx, 0)->mLLVMType == val->getType())
- return false;
- if (!llvm::isa<llvm::VectorType>(val->getType()))
- {
- return false;
- }
- auto usePtr = mIRBuilder->CreateBitCast(ptr.mValue, val->getType()->getPointerTo());
- mIRBuilder->CreateAlignedStore(val, usePtr, llvm::MaybeAlign(1));
- return true;
- }
- llvm::Type* BfIRCodeGen::GetLLVMPointerElementType(BfIRTypeEx* typeEx)
- {
- BF_ASSERT(typeEx != NULL);
- BF_ASSERT(typeEx->mLLVMType->isPointerTy());
- return GetTypeMember(typeEx, 0)->mLLVMType;
- }
- BfIRTypeEx* BfIRCodeGen::GetSizeAlignedType(BfIRTypeEntry* typeEntry)
- {
- if ((typeEntry->mAlignType == NULL) && ((typeEntry->mSize & (typeEntry->mAlign - 1)) != 0))
- {
- auto structType = llvm::dyn_cast<llvm::StructType>(typeEntry->mType->mLLVMType);
- if (structType != NULL)
- {
- //TODO: Fill out properly
- BF_ASSERT(structType->isPacked());
- auto alignTypeEx = new BfIRTypeEx();
- mIRTypeExs.Add(alignTypeEx);
- auto alignType = llvm::StructType::create(*mLLVMContext, (structType->getName().str() + "_ALIGNED").c_str());
- llvm::SmallVector<llvm::Type*, 8> members;
- for (int elemIdx = 0; elemIdx < (int)structType->getNumElements(); elemIdx++)
- {
- members.push_back(structType->getElementType(elemIdx));
- }
- int alignSize = BF_ALIGN(typeEntry->mSize, typeEntry->mAlign);
- int fillSize = alignSize - typeEntry->mSize;
- members.push_back(llvm::ArrayType::get(llvm::Type::getInt8Ty(*mLLVMContext), fillSize));
- alignType->setBody(members, structType->isPacked());
-
- alignTypeEx->mLLVMType = alignType;
- typeEntry->mAlignType = alignTypeEx;
- mAlignedTypeToNormalType[alignTypeEx] = typeEntry->mType;
- }
- }
- if (typeEntry->mAlignType != NULL)
- return typeEntry->mAlignType;
- return typeEntry->mType;
- }
- BfIRTypedValue BfIRCodeGen::GetAlignedPtr(const BfIRTypedValue& val)
- {
- BfIRTypedValue result = val;
- if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(val.mTypeEx->mLLVMType))
- {
- auto elemType = GetTypeMember(val.mTypeEx, 0);
- auto typeEntry = GetTypeEntry(elemType);
- if (typeEntry != NULL)
- {
- auto alignedType = GetSizeAlignedType(typeEntry);
- if (alignedType != elemType)
- result.mTypeEx = GetPointerTypeEx(alignedType);
- }
- }
- return result;
- }
- llvm::Value* BfIRCodeGen::DoCheckedIntrinsic(llvm::Intrinsic::ID intrin, llvm::Value* lhs, llvm::Value* rhs, bool useAsm)
- {
- if ((mTargetTriple.GetMachineType() != BfMachineType_x86) && (mTargetTriple.GetMachineType() != BfMachineType_x64))
- useAsm = false;
- CmdParamVec<llvm::Type*> useParams;
- useParams.push_back(lhs->getType());
- auto func = llvm::Intrinsic::getDeclaration(mLLVMModule, intrin, useParams);
- CmdParamVec<llvm::Value*> args;
- args.push_back(lhs);
- args.push_back(rhs);
- llvm::FunctionType* funcType = func->getFunctionType();
- auto aggResult = mIRBuilder->CreateCall(funcType, func, args);
- auto valResult = mIRBuilder->CreateExtractValue(aggResult, 0);
- auto failResult = mIRBuilder->CreateExtractValue(aggResult, 1);
- if (!useAsm)
- {
- mLockedBlocks.Add(mIRBuilder->GetInsertBlock());
- auto failBB = llvm::BasicBlock::Create(*mLLVMContext, "access.fail");
- auto passBB = llvm::BasicBlock::Create(*mLLVMContext, "access.pass");
- mIRBuilder->CreateCondBr(failResult, failBB, passBB);
- mActiveFunction->insert(mActiveFunction->end(), failBB);
- mIRBuilder->SetInsertPoint(failBB);
- auto trapDecl = llvm::Intrinsic::getDeclaration(mLLVMModule, llvm::Intrinsic::trap);
- auto callInst = mIRBuilder->CreateCall(trapDecl);
- callInst->addFnAttr(llvm::Attribute::NoReturn);
- mIRBuilder->CreateBr(passBB);
-
- mActiveFunction->insert(mActiveFunction->end(), passBB);
- mIRBuilder->SetInsertPoint(passBB);
- }
- else
- {
- if (mOverflowCheckAsm == NULL)
- {
- std::vector<llvm::Type*> paramTypes;
- paramTypes.push_back(llvm::Type::getInt8Ty(*mLLVMContext));
- auto funcType = llvm::FunctionType::get(llvm::Type::getVoidTy(*mLLVMContext), paramTypes, false);
- String asmStr =
- "testb $$1, $0\n"
- "jz 1f\n"
- "int $$3\n"
- "1:";
- mOverflowCheckAsm = llvm::InlineAsm::get(funcType,
- asmStr.c_str(), "r,~{dirflag},~{fpsr},~{flags}", true,
- false, llvm::InlineAsm::AD_ATT);
- }
- llvm::SmallVector<llvm::Value*, 1> llvmArgs;
- llvmArgs.push_back(mIRBuilder->CreateIntCast(failResult, llvm::Type::getInt8Ty(*mLLVMContext), false));
- llvm::CallInst* callInst = mIRBuilder->CreateCall(mOverflowCheckAsm, llvmArgs);
- callInst->addFnAttr(llvm::Attribute::NoUnwind);
- }
- return valResult;
- }
- void BfIRCodeGen::CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile)
- {
- auto sizeConst = llvm::dyn_cast<llvm::ConstantInt>(size);
- auto valConst = llvm::dyn_cast<llvm::ConstantInt>(val);
- if ((!mIsOptimized) && (sizeConst != NULL) && (valConst != NULL))
- {
- int64 sizeVal = sizeConst->getSExtValue();
- uint8 setVal = (uint8)valConst->getSExtValue();
- if (sizeVal <= 128)
- {
- //llvm::Value* intVal = mIRBuilder->CreatePtrToInt(addr, llvm::Type::getInt32Ty(*mLLVMContext))
- int curOffset = 0;
- int sizeLeft = (int)sizeVal;
- llvm::Value* headVal;
- if (mPtrSize >= 8)
- {
- headVal = NULL;
- auto intTy = llvm::Type::getInt64Ty(*mLLVMContext);
- auto constVal = llvm::ConstantInt::get(intTy,
- ((int64)setVal << 56) | ((int64)setVal << 48) | ((int64)setVal << 40) | ((int64)setVal << 32) |
- ((int64)setVal << 24) | ((int64)setVal << 16) | ((int64)setVal << 8) | ((int64)setVal));
- while (sizeLeft >= 8)
- {
- if (headVal == NULL)
- headVal = mIRBuilder->CreateBitCast(addr, intTy->getPointerTo());
- llvm::Value* ptrVal = headVal;
- if (curOffset != 0)
- ptrVal = mIRBuilder->CreateConstInBoundsGEP1_32(intTy, headVal, curOffset / 8);
- mIRBuilder->CreateStore(constVal, ptrVal, isVolatile);
- curOffset += 8;
- sizeLeft -= 8;
- }
- }
- if (sizeLeft >= 4)
- {
- headVal = NULL;
- auto intTy = llvm::Type::getInt32Ty(*mLLVMContext);
- auto constVal = llvm::ConstantInt::get(intTy, ((int)setVal << 24) | ((int)setVal << 16) | ((int)setVal << 8) | ((int)setVal));
- while (sizeLeft >= 4)
- {
- if (headVal == NULL)
- headVal = mIRBuilder->CreateBitCast(addr, intTy->getPointerTo());
- llvm::Value* ptrVal = headVal;
- if (curOffset != 0)
- ptrVal = mIRBuilder->CreateConstInBoundsGEP1_32(intTy, headVal, curOffset / 4);
- mIRBuilder->CreateStore(constVal, ptrVal, isVolatile);
- curOffset += 4;
- sizeLeft -= 4;
- }
- }
- if (sizeLeft >= 2)
- {
- headVal = NULL;
- auto intTy = llvm::Type::getInt16Ty(*mLLVMContext);
- auto constVal = llvm::ConstantInt::get(intTy, ((int)setVal << 8) | ((int)setVal));
- while (sizeLeft >= 2)
- {
- if (headVal == NULL)
- headVal = mIRBuilder->CreateBitCast(addr, intTy->getPointerTo());
- llvm::Value* ptrVal = headVal;
- if (curOffset != 0)
- ptrVal = mIRBuilder->CreateConstInBoundsGEP1_32(intTy, headVal, curOffset / 2);
- mIRBuilder->CreateStore(constVal, ptrVal, isVolatile);
- curOffset += 2;
- sizeLeft -= 2;
- }
- }
- if (sizeLeft >= 1)
- {
- headVal = NULL;
- auto intTy = llvm::Type::getInt8Ty(*mLLVMContext);
- auto constVal = llvm::ConstantInt::get(intTy, ((int)setVal));
- while (sizeLeft >= 1)
- {
- if (headVal == NULL)
- headVal = mIRBuilder->CreateBitCast(addr, intTy->getPointerTo());
- llvm::Value* ptrVal = headVal;
- if (curOffset != 0)
- ptrVal = mIRBuilder->CreateConstInBoundsGEP1_32(intTy, headVal, curOffset / 1);
- mIRBuilder->CreateStore(constVal, ptrVal, isVolatile);
- curOffset += 1;
- sizeLeft -= 1;
- }
- }
- return;
- }
- }
- mIRBuilder->CreateMemSet(addr, val, size, llvm::MaybeAlign(alignment), isVolatile);
- }
- void BfIRCodeGen::InitTarget()
- {
- llvm::SMDiagnostic Err;
- llvm::Triple theTriple = llvm::Triple(mLLVMModule->getTargetTriple());
- llvm::CodeGenOptLevel optLvl = llvm::CodeGenOptLevel::None;
- String cpuName = mTargetCPU;
- String arch = "";
- // Get the target specific parser.
- std::string Error;
- const llvm::Target *theTarget = llvm::TargetRegistry::lookupTarget(arch.c_str(), theTriple, Error);
- if (!theTarget)
- {
- Fail(StrFormat("Failed to create LLVM Target: %s", Error.c_str()));
- return;
- }
- llvm::TargetOptions Options = llvm::TargetOptions(); // InitTargetOptionsFromCodeGenFlags();
- String featuresStr;
- if (mCodeGenOptions.mOptLevel == BfOptLevel_O1)
- {
- //optLvl = CodeGenOpt::Less;
- }
- else if (mCodeGenOptions.mOptLevel == BfOptLevel_O2)
- optLvl = llvm::CodeGenOptLevel::Default;
- else if (mCodeGenOptions.mOptLevel == BfOptLevel_O3)
- optLvl = llvm::CodeGenOptLevel::Aggressive;
- if (theTriple.isWasm())
- featuresStr = "+atomics,+bulk-memory,+mutable-globals,+sign-ext";
- else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_SSE)
- featuresStr = "+sse";
- else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_SSE2)
- featuresStr = "+sse2";
- else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_SSE3)
- featuresStr = "+sse3";
- else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_SSE4)
- featuresStr = "+sse4";
- else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_SSE41)
- featuresStr = "+sse4.1";
- else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_AVX)
- featuresStr = "+avx";
- else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_AVX2)
- featuresStr = "+avx2";
- std::optional<llvm::Reloc::Model> relocModel;
- llvm::CodeModel::Model cmModel = llvm::CodeModel::Small;
- switch (mCodeGenOptions.mRelocType)
- {
- case BfRelocType_Static:
- relocModel = llvm::Reloc::Model::DynamicNoPIC;
- break;
- case BfRelocType_PIC:
- relocModel = llvm::Reloc::Model::PIC_;
- break;
- case BfRelocType_DynamicNoPIC:
- relocModel = llvm::Reloc::Model::DynamicNoPIC;
- break;
- case BfRelocType_ROPI:
- relocModel = llvm::Reloc::Model::ROPI;
- break;
- case BfRelocType_RWPI:
- relocModel = llvm::Reloc::Model::RWPI;
- break;
- case BfRelocType_ROPI_RWPI:
- relocModel = llvm::Reloc::Model::ROPI_RWPI;
- break;
- default: break;
- }
- switch (mCodeGenOptions.mPICLevel)
- {
- case BfPICLevel_Not:
- mLLVMModule->setPICLevel(llvm::PICLevel::Level::NotPIC);
- break;
- case BfPICLevel_Small:
- mLLVMModule->setPICLevel(llvm::PICLevel::Level::SmallPIC);
- break;
- case BfPICLevel_Big:
- mLLVMModule->setPICLevel(llvm::PICLevel::Level::BigPIC);
- break;
- default: break;
- }
- mLLVMTargetMachine =
- theTarget->createTargetMachine(theTriple.getTriple(), cpuName.c_str(), featuresStr.c_str(),
- Options, relocModel, cmModel, optLvl);
- mLLVMModule->setDataLayout(mLLVMTargetMachine->createDataLayout());
- }
- void BfIRCodeGen::HandleNextCmd()
- {
- if (mFailed)
- return;
- int curId = mCmdCount;
- BfIRCmd cmd = (BfIRCmd)mStream->Read();
- mCmdCount++;
- switch (cmd)
- {
- case BfIRCmd_Module_Start:
- {
- CMD_PARAM(String, moduleName);
- CMD_PARAM(int, ptrSize);
- CMD_PARAM(bool, isOptimized);
- BF_ASSERT(mLLVMModule == NULL);
- mModuleName = moduleName;
- mPtrSize = ptrSize;
- mIsOptimized = isOptimized;
- mLLVMModule = new llvm::Module(moduleName.c_str(), *mLLVMContext);
- mLLVMModule->setIsNewDbgInfoFormat(false);
- mIRBuilder = new llvm::IRBuilder<>(*mLLVMContext);
- //OutputDebugStrF("-------- Starting Module %s --------\n", moduleName.c_str());
- }
- break;
- case BfIRCmd_Module_SetTargetTriple:
- {
- CMD_PARAM(String, targetTriple);
- CMD_PARAM(String, targetCPU);
- mTargetTriple.Set(targetTriple);
- mTargetCPU = targetCPU;
- if (targetTriple.IsEmpty())
- mLLVMModule->setTargetTriple(llvm::sys::getDefaultTargetTriple());
- else
- mLLVMModule->setTargetTriple(targetTriple.c_str());
- InitTarget();
- }
- break;
- case BfIRCmd_Module_AddModuleFlag:
- {
- CMD_PARAM(String, flag);
- CMD_PARAM(int, val);
- mLLVMModule->addModuleFlag(llvm::Module::Warning, flag.c_str(), val);
- if (flag == "CodeView")
- mIsCodeView = true;
- }
- break;
- case BfIRCmd_WriteIR:
- {
- CMD_PARAM(String, fileName);
- std::error_code ec;
- llvm::raw_fd_ostream outStream(fileName.c_str(), ec, llvm::sys::fs::OpenFlags::OF_Text);
- if (ec)
- {
- Fail("Failed writing IR '" + fileName + "': " + ec.message());
- }
- else
- mLLVMModule->print(outStream, NULL);
- }
- break;
- case BfIRCmd_Abort:
- Fail("Stream aborted");
- break;
- case BfIRCmd_SetType:
- {
- CMD_PARAM(int, typeId);
-
- CMD_PARAM(BfIRTypeEx*, type);
- //llvm::Type* type;
- //llvm::Type* elementType;
- auto& typeEntry = GetTypeEntry(typeId);
- typeEntry.mType = type;
- if (typeEntry.mInstType == NULL)
- typeEntry.mInstType = type;
- mTypeToTypeIdMap[type] = typeId;
- }
- break;
- case BfIRCmd_SetInstType:
- {
- CMD_PARAM(int, typeId);
- CMD_PARAM(BfIRTypeEx*, type);
- GetTypeEntry(typeId).mInstType = type;
- }
- break;
- case BfIRCmd_PrimitiveType:
- {
- BfTypeCode typeCode = (BfTypeCode)mStream->Read();
- bool isSigned;
- SetResult(curId, GetLLVMType(typeCode, isSigned));
- }
- break;
- case BfIRCmd_CreateAnonymousStruct:
- {
- CMD_PARAM(CmdParamVec<BfIRTypeEx*>, members);
-
- CmdParamVec<llvm::Type*> llvmMembers;
- for (auto& memberType : members)
- llvmMembers.push_back(memberType->mLLVMType);
- auto structType = llvm::StructType::get(*mLLVMContext, llvmMembers);
- auto typeEx = CreateTypeEx(structType);
- for (auto& memberType : members)
- {
- BF_ASSERT(memberType != NULL);
- typeEx->mMembers.Add(memberType);
- }
- SetResult(curId, typeEx);
- }
- break;
- case BfIRCmd_CreateStruct:
- {
- CMD_PARAM(String, typeName);
- auto structType = llvm::StructType::create(*mLLVMContext, typeName.c_str());
- auto typeEx = CreateTypeEx(structType);
- SetResult(curId, typeEx);
- }
- break;
- case BfIRCmd_StructSetBody:
- {
- BfIRTypeEx* typeEx = NULL;
- BfIRTypeEntry* typeEntry = NULL;
- Read(typeEx, &typeEntry);
- CMD_PARAM(CmdParamVec<BfIRTypeEx*>, members);
- CMD_PARAM(int, instSize);
- CMD_PARAM(int, instAlign);
- CMD_PARAM(bool, isPacked);
- typeEx->mMembers.clear();
- auto type = typeEx->mLLVMType;
- CmdParamVec<llvm::Type*> llvmMembers;
- for (auto& memberType : members)
- {
- BF_ASSERT(memberType != NULL);
- typeEx->mMembers.Add(memberType);
- llvmMembers.push_back(memberType->mLLVMType);
- }
- BF_ASSERT(llvm::isa<llvm::StructType>(type));
- auto structType = (llvm::StructType*)type;
- if (structType->isOpaque())
- structType->setBody(llvmMembers, isPacked);
- if (typeEntry != NULL)
- {
- typeEntry->mSize = instSize;
- typeEntry->mAlign = instAlign;
- }
- }
- break;
- case BfIRCmd_Type:
- {
- CMD_PARAM(BfIRTypeEntry*, typeEntry);
- auto type = typeEntry->mType;
- SetResult(curId, type);
- }
- break;
- case BfIRCmd_TypeInst:
- {
- CMD_PARAM(BfIRTypeEntry*, typeEntry);
- SetResult(curId, typeEntry->mInstType);
- }
- break;
- case BfIRCmd_TypeInstPtr:
- {
- CMD_PARAM(BfIRTypeEntry*, typeEntry);
- SetResult(curId, GetPointerTypeEx(typeEntry->mInstType));
- }
- break;
- case BfIRCmd_GetType:
- {
- CMD_PARAM(BfIRTypedValue, typedValue);
- BF_ASSERT(typedValue.mTypeEx != NULL);
- SetResult(curId, typedValue.mTypeEx);
- }
- break;
- case BfIRCmd_GetPointerToFuncType:
- {
- BfIRTypeEx* funcType = NULL;
- ReadFunctionType(funcType);
- SetResult(curId, GetPointerTypeEx(funcType));
- }
- break;
- case BfIRCmd_GetPointerToType:
- {
- CMD_PARAM(BfIRTypeEx*, type);
- SetResult(curId, GetPointerTypeEx(type));
- }
- break;
- case BfIRCmd_GetSizedArrayType:
- {
- BfIRTypeEx* elementType = NULL;
- BfIRTypeEntry* elementTypeEntry = NULL;
- Read(elementType, &elementTypeEntry);
- auto typeEx = new BfIRTypeEx();
- typeEx->mMembers.Add(elementType);
- mIRTypeExs.Add(typeEx);
-
- CMD_PARAM(int, length);
- if (elementTypeEntry != NULL)
- typeEx->mLLVMType = llvm::ArrayType::get(GetSizeAlignedType(elementTypeEntry)->mLLVMType, length);
- else
- typeEx->mLLVMType = llvm::ArrayType::get(elementType->mLLVMType, length);
- SetResult(curId, typeEx);
- }
- break;
- case BfIRCmd_GetVectorType:
- {
- CMD_PARAM(BfIRTypeEx*, elementType);
- CMD_PARAM(int, length);
- auto llvmType = elementType->mLLVMType;
- if (llvmType->getScalarSizeInBits() == 1)
- {
- llvmType = llvm::Type::getInt8Ty(*mLLVMContext);
- }
- auto typeEx = new BfIRTypeEx();
- mIRTypeExs.Add(typeEx);
- typeEx->mLLVMType = llvm::FixedVectorType::get(llvmType, length);
- typeEx->mMembers.Add(elementType);
- SetResult(curId, typeEx);
- }
- break;
- case BfIRCmd_CreateConstAgg:
- {
- CMD_PARAM(BfIRTypeEx*, type);
- CMD_PARAM(CmdParamVec<llvm::Value*>, values)
- llvm::SmallVector<llvm::Constant*, 8> copyValues;
- if (auto arrayType = llvm::dyn_cast<llvm::ArrayType>(type->mLLVMType))
- {
- for (auto val : values)
- {
- auto constValue = llvm::dyn_cast<llvm::Constant>(val);
- BF_ASSERT(constValue != NULL);
- copyValues.push_back(constValue);
- }
- int fillCount = (int)(arrayType->getNumElements() - copyValues.size());
- if (fillCount > 0)
- {
- auto lastValue = copyValues.back();
- for (int i = 0; i < fillCount; i++)
- copyValues.push_back(lastValue);
- }
- BfIRTypedValue result;
- result.mTypeEx = type;
- result.mValue = llvm::ConstantArray::get(arrayType, copyValues);
- SetResult(curId, result);
- }
- else if (auto structType = llvm::dyn_cast<llvm::StructType>(type->mLLVMType))
- {
- FixValues(structType, values);
- for (auto val : values)
- {
- auto constValue = llvm::dyn_cast<llvm::Constant>(val);
- BF_ASSERT(constValue != NULL);
- copyValues.push_back(constValue);
- }
- BfIRTypedValue result;
- result.mTypeEx = type;
- result.mValue = llvm::ConstantStruct::get(structType, copyValues);
- SetResult(curId, result);
- }
- else
- Fail("Bad type");
- }
- break;
- case BfIRCmd_CreateConstStructZero:
- {
- CMD_PARAM(BfIRTypeEx*, type);
- BfIRTypedValue result;
- result.mTypeEx = type;
- result.mValue = llvm::ConstantAggregateZero::get(type->mLLVMType);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_CreateConstString:
- {
- CMD_PARAM(String, str);
- BfIRTypedValue result;
- result.mValue = llvm::ConstantDataArray::getString(*mLLVMContext, llvm::StringRef(str.c_str(), str.length()));
- result.mTypeEx = GetTypeEx(result.mValue->getType());
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_ConfigConst:
- {
- CMD_PARAM(int, constIdx);
- BfTypeCode typeCode = (BfTypeCode)mStream->Read();
- if (typeCode == BfTypeCode_IntPtr)
- typeCode = (mPtrSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64;
- llvm::Constant* constVal = (typeCode == BfTypeCode_Int32) ?
- mConfigConsts32[constIdx] :
- mConfigConsts64[constIdx];
- SetResult(curId, constVal);
- }
- break;
- case BfIRCmd_SetName:
- {
- CMD_PARAM_NOTRANS(llvm::Value*, val);
- CMD_PARAM(String, name);
- if (!val->getType()->isVoidTy())
- val->setName(name.c_str());
- }
- break;
- case BfIRCmd_CreateUndefValue:
- {
- CMD_PARAM(BfIRTypeEx*, type);
- BfIRTypedValue result;
- result.mTypeEx = type;
- result.mValue = llvm::UndefValue::get(type->mLLVMType);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_NumericCast:
- {
- CMD_PARAM(llvm::Value*, val);
- CMD_PARAM(bool, valIsSigned);
- BfTypeCode typeCode = (BfTypeCode)mStream->Read();
- BfTypeCode valTypeCode = GetTypeCode(val->getType(), valIsSigned);
- bool toSigned;
- auto toLLVMType = GetLLVMType(typeCode, toSigned);
- llvm::Value* retVal = NULL;
- if (BfIRBuilder::IsIntable(typeCode))
- {
- // Int -> Int
- if ((BfIRBuilder::IsIntable(valTypeCode)) || (valTypeCode == BfTypeCode_Boolean))
- {
- retVal = mIRBuilder->CreateIntCast(val, toLLVMType, toSigned && valIsSigned);
- }
- else // Float -> Int
- {
- if (BfIRBuilder::IsSigned(typeCode))
- retVal = mIRBuilder->CreateFPToSI(val, toLLVMType);
- else
- retVal = mIRBuilder->CreateFPToUI(val, toLLVMType);
- }
- }
- else
- {
- // Int -> Float
- if ((BfIRBuilder::IsIntable(valTypeCode)) || (valTypeCode == BfTypeCode_Boolean))
- {
- if (BfIRBuilder::IsSigned(valTypeCode))
- retVal = mIRBuilder->CreateSIToFP(val, toLLVMType);
- else
- retVal = mIRBuilder->CreateUIToFP(val, toLLVMType);
- }
- else // Float -> Float
- {
- retVal = mIRBuilder->CreateFPCast(val, toLLVMType);
- }
- }
- SetResult(curId, retVal);
- }
- break;
- case BfIRCmd_CmpEQ:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFCmpOEQ(lhs, rhs));
- else
- SetResult(curId, mIRBuilder->CreateICmpEQ(lhs, rhs));
- }
- break;
- case BfIRCmd_CmpNE:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFCmpUNE(lhs, rhs));
- else
- SetResult(curId, mIRBuilder->CreateICmpNE(lhs, rhs));
- }
- break;
- case BfIRCmd_CmpSLT:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFCmpOLT(lhs, rhs));
- else
- SetResult(curId, mIRBuilder->CreateICmpSLT(lhs, rhs));
- }
- break;
- case BfIRCmd_CmpULT:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFCmpOLT(lhs, rhs));
- else
- SetResult(curId, mIRBuilder->CreateICmpULT(lhs, rhs));
- }
- break;
- case BfIRCmd_CmpSLE:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFCmpOLE(lhs, rhs));
- else
- SetResult(curId, mIRBuilder->CreateICmpSLE(lhs, rhs));
- }
- break;
- case BfIRCmd_CmpULE:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFCmpOLE(lhs, rhs));
- else
- SetResult(curId, mIRBuilder->CreateICmpULE(lhs, rhs));
- }
- break;
- case BfIRCmd_CmpSGT:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFCmpOGT(lhs, rhs));
- else
- SetResult(curId, mIRBuilder->CreateICmpSGT(lhs, rhs));
- }
- break;
- case BfIRCmd_CmpUGT:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFCmpOGT(lhs, rhs));
- else
- SetResult(curId, mIRBuilder->CreateICmpUGT(lhs, rhs));
- }
- break;
- case BfIRCmd_CmpSGE:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFCmpOGE(lhs, rhs));
- else
- SetResult(curId, mIRBuilder->CreateICmpSGE(lhs, rhs));
- }
- break;
- case BfIRCmd_CmpUGE:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFCmpOGE(lhs, rhs));
- else
- SetResult(curId, mIRBuilder->CreateICmpUGE(lhs, rhs));
- }
- break;
- case BfIRCmd_Add:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- CMD_PARAM(int8, overflowCheckKind);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFAdd(lhs, rhs));
- else if ((overflowCheckKind & (BfOverflowCheckKind_Signed | BfOverflowCheckKind_Unsigned)) != 0)
- SetResult(curId, DoCheckedIntrinsic(((overflowCheckKind & BfOverflowCheckKind_Signed) != 0) ? llvm::Intrinsic::sadd_with_overflow : llvm::Intrinsic::uadd_with_overflow,
- lhs, rhs, (overflowCheckKind & BfOverflowCheckKind_Flag_UseAsm) != 0));
- else
- SetResult(curId, mIRBuilder->CreateAdd(lhs, rhs));
- }
- break;
- case BfIRCmd_Sub:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- CMD_PARAM(int8, overflowCheckKind);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFSub(lhs, rhs));
- else if ((overflowCheckKind & (BfOverflowCheckKind_Signed | BfOverflowCheckKind_Unsigned)) != 0)
- SetResult(curId, DoCheckedIntrinsic(((overflowCheckKind & BfOverflowCheckKind_Signed) != 0) ? llvm::Intrinsic::ssub_with_overflow : llvm::Intrinsic::usub_with_overflow,
- lhs, rhs, (overflowCheckKind & BfOverflowCheckKind_Flag_UseAsm) != 0));
- else
- SetResult(curId, mIRBuilder->CreateSub(lhs, rhs));
- }
- break;
- case BfIRCmd_Mul:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- CMD_PARAM(int8, overflowCheckKind);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFMul(lhs, rhs));
- else if ((overflowCheckKind & (BfOverflowCheckKind_Signed | BfOverflowCheckKind_Unsigned)) != 0)
- SetResult(curId, DoCheckedIntrinsic(((overflowCheckKind & BfOverflowCheckKind_Signed) != 0) ? llvm::Intrinsic::smul_with_overflow : llvm::Intrinsic::umul_with_overflow,
- lhs, rhs, (overflowCheckKind & BfOverflowCheckKind_Flag_UseAsm) != 0));
- else
- SetResult(curId, mIRBuilder->CreateMul(lhs, rhs));
- }
- break;
- case BfIRCmd_SDiv:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFDiv(lhs, rhs));
- else
- SetResult(curId, mIRBuilder->CreateSDiv(lhs, rhs));
- }
- break;
- case BfIRCmd_UDiv:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- SetResult(curId, mIRBuilder->CreateUDiv(lhs, rhs));
- }
- break;
- case BfIRCmd_SRem:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- if (lhs->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFRem(lhs, rhs));
- else
- SetResult(curId, mIRBuilder->CreateSRem(lhs, rhs));
- }
- break;
- case BfIRCmd_URem:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- SetResult(curId, mIRBuilder->CreateURem(lhs, rhs));
- }
- break;
- case BfIRCmd_And:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- SetResult(curId, mIRBuilder->CreateAnd(lhs, rhs));
- }
- break;
- case BfIRCmd_Or:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- SetResult(curId, mIRBuilder->CreateOr(lhs, rhs));
- }
- break;
- case BfIRCmd_Xor:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- SetResult(curId, mIRBuilder->CreateXor(lhs, rhs));
- }
- break;
- case BfIRCmd_Shl:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- SetResult(curId, mIRBuilder->CreateShl(lhs, rhs));
- }
- break;
- case BfIRCmd_AShr:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- SetResult(curId, mIRBuilder->CreateAShr(lhs, rhs));
- }
- break;
- case BfIRCmd_LShr:
- {
- CMD_PARAM(llvm::Value*, lhs);
- CMD_PARAM(llvm::Value*, rhs);
- SetResult(curId, mIRBuilder->CreateLShr(lhs, rhs));
- }
- break;
- case BfIRCmd_Neg:
- {
- CMD_PARAM(llvm::Value*, val);
- if (val->getType()->isFloatingPointTy())
- SetResult(curId, mIRBuilder->CreateFNeg(val));
- else
- SetResult(curId, mIRBuilder->CreateNeg(val));
- }
- break;
- case BfIRCmd_Not:
- {
- CMD_PARAM(llvm::Value*, val);
- SetResult(curId, mIRBuilder->CreateNot(val));
- }
- break;
- case BfIRCmd_BitCast:
- {
- CMD_PARAM(BfIRTypedValue, val);
- CMD_PARAM(BfIRTypeEx*, toType);
- BfIRTypedValue result;
- result.mTypeEx = toType;
- auto fromType = val.mValue->getType();
- if ((!fromType->isPointerTy()) || (!toType->mLLVMType->isPointerTy()))
- {
- if (fromType->isIntegerTy())
- result.mValue = mIRBuilder->CreateIntToPtr(val.mValue, toType->mLLVMType);
- else
- result.mValue = mIRBuilder->CreatePtrToInt(val.mValue, toType->mLLVMType);
- }
- else
- result.mValue = mIRBuilder->CreateBitCast(val.mValue, toType->mLLVMType);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_PtrToInt:
- {
- CMD_PARAM(llvm::Value*, val);
- auto typeCode = (BfTypeCode)mStream->Read();
- bool isSigned;
- BfIRTypedValue result;
- result.mTypeEx = GetTypeEx(typeCode, isSigned);
- result.mValue = mIRBuilder->CreatePtrToInt(val, result.mTypeEx->mLLVMType);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_IntToPtr:
- {
- CMD_PARAM(llvm::Value*, val);
- CMD_PARAM(BfIRTypeEx*, toType);
- BfIRTypedValue result;
- result.mTypeEx = toType;
- result.mValue = mIRBuilder->CreateIntToPtr(val, toType->mLLVMType);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_InboundsGEP1_32:
- {
- CMD_PARAM(BfIRTypedValue, val);
- CMD_PARAM(int, idx0);
-
- BfIRTypedValue result;
- result.mTypeEx = val.mTypeEx;
- auto alignedPtr = GetAlignedPtr(val);
- auto compositeType = GetTypeMember(alignedPtr.mTypeEx, 0);
- result.mValue = mIRBuilder->CreateConstInBoundsGEP1_32(compositeType->mLLVMType, alignedPtr.mValue, idx0);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_InboundsGEP2_32:
- {
- CMD_PARAM(BfIRTypedValue, val);
- CMD_PARAM(int, idx0);
- CMD_PARAM(int, idx1);
-
- auto compositeType = GetTypeMember(val.mTypeEx, 0);
- int elemIdx = BF_MIN(idx1, (int)compositeType->mMembers.mSize - 1);
- BfIRTypeEx* elemType = GetTypeMember(compositeType, elemIdx);
- BfIRTypedValue result;
- result.mValue = mIRBuilder->CreateConstInBoundsGEP2_32(compositeType->mLLVMType, val.mValue, idx0, idx1);
- result.mTypeEx = GetPointerTypeEx(elemType);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_InBoundsGEP1:
- {
- CMD_PARAM(BfIRTypedValue, val);
- CMD_PARAM(llvm::Value*, idx0);
- BfIRTypedValue result;
- auto alignedPtr = GetAlignedPtr(val);
- auto compositeType = GetTypeMember(alignedPtr.mTypeEx, 0);
- FixIndexer(idx0);
- result.mValue = mIRBuilder->CreateInBoundsGEP(compositeType->mLLVMType, alignedPtr.mValue, idx0);
- result.mTypeEx = val.mTypeEx;
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_InBoundsGEP2:
- {
- CMD_PARAM(BfIRTypedValue, val);
- CMD_PARAM(llvm::Value*, idx0);
- CMD_PARAM(llvm::Value*, idx1);
- FixIndexer(idx0);
- FixIndexer(idx1);
- llvm::Value* indices[2] = { idx0, idx1 };
- int elemIdx = 0;
- if (auto constInt = llvm::dyn_cast<llvm::ConstantInt>(idx1))
- elemIdx = BF_MIN((int)constInt->getSExtValue(), (int)val.mTypeEx->mMembers.mSize - 1);
- auto compositeType = GetTypeMember(val.mTypeEx, 0);
- BfIRTypeEx* elemType = GetTypeMember(compositeType, elemIdx);
- BfIRTypedValue result;
- result.mValue = mIRBuilder->CreateInBoundsGEP(compositeType->mLLVMType, val.mValue, llvm::ArrayRef(indices));
- result.mTypeEx = GetPointerTypeEx(elemType);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_IsNull:
- {
- CMD_PARAM(llvm::Value*, val);
- SetResult(curId, mIRBuilder->CreateIsNull(val));
- }
- break;
- case BfIRCmd_IsNotNull:
- {
- CMD_PARAM(llvm::Value*, val);
- SetResult(curId, mIRBuilder->CreateIsNotNull(val));
- }
- break;
- case BfIRCmd_ExtractValue:
- {
- CMD_PARAM(BfIRTypedValue, val);
- CMD_PARAM(int, idx);
-
- auto compositeType = val.mTypeEx;
- int elemIdx = BF_MIN(idx, (int)compositeType->mMembers.mSize - 1);
- auto elemType = GetTypeMember(compositeType, elemIdx);
- BfIRTypedValue result;
- result.mTypeEx = elemType;
- result.mValue = mIRBuilder->CreateExtractValue(val.mValue, llvm::ArrayRef((unsigned)idx));
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_InsertValue:
- {
- CMD_PARAM(BfIRTypedValue, agg);
- CMD_PARAM(BfIRTypedValue, val);
- CMD_PARAM(int, idx);
- BfIRTypedValue result;
- result.mTypeEx = agg.mTypeEx;
- result.mValue = mIRBuilder->CreateInsertValue(agg.mValue, val.mValue, llvm::ArrayRef((unsigned)idx));
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_Alloca:
- {
- CMD_PARAM(BfIRTypeEx*, type);
- if (type->mLLVMType->isStructTy())
- {
- BF_ASSERT(!((llvm::StructType*)type->mLLVMType)->isOpaque());
- }
- BfIRTypedValue result;
- result.mTypeEx = GetPointerTypeEx(type);
- result.mValue = mIRBuilder->CreateAlloca(type->mLLVMType);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_AllocaArray:
- {
- CMD_PARAM(BfIRTypeEx*, type);
- CMD_PARAM(llvm::Value*, arraySize);
- auto origType = type;
- auto typeEntry = GetTypeEntry(type);
- if (typeEntry != NULL)
- type = GetSizeAlignedType(typeEntry);
- BfIRTypedValue typedValue;
- typedValue.mTypeEx = GetPointerTypeEx(type);
-
- if (origType != type)
- {
- typedValue.mValue = mIRBuilder->CreateAlloca(type->mLLVMType, arraySize);
- SetResultAligned(curId, typedValue);
- }
- else
- {
- typedValue.mValue = mIRBuilder->CreateAlloca(type->mLLVMType, arraySize);
- SetResult(curId, typedValue);
- }
- }
- break;
- case BfIRCmd_SetAllocaAlignment:
- {
- CMD_PARAM_NOTRANS(llvm::Value*, val);
- CMD_PARAM(int, alignment);
- auto inst = llvm::dyn_cast<llvm::AllocaInst>(val);
- inst->setAlignment(llvm::Align(alignment));
- }
- break;
- case BfIRCmd_SetAllocaNoChkStkHint:
- {
- CMD_PARAM_NOTRANS(llvm::Value*, val);
- // LLVM does not support this
- }
- break;
- case BfIRCmd_LifetimeStart:
- {
- CMD_PARAM_NOTRANS(llvm::Value*, val);
- SetResult(curId, mIRBuilder->CreateLifetimeStart(val));
- }
- break;
- case BfIRCmd_LifetimeEnd:
- {
- CMD_PARAM_NOTRANS(llvm::Value*, val);
- SetResult(curId, mIRBuilder->CreateLifetimeEnd(val));
- }
- break;
- case BfIRCmd_LifetimeSoftEnd:
- {
- CMD_PARAM_NOTRANS(llvm::Value*, val);
- }
- break;
- case BfIRCmd_LifetimeExtend:
- {
- CMD_PARAM_NOTRANS(llvm::Value*, val);
- }
- break;
- case BfIRCmd_Load:
- {
- CMD_PARAM(BfIRTypedValue, typedValue);
- BF_ASSERT(typedValue.mTypeEx != NULL);
- CMD_PARAM(bool, isVolatile);
- BfIRTypedValue result;
- result.mTypeEx = GetTypeMember(typedValue.mTypeEx, 0);
- result.mValue = mIRBuilder->CreateLoad(result.mTypeEx->mLLVMType, typedValue.mValue, isVolatile);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_AlignedLoad:
- {
- CMD_PARAM(BfIRTypedValue, typedValue);
- BF_ASSERT(typedValue.mTypeEx != NULL);
- CMD_PARAM(int, alignment);
- CMD_PARAM(bool, isVolatile);
-
- BfIRTypedValue result;
- result.mTypeEx = GetTypeMember(typedValue.mTypeEx, 0);
- result.mValue = mIRBuilder->CreateAlignedLoad(result.mTypeEx->mLLVMType, typedValue.mValue, llvm::MaybeAlign(alignment), isVolatile);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_Store:
- {
- CMD_PARAM(BfIRTypedValue, val);
- CMD_PARAM(BfIRTypedValue, ptr);
- CMD_PARAM(bool, isVolatile);
- if ((!TryMemCpy(ptr, val.mValue)) &&
- (!TryVectorCpy(ptr, val.mValue)))
- SetResult(curId, mIRBuilder->CreateStore(val.mValue, ptr.mValue, isVolatile));
- }
- break;
- case BfIRCmd_AlignedStore:
- {
- CMD_PARAM(BfIRTypedValue, val);
- CMD_PARAM(BfIRTypedValue, ptr);
- CMD_PARAM(int, alignment);
- CMD_PARAM(bool, isVolatile);
- if ((!TryMemCpy(ptr, val.mValue)) &&
- (!TryVectorCpy(ptr, val.mValue)))
- SetResult(curId, mIRBuilder->CreateAlignedStore(val.mValue, ptr.mValue, llvm::MaybeAlign(alignment), isVolatile));
- }
- break;
- case BfIRCmd_MemSet:
- {
- CMD_PARAM(llvm::Value*, addr);
- CMD_PARAM(llvm::Value*, val);
- CMD_PARAM(llvm::Value*, size);
- CMD_PARAM(int, alignment);
- CreateMemSet(addr, val, size, alignment);
- }
- break;
- case BfIRCmd_Fence:
- {
- BfIRFenceType fenceType = (BfIRFenceType)mStream->Read();
- if (fenceType == BfIRFenceType_AcquireRelease)
- mIRBuilder->CreateFence(llvm::AtomicOrdering::AcquireRelease);
- }
- break;
- case BfIRCmd_StackSave:
- {
- //auto intrin = llvm::Intrinsic::getDeclaration(mLLVMModule, llvm::Intrinsic::stacksave);
- //CreateStackSave
- //auto callInst = mIRBuilder->CreateCall(intrin);
- BfIRTypedValue result;
- result.mValue = mIRBuilder->CreateStackSave();
- result.mTypeEx = GetTypeEx(result.mValue->getType());
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_StackRestore:
- {
- CMD_PARAM(llvm::Value*, stackVal);
- //auto intrin = llvm::Intrinsic::getDeclaration(mLLVMModule, llvm::Intrinsic::stackrestore);
- //auto callInst = mIRBuilder->CreateCall(intrin, llvm::SmallVector<llvm::Value*, 1> {stackVal });
- auto callInst = mIRBuilder->CreateStackRestore(stackVal);
- SetResult(curId, callInst);
- }
- break;
- case BfIRCmd_GlobalVariable:
- {
- CMD_PARAM(BfIRTypeEx*, varType);
- CMD_PARAM(bool, isConstant);
- BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
- CMD_PARAM(String, name);
- CMD_PARAM(bool, isTLS);
- CMD_PARAM(llvm::Constant*, initializer);
- auto globalVariable = mLLVMModule->getGlobalVariable(name.c_str());
- if (globalVariable == NULL)
- {
- globalVariable = new llvm::GlobalVariable(
- *mLLVMModule,
- varType->mLLVMType,
- isConstant,
- LLVMMapLinkageType(linkageType),
- initializer,
- name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
- }
- BfIRTypedValue result;
- result.mValue = globalVariable;
- result.mTypeEx = GetPointerTypeEx(varType);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_GlobalVar_SetUnnamedAddr:
- {
- CMD_PARAM(llvm::Value*, val);
- CMD_PARAM(bool, unnamedAddr);
- ((llvm::GlobalVariable*)val)->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
- }
- break;
- case BfIRCmd_GlobalVar_SetInitializer:
- {
- CMD_PARAM(llvm::Value*, val);
- CMD_PARAM(llvm::Constant*, initializer);
- ((llvm::GlobalVariable*)val)->setInitializer(initializer);
- }
- break;
- case BfIRCmd_GlobalVar_SetAlignment:
- {
- CMD_PARAM(llvm::Value*, val);
- CMD_PARAM(int, alignment);
- ((llvm::GlobalVariable*)val)->setAlignment(llvm::Align(alignment));
- }
- break;
- case BfIRCmd_GlobalVar_SetStorageKind:
- {
- CMD_PARAM(llvm::Value*, val);
- CMD_PARAM(int, storageKind);
- ((llvm::GlobalVariable*)val)->setDLLStorageClass((llvm::GlobalValue::DLLStorageClassTypes)storageKind);
- }
- break;
- case BfIRCmd_GlobalStringPtr:
- {
- CMD_PARAM(String, str);
- BfIRTypedValue result;
- result.mValue = mIRBuilder->CreateGlobalStringPtr(llvm::StringRef(str.c_str(), str.length()));
- result.mTypeEx = GetTypeEx(result.mValue->getType());
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_SetReflectTypeData:
- {
- CMD_PARAM(BfIRTypeEx*, type);
- CMD_PARAM(BfIRTypedValue, value);
- mReflectDataMap[type] = value;
- }
- break;
- case BfIRCmd_CreateBlock:
- {
- CMD_PARAM(String, name);
- CMD_PARAM(bool, addNow);
- auto block = llvm::BasicBlock::Create(*mLLVMContext, name.c_str());
- if (addNow)
- mActiveFunction->insert(mActiveFunction->end(), block);
- SetResult(curId, block);
- }
- break;
- case BfIRCmd_MaybeChainNewBlock:
- {
- CMD_PARAM(String, name);
- auto newBlock = mIRBuilder->GetInsertBlock();
- if (!newBlock->empty())
- {
- auto bb = llvm::BasicBlock::Create(*mLLVMContext, name.c_str());
- mIRBuilder->CreateBr(bb);
- mActiveFunction->insert(mActiveFunction->end(), bb);
- mIRBuilder->SetInsertPoint(bb);
- newBlock = bb;
- }
- SetResult(curId, newBlock);
- }
- break;
- case BfIRCmd_AddBlock:
- {
- CMD_PARAM(llvm::BasicBlock*, block);
- mActiveFunction->insert(mActiveFunction->end(), block);
- }
- break;
- case BfIRCmd_DropBlocks:
- {
- //TODO: Not even needed
- // CMD_PARAM(llvm::BasicBlock*, startingBlock);
- // auto& basicBlockList = mActiveFunction->getBasicBlockList();
- // int postExitBlockIdx = -1;
- //
- // auto itr = basicBlockList.rbegin();
- // int blockIdx = (int)basicBlockList.size() - 1;
- // while (itr != basicBlockList.rend())
- // {
- // auto& block = *itr++;
- // block.dropAllReferences();
- // if (&block == startingBlock)
- // {
- // postExitBlockIdx = blockIdx;
- // break;
- // }
- // blockIdx--;
- // }
- //
- // while ((int)basicBlockList.size() > postExitBlockIdx)
- // {
- // auto& block = basicBlockList.back();
- // block.eraseFromParent();
- // }
- }
- break;
- case BfIRCmd_MergeBlockDown:
- {
- CMD_PARAM(llvm::BasicBlock*, fromBlock);
- CMD_PARAM(llvm::BasicBlock*, intoBlock);
- //llvm::BasicBlock::InstListType& fromInstList = fromBlock->getInstList();
- //llvm::BasicBlock::InstListType& intoInstList = intoBlock->getInstList();
- //intoInstList.splice(intoInstList.begin(), fromInstList, fromInstList.begin(), fromInstList.end());
- intoBlock->splice(intoBlock->begin(), fromBlock);
- fromBlock->eraseFromParent();
- }
- break;
- case BfIRCmd_GetInsertBlock:
- {
- SetResult(curId, mIRBuilder->GetInsertBlock());
- }
- break;
- case BfIRCmd_SetInsertPoint:
- {
- CMD_PARAM(llvm::BasicBlock*, block);
- if (mLockedBlocks.Contains(block))
- Fail("Attempt to modify locked block");
- mIRBuilder->SetInsertPoint(block);
- }
- break;
- case BfIRCmd_SetInsertPointAtStart:
- {
- CMD_PARAM(llvm::BasicBlock*, block);
- auto itr = block->begin();
- if (itr != block->end())
- {
- // Some instructructions MUST be at start of the block
- auto instType = itr->getType();
- if (llvm::PHINode::classof(&*itr))
- ++itr;
- }
- mIRBuilder->SetInsertPoint(block, itr);
- // SetInsertPoint can clear the debug loc so reset it here
- mIRBuilder->SetCurrentDebugLocation(mDebugLoc);
- }
- break;
- case BfIRCmd_EraseFromParent:
- {
- CMD_PARAM(llvm::BasicBlock*, block);
- block->eraseFromParent();
- }
- break;
- case BfIRCmd_DeleteBlock:
- {
- CMD_PARAM(llvm::BasicBlock*, block);
- delete block;
- }
- break;
- case BfIRCmd_EraseInstFromParent:
- {
- CMD_PARAM(llvm::Value*, instVal);
- BF_ASSERT(llvm::isa<llvm::Instruction>(instVal));
- ((llvm::Instruction*)instVal)->eraseFromParent();
- }
- break;
- case BfIRCmd_CreateBr:
- case BfIRCmd_CreateBr_NoCollapse:
- {
- CMD_PARAM(llvm::BasicBlock*, block);
- mIRBuilder->CreateBr(block);
- }
- break;
- case BfIRCmd_CreateBr_Fake:
- {
- CMD_PARAM(llvm::BasicBlock*, block);
- // Do nothing
- }
- break;
- case BfIRCmd_CreateCondBr:
- {
- CMD_PARAM(llvm::Value*, condVal);
- CMD_PARAM(llvm::BasicBlock*, trueBlock);
- CMD_PARAM(llvm::BasicBlock*, falseBlock);
- mIRBuilder->CreateCondBr(condVal, trueBlock, falseBlock);
- }
- break;
- case BfIRCmd_MoveBlockToEnd:
- {
- CMD_PARAM(llvm::BasicBlock*, block);
- block->moveAfter(&block->getParent()->back());
- }
- break;
- case BfIRCmd_CreateSwitch:
- {
- CMD_PARAM(llvm::Value*, val);
- CMD_PARAM(llvm::BasicBlock*, dest);
- CMD_PARAM(int, numCases);
- SetResult(curId, mIRBuilder->CreateSwitch(val, dest, numCases));
- }
- break;
- case BfIRCmd_AddSwitchCase:
- {
- CMD_PARAM(llvm::Value*, switchVal);
- CMD_PARAM(llvm::Value*, caseVal);
- CMD_PARAM(llvm::BasicBlock*, caseBlock);
- BF_ASSERT(llvm::isa<llvm::SwitchInst>(switchVal));
- BF_ASSERT(llvm::isa<llvm::ConstantInt>(caseVal));
- ((llvm::SwitchInst*)switchVal)->addCase((llvm::ConstantInt*)caseVal, caseBlock);
- }
- break;
- case BfIRCmd_SetSwitchDefaultDest:
- {
- CMD_PARAM(llvm::Value*, switchVal);
- CMD_PARAM(llvm::BasicBlock*, caseBlock);
- ((llvm::SwitchInst*)switchVal)->setDefaultDest(caseBlock);
- }
- break;
- case BfIRCmd_CreatePhi:
- {
- CMD_PARAM(BfIRTypeEx*, type);
- CMD_PARAM(int, incomingCount);
- BfIRTypedValue result;
- result.mTypeEx = type;
- result.mValue = mIRBuilder->CreatePHI(type->mLLVMType, incomingCount);
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_AddPhiIncoming:
- {
- CMD_PARAM(llvm::Value*, phiValue);
- CMD_PARAM(llvm::Value*, value);
- CMD_PARAM(llvm::BasicBlock*, comingFrom);
- BF_ASSERT(llvm::isa<llvm::PHINode>(phiValue));
- ((llvm::PHINode*)phiValue)->addIncoming(value, comingFrom);
- }
- break;
- case BfIRCmd_GetIntrinsic:
- {
- CMD_PARAM(String, intrinName);
- CMD_PARAM(int, intrinId);
- CMD_PARAM(BfIRTypeEx*, returnType);
- CMD_PARAM(CmdParamVec<BfIRTypeEx*>, paramTypes);
- llvm::Function* func = NULL;
- struct _Intrinsics
- {
- llvm::Intrinsic::ID mID;
- int mArg0;
- int mArg1;
- int mArg2;
- };
- static _Intrinsics intrinsics[] =
- {
- { (llvm::Intrinsic::ID)-1, -1}, // PLATFORM,
- { llvm::Intrinsic::fabs, 0, -1},
- { (llvm::Intrinsic::ID)-2, -1}, // add,
- { (llvm::Intrinsic::ID)-2, -1}, // and,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicAdd,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicAnd,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpStore,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpStore_Weak,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpXChg,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicFence,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicLoad,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicMax,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicMin,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicNAnd,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicOr,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicStore,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicSub,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicUMax,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicUMin,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicXChg,
- { (llvm::Intrinsic::ID)-2, -1}, // AtomicXor,
- { llvm::Intrinsic::bswap, -1},
- { (llvm::Intrinsic::ID)-2, -1}, // cast,
- { llvm::Intrinsic::cos, 0, -1},
- { (llvm::Intrinsic::ID)-2, -1}, // cpuid
- { llvm::Intrinsic::debugtrap, -1}, // debugtrap,
- { (llvm::Intrinsic::ID)-2, -1}, // div
- { (llvm::Intrinsic::ID)-2, -1}, // eq
- { llvm::Intrinsic::floor, 0, -1},
- { (llvm::Intrinsic::ID)-2, -1}, // free
- { (llvm::Intrinsic::ID)-2, -1}, // gt
- { (llvm::Intrinsic::ID)-2, -1}, // gte
- { (llvm::Intrinsic::ID)-2, -1}, // index
- { llvm::Intrinsic::log, 0, -1},
- { llvm::Intrinsic::log10, 0, -1},
- { llvm::Intrinsic::log2, 0, -1},
- { (llvm::Intrinsic::ID)-2, -1}, // lt
- { (llvm::Intrinsic::ID)-2, -1}, // lte
- { (llvm::Intrinsic::ID)-2}, // malloc
- { (llvm::Intrinsic::ID)-2, -1}, // max
- { llvm::Intrinsic::memcpy, 0, 1, 2},
- { llvm::Intrinsic::memmove, 0, 2},
- { llvm::Intrinsic::memset, 0, 2},
- { (llvm::Intrinsic::ID)-2, -1}, // min
- { (llvm::Intrinsic::ID)-2, -1}, // mod
- { (llvm::Intrinsic::ID)-2, -1}, // mul
- { (llvm::Intrinsic::ID)-2, -1}, // neq
- { (llvm::Intrinsic::ID)-2, -1}, // not
- { (llvm::Intrinsic::ID)-2, -1}, // or
- { llvm::Intrinsic::pow, 0, -1},
- { llvm::Intrinsic::powi, 0, -1},
- { llvm::Intrinsic::returnaddress, -1},
- { llvm::Intrinsic::round, 0, -1},
- { (llvm::Intrinsic::ID)-2, -1}, // sar
- { (llvm::Intrinsic::ID)-2, -1}, // shl
- { (llvm::Intrinsic::ID)-2, -1}, // shr
- { (llvm::Intrinsic::ID)-2, -1}, // shuffle
- { llvm::Intrinsic::sin, 0, -1},
- { llvm::Intrinsic::sqrt, 0, -1},
- { (llvm::Intrinsic::ID)-2, -1}, // sub,
- { (llvm::Intrinsic::ID)-2, -1}, // va_arg,
- { llvm::Intrinsic::vaend, -1}, // va_end,
- { llvm::Intrinsic::vastart, -1}, // va_start,
- { (llvm::Intrinsic::ID)-2, -1}, // xgetbv
- { (llvm::Intrinsic::ID)-2, -1}, // xor
- };
- BF_STATIC_ASSERT(BF_ARRAY_COUNT(intrinsics) == BfIRIntrinsic_COUNT);
- CmdParamVec<llvm::Type*> useParams;
- if (intrinsics[intrinId].mArg0 != -1)
- {
- useParams.push_back(paramTypes[0]->mLLVMType);
- if (intrinsics[intrinId].mArg1 != -1)
- {
- useParams.push_back(paramTypes[1]->mLLVMType);
- if (intrinsics[intrinId].mArg2 != -1)
- {
- useParams.push_back(paramTypes[2]->mLLVMType);
- }
- }
- }
- bool isFakeIntrinsic = (int)intrinsics[intrinId].mID == -2;
- if (isFakeIntrinsic)
- {
- auto intrinsicData = mIntrinsicData.Alloc();
- intrinsicData->mName = intrinName;
- intrinsicData->mIntrinsic = (BfIRIntrinsic)intrinId;
- intrinsicData->mReturnType = returnType;
- BfIRCodeGenEntry entry;
- entry.mKind = BfIRCodeGenEntryKind_IntrinsicData;
- entry.mIntrinsicData = intrinsicData;
- mResults.TryAdd(curId, entry);
- break;
- }
- if (intrinId == BfIRIntrinsic__PLATFORM)
- {
- int colonPos = (int)intrinName.IndexOf(':');
- String platName = intrinName.Substring(0, colonPos);
- String platIntrinName = intrinName.Substring(colonPos + 1);
- if (platName.IsEmpty())
- {
- auto intrinsicData = mIntrinsicData.Alloc();
- intrinsicData->mName = platIntrinName;
- intrinsicData->mIntrinsic = BfIRIntrinsic__PLATFORM;
- intrinsicData->mReturnType = returnType;
- BfIRCodeGenEntry entry;
- entry.mKind = BfIRCodeGenEntryKind_IntrinsicData;
- entry.mIntrinsicData = intrinsicData;
- mResults.TryAdd(curId, entry);
- break;
- }
- llvm::Intrinsic::ID intrin = llvm::Intrinsic::getIntrinsicForClangBuiltin(platName.c_str(), platIntrinName.c_str());
- if ((int)intrin <= 0)
- FatalError(StrFormat("Unable to find intrinsic '%s'", intrinName.c_str()));
- else
- func = llvm::Intrinsic::getDeclaration(mLLVMModule, intrinsics[intrinId].mID, useParams);
- }
- else
- {
- BF_ASSERT(intrinsics[intrinId].mID != (llvm::Intrinsic::ID)-1);
- func = llvm::Intrinsic::getDeclaration(mLLVMModule, intrinsics[intrinId].mID, useParams);
- }
- mIntrinsicReverseMap[func] = intrinId;
- auto funcTypeEx = CreateTypeEx(func->getFunctionType());
- funcTypeEx->mMembers.Add(returnType);
- for (auto typeEx : paramTypes)
- funcTypeEx->mMembers.Add(typeEx);
- BfIRTypedValue result;
- result.mTypeEx = GetPointerTypeEx(funcTypeEx);
- result.mValue = func;
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_CreateFunctionType:
- {
- CMD_PARAM(BfIRTypeEx*, resultType);
- CMD_PARAM(CmdParamVec<BfIRTypeEx*>, paramTypes);
- CMD_PARAM(bool, isVarArg);
-
- CmdParamVec<llvm::Type*> llvmTypes;
- for (auto typeEx : paramTypes)
- {
- if (typeEx->mLLVMType->isPointerTy())
- {
- BF_ASSERT(!typeEx->mMembers.IsEmpty());
- }
- llvmTypes.push_back(typeEx->mLLVMType);
- }
- auto funcType = llvm::FunctionType::get(resultType->mLLVMType, llvmTypes, isVarArg);
- auto typeEx = CreateTypeEx(funcType);
- if (typeEx->mMembers.IsEmpty())
- {
- typeEx->mMembers.Add(resultType);
- for (auto paramType : paramTypes)
- typeEx->mMembers.Add(paramType);
- }
- SetResult(curId, typeEx);
- }
- break;
- case BfIRCmd_CreateFunction:
- {
- BfIRTypeEx* type = NULL;
- ReadFunctionType(type);
- BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
- CMD_PARAM(String, name);
- BfIRTypedValue result;
- result.mTypeEx = GetPointerTypeEx(type);
- auto func = mLLVMModule->getFunction(name.c_str());
- if ((func == NULL) || (func->getFunctionType() != type->mLLVMType))
- func = llvm::Function::Create((llvm::FunctionType*)type->mLLVMType, LLVMMapLinkageType(linkageType), name.c_str(), mLLVMModule);
- result.mValue = func;
- SetResult(curId, result);
- }
- break;
- case BfIRCmd_SetFunctionName:
- {
- CMD_PARAM(llvm::Value*, func);
- CMD_PARAM(String, name);
- llvm::Function* llvmFunc = llvm::dyn_cast<llvm::Function>(func);
- llvmFunc->setName(name.c_str());
- }
- break;
- case BfIRCmd_EnsureFunctionPatchable:
- {
- int minPatchSize = 5;
- int guessInstBytes = 1; // ret
- guessInstBytes += mActiveFunction->getFunctionType()->getNumParams() * 4;
- if (guessInstBytes < 5)
- {
- for (auto& block : *mActiveFunction)
- {
- for (auto& inst : block)
- {
- if (auto loadInst = llvm::dyn_cast<llvm::LoadInst>(&inst))
- guessInstBytes += 2;
- else if (auto storeInst = llvm::dyn_cast<llvm::StoreInst>(&inst))
- guessInstBytes += 2;
- else if (auto callInst = llvm::dyn_cast<llvm::CallInst>(&inst))
- {
- auto calledValue = callInst->getCalledOperand();
- if (calledValue == mNopInlineAsm)
- guessInstBytes += 1;
- else if (auto func = llvm::dyn_cast<llvm::Function>(calledValue))
- {
- if (!func->isIntrinsic())
- guessInstBytes += 4;
- }
- else
- guessInstBytes += 4;
- }
- if (guessInstBytes >= minPatchSize)
- break;
- }
- }
- }
- for (int i = guessInstBytes; i < minPatchSize; i++)
- AddNop();
- }
- break;
- case BfIRCmd_RemapBindFunction:
- {
- CMD_PARAM(BfIRTypedValue, func);
- // We need to store this value to a data segment so we get a symbol we can remap during hot swap
- // We actually do this to ensure that we don't bind to the NEW method but rather the old one- so
- // delegate equality checks still work
- llvm::Function* llvmFunc = llvm::dyn_cast<llvm::Function>(func.mValue);
- if (llvmFunc != NULL)
- {
- // I don't know why we mixed in HSPreserveIdx - that causes bound address to change after reloading, basically totally breaking
- // the whole point of this.
- //String funcName = StrFormat("bf_hs_preserve@%d@%s", mModule->mCompiler->mHSPreserveIdx++, func->getName());
- String funcName = StrFormat("bf_hs_preserve@%s_%s", llvmFunc->getName().data(), mLLVMModule->getName().data());
- llvm::GlobalVariable* globalVariable = mLLVMModule->getGlobalVariable(funcName.c_str());
- if (globalVariable == NULL)
- {
- globalVariable = new llvm::GlobalVariable(*mLLVMModule, llvmFunc->getType(), true, llvm::GlobalValue::ExternalLinkage, (llvm::Constant*)llvmFunc, funcName.c_str());
- }
- BfIRTypedValue result;
- result.mTypeEx = func.mTypeEx;
- result.mValue = mIRBuilder->CreateLoad(result.mTypeEx->mLLVMType, globalVariable);
- SetResult(curId, result);
- }
- else
- SetResult(curId, func);
- }
- break;
- case BfIRCmd_SetActiveFunction:
- {
- BfIRTypedValue func;
- ReadFunction(func);
- mActiveFunction = (llvm::Function*)func.mValue;
- if (mActiveFunction == NULL)
- mActiveFunctionType = NULL;
- else
- mActiveFunctionType = GetTypeMember(func.mTypeEx, 0);
- }
- break;
- case BfIRCmd_CreateCall:
- {
- BfIRTypedValue func;
- BfIRCodeGenEntry* codeGenEntry = NULL;
- Read(func, &codeGenEntry);
- CMD_PARAM(CmdParamVec<BfIRTypedValue>, args);
- if ((func.mValue == NULL) && (codeGenEntry != NULL) && (codeGenEntry->mKind == BfIRCodeGenEntryKind_IntrinsicData))
- {
- auto intrinsicData = codeGenEntry->mIntrinsicData;
- switch (intrinsicData->mIntrinsic)
- {
- case BfIRIntrinsic__PLATFORM:
- {
- if (intrinsicData->mName == "add_string_to_section")
- {
- llvm::StringRef strContent[2];
- llvm::ConstantDataArray* dataArray;
- for (int i = 0; i < 2; i++)
- {
- if (const llvm::ConstantExpr* ce = llvm::dyn_cast<llvm::ConstantExpr>(args[i].mValue))
- {
- llvm::Value* firstOperand = ce->getOperand(0);
- if (llvm::GlobalVariable* gv = llvm::dyn_cast<llvm::GlobalVariable>(firstOperand))
- {
- if (gv->getType()->isPointerTy())
- {
- if (dataArray = llvm::dyn_cast<llvm::ConstantDataArray>(gv->getInitializer()))
- strContent[i] = dataArray->getAsString();
- }
- }
- }
- else
- FatalError("Value is not ConstantExpr");
- }
- static int symbolCount = 0;
- symbolCount++;
- auto charType = llvm::IntegerType::get(*mLLVMContext, 8);
- std::vector<llvm::Constant*> chars(strContent[0].size());
- for (unsigned int i = 0; i < strContent[0].size(); i++)
- {
- chars[i] = llvm::ConstantInt::get(charType, strContent[0][i]);;
- }
- chars.push_back(llvm::ConstantInt::get(charType, 0));
- auto stringType = llvm::ArrayType::get(charType, chars.size());
- std::string symbolName = strContent[1].str() + "_" + std::to_string(symbolCount);
- llvm::StringRef resultStringRef(symbolName);
- auto globalVar = (llvm::GlobalVariable*)mLLVMModule->getOrInsertGlobal(symbolName, stringType);
- globalVar->setSection(strContent[1]);
- globalVar->setInitializer(llvm::ConstantArray::get(stringType, chars));
- globalVar->setConstant(true);
- globalVar->setLinkage(llvm::GlobalValue::LinkageTypes::ExternalLinkage);
- globalVar->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
- SetResult(curId, llvm::ConstantExpr::getBitCast(globalVar, charType->getPointerTo()));
- break;
- }
- FatalError(StrFormat("Unable to find intrinsic '%s'", intrinsicData->mName.c_str()));
- break;
- }
- case BfIRIntrinsic_Add:
- case BfIRIntrinsic_And:
- case BfIRIntrinsic_Div:
- case BfIRIntrinsic_Eq:
- case BfIRIntrinsic_Gt:
- case BfIRIntrinsic_GtE:
- case BfIRIntrinsic_Lt:
- case BfIRIntrinsic_LtE:
- case BfIRIntrinsic_Mod:
- case BfIRIntrinsic_Mul:
- case BfIRIntrinsic_Neq:
- case BfIRIntrinsic_Or:
- case BfIRIntrinsic_Sub:
- case BfIRIntrinsic_Xor:
- {
- auto val0 = TryToVector(args[0]);
- if (val0 != NULL)
- {
- auto vecType = llvm::dyn_cast<llvm::VectorType>(val0->getType());
- auto elemType = vecType->getElementType();
- bool isFP = elemType->isFloatingPointTy();
- llvm::Value* val1;
- if (args.size() < 2)
- {
- llvm::Value* val;
- if (isFP)
- val = llvm::ConstantFP::get(elemType, 1);
- else
- val = llvm::ConstantInt::get(elemType, 1);
- val1 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), val, (uint64)0);
- val1 = mIRBuilder->CreateInsertElement(val1, val, (uint64)1);
- val1 = mIRBuilder->CreateInsertElement(val1, val, (uint64)2);
- val1 = mIRBuilder->CreateInsertElement(val1, val, (uint64)3);
- }
- else if (args[1].mValue->getType()->isPointerTy())
- {
- auto ptrVal1 = mIRBuilder->CreateBitCast(args[1].mValue, vecType->getPointerTo());
- val1 = mIRBuilder->CreateAlignedLoad(vecType, ptrVal1, llvm::MaybeAlign(1));
- }
- else if (args[1].mValue->getType()->isVectorTy())
- {
- val1 = args[1].mValue;
- }
- else
- {
- val1 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), args[1].mValue, (uint64)0);
- val1 = mIRBuilder->CreateInsertElement(val1, args[1].mValue, (uint64)1);
- val1 = mIRBuilder->CreateInsertElement(val1, args[1].mValue, (uint64)2);
- val1 = mIRBuilder->CreateInsertElement(val1, args[1].mValue, (uint64)3);
- }
- if (isFP)
- {
- llvm::Value* result = NULL;
- switch (intrinsicData->mIntrinsic)
- {
- case BfIRIntrinsic_Add:
- result = mIRBuilder->CreateFAdd(val0, val1);
- break;
- case BfIRIntrinsic_Div:
- result = mIRBuilder->CreateFDiv(val0, val1);
- break;
- case BfIRIntrinsic_Eq:
- result = mIRBuilder->CreateFCmpOEQ(val0, val1);
- break;
- case BfIRIntrinsic_Gt:
- result = mIRBuilder->CreateFCmpOGT(val0, val1);
- break;
- case BfIRIntrinsic_GtE:
- result = mIRBuilder->CreateFCmpOGE(val0, val1);
- break;
- case BfIRIntrinsic_Lt:
- result = mIRBuilder->CreateFCmpOLT(val0, val1);
- break;
- case BfIRIntrinsic_LtE:
- result = mIRBuilder->CreateFCmpOLE(val0, val1);
- break;
- case BfIRIntrinsic_Mod:
- result = mIRBuilder->CreateFRem(val0, val1);
- break;
- case BfIRIntrinsic_Mul:
- result = mIRBuilder->CreateFMul(val0, val1);
- break;
- case BfIRIntrinsic_Neq:
- result = mIRBuilder->CreateFCmpONE(val0, val1);
- break;
- case BfIRIntrinsic_Sub:
- result = mIRBuilder->CreateFSub(val0, val1);
- break;
- default:
- FatalError("Intrinsic argument error");
- }
- if (result != NULL)
- {
- if (auto vecType = llvm::dyn_cast<llvm::FixedVectorType>(result->getType()))
- {
- if (auto intType = llvm::dyn_cast<llvm::IntegerType>(vecType->getElementType()))
- {
- if (intType->getBitWidth() == 1)
- {
- auto toType = llvm::FixedVectorType::get(llvm::IntegerType::get(*mLLVMContext, 8), vecType->getNumElements());
- result = mIRBuilder->CreateZExt(result, toType);
- }
- }
- }
- SetResult(curId, result);
- }
- }
- else
- {
- llvm::Value* result = NULL;
- switch (intrinsicData->mIntrinsic)
- {
- case BfIRIntrinsic_And:
- result = mIRBuilder->CreateAnd(val0, val1);
- break;
- case BfIRIntrinsic_Add:
- result = mIRBuilder->CreateAdd(val0, val1);
- break;
- case BfIRIntrinsic_Div:
- result = mIRBuilder->CreateSDiv(val0, val1);
- break;
- case BfIRIntrinsic_Eq:
- result = mIRBuilder->CreateICmpEQ(val0, val1);
- break;
- case BfIRIntrinsic_Gt:
- result = mIRBuilder->CreateICmpSGT(val0, val1);
- break;
- case BfIRIntrinsic_GtE:
- result = mIRBuilder->CreateICmpSGE(val0, val1);
- break;
- case BfIRIntrinsic_Lt:
- result = mIRBuilder->CreateICmpSLT(val0, val1);
- break;
- case BfIRIntrinsic_LtE:
- result = mIRBuilder->CreateICmpSLE(val0, val1);
- break;
- case BfIRIntrinsic_Mod:
- result = mIRBuilder->CreateSRem(val0, val1);
- break;
- case BfIRIntrinsic_Mul:
- result = mIRBuilder->CreateMul(val0, val1);
- break;
- case BfIRIntrinsic_Neq:
- result = mIRBuilder->CreateICmpNE(val0, val1);
- break;
- case BfIRIntrinsic_Or:
- result = mIRBuilder->CreateOr(val0, val1);
- break;
- case BfIRIntrinsic_Sub:
- result = mIRBuilder->CreateSub(val0, val1);
- break;
- case BfIRIntrinsic_Xor:
- result = mIRBuilder->CreateXor(val0, val1);
- break;
- default:
- FatalError("Intrinsic argument error");
- }
- if (result != NULL)
- {
- if (auto vecType = llvm::dyn_cast<llvm::FixedVectorType>(result->getType()))
- {
- if (auto intType = llvm::dyn_cast<llvm::IntegerType>(vecType->getElementType()))
- {
- if (intType->getBitWidth() == 1)
- {
- auto toType = llvm::FixedVectorType::get(llvm::IntegerType::get(*mLLVMContext, 8), vecType->getNumElements());
- result = mIRBuilder->CreateZExt(result, toType);
- }
- }
- }
- SetResult(curId, result);
- }
- }
- }
- else if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(args[1].mTypeEx->mLLVMType))
- {
- //auto ptrElemType = ptrType->getElementType();
- auto ptrElemType = GetLLVMPointerElementType(args[1].mTypeEx);
- if (auto arrType = llvm::dyn_cast<llvm::ArrayType>(ptrElemType))
- {
- auto vecType = llvm::FixedVectorType::get(arrType->getArrayElementType(), (uint)arrType->getArrayNumElements());
- auto vecPtrType = vecType->getPointerTo();
- llvm::Value* val0;
- val0 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), args[0].mValue, (uint64)0);
- val0 = mIRBuilder->CreateInsertElement(val0, args[0].mValue, (uint64)1);
- val0 = mIRBuilder->CreateInsertElement(val0, args[0].mValue, (uint64)2);
- val0 = mIRBuilder->CreateInsertElement(val0, args[0].mValue, (uint64)3);
- auto ptrVal1 = mIRBuilder->CreateBitCast(args[1].mValue, vecPtrType);
- auto val1 = mIRBuilder->CreateAlignedLoad(vecType, ptrVal1, llvm::MaybeAlign(1));
- switch (intrinsicData->mIntrinsic)
- {
- case BfIRIntrinsic_Div:
- SetResult(curId, mIRBuilder->CreateFDiv(val0, val1));
- break;
- case BfIRIntrinsic_Mod:
- SetResult(curId, mIRBuilder->CreateFRem(val0, val1));
- break;
- default:
- FatalError("Intrinsic argument error");
- }
- }
- }
- else
- {
- FatalError("Intrinsic argument error");
- }
- }
- break;
- case BfIRIntrinsic_Min:
- case BfIRIntrinsic_Max:
- {
- // Get arguments as vectors
- auto val0 = TryToVector(args[0]);
- if (val0 == NULL)
- FatalError("Intrinsic argument error");
- auto val1 = TryToVector(args[1]);
- if (val1 == NULL)
- FatalError("Intrinsic argument error");
- // Make sure both argument types are the same
- auto vecType = llvm::dyn_cast<llvm::VectorType>(val0->getType());
- if (vecType != llvm::dyn_cast<llvm::VectorType>(val1->getType()))
- FatalError("Intrinsic argument error");
- // Make sure the type is not scalable
- if (vecType->getElementCount().isScalable())
- FatalError("Intrinsic argument error");
- // Make sure the element type is either float or double
- auto elemType = vecType->getElementType();
- if (!elemType->isFloatTy() && !elemType->isDoubleTy())
- FatalError("Intrinsic argument error");
- // Get some properties for easier access
- bool isFloat = elemType->isFloatTy();
- bool isMin = intrinsicData->mIntrinsic == BfIRIntrinsic_Min;
- auto elemCount = vecType->getElementCount().getFixedValue();
- // Get the intrinsic function
- const char* funcName;
- if (isFloat)
- {
- if (elemCount == 4)
- {
- funcName = isMin ? "llvm.x86.sse.min.ps" : "llvm.x86.sse.max.ps";
- SetActiveFunctionSimdType(BfIRSimdType_SSE);
- }
- else if (elemCount == 8)
- {
- funcName = isMin ? "llvm.x86.avx.min.ps.256" : "llvm.x86.avx.max.ps.256";
- SetActiveFunctionSimdType(BfIRSimdType_AVX2);
- }
- else if (elemCount == 16)
- {
- funcName = isMin ? "llvm.x86.avx512.min.ps.512" : "llvm.x86.avx512.max.ps.512";
- SetActiveFunctionSimdType(BfIRSimdType_AVX512);
- }
- else
- FatalError("Intrinsic argument error");
- }
- else
- {
- if (elemCount == 2)
- {
- funcName = isMin ? "llvm.x86.sse.min.pd" : "llvm.x86.sse.max.pd";
- SetActiveFunctionSimdType(BfIRSimdType_SSE);
- }
- else if (elemCount == 4)
- {
- funcName = isMin ? "llvm.x86.avx.min.pd.256" : "llvm.x86.avx.max.pd.256";
- SetActiveFunctionSimdType(BfIRSimdType_AVX2);
- }
- else if (elemCount == 8)
- {
- funcName = isMin ? "llvm.x86.avx512.min.pd.512" : "llvm.x86.avx512.max.pd.512";
- SetActiveFunctionSimdType(BfIRSimdType_AVX512);
- }
- else
- FatalError("Intrinsic argument error");
- }
- auto func = mLLVMModule->getOrInsertFunction(funcName, vecType, vecType, vecType);
- // Call intrinsic
- llvm::SmallVector<llvm::Value*, 2> args;
- args.push_back(val0);
- args.push_back(val1);
- SetResult(curId, mIRBuilder->CreateCall(func, args));
- }
- break;
- case BfIRIntrinsic_Cpuid:
- {
- llvm::Type* elemType = llvm::Type::getInt32Ty(*mLLVMContext);
- // Check argument errors
- if (args.size() != 6 || !args[0].mValue->getType()->isIntegerTy(32) || !args[1].mValue->getType()->isIntegerTy(32))
- FatalError("Intrinsic argument error");
- // for (int i = 2; i < 6; i++)
- // {
- // llvm::Type* type = args[i]->getType();
- //
- // if (!type->isPointerTy() || !GetPointerElementType(args[1])->isIntegerTy(32))
- // FatalError("Intrinsic argument error");
- // }
- // Get asm return type
- llvm::SmallVector<llvm::Type*, 4> asmReturnTypes;
- asmReturnTypes.push_back(elemType);
- asmReturnTypes.push_back(elemType);
- asmReturnTypes.push_back(elemType);
- asmReturnTypes.push_back(elemType);
- llvm::Type* returnType = llvm::StructType::get(*mLLVMContext, asmReturnTypes);
- // Get asm function
- llvm::SmallVector<llvm::Type*, 2> funcParams;
- funcParams.push_back(elemType);
- funcParams.push_back(elemType);
- llvm::FunctionType* funcType = llvm::FunctionType::get(returnType, funcParams, false);
- llvm::InlineAsm* func = llvm::InlineAsm::get(funcType, "xchgq %rbx,${1:q}\ncpuid\nxchgq %rbx,${1:q}", "={ax},=r,={cx},={dx},0,2,~{dirflag},~{fpsr},~{flags}", false);
- // Call asm function
- llvm::SmallVector<llvm::Value*, 2> funcArgs;
- funcArgs.push_back(args[0].mValue);
- funcArgs.push_back(args[1].mValue);
- llvm::Value* asmResult = mIRBuilder->CreateCall(func, funcArgs);
- // Store results
- mIRBuilder->CreateStore(mIRBuilder->CreateExtractValue(asmResult, 0), args[2].mValue);
- mIRBuilder->CreateStore(mIRBuilder->CreateExtractValue(asmResult, 1), args[3].mValue);
- mIRBuilder->CreateStore(mIRBuilder->CreateExtractValue(asmResult, 2), args[4].mValue);
- mIRBuilder->CreateStore(mIRBuilder->CreateExtractValue(asmResult, 3), args[5].mValue);
- }
- break;
- case BfIRIntrinsic_Xgetbv:
- {
- if (args.size() != 1 || !args[0].mValue->getType()->isIntegerTy(32))
- FatalError("Intrinsic argument error");
- auto func = mLLVMModule->getOrInsertFunction("llvm.x86.xgetbv", llvm::Type::getInt64Ty(*mLLVMContext), llvm::Type::getInt32Ty(*mLLVMContext));
- SetResult(curId, mIRBuilder->CreateCall(func, args[0].mValue));
- }
- break;
- case BfIRIntrinsic_Not:
- {
- auto val0 = TryToVector(args[0]);
- SetResult(curId, mIRBuilder->CreateNot(val0));
- }
- break;
- case BfIRIntrinsic_Shuffle:
- {
- llvm::SmallVector<int, 8> intMask;
- for (int i = 7; i < (int)intrinsicData->mName.length(); i++)
- intMask.push_back((int)(intrinsicData->mName[i] - '0'));
- auto val0 = TryToVector(args[0]);
- if (val0 != NULL)
- {
- SetResult(curId, mIRBuilder->CreateShuffleVector(val0, val0, intMask));
- }
- else
- {
- FatalError("Intrinsic argument error");
- }
- }
- break;
- case BfIRIntrinsic_Index:
- {
- llvm::Value* gepArgs[] = {
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0),
- args[1].mValue };
- auto gep = mIRBuilder->CreateInBoundsGEP(GetLLVMPointerElementType(args[0].mTypeEx), args[0].mValue, llvm::ArrayRef(gepArgs));
- if (args.size() >= 3)
- mIRBuilder->CreateStore(args[2].mValue, gep);
- else
- {
- BfIRTypedValue result;
- result.mTypeEx = GetTypeMember(args[0].mTypeEx, 0);
- result.mValue = mIRBuilder->CreateLoad(result.mTypeEx->mLLVMType, gep);
- SetResult(curId, result);
- }
- }
- break;
- case BfIRIntrinsic_AtomicCmpStore:
- case BfIRIntrinsic_AtomicCmpStore_Weak:
- case BfIRIntrinsic_AtomicCmpXChg:
- {
- auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[3].mValue);
- if (memoryKindConst == NULL)
- {
- FatalError("Non-constant success ordering on Atomic_CmpXChg");
- break;
- }
- auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
- auto successOrdering = llvm::AtomicOrdering::Unordered;
- auto failOrdering = llvm::AtomicOrdering::Unordered;
- switch (memoryKind & BfIRAtomicOrdering_ORDERMASK)
- {
- case BfIRAtomicOrdering_Acquire:
- successOrdering = llvm::AtomicOrdering::Acquire;
- failOrdering = llvm::AtomicOrdering::Acquire;
- break;
- case BfIRAtomicOrdering_AcqRel:
- successOrdering = llvm::AtomicOrdering::AcquireRelease;
- failOrdering = llvm::AtomicOrdering::Acquire;
- break;
- case BfIRAtomicOrdering_Relaxed:
- successOrdering = llvm::AtomicOrdering::Monotonic;
- failOrdering = llvm::AtomicOrdering::Monotonic;
- break;
- case BfIRAtomicOrdering_Release:
- successOrdering = llvm::AtomicOrdering::Release;
- failOrdering = llvm::AtomicOrdering::Monotonic;
- break;
- case BfIRAtomicOrdering_SeqCst:
- successOrdering = llvm::AtomicOrdering::SequentiallyConsistent;
- failOrdering = llvm::AtomicOrdering::SequentiallyConsistent;
- break;
- default:
- Fail("Invalid success ordering on Atomic_CmpXChg");
- break;
- }
- if (args.size() >= 5)
- {
- auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[4].mValue);
- if (memoryKindConst == NULL)
- {
- FatalError("Non-constant fail ordering on Atomic_CmpXChg");
- break;
- }
- auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
- switch (memoryKind & BfIRAtomicOrdering_ORDERMASK)
- {
- case BfIRAtomicOrdering_Acquire:
- failOrdering = llvm::AtomicOrdering::Acquire;
- break;
- case BfIRAtomicOrdering_Relaxed:
- failOrdering = llvm::AtomicOrdering::Monotonic;
- break;
- case BfIRAtomicOrdering_SeqCst:
- failOrdering = llvm::AtomicOrdering::SequentiallyConsistent;
- break;
- default:
- FatalError("Invalid fail ordering on Atomic_CmpXChg");
- break;
- }
- }
- auto inst = mIRBuilder->CreateAtomicCmpXchg(args[0].mValue, args[1].mValue, args[2].mValue, llvm::MaybeAlign(), successOrdering, failOrdering);
- if (intrinsicData->mIntrinsic == BfIRIntrinsic_AtomicCmpStore_Weak)
- inst->setWeak(true);
- if ((memoryKind & BfIRAtomicOrdering_Volatile) != 0)
- inst->setVolatile(true);
- if (intrinsicData->mIntrinsic == BfIRIntrinsic_AtomicCmpXChg)
- {
- auto prevVal = mIRBuilder->CreateExtractValue(inst, 0);
- SetResult(curId, prevVal);
- }
- else
- {
- auto successVal = mIRBuilder->CreateExtractValue(inst, 1);
- SetResult(curId, successVal);
- }
- }
- break;
- case BfIRIntrinsic_AtomicFence:
- {
- if (args.size() == 0)
- {
- if ((mTargetTriple.GetMachineType() != BfMachineType_x86) && (mTargetTriple.GetMachineType() != BfMachineType_x64))
- {
- Fail("Unable to create compiler barrier on this platform");
- }
- else
- {
- // Compiler barrier
- llvm::SmallVector<llvm::Type*, 8> paramTypes;
- llvm::FunctionType* funcType = llvm::FunctionType::get(llvm::Type::getVoidTy(*mLLVMContext), paramTypes, false);
- auto fenceFunc = llvm::InlineAsm::get(funcType,
- "", "~{memory},~{dirflag},~{fpsr},~{flags}", true, false, llvm::InlineAsm::AD_ATT);
- mIRBuilder->CreateCall(fenceFunc);
- }
- break;
- }
- auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[0].mValue);
- if (memoryKindConst == NULL)
- {
- FatalError("Non-constant success ordering on AtomicFence");
- break;
- }
- auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
- auto ordering = llvm::AtomicOrdering::SequentiallyConsistent;
- switch (memoryKind & BfIRAtomicOrdering_ORDERMASK)
- {
- case BfIRAtomicOrdering_Acquire:
- ordering = llvm::AtomicOrdering::Acquire;
- break;
- case BfIRAtomicOrdering_AcqRel:
- ordering = llvm::AtomicOrdering::AcquireRelease;
- break;
- case BfIRAtomicOrdering_Release:
- ordering = llvm::AtomicOrdering::Release;
- break;
- case BfIRAtomicOrdering_SeqCst:
- ordering = llvm::AtomicOrdering::SequentiallyConsistent;
- break;
- default:
- Fail("Invalid ordering on atomic operation");
- break;
- }
- mIRBuilder->CreateFence(ordering);
- }
- break;
- case BfIRIntrinsic_AtomicLoad:
- {
- auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[1].mValue);
- if (memoryKindConst == NULL)
- {
- FatalError("Non-constant success ordering on AtomicLoad");
- break;
- }
- BfIRTypedValue result;
- result.mTypeEx = GetTypeMember(args[0].mTypeEx, 0);
- auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
- auto ptrType = llvm::dyn_cast<llvm::PointerType>(args[0].mValue->getType());
- auto loadInst = mIRBuilder->CreateAlignedLoad(result.mTypeEx->mLLVMType, args[0].mValue, llvm::MaybeAlign((uint)GetLLVMPointerElementType(args[0].mTypeEx)->getPrimitiveSizeInBits() / 8));
- switch (memoryKind & BfIRAtomicOrdering_ORDERMASK)
- {
- case BfIRAtomicOrdering_Acquire:
- loadInst->setAtomic(llvm::AtomicOrdering::Acquire);
- break;
- case BfIRAtomicOrdering_Relaxed:
- loadInst->setAtomic(llvm::AtomicOrdering::Monotonic);
- break;
- case BfIRAtomicOrdering_SeqCst:
- loadInst->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
- break;
- default:
- BF_FATAL("BadAtomic");
- }
- if ((memoryKind & BfIRAtomicOrdering_Volatile) != 0)
- loadInst->setVolatile(true);
- result.mValue = loadInst;
- SetResult(curId, result);
- }
- break;
- case BfIRIntrinsic_AtomicStore:
- {
- auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[2].mValue);
- if (memoryKindConst == NULL)
- {
- FatalError("Non-constant success ordering on AtomicLoad");
- break;
- }
- auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
- auto storeInst = mIRBuilder->CreateAlignedStore(args[1].mValue, args[0].mValue, llvm::MaybeAlign((uint)args[1].mValue->getType()->getPrimitiveSizeInBits() / 8));
- switch (memoryKind & BfIRAtomicOrdering_ORDERMASK)
- {
- case BfIRAtomicOrdering_Relaxed:
- storeInst->setAtomic(llvm::AtomicOrdering::Monotonic);
- break;
- case BfIRAtomicOrdering_Release:
- storeInst->setAtomic(llvm::AtomicOrdering::Release);
- break;
- case BfIRAtomicOrdering_SeqCst:
- storeInst->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
- break;
- }
- if ((memoryKind & BfIRAtomicOrdering_Volatile) != 0)
- storeInst->setVolatile(true);
- SetResult(curId, storeInst);
- }
- break;
- case BfIRIntrinsic_AtomicAdd:
- case BfIRIntrinsic_AtomicAnd:
- case BfIRIntrinsic_AtomicMax:
- case BfIRIntrinsic_AtomicMin:
- case BfIRIntrinsic_AtomicNAnd:
- case BfIRIntrinsic_AtomicOr:
- case BfIRIntrinsic_AtomicSub:
- case BfIRIntrinsic_AtomicUMax:
- case BfIRIntrinsic_AtomicUMin:
- case BfIRIntrinsic_AtomicXChg:
- case BfIRIntrinsic_AtomicXor:
- {
- bool isFloat = args[1].mValue->getType()->isFloatingPointTy();
- auto op = llvm::AtomicRMWInst::BinOp::Add;
- switch (intrinsicData->mIntrinsic)
- {
- case BfIRIntrinsic_AtomicAdd:
- op = llvm::AtomicRMWInst::BinOp::Add;
- break;
- case BfIRIntrinsic_AtomicAnd:
- op = llvm::AtomicRMWInst::BinOp::And;
- break;
- case BfIRIntrinsic_AtomicMax:
- op = llvm::AtomicRMWInst::BinOp::Max;
- break;
- case BfIRIntrinsic_AtomicMin:
- op = llvm::AtomicRMWInst::BinOp::Min;
- break;
- case BfIRIntrinsic_AtomicNAnd:
- op = llvm::AtomicRMWInst::BinOp::Nand;
- break;
- case BfIRIntrinsic_AtomicOr:
- op = llvm::AtomicRMWInst::BinOp::Or;
- break;
- case BfIRIntrinsic_AtomicSub:
- op = llvm::AtomicRMWInst::BinOp::Sub;
- break;
- case BfIRIntrinsic_AtomicUMax:
- op = llvm::AtomicRMWInst::BinOp::UMax;
- break;
- case BfIRIntrinsic_AtomicUMin:
- op = llvm::AtomicRMWInst::BinOp::UMin;
- break;
- case BfIRIntrinsic_AtomicXChg:
- op = llvm::AtomicRMWInst::BinOp::Xchg;
- break;
- case BfIRIntrinsic_AtomicXor:
- op = llvm::AtomicRMWInst::BinOp::Xor;
- break;
- default: break;
- }
- auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[2].mValue);
- if (memoryKindConst == NULL)
- {
- FatalError("Non-constant ordering on atomic operation");
- break;
- }
- auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
- auto ordering = llvm::AtomicOrdering::Unordered;
- switch (memoryKind & BfIRAtomicOrdering_ORDERMASK)
- {
- case BfIRAtomicOrdering_Acquire:
- ordering = llvm::AtomicOrdering::Acquire;
- break;
- case BfIRAtomicOrdering_AcqRel:
- ordering = llvm::AtomicOrdering::AcquireRelease;
- break;
- case BfIRAtomicOrdering_Relaxed:
- ordering = llvm::AtomicOrdering::Monotonic;
- break;
- case BfIRAtomicOrdering_Release:
- ordering = llvm::AtomicOrdering::Release;
- break;
- case BfIRAtomicOrdering_SeqCst:
- ordering = llvm::AtomicOrdering::SequentiallyConsistent;
- break;
- default:
- Fail("Invalid ordering on atomic operation");
- break;
- }
- auto atomicRMW = mIRBuilder->CreateAtomicRMW(op, args[0].mValue, args[1].mValue, llvm::MaybeAlign(), ordering);
- if ((memoryKind & BfIRAtomicOrdering_Volatile) != 0)
- atomicRMW->setVolatile(true);
- llvm::Value* result = atomicRMW;
- if ((memoryKind & BfIRAtomicOrdering_ReturnModified) != 0)
- {
- switch (intrinsicData->mIntrinsic)
- {
- case BfIRIntrinsic_AtomicAdd:
- if (isFloat)
- result = mIRBuilder->CreateFAdd(atomicRMW, args[1].mValue);
- else
- result = mIRBuilder->CreateAdd(atomicRMW, args[1].mValue);
- break;
- case BfIRIntrinsic_AtomicAnd:
- result = mIRBuilder->CreateAnd(atomicRMW, args[1].mValue);
- break;
- case BfIRIntrinsic_AtomicMax:
- case BfIRIntrinsic_AtomicMin:
- case BfIRIntrinsic_AtomicUMax:
- case BfIRIntrinsic_AtomicUMin:
- {
- llvm::Value* cmpVal = NULL;
- switch (intrinsicData->mIntrinsic)
- {
- case BfIRIntrinsic_AtomicMax:
- if (isFloat)
- cmpVal = mIRBuilder->CreateFCmpOGE(atomicRMW, args[1].mValue);
- else
- cmpVal = mIRBuilder->CreateICmpSGE(atomicRMW, args[1].mValue);
- break;
- case BfIRIntrinsic_AtomicMin:
- if (isFloat)
- cmpVal = mIRBuilder->CreateFCmpOLE(atomicRMW, args[1].mValue);
- else
- cmpVal = mIRBuilder->CreateICmpSLE(atomicRMW, args[1].mValue);
- break;
- case BfIRIntrinsic_AtomicUMax:
- cmpVal = mIRBuilder->CreateICmpUGE(atomicRMW, args[1].mValue);
- break;
- case BfIRIntrinsic_AtomicUMin:
- cmpVal = mIRBuilder->CreateICmpULE(atomicRMW, args[1].mValue);
- break;
- default: break;
- }
- result = mIRBuilder->CreateSelect(cmpVal, atomicRMW, args[1].mValue);
- }
- break;
- case BfIRIntrinsic_AtomicNAnd:
- result = mIRBuilder->CreateAnd(atomicRMW, args[1].mValue);
- result = mIRBuilder->CreateNot(result);
- break;
- case BfIRIntrinsic_AtomicOr:
- result = mIRBuilder->CreateOr(atomicRMW, args[1].mValue);
- break;
- case BfIRIntrinsic_AtomicSub:
- if (isFloat)
- result = mIRBuilder->CreateFSub(atomicRMW, args[1].mValue);
- else
- result = mIRBuilder->CreateSub(atomicRMW, args[1].mValue);
- break;
- case BfIRIntrinsic_AtomicXor:
- result = mIRBuilder->CreateXor(atomicRMW, args[1].mValue);
- break;
- case BfIRIntrinsic_AtomicXChg:
- result = args[1].mValue;
- break;
- default: break;
- }
- }
- SetResult(curId, result);
- }
- break;
- case BfIRIntrinsic_Cast:
- {
- BfIRTypedValue result;
- result.mTypeEx = intrinsicData->mReturnType;
- auto arg0Type = args[0].mValue->getType();
- if (arg0Type->isPointerTy())
- {
- if (intrinsicData->mReturnType->mLLVMType->isPointerTy())
- {
- result.mValue = mIRBuilder->CreateBitCast(args[0].mValue, intrinsicData->mReturnType->mLLVMType);
- }
- else
- {
- auto castedRes = mIRBuilder->CreateBitCast(args[0].mValue, intrinsicData->mReturnType->mLLVMType->getPointerTo());
- result.mValue = mIRBuilder->CreateAlignedLoad(intrinsicData->mReturnType->mLLVMType, castedRes, llvm::MaybeAlign(1));
- }
- }
- else if ((arg0Type->isVectorTy()) && (intrinsicData->mReturnType->mLLVMType->isVectorTy()))
- {
- result.mValue = mIRBuilder->CreateBitCast(args[0].mValue, intrinsicData->mReturnType->mLLVMType);
- }
- else
- FatalError("Invalid cast intrinsic values");
- SetResult(curId, result);
- }
- break;
- case BfIRIntrinsic_VAArg:
- {
- auto constInt = llvm::dyn_cast<llvm::ConstantInt>(args[2].mValue);
- auto argType = GetLLVMTypeById((int)constInt->getSExtValue());
- auto vaArgVal = mIRBuilder->CreateVAArg(args[0].mValue, argType);
- auto resultPtr = mIRBuilder->CreateBitCast(args[1].mValue, argType->getPointerTo());
- mIRBuilder->CreateStore(vaArgVal, resultPtr);
- }
- break;
- default:
- FatalError("Unhandled intrinsic");
- }
- break;
- }
- if (auto funcPtr = llvm::dyn_cast<llvm::Function>(func.mValue))
- {
- // if (funcPtr->getName() == "__FAILCALL")
- // {
- // FatalError("__FAILCALL");
- // }
- int intrinId = -1;
- if (mIntrinsicReverseMap.TryGetValue(funcPtr, &intrinId))
- {
- if (intrinId == BfIRIntrinsic_MemSet)
- {
- int align = 1;
- BF_ASSERT(args.size() == 5);
- auto alignConst = llvm::dyn_cast<llvm::ConstantInt>(args[3].mValue);
- if (alignConst != NULL)
- align = (int)alignConst->getSExtValue();
- bool isVolatile = false;
- auto volatileConst = llvm::dyn_cast<llvm::ConstantInt>(args[4].mValue);
- if ((volatileConst != NULL) && (volatileConst->getSExtValue() != 0))
- isVolatile = true;
- CreateMemSet(args[0].mValue, args[1].mValue, args[2].mValue, align, isVolatile);
- break;
- }
- else if ((intrinId == BfIRIntrinsic_MemCpy) || (intrinId == BfIRIntrinsic_MemMove))
- {
- int align = 1;
- BF_ASSERT(args.size() == 5);
- auto alignConst = llvm::dyn_cast<llvm::ConstantInt>(args[3].mValue);
- if (alignConst != NULL)
- align = (int)alignConst->getSExtValue();
- bool isVolatile = false;
- auto volatileConst = llvm::dyn_cast<llvm::ConstantInt>(args[4].mValue);
- if ((volatileConst != NULL) && (volatileConst->getSExtValue() != 0))
- isVolatile = true;
- if (intrinId == BfIRIntrinsic_MemCpy)
- mIRBuilder->CreateMemCpy(args[0].mValue, llvm::MaybeAlign(align), args[1].mValue, llvm::MaybeAlign(align), args[2].mValue, isVolatile);
- else
- mIRBuilder->CreateMemMove(args[0].mValue, llvm::MaybeAlign(align), args[1].mValue, llvm::MaybeAlign(align), args[2].mValue, isVolatile);
- break;
- }
- }
- }
- llvm::Value* val0 = NULL;
- llvm::Value* val1 = NULL;
- if (args.size() > 0)
- {
- val0 = args[0].mValue;
- }
- if (args.size() > 1)
- {
- val1 = args[1].mValue;
- }
- llvm::FunctionType* funcType = NULL;
- if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(func.mValue->getType()))
- funcType = llvm::dyn_cast<llvm::FunctionType>(GetLLVMPointerElementType(func.mTypeEx));
- CmdParamVec<llvm::Value*> llvmArgs;
- for (auto& arg : args)
- llvmArgs.push_back(arg.mValue);
- auto funcTypeEx = GetTypeMember(func.mTypeEx, 0);
- auto returnTypeEx = GetTypeMember(funcTypeEx, 0);
-
- BfIRTypedValue result;
- result.mTypeEx = returnTypeEx;
- result.mValue = mIRBuilder->CreateCall(funcType, func.mValue, llvmArgs);
- SetResult(curId, result);
- mLastFuncCalled.mValue = result.mValue;
- mLastFuncCalled.mTypeEx = funcTypeEx;
- }
- break;
- case BfIRCmd_SetCallCallingConv:
- {
- CMD_PARAM(llvm::Value*, callInst);
- BfIRCallingConv callingConv = (BfIRCallingConv)mStream->Read();
- BF_ASSERT(llvm::isa<llvm::CallInst>(callInst));
- ((llvm::CallInst*)callInst)->setCallingConv(GetLLVMCallingConv(callingConv, mTargetTriple));
- }
- break;
- case BfIRCmd_SetFuncCallingConv:
- {
- CMD_PARAM(llvm::Function*, func);
- BfIRCallingConv callingConv = (BfIRCallingConv)mStream->Read();
- ((llvm::Function*)func)->setCallingConv(GetLLVMCallingConv(callingConv, mTargetTriple));
- }
- break;
- case BfIRCmd_SetTailCall:
- {
- CMD_PARAM(llvm::Value*, callInst);
- BF_ASSERT(llvm::isa<llvm::CallInst>(callInst));
- ((llvm::CallInst*)callInst)->setTailCall();
- }
- break;
- case BfIRCmd_SetCallAttribute:
- {
- CMD_PARAM(llvm::Value*, callInst);
- CMD_PARAM(int, paramIdx);
- BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
- BF_ASSERT(llvm::isa<llvm::CallInst>(callInst));
- llvm::Attribute::AttrKind attr = llvm::Attribute::None;
- if (attribute == BfIRAttribute_NoReturn)
- attr = llvm::Attribute::NoReturn;
- ((llvm::CallInst*)callInst)->addParamAttr(paramIdx, attr);
- }
- break;
- case BfIRCmd_CreateRet:
- {
- CMD_PARAM(llvm::Value*, val);
- SetResult(curId, mIRBuilder->CreateRet(val));
- }
- break;
- case BfIRCmd_CreateRetVoid:
- {
- mIRBuilder->CreateRetVoid();
- }
- break;
- case BfIRCmd_CreateUnreachable:
- {
- mIRBuilder->CreateUnreachable();
- }
- break;
- case BfIRCmd_Call_AddAttribute:
- {
- CMD_PARAM(BfIRTypedValue, inst);
- CMD_PARAM(int, argIdx);
- BF_ASSERT(inst.mValue == mLastFuncCalled.mValue);
- BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
- auto attr = LLVMMapAttribute(attribute);
- auto callInst = llvm::dyn_cast<llvm::CallInst>(inst.mValue);
- BfIRTypeEx* funcType = mLastFuncCalled.mTypeEx;
- if (attr == llvm::Attribute::StructRet)
- {
- auto elemPtrType = GetTypeMember(funcType, argIdx);
- auto elemType = GetTypeMember(elemPtrType, 0);
- llvm::Attribute sret = llvm::Attribute::getWithStructRetType(*mLLVMContext, elemType->mLLVMType);
- ((llvm::CallInst*)callInst)->addParamAttr(argIdx - 1, sret);
- }
- else
- {
- if (argIdx == -1)
- ((llvm::CallInst*)callInst)->addFnAttr(attr);
- else if (argIdx == 0)
- ((llvm::CallInst*)callInst)->addRetAttr(attr);
- else
- ((llvm::CallInst*)callInst)->addParamAttr(argIdx - 1, attr);
- }
- }
- break;
- case BfIRCmd_Call_AddAttribute1:
- {
- CMD_PARAM(BfIRTypedValue, inst);
- CMD_PARAM(int, argIdx);
- BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
- CMD_PARAM(int, arg);
- BF_ASSERT(inst.mValue == mLastFuncCalled.mValue);
- auto callInst = llvm::dyn_cast<llvm::CallInst>(inst.mValue);
- if (callInst != NULL)
- {
- BfIRTypeEx* funcType = mLastFuncCalled.mTypeEx;
- if (attribute == BfIRAttribute_Dereferencable)
- {
- ((llvm::CallInst*)callInst)->addDereferenceableParamAttr(argIdx - 1, arg);
- }
- else if (attribute == BfIRAttribute_ByVal)
- {
- auto elemPtrType = GetTypeMember(funcType, argIdx);
- auto elemType = GetTypeMember(elemPtrType, 0);
- llvm::Attribute byValAttr = llvm::Attribute::getWithByValType(*mLLVMContext, elemType->mLLVMType);
- llvm::Attribute alignAttr = llvm::Attribute::getWithAlignment(*mLLVMContext, llvm::Align(arg));
- ((llvm::CallInst*)callInst)->addParamAttr(argIdx - 1, byValAttr);
- ((llvm::CallInst*)callInst)->addParamAttr(argIdx - 1, alignAttr);
- }
- }
- }
- break;
- case BfIRCmd_Func_AddAttribute:
- {
- BfIRTypedValue typedValue;
- ReadFunction(typedValue);
- CMD_PARAM(int, argIdx);
- auto func = llvm::dyn_cast<llvm::Function>(typedValue.mValue);
- auto funcType = GetTypeMember(typedValue.mTypeEx, 0);
- BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
- if (attribute == BFIRAttribute_DllImport)
- {
- func->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
- }
- else if (attribute == BFIRAttribute_DllExport)
- {
- func->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
- mHadDLLExport = true;
- }
- else if (attribute == BFIRAttribute_NoFramePointerElim)
- {
- func->addFnAttr("no-frame-pointer-elim", "true");
- }
- else if ((attribute == BFIRAttribute_Constructor) || (attribute == BFIRAttribute_Destructor))
- {
- CmdParamVec<llvm::Type*> members;
- members.push_back(llvm::Type::getInt32Ty(*mLLVMContext));
- members.push_back(func->getType());
- members.push_back(llvm::PointerType::get(*mLLVMContext, 0));
- llvm::StructType* structType = llvm::StructType::get(*mLLVMContext, members);
- CmdParamVec<llvm::Constant*> structVals;
- structVals.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0x7FFFFF00));
- structVals.push_back(func);
- structVals.push_back(llvm::ConstantPointerNull::get(llvm::PointerType::get(*mLLVMContext, 0)));
- auto constStruct = llvm::ConstantStruct::get(structType, structVals);
- CmdParamVec<llvm::Constant*> structArrVals;
- structArrVals.push_back(constStruct);
- auto arrTy = llvm::ArrayType::get(structType, 1);
- auto constArr = llvm::ConstantArray::get(arrTy, structArrVals);
- auto globalVariable = new llvm::GlobalVariable(
- *mLLVMModule,
- arrTy,
- false,
- llvm::GlobalValue::AppendingLinkage,
- constArr,
- (attribute == BFIRAttribute_Constructor) ? "llvm.global_ctors" : "llvm.global_dtors",
- NULL, llvm::GlobalValue::NotThreadLocal);
- }
- else
- {
- auto attr = LLVMMapAttribute(attribute);
- if (attr == llvm::Attribute::StructRet)
- {
- auto elemPtrType = GetTypeMember(funcType, argIdx);
- auto elemType = GetTypeMember(elemPtrType, 0);
- llvm::Attribute sret = llvm::Attribute::getWithStructRetType(*mLLVMContext, elemType->mLLVMType);
- func->addParamAttr(argIdx - 1, sret);
- }
- else if (attr != llvm::Attribute::None)
- {
- if (argIdx < 0)
- {
- switch (attr)
- {
- case llvm::Attribute::UWTable:
- {
- llvm::AttrBuilder attrBuilder(*mLLVMContext);
- attrBuilder.addUWTableAttr(llvm::UWTableKind::Default);
- func->addFnAttrs(attrBuilder);
- }
- break;
- default:
- func->addFnAttr(attr);
- }
- }
- else if (argIdx == 0)
- func->addRetAttr(attr);
- else
- func->addParamAttr(argIdx - 1, attr);
- }
- }
- }
- break;
- case BfIRCmd_Func_AddAttribute1:
- {
- BfIRTypedValue typedValue;
- ReadFunction(typedValue);
- CMD_PARAM(int, argIdx);
- auto func = llvm::dyn_cast<llvm::Function>(typedValue.mValue);
- auto funcType = GetTypeMember(typedValue.mTypeEx, 0);
-
- BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
- CMD_PARAM(int, arg);
- if (attribute == BfIRAttribute_Dereferencable)
- {
- ((llvm::Function*)func)->addDereferenceableParamAttr(argIdx - 1, arg);
- }
- else if (attribute == BfIRAttribute_ByVal)
- {
- auto elemPtrType = GetTypeMember(funcType, argIdx);
- auto elemType = GetTypeMember(elemPtrType, 0);
- auto funcType = func->getFunctionType();
- llvm::Attribute byValAttr = llvm::Attribute::getWithByValType(*mLLVMContext, elemType->mLLVMType);
- llvm::Attribute alignAttr = llvm::Attribute::getWithAlignment(*mLLVMContext, llvm::Align(arg));
- func->addParamAttr(argIdx - 1, byValAttr);
- func->addParamAttr(argIdx - 1, alignAttr);
- }
- }
- break;
- case BfIRCmd_Func_SetParamName:
- {
- CMD_PARAM(llvm::Function*, func);
- CMD_PARAM(int, argIdx);
- CMD_PARAM(String, name);
- if (argIdx > func->arg_size())
- {
- Fail("BfIRCmd_Func_SetParamName argIdx error");
- break;
- }
- auto argItr = func->arg_begin();
- for (int i = 1; i < argIdx; i++)
- ++argItr;
- argItr->setName(name.c_str());
- }
- break;
- case BfIRCmd_Func_DeleteBody:
- {
- CMD_PARAM(llvm::Function*, func);
- BF_ASSERT(llvm::isa<llvm::Function>(func));
- ((llvm::Function*)func)->deleteBody();
- }
- break;
- case BfIRCmd_Func_SafeRename:
- {
- CMD_PARAM(llvm::Function*, func);
- func->setName(llvm::Twine((Beefy::String(func->getName().data()) + StrFormat("__RENAME%d", curId)).c_str()));
- }
- break;
- case BfIRCmd_Func_SafeRenameFrom:
- {
- CMD_PARAM(llvm::Function*, func);
- CMD_PARAM(String, prevName);
- if (String(func->getName().data()) == prevName)
- func->setName(llvm::Twine((Beefy::String(func->getName().data()) + StrFormat("__RENAME%d", curId)).c_str()));
- }
- break;
- case BfIRCmd_Func_SetLinkage:
- {
- CMD_PARAM(llvm::Function*, func);
- BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
- ((llvm::Function*)func)->setLinkage(LLVMMapLinkageType(linkageType));
- }
- break;
- case BfIRCmd_SaveDebugLocation:
- {
- mSavedDebugLocs.push_back(mIRBuilder->getCurrentDebugLocation());
- }
- break;
- case BfIRCmd_RestoreDebugLocation:
- {
- mDebugLoc = mSavedDebugLocs[mSavedDebugLocs.size() - 1];
- mIRBuilder->SetCurrentDebugLocation(mDebugLoc);
- mSavedDebugLocs.pop_back();
- }
- break;
- case BfIRCmd_DupDebugLocation:
- break;
- case BfIRCmd_ClearDebugLocation:
- {
- mDebugLoc = llvm::DebugLoc();
- mIRBuilder->SetCurrentDebugLocation(llvm::DebugLoc());
- }
- break;
- case BfIRCmd_ClearDebugLocationInst:
- {
- CMD_PARAM_NOTRANS(llvm::Value*, instValue);
- BF_ASSERT(llvm::isa<llvm::Instruction>(instValue));
- if (llvm::dyn_cast<llvm::DbgDeclareInst>(instValue))
- {
- printf("BfIRCmd_ClearDebugLocationInst on DbgDeclareInst in %s\n", mModuleName.c_str());
- }
- else
- {
- ((llvm::Instruction*)instValue)->setDebugLoc(llvm::DebugLoc());
- }
- }
- break;
- case BfIRCmd_ClearDebugLocationInstLast:
- {
- llvm::BasicBlock* bb = mIRBuilder->GetInsertBlock();
- if (bb != NULL)
- {
- if (!bb->empty())
- {
- auto& inst = bb->back();
- if (llvm::dyn_cast<llvm::DbgDeclareInst>(&inst))
- {
- printf("BfIRCmd_ClearDebugLocationInstLast on DbgDeclareInst\n");
- }
- else
- {
- inst.setDebugLoc(llvm::DebugLoc());
- }
- }
- }
- }
- break;
- case BfIRCmd_UpdateDebugLocation:
- {
- CMD_PARAM_NOTRANS(llvm::Value*, instValue);
- BF_ASSERT(llvm::isa<llvm::Instruction>(instValue));
- if ((llvm::dyn_cast<llvm::DbgDeclareInst>(instValue)) && (!mIRBuilder->getCurrentDebugLocation()))
- {
- printf("BfIRCmd_UpdateDebugLocation NULL on DbgDeclareInst\n");
- }
- else
- {
- ((llvm::Instruction*)instValue)->setDebugLoc(mIRBuilder->getCurrentDebugLocation());
- }
- }
- break;
- case BfIRCmd_SetCurrentDebugLocation:
- {
- CMD_PARAM(int, line);
- CMD_PARAM(int, column);
- CMD_PARAM(llvm::MDNode*, diScope);
- CMD_PARAM(llvm::MDNode*, diInlinedAt);
- if (line == 0)
- column = 0;
- mCurLine = line;
- mDebugLoc = llvm::DILocation::get(*mLLVMContext, line, column, diScope, diInlinedAt);
- #ifdef _DEBUG
- llvm::DILocation* DL = mDebugLoc;
- if (DL != NULL)
- {
- llvm::Metadata* Parent = DL->getRawScope();
- llvm::DILocalScope* Scope = DL->getInlinedAtScope();
- llvm::DISubprogram* SP = Scope->getSubprogram();
- if (SP != NULL)
- {
- BF_ASSERT(SP->describes(mActiveFunction));
- }
- }
- #endif
- }
- break;
- case BfIRCmd_Nop:
- case BfIRCmd_EnsureInstructionAt:
- AddNop();
- break;
- case BfIRCmd_StatementStart:
- // We only commit the debug loc for statement starts
- mIRBuilder->SetCurrentDebugLocation(mDebugLoc);
- mHasDebugLoc = true;
- break;
- case BfIRCmd_ObjectAccessCheck:
- {
- CMD_PARAM(llvm::Value*, val);
- CMD_PARAM(bool, useAsm);
- auto curLLVMFunc = mActiveFunction;
- auto irBuilder = mIRBuilder;
- if ((mTargetTriple.GetMachineType() != BfMachineType_x86) && (mTargetTriple.GetMachineType() != BfMachineType_x64))
- useAsm = false;
- if (!useAsm)
- {
- mLockedBlocks.Add(irBuilder->GetInsertBlock());
- // This is generates slower code than the inline asm in debug mode, but can optimize well in release
- auto int8Ty = llvm::Type::getInt8Ty(*mLLVMContext);
- auto int8Ptr = irBuilder->CreateBitCast(val, int8Ty->getPointerTo());
- auto int8Val = irBuilder->CreateLoad(int8Ty, int8Ptr);
- auto cmpResult = irBuilder->CreateICmpUGE(int8Val, llvm::ConstantInt::get(int8Ty, 0x80));
- auto failBB = llvm::BasicBlock::Create(*mLLVMContext, "access.fail");
- auto passBB = llvm::BasicBlock::Create(*mLLVMContext, "access.pass");
- irBuilder->CreateCondBr(cmpResult, failBB, passBB);
- curLLVMFunc->insert(curLLVMFunc->end(), failBB);
- irBuilder->SetInsertPoint(failBB);
- auto trapDecl = llvm::Intrinsic::getDeclaration(mLLVMModule, llvm::Intrinsic::trap);
- auto callInst = irBuilder->CreateCall(trapDecl);
- callInst->addFnAttr(llvm::Attribute::NoReturn);
- irBuilder->CreateBr(passBB);
- curLLVMFunc->insert(curLLVMFunc->end(), passBB);
- irBuilder->SetInsertPoint(passBB);
- SetResult(curId, passBB);
- }
- else
- {
- llvm::Type* voidPtrType = llvm::PointerType::get(*mLLVMContext, 0);
- if (mObjectCheckAsm == NULL)
- {
- std::vector<llvm::Type*> paramTypes;
- paramTypes.push_back(voidPtrType);
- auto funcType = llvm::FunctionType::get(llvm::Type::getVoidTy(*mLLVMContext), paramTypes, false);
- String asmStr =
- "cmpb $$128, ($0)\n"
- "jb 1f\n"
- "int $$3\n"
- "1:";
- mObjectCheckAsm = llvm::InlineAsm::get(funcType,
- asmStr.c_str(), "r,~{dirflag},~{fpsr},~{flags}", true,
- false, llvm::InlineAsm::AD_ATT);
- }
- llvm::SmallVector<llvm::Value*, 1> llvmArgs;
- llvmArgs.push_back(mIRBuilder->CreateBitCast(val, voidPtrType));
- llvm::CallInst* callInst = irBuilder->CreateCall(mObjectCheckAsm, llvmArgs);
- callInst->addFnAttr(llvm::Attribute::NoUnwind);
- SetResult(curId, mIRBuilder->GetInsertBlock());
- }
- }
- break;
- case BfIRCmd_DbgInit:
- {
- mDIBuilder = new llvm::DIBuilder(*mLLVMModule);
- }
- break;
- case BfIRCmd_DbgFinalize:
- {
- for (auto& typeEntryPair : mTypes)
- {
- auto& typeEntry = typeEntryPair.mValue;
- if (typeEntry.mInstDIType != NULL)
- typeEntry.mInstDIType->resolveCycles();
- }
- mDIBuilder->finalize();
- }
- break;
- case BfIRCmd_DbgCreateCompileUnit:
- {
- CMD_PARAM(int, lang);
- CMD_PARAM(String, fileName);
- CMD_PARAM(String, directory);
- CMD_PARAM(String, producer);
- CMD_PARAM(bool, isOptimized);
- CMD_PARAM(String, flags);
- CMD_PARAM(int, runtimeVer);
- CMD_PARAM(bool, linesOnly);
- auto diFile = mDIBuilder->createFile(fileName.c_str(), directory.c_str());
- mDICompileUnit = mDIBuilder->createCompileUnit(lang, diFile, producer.c_str(), isOptimized, flags.c_str(), runtimeVer, "", linesOnly ? llvm::DICompileUnit::LineTablesOnly : llvm::DICompileUnit::FullDebug);
- SetResult(curId, mDICompileUnit);
- }
- break;
- case BfIRCmd_DbgCreateFile:
- {
- CMD_PARAM(String, fileName);
- CMD_PARAM(String, directory);
- CMD_PARAM(Val128, md5Hash);
- char hashStr[64];
- for (int i = 0; i < 16; i++)
- sprintf(&hashStr[i * 2], "%.2x", ((uint8*)&md5Hash)[i]);
- SetResult(curId, mDIBuilder->createFile(fileName.c_str(), directory.c_str(),
- llvm::DIFile::ChecksumInfo<llvm::StringRef>(llvm::DIFile::CSK_MD5, hashStr)));
- }
- break;
- case BfIRCmd_ConstValueI64:
- {
- CMD_PARAM(int64, val);
- SetResult(curId, mDIBuilder->createConstantValueExpression((uint64)val));
- }
- break;
- case BfIRCmd_DbgGetCurrentLocation:
- {
- auto debugLoc = mIRBuilder->getCurrentDebugLocation();
- if (!debugLoc)
- debugLoc = mDebugLoc;
- SetResult(curId, debugLoc);
- }
- break;
- case BfIRCmd_DbgSetType:
- {
- CMD_PARAM(int, typeId);
- CMD_PARAM(llvm::MDNode*, type);
- auto& typeEntry = GetTypeEntry(typeId);
- typeEntry.mDIType = (llvm::DIType*)type;
- if (typeEntry.mInstDIType == NULL)
- typeEntry.mInstDIType = (llvm::DIType*)type;
- }
- break;
- case BfIRCmd_DbgSetInstType:
- {
- CMD_PARAM(int, typeId);
- CMD_PARAM(llvm::MDNode*, type);
- GetTypeEntry(typeId).mInstDIType = (llvm::DIType*)type;
- }
- break;
- case BfIRCmd_DbgGetType:
- {
- CMD_PARAM(int, typeId);
- SetResult(curId, GetTypeEntry(typeId).mDIType);
- }
- break;
- case BfIRCmd_DbgGetTypeInst:
- {
- CMD_PARAM(int, typeId);
- SetResult(curId, GetTypeEntry(typeId).mInstDIType);
- }
- break;
- case BfIRCmd_DbgTrackDITypes:
- {
- CMD_PARAM(int, typeId);
- auto& typeEntry = GetTypeEntry(typeId);
- if (typeEntry.mDIType != NULL)
- llvm::MetadataTracking::track(*(llvm::Metadata**)&typeEntry.mDIType);
- if (typeEntry.mInstDIType != NULL)
- llvm::MetadataTracking::track(*(llvm::Metadata**)&typeEntry.mInstDIType);
- }
- break;
- case BfIRCmd_DbgCreateNamespace:
- {
- CMD_PARAM(llvm::MDNode*, scope);
- CMD_PARAM(String, name);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, lineNum);
- BF_ASSERT(file != NULL);
- SetResult(curId, mDIBuilder->createNameSpace((llvm::DIScope*)scope, name.c_str(), true));
- }
- break;
- case BfIRCmd_DbgCreateImportedModule:
- {
- CMD_PARAM(llvm::MDNode*, context);
- CMD_PARAM(llvm::MDNode*, namespaceNode);
- CMD_PARAM(int, lineNum);
- //SetResult(curId, mDIBuilder->createImportedModule((llvm::DIScope*)context, (llvm::DINamespace*)namespaceNode, lineNum));
- }
- break;
- case BfIRCmd_DbgCreateBasicType:
- {
- CMD_PARAM(String, name);
- CMD_PARAM(int64, sizeInBits);
- CMD_PARAM(int64, alignInBits);
- CMD_PARAM(int, encoding);
- SetResult(curId, mDIBuilder->createBasicType(name.c_str(), sizeInBits, encoding));
- }
- break;
- case BfIRCmd_DbgCreateStructType:
- {
- CMD_PARAM(llvm::MDNode*, context);
- CMD_PARAM(String, name);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, lineNum);
- CMD_PARAM(int64, sizeInBits);
- CMD_PARAM(int64, alignInBits);
- CMD_PARAM(int, flags);
- CMD_PARAM(llvm::MDNode*, derivedFrom);
- CMD_PARAM(CmdParamVec<llvm::Metadata*>, members);
- auto diMembersArray = mDIBuilder->getOrCreateArray(members);
- BF_ASSERT(file != NULL);
- llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
- auto mdStruct = mDIBuilder->createStructType((llvm::DIScope*)context, name.c_str(), (llvm::DIFile*)file, lineNum, sizeInBits, (uint32)alignInBits, diFlags, (llvm::DIType*)derivedFrom, diMembersArray);
- SetResult(curId, mdStruct);
- //OutputDebugStrF("BfIRCmd_DbgCreateStructType %p\n", mdStruct);
- }
- break;
- case BfIRCmd_DbgCreateEnumerationType:
- {
- CMD_PARAM(llvm::MDNode*, context);
- CMD_PARAM(String, name);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, lineNum);
- CMD_PARAM(int64, sizeInBits);
- CMD_PARAM(int64, alignInBits);
- CMD_PARAM(CmdParamVec<llvm::Metadata*>, members);
- CMD_PARAM(llvm::MDNode*, underlyingType);
- auto diMembersArray = mDIBuilder->getOrCreateArray(members);
- /*static int typeIdx = 0;
- if (name == "TypeCode")
- name += StrFormat("_%d", typeIdx);
- typeIdx++;*/
- BF_ASSERT(file != NULL);
- auto enumType = mDIBuilder->createEnumerationType((llvm::DIScope*)context, name.c_str(), (llvm::DIFile*)file, lineNum, sizeInBits, (uint32)alignInBits, diMembersArray, (llvm::DIType*)underlyingType);
- SetResult(curId, enumType);
- //OutputDebugStrF("BfIRCmd_DbgCreateEnumerationType %p\n", enumType);
- }
- break;
- case BfIRCmd_DbgCreatePointerType:
- {
- CMD_PARAM(llvm::MDNode*, diType);
- SetResult(curId, mDIBuilder->createPointerType((llvm::DIType*)diType, mPtrSize*8, (uint32)mPtrSize * 8));
- }
- break;
- case BfIRCmd_DbgCreateReferenceType:
- {
- CMD_PARAM(llvm::MDNode*, diType);
- SetResult(curId, mDIBuilder->createReferenceType(llvm::dwarf::DW_TAG_reference_type, (llvm::DIType*)diType));
- }
- break;
- case BfIRCmd_DbgCreateConstType:
- {
- CMD_PARAM(llvm::MDNode*, diType);
- SetResult(curId, mDIBuilder->createQualifiedType(llvm::dwarf::DW_TAG_const_type, (llvm::DIType*)diType));
- }
- break;
- case BfIRCmd_DbgCreateArtificialType:
- {
- CMD_PARAM(llvm::MDNode*, diType);
- SetResult(curId, mDIBuilder->createArtificialType((llvm::DIType*)diType));
- }
- break;
- case BfIRCmd_DbgCreateArrayType:
- {
- CMD_PARAM(int64, sizeInBits);
- CMD_PARAM(int64, alignInBits);
- CMD_PARAM(llvm::MDNode*, elementType);
- CMD_PARAM(int64, numElements);
- llvm::SmallVector<llvm::Metadata*, 1> diSizeVec;
- diSizeVec.push_back(mDIBuilder->getOrCreateSubrange(0, numElements));
- auto diSizeArray = mDIBuilder->getOrCreateArray(diSizeVec);
- SetResult(curId, mDIBuilder->createArrayType(sizeInBits, (uint32)alignInBits, (llvm::DIType*)elementType, diSizeArray));
- }
- break;
- case BfIRCmd_DbgCreateReplaceableCompositeType:
- {
- CMD_PARAM(int, tag);
- CMD_PARAM(String, name);
- CMD_PARAM(llvm::MDNode*, scope);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, line);
- CMD_PARAM(int64, sizeInBits);
- CMD_PARAM(int64, alignInBits);
- CMD_PARAM(int, flags);
- BF_ASSERT(file != NULL);
- llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
- SetResult(curId, mDIBuilder->createReplaceableCompositeType(tag, name.c_str(), (llvm::DIScope*)scope, (llvm::DIFile*)file, line, 0, sizeInBits, (uint32)alignInBits, diFlags));
- }
- break;
- case BfIRCmd_DbgCreateForwardDecl:
- {
- CMD_PARAM(int, tag);
- CMD_PARAM(String, name);
- CMD_PARAM(llvm::MDNode*, scope);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, line);
- BF_ASSERT(file != NULL);
- auto diType = mDIBuilder->createForwardDecl(tag, name.c_str(), (llvm::DIScope*)scope, (llvm::DIFile*)file, line);
- SetResult(curId, diType);
- }
- break;
- case BfIRCmd_DbgCreateSizedForwardDecl:
- {
- CMD_PARAM(int, tag);
- CMD_PARAM(String, name);
- CMD_PARAM(llvm::MDNode*, scope);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, line);
- CMD_PARAM(int64, sizeInBits);
- CMD_PARAM(int64, alignInBits);
- BF_ASSERT(file != NULL);
- SetResult(curId, mDIBuilder->createForwardDecl(tag, name.c_str(), (llvm::DIScope*)scope, (llvm::DIFile*)file, line, 0, sizeInBits, (uint32)alignInBits));
- }
- break;
- case BeIRCmd_DbgSetTypeSize:
- {
- CMD_PARAM(llvm::MDNode*, mdType);
- CMD_PARAM(int64, sizeInBits);
- CMD_PARAM(int64, alignInBits);
- class DIMutType : public llvm::DIType
- {
- public:
- void Resize(int64 newSize, int32 newAlign)
- {
- init(getLine(), newSize, newAlign, getOffsetInBits(), getFlags());
- }
- };
- auto diType = (DIMutType*)mdType;
- diType->Resize(sizeInBits, (int32)alignInBits);
- }
- break;
- case BfIRCmd_DbgReplaceAllUses:
- {
- CMD_PARAM(llvm::MDNode*, diPrevNode);
- CMD_PARAM(llvm::MDNode*, diNewNode);
- diPrevNode->replaceAllUsesWith(diNewNode);
- }
- break;
- case BfIRCmd_DbgDeleteTemporary:
- {
- CMD_PARAM(llvm::MDNode*, diNode);
- llvm::MDNode::deleteTemporary(diNode);
- }
- break;
- case BfIRCmd_DbgMakePermanent:
- {
- CMD_PARAM(llvm::MDNode*, diNode);
- CMD_PARAM(llvm::MDNode*, diBaseType);
- CMD_PARAM(CmdParamVec<llvm::Metadata*>, members);
- llvm::MDNode* newNode = diNode;
- if (auto diComposite = llvm::dyn_cast<llvm::DICompositeType>(diNode))
- {
- //diComposite->getBaseType()
- if (diBaseType != NULL)
- {
- // It's unfortunate we have to hard-code the '3' here
- diComposite->replaceOperandWith(3, diBaseType);
- BF_ASSERT(diComposite->getBaseType() == diBaseType);
- }
- if (members.size() != 0)
- {
- llvm::DINodeArray elements = mDIBuilder->getOrCreateArray(members);
- mDIBuilder->replaceArrays(diComposite, elements);
- }
- newNode = llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(diComposite));
- }
- /*else if (auto diEnumerator = llvm::dyn_cast<llvm::DIEnumerator>(diNode))
- {
- if (members.size() != 0)
- {
- llvm::DINodeArray elements = mDIBuilder->getOrCreateArray(diNode);
- mDIBuilder->set(diComposite, elements);
- }
- newNode = llvm::MDNode::replaceWithPermanent(llvm::TempDIEnumerator(diEnumerator));
- }*/
- SetResult(curId, newNode);
- break;
- }
- case BfIRCmd_CreateEnumerator:
- {
- CMD_PARAM(String, name);
- CMD_PARAM(int64, val);
- SetResult(curId, mDIBuilder->createEnumerator(name.c_str(), val));
- }
- break;
- case BfIRCmd_DbgCreateMemberType:
- {
- CMD_PARAM(llvm::MDNode*, scope);
- CMD_PARAM(String, name);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, lineNumber);
- CMD_PARAM(int64, sizeInBits);
- CMD_PARAM(int64, alignInBits);
- CMD_PARAM(int64, offsetInBits);
- CMD_PARAM(int, flags);
- CMD_PARAM(llvm::MDNode*, type);
- BF_ASSERT(file != NULL);
- llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
- /*Beefy::debug_ostream os;
- os << "BfIRCmd_DbgCreateMemberType " << name.c_str() << "\n";
- scope->print(os);
- os << "\n";
- type->print(os);
- os << "\n";
- os.flush();*/
- const char* namePtr = name.c_str();
- if (name.IsEmpty())
- namePtr = NULL;
- auto member = mDIBuilder->createMemberType((llvm::DIScope*)scope, namePtr, (llvm::DIFile*)file, lineNumber, sizeInBits, (uint32)alignInBits, offsetInBits, diFlags, (llvm::DIType*)type);
- SetResult(curId, member);
- //OutputDebugStrF("BfIRCmd_DbgCreateMemberType = %p\n", member);
- }
- break;
- case BfIRCmd_DbgStaticCreateMemberType:
- {
- CMD_PARAM(llvm::MDNode*, scope);
- CMD_PARAM(String, name);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, lineNumber);
- CMD_PARAM(llvm::MDNode*, type);
- CMD_PARAM(int, flags);
- CMD_PARAM(llvm::Constant*, val);
- BF_ASSERT(file != NULL);
- llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
- /*Beefy::debug_ostream os;
- os << "BfIRCmd_DbgStaticCreateMemberType " << name.c_str() << "\n";
- scope->print(os);
- os << "\n";
- type->print(os);
- os << "\n";
- os.flush();*/
- auto member = mDIBuilder->createStaticMemberType((llvm::DIScope*)scope, name.c_str(), (llvm::DIFile*)file, lineNumber, (llvm::DIType*)type, diFlags, val, llvm::dwarf::DW_TAG_member);
- SetResult(curId, member);
- //OutputDebugStrF("BfIRCmd_DbgStaticCreateMemberType = %p\n", member);
- }
- break;
- case BfIRCmd_DbgCreateInheritance:
- {
- CMD_PARAM(llvm::MDNode*, type);
- CMD_PARAM(llvm::MDNode*, baseType);
- CMD_PARAM(int64, baseOffset);
- CMD_PARAM(int, flags);
- llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
- auto member = mDIBuilder->createInheritance((llvm::DIType*)type, (llvm::DIType*)baseType, baseOffset, 0, diFlags);
- SetResult(curId, member);
- //OutputDebugStrF("BfIRCmd_DbgCreateInheritance = %p\n", member);
- }
- break;
- case BfIRCmd_DbgCreateMethod:
- {
- CMD_PARAM(llvm::MDNode*, context);
- CMD_PARAM(String, name);
- CMD_PARAM(String, linkageName);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, lineNum);
- CMD_PARAM(llvm::MDNode*, type);
- CMD_PARAM(bool, isLocalToUnit);
- CMD_PARAM(bool, isDefinition);
- CMD_PARAM(int, vk);
- CMD_PARAM(int, vIndex);
- CMD_PARAM(llvm::MDNode*, vTableHolder);
- CMD_PARAM(int, flags);
- CMD_PARAM(bool, isOptimized);
- CMD_PARAM(llvm::Value*, fn);
- CMD_PARAM(CmdParamVec<llvm::MDNode*>, genericArgs);
- CMD_PARAM(CmdParamVec<llvm::Constant*>, genericConstValueArgs);
- BF_ASSERT(file != NULL);
- llvm::DITemplateParameterArray templateParamArr = NULL;
- llvm::DINodeArray templateParamNodes;
- if (genericArgs.size() != 0)
- {
- llvm::SmallVector<llvm::Metadata*, 16> templateParams;
- for (int i = 0; i < (int)genericArgs.size(); i++)
- {
- auto genericArg = (llvm::DIType*)genericArgs[i];
- String name = StrFormat("T%d", i);
- llvm::Constant* constant = NULL;
- if (i < genericConstValueArgs.size())
- constant = genericConstValueArgs[i];
- if (constant != NULL)
- templateParams.push_back(mDIBuilder->createTemplateValueParameter(mDICompileUnit, name.c_str(), genericArg, false, constant));
- else
- templateParams.push_back(mDIBuilder->createTemplateTypeParameter(mDICompileUnit, name.c_str(), genericArg, false));
- }
- templateParamNodes = mDIBuilder->getOrCreateArray(templateParams);
- templateParamArr = templateParamNodes.get();
- }
- llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
- llvm::DISubprogram::DISPFlags dispFlags = llvm::DISubprogram::DISPFlags::SPFlagZero;
- if (isLocalToUnit)
- dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagLocalToUnit);
- if (isDefinition)
- dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagDefinition);
- if (isOptimized)
- dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagOptimized);
- if (vk != 0)
- dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagVirtual);
- auto diSubProgram = mDIBuilder->createMethod((llvm::DIScope*)context, name.c_str(), linkageName.c_str(), (llvm::DIFile*)file, lineNum,
- (llvm::DISubroutineType*)type, vIndex, 0, (llvm::DIType*)vTableHolder, diFlags, dispFlags, templateParamArr);
- if (fn != NULL)
- ((llvm::Function*)fn)->setSubprogram(diSubProgram);
- SetResult(curId, diSubProgram);
- //OutputDebugStrF("BfIRCmd_DbgCreateMethod = %p\n", diSubProgram);
- }
- break;
- case BfIRCmd_DbgCreateFunction:
- {
- CMD_PARAM(llvm::MDNode*, context);
- CMD_PARAM(String, name);
- CMD_PARAM(String, linkageName);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, lineNum);
- CMD_PARAM(llvm::MDNode*, type);
- CMD_PARAM(bool, isLocalToUnit);
- CMD_PARAM(bool, isDefinition);
- CMD_PARAM(int, scopeLine);
- CMD_PARAM(int, flags);
- CMD_PARAM(bool, isOptimized);
- CMD_PARAM(llvm::Value*, fn);
- BF_ASSERT(file != NULL);
- llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
- llvm::DISubprogram::DISPFlags dispFlags = llvm::DISubprogram::DISPFlags::SPFlagZero;
- if (isLocalToUnit)
- dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagLocalToUnit);
- if (isDefinition)
- dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagDefinition);
- if (isOptimized)
- dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagOptimized);
- auto diSubProgram = mDIBuilder->createFunction((llvm::DIScope*)context, name.c_str(), linkageName.c_str(), (llvm::DIFile*)file, lineNum,
- (llvm::DISubroutineType*)type, scopeLine, diFlags, dispFlags);
- if (fn != NULL)
- ((llvm::Function*)fn)->setSubprogram(diSubProgram);
- SetResult(curId, diSubProgram);
- //OutputDebugStrF("BfIRCmd_DbgCreateFunction = %p\n", diSubProgram);
- }
- break;
- case BfIRCmd_DbgCreateParameterVariable:
- {
- CMD_PARAM(llvm::MDNode*, scope);
- CMD_PARAM(String, name);
- CMD_PARAM(int, argNo);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, lineNum);
- CMD_PARAM(llvm::MDNode*, type);
- CMD_PARAM(bool, alwaysPreserve);
- CMD_PARAM(int, flags);
- BF_ASSERT(file != NULL);
- llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
- SetResult(curId, mDIBuilder->createParameterVariable((llvm::DIScope*)scope, name.c_str(), argNo, (llvm::DIFile*)file, lineNum, (llvm::DIType*)type,
- alwaysPreserve, diFlags));
- }
- break;
- case BfIRCmd_DbgCreateSubroutineType:
- {
- CMD_PARAM(CmdParamVec<llvm::Metadata*>, elements);
- auto diArray = mDIBuilder->getOrCreateTypeArray(elements);
- SetResult(curId, mDIBuilder->createSubroutineType(diArray));
- }
- break;
- case BfIRCmd_DbgCreateAutoVariable:
- {
- CMD_PARAM(llvm::MDNode*, scope);
- CMD_PARAM(String, name);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, lineNo);
- CMD_PARAM(llvm::MDNode*, type);
- CMD_PARAM(int, initType);
- BF_ASSERT(file != NULL);
- llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)0;
- auto loc = mIRBuilder->getCurrentDebugLocation();
- auto dbgLoc = loc.getAsMDNode();
- SetResult(curId, mDIBuilder->createAutoVariable((llvm::DIScope*)scope, name.c_str(), (llvm::DIFile*)file, lineNo, (llvm::DIType*)type, false, diFlags));
- }
- break;
- case BfIRCmd_DbgInsertValueIntrinsic:
- {
- CMD_PARAM(llvm::Value*, val);
- CMD_PARAM(llvm::MDNode*, varInfo);
- auto diVariable = (llvm::DILocalVariable*)varInfo;
- if (val == NULL)
- {
- val = llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0);
- }
- else if (mIsCodeView)
- {
- if (auto constant = llvm::dyn_cast<llvm::Constant>(val))
- {
- int64 writeVal = 0;
- if (auto constantInt = llvm::dyn_cast<llvm::ConstantInt>(val))
- {
- writeVal = constantInt->getSExtValue();
- }
- auto nameRef = diVariable->getName();
- if (writeVal < 0)
- diVariable->replaceOperandWith(1, llvm::MDString::get(*mLLVMContext, (String(nameRef.data()) + StrFormat("$_%llu", -writeVal)).c_str()));
- else
- diVariable->replaceOperandWith(1, llvm::MDString::get(*mLLVMContext, (String(nameRef.data()) + StrFormat("$%llu", writeVal)).c_str()));
- }
- }
- mDIBuilder->insertDbgValueIntrinsic(val, diVariable, mDIBuilder->createExpression(),
- mIRBuilder->getCurrentDebugLocation(), (llvm::BasicBlock*)mIRBuilder->GetInsertBlock());
- }
- break;
- case BfIRCmd_DbgInsertDeclare:
- {
- CMD_PARAM(llvm::Value*, val);
- CMD_PARAM(llvm::MDNode*, varInfo);
- CMD_PARAM(llvm::Value*, insertBefore);
- llvm::Instruction* insertBeforeInst = NULL;
- if (insertBefore != NULL)
- insertBeforeInst = llvm::dyn_cast<llvm::Instruction>(insertBefore);
- // Protect against lack of debug location
- if (mIRBuilder->getCurrentDebugLocation())
- {
- if (insertBeforeInst != NULL)
- {
- auto& dbgResult = mDIBuilder->insertDeclare(val, (llvm::DILocalVariable*)varInfo, mDIBuilder->createExpression(),
- mIRBuilder->getCurrentDebugLocation(), insertBeforeInst);
- bool isA = dbgResult.is<llvm::Instruction*>();
- auto inst = dbgResult.get<llvm::Instruction*>();
- SetResult(curId, inst);
- }
- else
- {
- auto& dbgResult = mDIBuilder->insertDeclare(val, (llvm::DILocalVariable*)varInfo, mDIBuilder->createExpression(),
- mIRBuilder->getCurrentDebugLocation(), mIRBuilder->GetInsertBlock());
- bool isA = dbgResult.is<llvm::Instruction*>();
- auto inst = dbgResult.get<llvm::Instruction*>();
- SetResult(curId, inst);
- }
- }
- }
- break;
- case BfIRCmd_DbgLifetimeEnd:
- {
- CMD_PARAM(llvm::MDNode*, varInfo);
- }
- break;
- case BfIRCmd_DbgCreateGlobalVariable:
- {
- CMD_PARAM(llvm::MDNode*, context);
- CMD_PARAM(String, name);
- CMD_PARAM(String, linkageName);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, lineNum);
- CMD_PARAM(llvm::MDNode*, type);
- CMD_PARAM(bool, isLocalToUnit);
- CMD_PARAM(llvm::Constant*, val);
- CMD_PARAM(llvm::MDNode*, decl);
- //BF_ASSERT(file != NULL);
- llvm::DIExpression* diExpr = NULL;
- auto gve = mDIBuilder->createGlobalVariableExpression((llvm::DIScope*)context, name.c_str(), linkageName.c_str(), (llvm::DIFile*)file, lineNum, (llvm::DIType*)type,
- isLocalToUnit, true, diExpr, decl);
- if (val != NULL)
- {
- if (auto globalVar = llvm::dyn_cast<llvm::GlobalVariable>(val))
- {
- globalVar->addDebugInfo(gve);
- }
- }
- SetResult(curId, diExpr);
- }
- break;
- case BfIRCmd_DbgCreateLexicalBlock:
- {
- CMD_PARAM(llvm::MDNode*, scope);
- CMD_PARAM(llvm::MDNode*, file);
- CMD_PARAM(int, lineNum);
- CMD_PARAM(int, col);
- if (lineNum == 0)
- col = 0;
- BF_ASSERT(file != NULL);
- SetResult(curId, mDIBuilder->createLexicalBlock((llvm::DIScope*)scope, (llvm::DIFile*)file, (unsigned)lineNum, (unsigned)col));
- }
- break;
- case BfIRCmd_DbgCreateAnnotation:
- {
- CMD_PARAM(llvm::MDNode*, scope);
- CMD_PARAM(String, name);
- CMD_PARAM(llvm::Value*, value);
- if (auto dbgFunc = llvm::dyn_cast<llvm::DISubprogram>(scope))
- {
- auto beType = value->getType();
- auto diType = mDIBuilder->createBasicType("int32", 4 * 8, llvm::dwarf::DW_ATE_signed);
- llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)0;
- auto loc = mIRBuilder->getCurrentDebugLocation();
- auto dbgLoc = loc.getAsMDNode();
- auto diScope = (llvm::DIScope*)scope;
- String dbgName = "#" + name;
- int64 writeVal = 0;
- if (auto constant = llvm::dyn_cast<llvm::ConstantInt>(value))
- {
- writeVal = constant->getSExtValue();
- }
- if (writeVal < 0)
- dbgName += StrFormat("$_%llu", -writeVal);
- else
- dbgName += StrFormat("$%llu", writeVal);
- auto dbgVar = mDIBuilder->createAutoVariable((llvm::DIScope*)scope, dbgName.c_str(), (llvm::DIFile*)diScope->getFile(), 0, diType, false, diFlags);
- mDIBuilder->insertDbgValueIntrinsic(value, dbgVar, mDIBuilder->createExpression(),
- mIRBuilder->getCurrentDebugLocation(), (llvm::BasicBlock*)mIRBuilder->GetInsertBlock());
- }
- }
- break;
- default:
- BF_FATAL("Unhandled");
- break;
- }
- }
- void BfIRCodeGen::SetCodeGenOptions(BfCodeGenOptions codeGenOptions)
- {
- mCodeGenOptions = codeGenOptions;
- }
- void BfIRCodeGen::SetConfigConst(int idx, int value)
- {
- auto constVal = llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), value);
- BF_ASSERT(idx == (int)mConfigConsts32.size());
- mConfigConsts32.Add(constVal);
- constVal = llvm::ConstantInt::get(llvm::Type::getInt64Ty(*mLLVMContext), value);
- BF_ASSERT(idx == (int)mConfigConsts64.size());
- mConfigConsts64.Add(constVal);
- }
- void BfIRCodeGen::SetActiveFunctionSimdType(BfIRSimdType type)
- {
- BfIRSimdType currentType;
- bool contains = mFunctionsUsingSimd.TryGetValue(mActiveFunction, ¤tType);
- if (!contains || type > currentType)
- mFunctionsUsingSimd[mActiveFunction] = type;
- }
- String BfIRCodeGen::GetSimdTypeString(BfIRSimdType type)
- {
- switch (type)
- {
- case BfIRSimdType_SSE:
- return "+sse,+mmx";
- case BfIRSimdType_SSE2:
- return "+sse2,+sse,+mmx";
- case BfIRSimdType_AVX:
- return "+avx,+sse4.2,+sse4.1,+sse3,+sse2,+sse,+mmx";
- case BfIRSimdType_AVX2:
- return "+avx2,+avx,+sse4.2,+sse4.1,+sse3,+sse2,+sse,+mmx";
- case BfIRSimdType_AVX512:
- return "+avx512f,+avx2,+avx,+sse4.2,+sse4.1,+sse3,+sse2,+sse,+mmx";
- default:
- return "";
- }
- }
- BfIRSimdType BfIRCodeGen::GetSimdTypeFromFunction(llvm::Function* function)
- {
- if (function->hasFnAttribute("target-features"))
- {
- auto str = function->getFnAttribute("target-features").getValueAsString();
- if (str.contains("+avx512f"))
- return BfIRSimdType_AVX512;
- if (str.contains("+avx2"))
- return BfIRSimdType_AVX2;
- if (str.contains("+avx"))
- return BfIRSimdType_AVX;
- if (str.contains("+sse2"))
- return BfIRSimdType_SSE2;
- if (str.contains("+sse"))
- return BfIRSimdType_SSE;
- }
- return BfIRSimdType_None;
- }
- BfIRTypedValue BfIRCodeGen::GetTypedValue(int id)
- {
- auto& result = mResults[id];
- if (result.mKind == BfIRCodeGenEntryKind_TypedValue)
- return result.mTypedValue;
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue);
-
- BfIRTypedValue typedValue;
- typedValue.mTypeEx = NULL;
- typedValue.mValue = result.mLLVMValue;
- return typedValue;
- }
- llvm::Value* BfIRCodeGen::GetLLVMValue(int id)
- {
- auto& result = mResults[id];
- if (result.mKind == BfIRCodeGenEntryKind_TypedValue)
- return result.mTypedValue.mValue;
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue);
- return result.mLLVMValue;
- }
- llvm::Type* BfIRCodeGen::GetLLVMType(int id)
- {
- auto& result = mResults[id];
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMType);
- return result.mLLVMType;
- }
- llvm::BasicBlock * BfIRCodeGen::GetLLVMBlock(int id)
- {
- auto& result = mResults[id];
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMBasicBlock);
- return result.mLLVMBlock;
- }
- llvm::MDNode* BfIRCodeGen::GetLLVMMetadata(int id)
- {
- auto& result = mResults[id];
- BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMMetadata);
- return result.mLLVMMetadata;
- }
- llvm::Type* BfIRCodeGen::GetLLVMTypeById(int id)
- {
- return GetTypeEntry(id).mType->mLLVMType;
- }
- // LLVM/Clang 18.1.4
- static void addSanitizers(const llvm::Triple& TargetTriple, BfCodeGenOptions& CodeGenOpts, llvm::PassBuilder& PB)
- {
- #if 0
- auto SanitizersCallback = [&](llvm::ModulePassManager& MPM, llvm::OptimizationLevel Level) {
- if (CodeGenOpts.hasSanitizeCoverage())
- {
- auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts);
- MPM.addPass(SanitizerCoveragePass(
- SancovOpts, CodeGenOpts.SanitizeCoverageAllowlistFiles,
- CodeGenOpts.SanitizeCoverageIgnorelistFiles));
- }
- if (CodeGenOpts.hasSanitizeBinaryMetadata()) {
- MPM.addPass(SanitizerBinaryMetadataPass(
- getSanitizerBinaryMetadataOptions(CodeGenOpts),
- CodeGenOpts.SanitizeMetadataIgnorelistFiles));
- }
- auto MSanPass = [&](SanitizerMask Mask, bool CompileKernel) {
- if (LangOpts.Sanitize.has(Mask)) {
- int TrackOrigins = CodeGenOpts.SanitizeMemoryTrackOrigins;
- bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
- MemorySanitizerOptions options(TrackOrigins, Recover, CompileKernel,
- CodeGenOpts.SanitizeMemoryParamRetval);
- MPM.addPass(MemorySanitizerPass(options));
- if (Level != OptimizationLevel::O0) {
- // MemorySanitizer inserts complex instrumentation that mostly follows
- // the logic of the original code, but operates on "shadow" values. It
- // can benefit from re-running some general purpose optimization
- // passes.
- MPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());
- FunctionPassManager FPM;
- FPM.addPass(EarlyCSEPass(true /* Enable mem-ssa. */));
- FPM.addPass(InstCombinePass());
- FPM.addPass(JumpThreadingPass());
- FPM.addPass(GVNPass());
- FPM.addPass(InstCombinePass());
- MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
- }
- }
- };
- MSanPass(SanitizerKind::Memory, false);
- MSanPass(SanitizerKind::KernelMemory, true);
- if (LangOpts.Sanitize.has(SanitizerKind::Thread)) {
- MPM.addPass(ModuleThreadSanitizerPass());
- MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
- }
- auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
- if (LangOpts.Sanitize.has(Mask)) {
- bool UseGlobalGC = asanUseGlobalsGC(TargetTriple, CodeGenOpts);
- bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator;
- llvm::AsanDtorKind DestructorKind =
- CodeGenOpts.getSanitizeAddressDtor();
- AddressSanitizerOptions Opts;
- Opts.CompileKernel = CompileKernel;
- Opts.Recover = CodeGenOpts.SanitizeRecover.has(Mask);
- Opts.UseAfterScope = CodeGenOpts.SanitizeAddressUseAfterScope;
- Opts.UseAfterReturn = CodeGenOpts.getSanitizeAddressUseAfterReturn();
- MPM.addPass(AddressSanitizerPass(Opts, UseGlobalGC, UseOdrIndicator,
- DestructorKind));
- }
- };
- ASanPass(SanitizerKind::Address, false);
- ASanPass(SanitizerKind::KernelAddress, true);
- auto HWASanPass = [&](SanitizerMask Mask, bool CompileKernel) {
- if (LangOpts.Sanitize.has(Mask)) {
- bool Recover = CodeGenOpts.SanitizeRecover.has(Mask);
- MPM.addPass(HWAddressSanitizerPass(
- { CompileKernel, Recover,
- /*DisableOptimization=*/CodeGenOpts.OptimizationLevel == 0 }));
- }
- };
- HWASanPass(SanitizerKind::HWAddress, false);
- HWASanPass(SanitizerKind::KernelHWAddress, true);
- if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) {
- MPM.addPass(DataFlowSanitizerPass(LangOpts.NoSanitizeFiles));
- }
- };
- if (ClSanitizeOnOptimizerEarlyEP) {
- PB.registerOptimizerEarlyEPCallback(
- [SanitizersCallback](ModulePassManager& MPM, OptimizationLevel Level) {
- ModulePassManager NewMPM;
- SanitizersCallback(NewMPM, Level);
- if (!NewMPM.isEmpty()) {
- // Sanitizers can abandon<GlobalsAA>.
- NewMPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());
- MPM.addPass(std::move(NewMPM));
- }
- });
- }
- else {
- // LastEP does not need GlobalsAA.
- PB.registerOptimizerLastEPCallback(SanitizersCallback);
- }
- #endif
- }
- // LLVM/Clang 18.1.4
- static void addKCFIPass(const llvm::Triple& TargetTriple, const BfCodeGenOptions& codeGenOpts, llvm::PassBuilder& PB)
- {
- #if 0
- // If the back-end supports KCFI operand bundle lowering, skip KCFIPass.
- if (TargetTriple.getArch() == llvm::Triple::x86_64 ||
- TargetTriple.isAArch64(64) || TargetTriple.isRISCV())
- return;
- // Ensure we lower KCFI operand bundles with -O0.
- PB.registerOptimizerLastEPCallback(
- [&](ModulePassManager& MPM, OptimizationLevel Level) {
- if (Level == OptimizationLevel::O0 &&
- LangOpts.Sanitize.has(SanitizerKind::KCFI))
- MPM.addPass(createModuleToFunctionPassAdaptor(KCFIPass()));
- });
- // When optimizations are requested, run KCIFPass after InstCombine to
- // avoid unnecessary checks.
- PB.registerPeepholeEPCallback(
- [&](FunctionPassManager& FPM, OptimizationLevel Level) {
- if (Level != OptimizationLevel::O0 &&
- LangOpts.Sanitize.has(SanitizerKind::KCFI))
- FPM.addPass(KCFIPass());
- });
- #endif
- }
- /// Check whether we should emit a module summary for regular LTO.
- /// The module summary should be emitted by default for regular LTO
- /// except for ld64 targets.
- ///
- /// \return True if the module summary should be emitted.
- static bool shouldEmitRegularLTOSummary(const llvm::Triple& targetTriple, const BfCodeGenOptions& codeGenOptions, bool PrepareForLTO)
- {
- return PrepareForLTO /*&& !CodeGenOpts.DisableLLVMPasses*/ &&
- targetTriple.getVendor() != llvm::Triple::Apple;
- }
- /// Check whether we should emit a flag for UnifiedLTO.
- /// The UnifiedLTO module flag should be set when UnifiedLTO is enabled for
- /// ThinLTO or Full LTO with module summaries.
- static bool shouldEmitUnifiedLTOModueFlag(const llvm::Triple& targetTriple, const BfCodeGenOptions& codeGenOptions, bool PrepareForLTO)
- {
- return false;
- /*return CodeGenOpts.UnifiedLTO &&
- (CodeGenOpts.PrepareForThinLTO || shouldEmitRegularLTOSummary());*/
- }
- void BfIRCodeGen::RunOptimizationPipeline(const llvm::Triple& targetTriple)
- {
- bool verifyModule = true;
- std::optional<llvm::PGOOptions> pgoOptions;
- mLLVMTargetMachine->setPGOOption(pgoOptions);
- llvm::PipelineTuningOptions pto;
- pto.LoopUnrolling = !mCodeGenOptions.mDisableUnrollLoops;
- // For historical reasons, loop interleaving is set to mirror setting for loop unrolling.
- pto.LoopInterleaving = !mCodeGenOptions.mDisableUnrollLoops;
- pto.LoopVectorization = mCodeGenOptions.mLoopVectorize;
- pto.SLPVectorization = mCodeGenOptions.mSLPVectorize;
- pto.MergeFunctions = mCodeGenOptions.mMergeFunctions;
- //TODO:
- //pto.CallGraphProfile = ???
- //pto.UnifiedLTO = ???
- llvm::LoopAnalysisManager LAM;
- llvm::FunctionAnalysisManager FAM;
- llvm::CGSCCAnalysisManager CGAM;
- llvm::ModuleAnalysisManager MAM;
- llvm::PassInstrumentationCallbacks PIC;
- // PrintPassOptions PrintPassOpts;
- // PrintPassOpts.Indent = DebugPassStructure;
- // PrintPassOpts.SkipAnalyses = DebugPassStructure;
- // StandardInstrumentations SI(
- // TheModule->getContext(),
- // (CodeGenOpts.DebugPassManager || DebugPassStructure),
- // CodeGenOpts.VerifyEach, PrintPassOpts);
- // SI.registerCallbacks(PIC, &MAM);
- llvm::PassBuilder PB(mLLVMTargetMachine, pto, pgoOptions, &PIC);
- // Register all the basic analyses with the managers.
- PB.registerModuleAnalyses(MAM);
- PB.registerCGSCCAnalyses(CGAM);
- PB.registerFunctionAnalyses(FAM);
- PB.registerLoopAnalyses(LAM);
- PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
-
- //llvm::ModulePassManager MPM;
- // Add a verifier pass, before any other passes, to catch CodeGen issues.
- llvm::ModulePassManager MPM;
- if (verifyModule)
- MPM.addPass(llvm::VerifierPass());
- bool disableLLVMPasses = false;
- if (!disableLLVMPasses)
- {
- llvm::OptimizationLevel Level;
- bool PrepareForLTO = false;
- bool PrepareForThinLTO = mCodeGenOptions.mLTOType == BfLTOType_Thin;
- //bool performThinLTO = false;
- Level = llvm::OptimizationLevel::O0;
- switch (mCodeGenOptions.mOptLevel)
- {
- case BfOptLevel_O0:
- Level = llvm::OptimizationLevel::O0;
- break;
- case BfOptLevel_O1:
- Level = llvm::OptimizationLevel::O1;
- break;
- case BfOptLevel_O2:
- Level = llvm::OptimizationLevel::O2;
- break;
- case BfOptLevel_O3:
- Level = llvm::OptimizationLevel::O3;
- break;
- case BfOptLevel_Og:
- Level = llvm::OptimizationLevel::O1;
- break;
- }
- bool IsThinLTOPostLink = false;
- #if 0
- // If we reached here with a non-empty index file name, then the index
- // file was empty and we are not performing ThinLTO backend compilation
- // (used in testing in a distributed build environment).
- bool IsThinLTOPostLink = !CodeGenOpts.ThinLTOIndexFile.empty();
- // If so drop any the type test assume sequences inserted for whole program
- // vtables so that codegen doesn't complain.
- if (IsThinLTOPostLink)
- PB.registerPipelineStartEPCallback(
- [](ModulePassManager& MPM, OptimizationLevel Level) {
- MPM.addPass(LowerTypeTestsPass(/*ExportSummary=*/nullptr,
- /*ImportSummary=*/nullptr,
- /*DropTypeTests=*/true));
- });
- // Register callbacks to schedule sanitizer passes at the appropriate part
- // of the pipeline.
- if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))
- PB.registerScalarOptimizerLateEPCallback(
- [](FunctionPassManager& FPM, OptimizationLevel Level) {
- FPM.addPass(BoundsCheckingPass());
- });
- #endif
- // Don't add sanitizers if we are here from ThinLTO PostLink. That already
- // done on PreLink stage.
- if (!IsThinLTOPostLink) {
- addSanitizers(targetTriple, mCodeGenOptions, PB);
- addKCFIPass(targetTriple, mCodeGenOptions, PB);
- }
- #if 0
- if (std::optional<GCOVOptions> Options =
- getGCOVOptions(CodeGenOpts, LangOpts))
- PB.registerPipelineStartEPCallback(
- [Options](ModulePassManager& MPM, OptimizationLevel Level) {
- MPM.addPass(GCOVProfilerPass(*Options));
- });
- if (std::optional<InstrProfOptions> Options =
- getInstrProfOptions(CodeGenOpts, LangOpts))
- PB.registerPipelineStartEPCallback(
- [Options](ModulePassManager& MPM, OptimizationLevel Level) {
- MPM.addPass(InstrProfilingLoweringPass(*Options, false));
- });
- // TODO: Consider passing the MemoryProfileOutput to the pass builder via
- // the PGOOptions, and set this up there.
- if (!CodeGenOpts.MemoryProfileOutput.empty()) {
- PB.registerOptimizerLastEPCallback(
- [](ModulePassManager& MPM, OptimizationLevel Level) {
- MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));
- MPM.addPass(ModuleMemProfilerPass());
- });
- }
- #endif
- if (mCodeGenOptions.mLTOType == BfLTOType_Fat)
- {
- MPM.addPass(PB.buildFatLTODefaultPipeline(
- Level, PrepareForThinLTO,
- PrepareForThinLTO || shouldEmitRegularLTOSummary(targetTriple, mCodeGenOptions, PrepareForLTO)));
- }
- else if (PrepareForThinLTO)
- {
- MPM.addPass(PB.buildThinLTOPreLinkDefaultPipeline(Level));
- }
- else if (PrepareForLTO)
- {
- MPM.addPass(PB.buildLTOPreLinkDefaultPipeline(Level));
- }
- else
- {
- MPM.addPass(PB.buildPerModuleDefaultPipeline(Level));
- }
- }
- // Re-link against any bitcodes supplied via the -mlink-builtin-bitcode option
- // Some optimizations may generate new function calls that would not have
- // been linked pre-optimization (i.e. fused sincos calls generated by
- // AMDGPULibCalls::fold_sincos.)
- //TODO:
- // if (ClRelinkBuiltinBitcodePostop)
- // MPM.addPass(LinkInModulesPass(BC, false));
- // Add a verifier pass if requested. We don't have to do this if the action
- // requires code generation because there will already be a verifier pass in
- // the code-generation pipeline.
- // Since we already added a verifier pass above, this
- // might even not run the analysis, if previous passes caused no changes.
- // if (!actionRequiresCodeGen(Action) && CodeGenOpts.VerifyModule)
- // MPM.addPass(VerifierPass());
- //TODO:
- #if 0
- if (Action == Backend_EmitBC || Action == Backend_EmitLL || CodeGenOpts.FatLTO)
- {
- if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) {
- if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
- TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
- CodeGenOpts.EnableSplitLTOUnit);
- if (Action == Backend_EmitBC) {
- if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
- ThinLinkOS = openOutputFile(CodeGenOpts.ThinLinkBitcodeFile);
- if (!ThinLinkOS)
- return;
- }
- MPM.addPass(ThinLTOBitcodeWriterPass(
- *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
- }
- else if (Action == Backend_EmitLL) {
- MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
- /*EmitLTOSummary=*/true));
- }
- }
- else {
- // Emit a module summary by default for Regular LTO except for ld64
- // targets
- bool EmitLTOSummary = shouldEmitRegularLTOSummary();
- if (EmitLTOSummary) {
- if (!TheModule->getModuleFlag("ThinLTO") && !CodeGenOpts.UnifiedLTO)
- TheModule->addModuleFlag(llvm::Module::Error, "ThinLTO", uint32_t(0));
- if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
- TheModule->addModuleFlag(llvm::Module::Error, "EnableSplitLTOUnit",
- uint32_t(1));
- }
- if (Action == Backend_EmitBC) {
- MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
- EmitLTOSummary));
- }
- else if (Action == Backend_EmitLL) {
- MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
- EmitLTOSummary));
- }
- }
- if (shouldEmitUnifiedLTOModueFlag())
- TheModule->addModuleFlag(llvm::Module::Error, "UnifiedLTO", uint32_t(1));
- }
- #endif
- // Print a textual, '-passes=' compatible, representation of pipeline if
- // requested.
- // if (PrintPipelinePasses) {
- // MPM.printPipeline(outs(), [&PIC](StringRef ClassName) {
- // auto PassName = PIC.getPassNameForClassName(ClassName);
- // return PassName.empty() ? ClassName : PassName;
- // });
- // outs() << "\n";
- // return;
- // }
- //
- // if (LangOpts.HIPStdPar && !LangOpts.CUDAIsDevice &&
- // LangOpts.HIPStdParInterposeAlloc)
- // MPM.addPass(HipStdParAllocationInterpositionPass());
- // Now that we have all of the passes ready, run them.
- {
- //PrettyStackTraceString CrashInfo("Optimizer");
- //llvm::TimeTraceScope TimeScope("Optimizer");
- MPM.run(*mLLVMModule, MAM);
- }
- }
- bool BfIRCodeGen::WriteObjectFile(const StringImpl& outFileName)
- {
- ApplySimdFeatures();
- // {
- // PassManagerBuilderWrapper pmBuilder;
- //
- //
- // }
- mHasDebugLoc = false; // So fails don't show a line number
- bool enableLTO = mCodeGenOptions.mLTOType != BfLTOType_None;
- if (enableLTO)
- {
- // We have some constructs which trip up ThinLTO, and it's not useful to LTO here anyway
- if (GetFileName(outFileName) == "vdata.obj")
- {
- enableLTO = false;
- }
- if (mHadDLLExport) // LTO bug in LLVM-link?
- enableLTO = false;
- }
- std::error_code EC;
- llvm::sys::fs::OpenFlags OpenFlags = llvm::sys::fs::OF_None;
- llvm::raw_fd_ostream out(outFileName.c_str(), EC, OpenFlags);
- if (EC)
- return false;
- // Build up all of the passes that we want to do to the module.
- //llvm::legacy::PassManager PM;
- llvm::legacy::PassManager PM;
- llvm::Triple theTriple = llvm::Triple(mLLVMModule->getTargetTriple());
- // Add an appropriate TargetLibraryInfo pass for the module's triple.
- llvm::TargetLibraryInfoImpl TLII(theTriple);
- PM.add(new llvm::TargetLibraryInfoWrapperPass(TLII));
- // Add the target data from the target machine, if it exists, or the module.
- //PM.add(new DataLayoutPass());
- RunOptimizationPipeline(theTriple);
- llvm::raw_fd_ostream* outStream = NULL;
- defer ( delete outStream; );
- if ((enableLTO) || (mCodeGenOptions.mWriteBitcode))
- {
- std::error_code ec;
- outStream = new llvm::raw_fd_ostream(outFileName.c_str(), ec, llvm::sys::fs::OF_None);
- if (outStream->has_error())
- {
- return false;
- }
- // if (enableLTO)
- // PM.add(createWriteThinLTOBitcodePass(*outStream, NULL));
- //else
- PM.add(createBitcodeWriterPass(*outStream, false));
- }
- // TargetPassConfig *PassConfig = target->createPassConfig(PM);
- // PM.add(new BfPass());
- // PM.add(sBfPass);
- // Do
- {
- //formatted_raw_ostream FOS(out);
- //raw_pwrite_stream *OS = &out->os();
- //TODO:
- llvm::AnalysisID StartAfterID = nullptr;
- llvm::AnalysisID StopAfterID = nullptr;
- const llvm::PassRegistry *PR = llvm::PassRegistry::getPassRegistry();
-
- //WriteBitcode
- bool noVerify = false; // Option
-
- if ((!enableLTO) && (!mCodeGenOptions.mWriteBitcode))
- {
- // Ask the target to add backend passes as necessary.
- if (mLLVMTargetMachine->addPassesToEmitFile(PM, out, NULL,
- (mCodeGenOptions.mAsmKind != BfAsmKind_None) ? llvm::CodeGenFileType::AssemblyFile : llvm::CodeGenFileType::ObjectFile,
- //TargetMachine::CGFT_AssemblyFile,
- noVerify /*, StartAfterID, StopAfterID*/))
- {
- Fail("Target does not support generation of this file type");
- /*errs() << argv[0] << ": target does not support generation of this"
- << " file type!\n";*/
- return false;
- }
- }
- bool success = PM.run(*mLLVMModule);
- if ((mCodeGenOptions.mOptLevel > BfOptLevel_O0) && (mCodeGenOptions.mWriteLLVMIR))
- {
- BP_ZONE("BfCodeGen::RunLoop.LLVM.IR");
- String fileName = outFileName;
- int dotPos = (int)fileName.LastIndexOf('.');
- if (dotPos != -1)
- fileName.RemoveToEnd(dotPos);
- fileName += "_OPT.ll";
- String irError;
- WriteIR(fileName, irError);
- }
- }
- return true;
- }
- bool BfIRCodeGen::WriteIR(const StringImpl& outFileName, StringImpl& error)
- {
- std::error_code ec;
- llvm::raw_fd_ostream outStream(outFileName.c_str(), ec, llvm::sys::fs::OpenFlags::OF_Text);
- if (ec)
- {
- error = ec.message();
- return false;
- }
- mLLVMModule->print(outStream, NULL);
- return true;
- }
- void BfIRCodeGen::ApplySimdFeatures()
- {
- Array<std::tuple<llvm::Function*, BfIRSimdType>> functionsToProcess;
- for (auto pair : mFunctionsUsingSimd)
- functionsToProcess.Add({ pair.mKey, pair.mValue });
- while (functionsToProcess.Count() > 0)
- {
- auto tuple = functionsToProcess.front();
- functionsToProcess.RemoveAt(0);
- auto function = std::get<0>(tuple);
- auto simdType = std::get<1>(tuple);
- auto currentSimdType = GetSimdTypeFromFunction(function);
- simdType = simdType > currentSimdType ? simdType : currentSimdType;
- function->addFnAttr("target-features", GetSimdTypeString(simdType).c_str());
- if (function->hasFnAttribute(llvm::Attribute::AlwaysInline))
- {
- for (auto user : function->users())
- {
- if (auto call = llvm::dyn_cast<llvm::CallInst>(user))
- {
- auto func = call->getFunction();
- functionsToProcess.Add({ func, simdType });
- }
- }
- }
- }
- }
- int BfIRCodeGen::GetIntrinsicId(const StringImpl& name)
- {
- auto itr = std::lower_bound(std::begin(gIntrinEntries), std::end(gIntrinEntries), name);
- if (itr != std::end(gIntrinEntries) && strcmp(itr->mName, name.c_str()) == 0)
- {
- int id = (int)(itr - gIntrinEntries);
- return id;
- }
- if (name.StartsWith("shuffle"))
- return BfIRIntrinsic_Shuffle;
- if (name.Contains(':'))
- return BfIRIntrinsic__PLATFORM;
- return -1;
- }
- const char* BfIRCodeGen::GetIntrinsicName(int intrinId)
- {
- return gIntrinEntries[intrinId].mName;
- }
- void BfIRCodeGen::SetAsmKind(BfAsmKind asmKind)
- {
- const char* args[] = {"", (asmKind == BfAsmKind_ATT) ? "-x86-asm-syntax=att" : "-x86-asm-syntax=intel" };
- llvm::cl::ParseCommandLineOptions(2, args);
- }
- #ifdef BF_PLATFORM_LINUX
- //HACK: I don't know why this is needed, but we get link errors if we don't have it.
- int BF_LinuxFixLinkage()
- {
- llvm::MCContext* ctx = NULL;
- llvm::raw_pwrite_stream* stream = NULL;
- createWasmStreamer(*ctx, NULL, NULL, NULL, false);
- createMachOStreamer(*ctx, NULL, NULL, NULL, false, false, false);
- createAsmStreamer(*ctx, NULL, false, false, NULL, NULL, NULL, false);
- createELFStreamer(*ctx, NULL, NULL, NULL, false);
- return 0;
- }
- #endif
- //#include "aarch64/Disassembler/X86DisassemblerDecoder.h"
- //#include "X86/MCTargetDesc/X86MCTargetDesc.h"
- //#include "X86/MCTargetDesc/X86BaseInfo.h"
- //#include "X86InstrInfo.h"
- #ifdef BF_PLATFORM_MACOS
- #include "AArch64/MCTargetDesc/AArch64MCTargetDesc.h"
- //#include "AArch64/MCTargetDesc/AArch64BaseInfo.h"
- //#include "../X86InstrInfo.h"
- int BF_AARC64_Linkage()
- {
- LLVMInitializeAArch64TargetInfo();
- LLVMInitializeAArch64Target();
- LLVMInitializeAArch64TargetMC();
- return 0;
- }
- #endif
- void BfIRCodeGen::StaticInit()
- {
- LLVMInitializeX86TargetInfo();
- LLVMInitializeX86Target();
- LLVMInitializeX86TargetMC();
- LLVMInitializeX86AsmPrinter();
- LLVMInitializeX86AsmParser();
- LLVMInitializeX86Disassembler();
- LLVMInitializeARMTargetInfo();
- LLVMInitializeARMTarget();
- LLVMInitializeARMTargetMC();
- LLVMInitializeARMAsmPrinter();
- LLVMInitializeAArch64TargetInfo();
- LLVMInitializeAArch64Target();
- LLVMInitializeAArch64TargetMC();
- LLVMInitializeAArch64AsmPrinter();
- //LLVMInitializeAArch64Parser();
- //LLVMInitializeX86Disassembler();
- LLVMInitializeWebAssemblyTargetInfo();
- LLVMInitializeWebAssemblyTarget();
- LLVMInitializeWebAssemblyTargetMC();
- LLVMInitializeWebAssemblyAsmPrinter();
- //LLVMInitializeWebAssemblyAsmParser();
- LLVMInitializeWebAssemblyDisassembler();
- }
|