BfIRBuilder.cpp 173 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292
  1. #pragma warning(disable:4146)
  2. #include "BeefySysLib/util/BeefPerf.h"
  3. #include "BfIRBuilder.h"
  4. #include "BfUtil.h"
  5. #include "BfModule.h"
  6. #include "BfContext.h"
  7. #include "BfResolvedTypeUtils.h"
  8. #include "BfIRCodeGen.h"
  9. #include "BfMangler.h"
  10. #include "BfCompiler.h"
  11. #include "BfSystem.h"
  12. #include "../Backend/BeIRCodeGen.h"
  13. #pragma warning(push)
  14. #pragma warning(disable:4141)
  15. #pragma warning(disable:4146)
  16. #pragma warning(disable:4291)
  17. #pragma warning(disable:4244)
  18. #pragma warning(disable:4267)
  19. #pragma warning(disable:4624)
  20. #pragma warning(disable:4800)
  21. #pragma warning(disable:4996)
  22. #include "llvm/IR/Module.h"
  23. #include "llvm/IR/Constants.h"
  24. #include "llvm/IR/GlobalValue.h"
  25. #include "llvm/IR/GlobalVariable.h"
  26. #include "llvm/ADT/ArrayRef.h"
  27. #include "llvm/IR/InlineAsm.h"
  28. #include "llvm/Support/FileSystem.h"
  29. #include "llvm/IR/DIBuilder.h"
  30. #pragma warning(pop)
  31. static bool gDebugDbgLoc = false;
  32. USING_NS_BF;
  33. #define NEW_CMD_INSERTED NewCmdInserted()
  34. #define NEW_CMD_INSERTED_IRVALUE NewCmdInserted();
  35. #define NEW_CMD_INSERTED_IRTYPE NewCmdInserted();
  36. #define NEW_CMD_INSERTED_IRFUNCTYPE NewCmdInserted();
  37. #define NEW_CMD_INSERTED_IRBLOCK NewCmdInserted();
  38. #define NEW_CMD_INSERTED_IRMD NewCmdInserted();
  39. #define BINOPFUNC_APPLY(lhs, rhs, OP) \
  40. auto constLHS = GetConstantById(lhs.mId); \
  41. auto constRHS = GetConstantById(rhs.mId); \
  42. if (constLHS->mConstType == BfConstType_Undef) return lhs; \
  43. if (constRHS->mConstType == BfConstType_Undef) return rhs; \
  44. if ((constLHS->mTypeCode < BfTypeCode_Length) && (constRHS->mTypeCode < BfTypeCode_Length)) \
  45. { \
  46. BF_ASSERT(constLHS->mTypeCode == constRHS->mTypeCode); \
  47. uint64 val = 0; \
  48. switch (constLHS->mTypeCode) \
  49. { \
  50. case BfTypeCode_Boolean: val = OP(constLHS->mInt8, constRHS->mInt8); break; \
  51. case BfTypeCode_Int8: val = OP(constLHS->mInt8, constRHS->mInt8); break; \
  52. case BfTypeCode_Char8: val = OP(constLHS->mUInt8, constRHS->mUInt8); break; \
  53. case BfTypeCode_UInt8: val = OP(constLHS->mUInt8, constRHS->mUInt8); break; \
  54. case BfTypeCode_Int16: val = OP(constLHS->mInt16, constRHS->mInt16); break; \
  55. case BfTypeCode_UInt16: val = OP(constLHS->mUInt16, constRHS->mUInt16); break; \
  56. case BfTypeCode_Char16: val = OP(constLHS->mUInt16, constRHS->mUInt16); break; \
  57. case BfTypeCode_Int32: val = OP(constLHS->mInt32, constRHS->mInt32); break; \
  58. case BfTypeCode_UInt32: val = OP(constLHS->mUInt32, constRHS->mUInt32); break; \
  59. case BfTypeCode_Char32: val = OP(constLHS->mUInt32, constRHS->mUInt32); break; \
  60. case BfTypeCode_Int64: val = OP(constLHS->mInt64, constRHS->mInt64); break; \
  61. case BfTypeCode_UInt64: val = OP(constLHS->mUInt64, constRHS->mUInt64); break; \
  62. case BfTypeCode_Float: \
  63. case BfTypeCode_Double: \
  64. return CreateConst(constLHS->mTypeCode, OP(constLHS->mDouble, constRHS->mDouble)); break; \
  65. default: break; \
  66. } \
  67. return CreateConst(constLHS->mTypeCode, val); \
  68. }
  69. #define INT_BINOPFUNC_APPLY(lhs, rhs, OP) \
  70. auto constLHS = GetConstantById(lhs.mId); \
  71. auto constRHS = GetConstantById(rhs.mId); \
  72. if (constLHS->mConstType == BfConstType_Undef) return lhs; \
  73. if (constRHS->mConstType == BfConstType_Undef) return rhs; \
  74. if ((constLHS->mTypeCode < BfTypeCode_Length) && (constRHS->mTypeCode < BfTypeCode_Length)) \
  75. { \
  76. BF_ASSERT(constLHS->mTypeCode == constRHS->mTypeCode); \
  77. uint64 val = 0; \
  78. switch (constLHS->mTypeCode) \
  79. { \
  80. case BfTypeCode_Boolean: val = OP(constLHS->mInt8, constRHS->mInt8); break; \
  81. case BfTypeCode_Int8: val = OP(constLHS->mInt8, constRHS->mInt8); break; \
  82. case BfTypeCode_Char8: val = OP(constLHS->mUInt8, constRHS->mUInt8); break; \
  83. case BfTypeCode_UInt8: val = OP(constLHS->mUInt8, constRHS->mUInt8); break; \
  84. case BfTypeCode_Int16: val = OP(constLHS->mInt16, constRHS->mInt16); break; \
  85. case BfTypeCode_UInt16: val = OP(constLHS->mUInt16, constRHS->mUInt16); break; \
  86. case BfTypeCode_Char16: val = OP(constLHS->mUInt16, constRHS->mUInt16); break; \
  87. case BfTypeCode_Int32: val = OP(constLHS->mInt32, constRHS->mInt32); break; \
  88. case BfTypeCode_UInt32: val = OP(constLHS->mUInt32, constRHS->mUInt32); break; \
  89. case BfTypeCode_Char32: val = OP(constLHS->mUInt32, constRHS->mUInt32); break; \
  90. case BfTypeCode_Int64: val = OP(constLHS->mInt64, constRHS->mInt64); break; \
  91. case BfTypeCode_UInt64: val = OP(constLHS->mUInt64, constRHS->mUInt64); break; \
  92. default: break; \
  93. } \
  94. return CreateConst(constLHS->mTypeCode, val); \
  95. }
  96. #define BINOP_APPLY(lhs, rhs, OP) \
  97. auto constLHS = GetConstantById(lhs.mId); \
  98. auto constRHS = GetConstantById(rhs.mId); \
  99. if (constLHS->mConstType == BfConstType_Undef) return lhs; \
  100. if (constRHS->mConstType == BfConstType_Undef) return rhs; \
  101. if ((constLHS->mTypeCode < BfTypeCode_Length) && (constRHS->mTypeCode < BfTypeCode_Length)) \
  102. { \
  103. BF_ASSERT(constLHS->mTypeCode == constRHS->mTypeCode); \
  104. uint64 val = 0; \
  105. switch (constLHS->mTypeCode) \
  106. { \
  107. case BfTypeCode_Boolean: val = constLHS->mInt8 OP constRHS->mInt8; break; \
  108. case BfTypeCode_Int8: val = constLHS->mInt8 OP constRHS->mInt8; break; \
  109. case BfTypeCode_Char8: val = constLHS->mUInt8 OP constRHS->mUInt8; break; \
  110. case BfTypeCode_UInt8: val = constLHS->mUInt8 OP constRHS->mUInt8; break; \
  111. case BfTypeCode_Int16: val = constLHS->mInt16 OP constRHS->mInt16; break; \
  112. case BfTypeCode_UInt16: val = constLHS->mUInt16 OP constRHS->mUInt16; break; \
  113. case BfTypeCode_Char16: val = constLHS->mUInt16 OP constRHS->mUInt16; break; \
  114. case BfTypeCode_Int32: val = constLHS->mInt32 OP constRHS->mInt32; break; \
  115. case BfTypeCode_UInt32: val = constLHS->mUInt32 OP constRHS->mUInt32; break; \
  116. case BfTypeCode_Char32: val = constLHS->mUInt32 OP constRHS->mUInt32; break; \
  117. case BfTypeCode_Int64: val = constLHS->mInt64 OP constRHS->mInt64; break; \
  118. case BfTypeCode_UInt64: val = constLHS->mUInt64 OP constRHS->mUInt64; break; \
  119. case BfTypeCode_Float: \
  120. case BfTypeCode_Double: \
  121. return CreateConst(constLHS->mTypeCode, constLHS->mDouble OP constRHS->mDouble); break; \
  122. default: break; \
  123. } \
  124. return CreateConst(constLHS->mTypeCode, val); \
  125. }
  126. #define INT_BINOP_APPLY(constLHS, constRHS, OP) \
  127. if (constLHS->mConstType == BfConstType_Undef) return lhs; \
  128. if (constRHS->mConstType == BfConstType_Undef) return rhs; \
  129. if ((constLHS->mTypeCode < BfTypeCode_Length) && (constRHS->mTypeCode < BfTypeCode_Length)) \
  130. { \
  131. BF_ASSERT(constLHS->mTypeCode == constRHS->mTypeCode); \
  132. uint64 val = 0; \
  133. switch (constLHS->mTypeCode) \
  134. { \
  135. case BfTypeCode_Int8: return CreateConst(constLHS->mTypeCode, constLHS->mInt8 OP constRHS->mInt8); \
  136. case BfTypeCode_Char8: return CreateConst(constLHS->mTypeCode, constLHS->mUInt8 OP constRHS->mUInt8); \
  137. case BfTypeCode_UInt8: return CreateConst(constLHS->mTypeCode, constLHS->mUInt8 OP constRHS->mUInt8); \
  138. case BfTypeCode_Int16: return CreateConst(constLHS->mTypeCode, constLHS->mInt16 OP constRHS->mInt16); \
  139. case BfTypeCode_UInt16: return CreateConst(constLHS->mTypeCode, constLHS->mUInt16 OP constRHS->mUInt16); \
  140. case BfTypeCode_Char16: return CreateConst(constLHS->mTypeCode, constLHS->mUInt16 OP constRHS->mUInt16); \
  141. case BfTypeCode_Int32: return CreateConst(constLHS->mTypeCode, constLHS->mInt32 OP constRHS->mInt32); \
  142. case BfTypeCode_UInt32: return CreateConst(constLHS->mTypeCode, (uint64)(constLHS->mUInt32 OP constRHS->mUInt32)); \
  143. case BfTypeCode_Char32: return CreateConst(constLHS->mTypeCode, (uint64)(constLHS->mUInt32 OP constRHS->mUInt32)); \
  144. case BfTypeCode_Int64: return CreateConst(constLHS->mTypeCode, (uint64)(constLHS->mInt64 OP constRHS->mInt64)); \
  145. case BfTypeCode_UInt64: return CreateConst(constLHS->mTypeCode, constLHS->mUInt64 OP constRHS->mUInt64); \
  146. default: break; \
  147. } \
  148. }
  149. #define UNARYOP_APPLY(val, OP) \
  150. auto constVal = GetConstantById(val.mId); \
  151. if (constVal->mConstType == BfConstType_Undef) return val; \
  152. if (constVal->mTypeCode < BfTypeCode_Length) \
  153. { \
  154. uint64 val = 0; \
  155. switch (constVal->mTypeCode) \
  156. { \
  157. case BfTypeCode_Int8: val = OP constVal->mInt8; break; \
  158. case BfTypeCode_UInt8: val = OP constVal->mUInt8; break; \
  159. case BfTypeCode_Char8: val = OP constVal->mUInt8; break; \
  160. case BfTypeCode_Int16: val = OP constVal->mInt16; break; \
  161. case BfTypeCode_UInt16: val = OP constVal->mUInt16; break; \
  162. case BfTypeCode_Char16: val = OP constVal->mUInt16; break; \
  163. case BfTypeCode_Int32: val = OP constVal->mInt32; break; \
  164. case BfTypeCode_UInt32: val = OP constVal->mUInt32; break; \
  165. case BfTypeCode_Char32: val = OP constVal->mUInt32; break; \
  166. case BfTypeCode_Int64: val = OP constVal->mInt64; break; \
  167. case BfTypeCode_UInt64: val = OP constVal->mUInt64; break; \
  168. case BfTypeCode_Float: \
  169. case BfTypeCode_Double: \
  170. return CreateConst(constVal->mTypeCode, OP constVal->mDouble); break; \
  171. default: break; \
  172. } \
  173. return CreateConst(constVal->mTypeCode, val); \
  174. }
  175. #define CMP_APPLY(lhs, rhs, OP) \
  176. auto constLHS = GetConstantById(lhs.mId); \
  177. auto constRHS = GetConstantById(rhs.mId); \
  178. if ((constLHS->mConstType == BfConstType_Undef) || (constRHS->mConstType == BfConstType_Undef)) \
  179. { \
  180. return GetUndefConstValue(MapType(mModule->GetPrimitiveType(BfTypeCode_Boolean))); \
  181. } \
  182. if ((constLHS->mTypeCode == BfTypeCode_NullPtr) || (constRHS->mTypeCode == BfTypeCode_NullPtr)) \
  183. { \
  184. bool val = constLHS->mTypeCode OP constRHS->mTypeCode; \
  185. return CreateConst(BfTypeCode_Boolean, val ? (uint64)1 : (uint64)0); \
  186. } \
  187. if ((constLHS->mTypeCode < BfTypeCode_Length) && (constRHS->mTypeCode < BfTypeCode_Length)) \
  188. { \
  189. BF_ASSERT(constLHS->mTypeCode == constRHS->mTypeCode); \
  190. bool val = 0; \
  191. switch (constLHS->mTypeCode) \
  192. { \
  193. case BfTypeCode_Boolean: val = constLHS->mInt8 OP constRHS->mInt8; break; \
  194. case BfTypeCode_Int8: val = constLHS->mInt8 OP constRHS->mInt8; break; \
  195. case BfTypeCode_UInt8: val = constLHS->mUInt8 OP constRHS->mUInt8; break; \
  196. case BfTypeCode_Int16: val = constLHS->mInt16 OP constRHS->mInt16; break; \
  197. case BfTypeCode_UInt16: val = constLHS->mUInt16 OP constRHS->mUInt16; break; \
  198. case BfTypeCode_Int32: val = constLHS->mInt32 OP constRHS->mInt32; break; \
  199. case BfTypeCode_UInt32: val = constLHS->mUInt32 OP constRHS->mUInt32; break; \
  200. case BfTypeCode_Int64: val = constLHS->mInt64 OP constRHS->mInt64; break; \
  201. case BfTypeCode_UInt64: val = constLHS->mUInt64 OP constRHS->mUInt64; break; \
  202. case BfTypeCode_Float: val = constLHS->mDouble OP constRHS->mDouble; break; \
  203. case BfTypeCode_Double: val = constLHS->mDouble OP constRHS->mDouble; break; \
  204. default: break; \
  205. } \
  206. return CreateConst(BfTypeCode_Boolean, val ? (uint64)1 : (uint64)0); \
  207. }
  208. static llvm::GlobalValue::LinkageTypes LLVMMapLinkageType(BfIRLinkageType linkageType)
  209. {
  210. llvm::GlobalValue::LinkageTypes llvmLinkageType;
  211. if (linkageType == BfIRLinkageType_Internal)
  212. llvmLinkageType = llvm::GlobalValue::InternalLinkage;
  213. else
  214. llvmLinkageType = llvm::GlobalValue::ExternalLinkage;
  215. return llvmLinkageType;
  216. }
  217. BfIRValue BfIRValue::sValueless(BfIRValueFlags_Value, -1);
  218. bool BfIRValue::IsFake() const
  219. {
  220. return mId < -1;
  221. }
  222. bool BfIRValue::IsConst() const
  223. {
  224. return (mFlags & BfIRValueFlags_Const) != 0;
  225. }
  226. bool BfIRValue::IsArg() const
  227. {
  228. return (mFlags & BfIRValueFlags_Arg) != 0;
  229. }
  230. bool BfIRValue::IsFromLLVM() const
  231. {
  232. return (mFlags & BfIRValueFlags_FromLLVM) != 0;
  233. }
  234. //////////////////////////////////////////////////////////////////////////
  235. BfIRFunction::BfIRFunction()
  236. {
  237. //mFlags = BfIRValueFlags_None;
  238. mId = -1;
  239. }
  240. //////////////////////////////////////////////////////////////////////////
  241. BfIRFunctionType::BfIRFunctionType()
  242. {
  243. mId = -1;
  244. }
  245. //////////////////////////////////////////////////////////////////////////
  246. BfIRBlock::BfIRBlock()
  247. {
  248. mFlags = BfIRValueFlags_None;
  249. mId = -1;
  250. }
  251. //////////////////////////////////////////////////////////////////////////
  252. BfIRConstHolder::BfIRConstHolder(BfModule* module)
  253. {
  254. mModule = module;
  255. }
  256. BfIRConstHolder::~BfIRConstHolder()
  257. {
  258. }
  259. String BfIRConstHolder::ToString(BfIRValue irValue)
  260. {
  261. if ((irValue.mFlags & BfIRValueFlags_Const) != 0)
  262. {
  263. auto constant = GetConstantById(irValue.mId);
  264. if (constant->mTypeCode == BfTypeCode_None)
  265. {
  266. return "void";
  267. }
  268. else if (constant->mTypeCode == BfTypeCode_NullPtr)
  269. {
  270. String ret;
  271. if (constant->mIRType)
  272. {
  273. ret += ToString(constant->mIRType);
  274. ret += " ";
  275. }
  276. ret += "null";
  277. return ret;
  278. }
  279. else if (constant->mTypeCode == BfTypeCode_Boolean)
  280. {
  281. return constant->mBool ? "true" : "false";
  282. }
  283. else if (constant->mTypeCode == BfTypeCode_Float)
  284. {
  285. return StrFormat("Constant %ff", constant->mDouble);
  286. }
  287. else if (constant->mTypeCode == BfTypeCode_Double)
  288. {
  289. return StrFormat("Constant %f", constant->mDouble);
  290. }
  291. else if (IsInt(constant->mTypeCode))
  292. {
  293. return StrFormat("Constant %lld", constant->mInt64);
  294. }
  295. else if (constant->mTypeCode == BfTypeCode_CharPtr)
  296. {
  297. return StrFormat("CharPtr %d", constant->mInt64);
  298. }
  299. else if (constant->mTypeCode == BfTypeCode_StringId)
  300. {
  301. return StrFormat("StringId %d", constant->mInt64);
  302. }
  303. else if (constant->mConstType == BfConstType_GlobalVar)
  304. {
  305. auto gvConst = (BfGlobalVar*)constant;
  306. return String("GlobalVar ") + gvConst->mName;
  307. }
  308. else if (constant->mConstType == BfConstType_BitCast)
  309. {
  310. auto bitcast = (BfConstantBitCast*)constant;
  311. BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget);
  312. return ToString(bitcast->mToType) += " bitcast " + ToString(targetConst);
  313. }
  314. else if (constant->mConstType == BfConstType_Box)
  315. {
  316. auto box = (BfConstantBox*)constant;
  317. BfIRValue targetConst(BfIRValueFlags_Const, box->mTarget);
  318. return ToString(box->mToType) + " box " + ToString(targetConst);
  319. }
  320. else if (constant->mConstType == BfConstType_GEP32_1)
  321. {
  322. auto gepConst = (BfConstantGEP32_1*)constant;
  323. BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
  324. return ToString(targetConst) + StrFormat(" Gep32 %d", gepConst->mIdx0);
  325. }
  326. else if (constant->mConstType == BfConstType_GEP32_2)
  327. {
  328. auto gepConst = (BfConstantGEP32_2*)constant;
  329. BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
  330. return ToString(targetConst) + StrFormat(" Gep32 %d,%d", gepConst->mIdx0, gepConst->mIdx1);
  331. }
  332. else if (constant->mConstType == BfConstType_ExtractValue)
  333. {
  334. auto gepConst = (BfConstantExtractValue*)constant;
  335. BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
  336. return ToString(targetConst) + StrFormat(" ExtractValue %d", gepConst->mIdx0);
  337. }
  338. else if (constant->mConstType == BfConstType_PtrToInt)
  339. {
  340. auto ptrToIntConst = (BfConstantPtrToInt*)constant;
  341. BfIRValue targetConst(BfIRValueFlags_Const, ptrToIntConst->mTarget);
  342. return ToString(targetConst) + StrFormat(" PtrToInt TypeCode:%d", ptrToIntConst->mToTypeCode);
  343. }
  344. else if (constant->mConstType == BfConstType_IntToPtr)
  345. {
  346. auto bitcast = (BfConstantIntToPtr*)constant;
  347. BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget);
  348. return ToString(targetConst) + " IntToPtr " + ToString(bitcast->mToType);
  349. }
  350. else if (constant->mConstType == BfConstType_Agg)
  351. {
  352. auto constAgg = (BfConstantAgg*)constant;
  353. String str = ToString(constAgg->mType);
  354. str += " (";
  355. for (int i = 0; i < (int)constAgg->mValues.size(); i++)
  356. {
  357. if (i > 0)
  358. str += ", ";
  359. str += ToString(constAgg->mValues[i]);
  360. }
  361. str += ")";
  362. return str;
  363. }
  364. else if (constant->mConstType == BfConstType_AggZero)
  365. {
  366. return ToString(constant->mIRType) + " zeroinitializer";
  367. }
  368. else if (constant->mConstType == BfConstType_AggCE)
  369. {
  370. auto constAgg = (BfConstantAggCE*)constant;
  371. return ToString(constAgg->mType) + StrFormat(" aggCe@%p", constAgg->mCEAddr);
  372. }
  373. else if (constant->mConstType == BfConstType_ArrayZero8)
  374. {
  375. return StrFormat("zero8[%d]", constant->mInt32);
  376. }
  377. else if (constant->mConstType == BfConstType_TypeOf)
  378. {
  379. auto typeofConst = (BfTypeOf_Const*)constant;
  380. return "typeof " + mModule->TypeToString(typeofConst->mType);
  381. }
  382. else if (constant->mConstType == BfConstType_TypeOf_Comptime)
  383. {
  384. auto typeofConst = (BfTypeOf_Const*)constant;
  385. return "typeof_comptime " + mModule->TypeToString(typeofConst->mType);
  386. }
  387. else if (constant->mConstType == BfConstType_TypeOf_WithData)
  388. {
  389. auto typeofConst = (BfTypeOf_WithData_Const*)constant;
  390. return "typeof_withData " + mModule->TypeToString(typeofConst->mType);
  391. }
  392. else if (constant->mConstType == BfConstType_Undef)
  393. {
  394. auto constUndef = (BfConstantUndef*)constant;
  395. return "undef " + ToString(constUndef->mType);
  396. }
  397. else
  398. {
  399. BF_FATAL("Unhandled");
  400. }
  401. }
  402. else if ((irValue.mFlags & BfIRValueFlags_Arg) != 0)
  403. {
  404. return StrFormat("Arg %d", irValue.mId);
  405. }
  406. else if (irValue.mFlags != 0)
  407. {
  408. return "Value???";
  409. }
  410. else
  411. {
  412. BF_ASSERT(irValue.mId == -1);
  413. }
  414. return "empty";
  415. }
  416. String BfIRConstHolder::ToString(BfIRType irType)
  417. {
  418. if (irType.mKind == BfIRTypeData::TypeKind_TypeId)
  419. {
  420. return StrFormat("Type#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str());
  421. }
  422. else if (irType.mKind == BfIRTypeData::TypeKind_TypeInstId)
  423. {
  424. return StrFormat("TypeInst#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str());
  425. }
  426. else if (irType.mKind == BfIRTypeData::TypeKind_TypeInstPtrId)
  427. {
  428. return StrFormat("TypeInstPtr#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str());
  429. }
  430. else if (irType.mKind == BfIRTypeData::TypeKind_SizedArray)
  431. {
  432. auto sizedArrayType = (BfConstantSizedArrayType*)GetConstantById(irType.mId);
  433. return StrFormat("%s[%d]", ToString(sizedArrayType->mType).c_str(), (int)sizedArrayType->mLength);
  434. }
  435. else
  436. {
  437. return "Type ???";
  438. }
  439. }
  440. void BfIRConstHolder::pv(const BfIRValue& irValue)
  441. {
  442. OutputDebugStrF("%s\n", ToString(irValue).c_str());
  443. }
  444. void BfIRConstHolder::FixTypeCode(BfTypeCode& typeCode)
  445. {
  446. if (typeCode == BfTypeCode_IntUnknown)
  447. typeCode = BfTypeCode_Int64;
  448. if (typeCode == BfTypeCode_UIntUnknown)
  449. typeCode = BfTypeCode_UInt64;
  450. if (typeCode == BfTypeCode_IntPtr)
  451. {
  452. if (mModule->mSystem->mPtrSize == 4)
  453. typeCode = BfTypeCode_Int32;
  454. else
  455. typeCode = BfTypeCode_Int64;
  456. }
  457. else if (typeCode == BfTypeCode_UIntPtr)
  458. {
  459. if (mModule->mSystem->mPtrSize == 4)
  460. typeCode = BfTypeCode_UInt32;
  461. else
  462. typeCode = BfTypeCode_UInt64;
  463. }
  464. }
  465. int BfIRConstHolder::GetSize(BfTypeCode typeCode, int ptrSize)
  466. {
  467. switch (typeCode)
  468. {
  469. case BfTypeCode_None: return 0;
  470. case BfTypeCode_CharPtr: return ptrSize;
  471. case BfTypeCode_StringId: return 4;
  472. case BfTypeCode_Pointer: return ptrSize;
  473. case BfTypeCode_NullPtr: return ptrSize;
  474. case BfTypeCode_Self: return 0;
  475. case BfTypeCode_Dot: return 0;
  476. case BfTypeCode_Var: return 0;
  477. case BfTypeCode_Let: return 0;
  478. case BfTypeCode_Boolean: return 1;
  479. case BfTypeCode_Int8: return 1;
  480. case BfTypeCode_UInt8: return 1;
  481. case BfTypeCode_Int16: return 2;
  482. case BfTypeCode_UInt16: return 2;
  483. case BfTypeCode_Int24: return 3;
  484. case BfTypeCode_UInt24: return 3;
  485. case BfTypeCode_Int32: return 4;
  486. case BfTypeCode_UInt32: return 4;
  487. case BfTypeCode_Int40: return 5;
  488. case BfTypeCode_UInt40: return 5;
  489. case BfTypeCode_Int48: return 6;
  490. case BfTypeCode_UInt48: return 6;
  491. case BfTypeCode_Int56: return 7;
  492. case BfTypeCode_UInt56: return 7;
  493. case BfTypeCode_Int64: return 8;
  494. case BfTypeCode_UInt64: return 8;
  495. case BfTypeCode_Int128: return 16;
  496. case BfTypeCode_UInt128: return 16;
  497. case BfTypeCode_IntPtr: return ptrSize;
  498. case BfTypeCode_UIntPtr: return ptrSize;
  499. case BfTypeCode_IntUnknown: return 0;
  500. case BfTypeCode_UIntUnknown: return 0;
  501. case BfTypeCode_Char8: return 1;
  502. case BfTypeCode_Char16: return 2;
  503. case BfTypeCode_Char32: return 4;
  504. case BfTypeCode_Float: return 4;
  505. case BfTypeCode_Double: return 8;
  506. case BfTypeCode_Float2: return 8;
  507. case BfTypeCode_Object: return ptrSize;
  508. case BfTypeCode_Interface: return ptrSize;
  509. case BfTypeCode_Struct: return 0;
  510. case BfTypeCode_Enum: return 0;
  511. case BfTypeCode_TypeAlias: return 0;
  512. case BfTypeCode_Extension: return 0;
  513. case BfTypeCode_FloatX2: return 4 * 2;
  514. case BfTypeCode_FloatX3: return 4 * 3;
  515. case BfTypeCode_FloatX4: return 4 * 4;
  516. case BfTypeCode_DoubleX2: return 8 * 2;
  517. case BfTypeCode_DoubleX3: return 8 * 3;
  518. case BfTypeCode_DoubleX4: return 8 * 4;
  519. case BfTypeCode_Int64X2: return 8 * 2;
  520. case BfTypeCode_Int64X3: return 8 * 3;
  521. case BfTypeCode_Int64X4: return 8 * 4;
  522. default: return 0;
  523. }
  524. }
  525. int BfIRConstHolder::GetSize(BfTypeCode typeCode)
  526. {
  527. return GetSize(typeCode, mModule->mSystem->mPtrSize);
  528. }
  529. bool BfIRConstHolder::IsInt(BfTypeCode typeCode)
  530. {
  531. return (typeCode >= BfTypeCode_Int8) && (typeCode <= BfTypeCode_Char32);
  532. }
  533. bool BfIRConstHolder::IsChar(BfTypeCode typeCode)
  534. {
  535. return (typeCode >= BfTypeCode_Char8) && (typeCode <= BfTypeCode_Char32);
  536. }
  537. bool BfIRConstHolder::IsIntable(BfTypeCode typeCode)
  538. {
  539. return (typeCode >= BfTypeCode_Boolean) && (typeCode <= BfTypeCode_Char32);
  540. }
  541. bool BfIRConstHolder::IsSigned(BfTypeCode typeCode)
  542. {
  543. return (typeCode == BfTypeCode_Int64) ||
  544. (typeCode == BfTypeCode_Int32) ||
  545. (typeCode == BfTypeCode_Int16) ||
  546. (typeCode == BfTypeCode_Int8) ||
  547. (typeCode == BfTypeCode_IntPtr);
  548. }
  549. bool BfIRConstHolder::IsFloat(BfTypeCode typeCode)
  550. {
  551. return (typeCode == BfTypeCode_Float) ||
  552. (typeCode == BfTypeCode_Double);
  553. }
  554. const char* BfIRConstHolder::AllocStr(const StringImpl& str)
  555. {
  556. char* strCopy = (char*)mTempAlloc.AllocBytes((int)str.length() + 1);
  557. memcpy(strCopy, str.c_str(), str.length());
  558. return strCopy;
  559. }
  560. BfConstant* BfIRConstHolder::GetConstantById(int id)
  561. {
  562. return (BfConstant*)mTempAlloc.GetChunkedPtr(id);
  563. }
  564. BfConstant* BfIRConstHolder::GetConstant(BfIRValue id)
  565. {
  566. if (!id.IsConst())
  567. return NULL;
  568. #ifdef CHECK_CONSTHOLDER
  569. BF_ASSERT(id.mHolder == this);
  570. #endif
  571. return GetConstantById(id.mId);
  572. }
  573. bool BfIRConstHolder::TryGetBool(BfIRValue id, bool& boolVal)
  574. {
  575. auto constant = GetConstant(id);
  576. if ((constant != NULL) && (constant->mTypeCode == BfTypeCode_Boolean))
  577. {
  578. boolVal = constant->mBool;
  579. return true;
  580. }
  581. return false;
  582. }
  583. int BfIRConstHolder::IsZero(BfIRValue value)
  584. {
  585. auto constant = GetConstant(value);
  586. if (constant == NULL)
  587. return -1;
  588. if ((constant->mTypeCode >= BfTypeCode_Boolean) && (constant->mTypeCode <= BfTypeCode_Double))
  589. {
  590. return (constant->mUInt64 == 0) ? 1 : 0;
  591. }
  592. if (constant->mConstType == BfConstType_AggZero)
  593. return 1;
  594. if (constant->mConstType == BfConstType_Agg)
  595. {
  596. auto constAgg = (BfConstantAgg*)constant;
  597. for (int i = 0; i < constAgg->mValues.mSize; i++)
  598. {
  599. int elemResult = IsZero(constAgg->mValues[i]);
  600. if (elemResult != 1)
  601. return elemResult;
  602. }
  603. return 1;
  604. }
  605. return -1;
  606. }
  607. bool BfIRConstHolder::IsConstValue(BfIRValue value)
  608. {
  609. auto constant = GetConstant(value);
  610. if (constant == NULL)
  611. return false;
  612. if (constant->mConstType == BfConstType_GlobalVar)
  613. return false;
  614. if (constant->mConstType == BfConstType_Undef)
  615. return false;
  616. if (constant->mConstType == BfConstType_GEP32_2)
  617. return IsConstValue(BfIRValue(BfIRValueFlags_Const, ((BfConstantGEP32_2*)constant)->mTarget));
  618. if (constant->mConstType == BfConstType_BitCast)
  619. return IsConstValue(BfIRValue(BfIRValueFlags_Const, ((BfConstantBitCast*)constant)->mTarget));
  620. return true;
  621. }
  622. int BfIRConstHolder::CheckConstEquality(BfIRValue lhs, BfIRValue rhs)
  623. {
  624. auto constLHS = GetConstant(lhs);
  625. if (constLHS == NULL)
  626. return -1;
  627. auto constRHS = GetConstant(rhs);
  628. if (constRHS == NULL)
  629. return -1;
  630. if (constLHS == constRHS)
  631. return 1;
  632. if (constLHS->mConstType == BfConstType_BitCast)
  633. return CheckConstEquality(BfIRValue(BfIRValueFlags_Const, ((BfConstantBitCast*)constLHS)->mTarget), rhs);
  634. if (constRHS->mConstType == BfConstType_BitCast)
  635. return CheckConstEquality(lhs, BfIRValue(BfIRValueFlags_Const, ((BfConstantBitCast*)constRHS)->mTarget));
  636. int lhsZero = IsZero(lhs);
  637. if (lhsZero != -1)
  638. {
  639. int rhsZero = IsZero(rhs);
  640. if (rhsZero != -1)
  641. {
  642. if (lhsZero || rhsZero)
  643. return (lhsZero == rhsZero) ? 1 : 0;
  644. }
  645. }
  646. if (((constLHS->mConstType == BfConstType_TypeOf) || (constLHS->mConstType == BfConstType_TypeOf_WithData) || (constLHS->mConstType == BfConstType_TypeOf_Comptime)) &&
  647. ((constRHS->mConstType == BfConstType_TypeOf) || (constRHS->mConstType == BfConstType_TypeOf_WithData) || (constRHS->mConstType == BfConstType_TypeOf_Comptime)))
  648. {
  649. auto typeOfLHS = (BfTypeOf_Const*)constLHS;
  650. auto typeOfRHS = (BfTypeOf_Const*)constRHS;
  651. return (typeOfLHS->mType == typeOfRHS->mType) ? 1 : 0;
  652. }
  653. if (constLHS->mTypeCode != constRHS->mTypeCode)
  654. return -1;
  655. if ((constLHS->mTypeCode >= BfTypeCode_Boolean) && (constLHS->mTypeCode <= BfTypeCode_Double))
  656. {
  657. return (constLHS->mUInt64 == constRHS->mUInt64) ? 1 : 0;
  658. }
  659. if (constLHS->mConstType == BfConstType_Agg)
  660. {
  661. auto aggLHS = (BfConstantAgg*)constLHS;
  662. auto aggRHS = (BfConstantAgg*)constRHS;
  663. if (aggLHS->mValues.mSize != aggRHS->mValues.mSize)
  664. return -1;
  665. for (int i = 0; i < aggLHS->mValues.mSize; i++)
  666. {
  667. int elemResult = CheckConstEquality(aggLHS->mValues[i], aggRHS->mValues[i]);
  668. if (elemResult != 1)
  669. return elemResult;
  670. }
  671. return 1;
  672. }
  673. //TODO: Why did we do this? This made global variable comparisons (ie: sA != sB) const-evaluate to false always
  674. // if (constLHS->mConstType == BfConstType_GlobalVar)
  675. // {
  676. // // We would have already caught the (constLHS == constRHS) case further up
  677. // return 0;
  678. // }
  679. return -1;
  680. }
  681. BfIRType BfIRConstHolder::GetSizedArrayType(BfIRType elementType, int length)
  682. {
  683. auto constSizedArrayType = mTempAlloc.Alloc<BfConstantSizedArrayType>();
  684. constSizedArrayType->mConstType = BfConstType_SizedArrayType;
  685. constSizedArrayType->mType = elementType;
  686. constSizedArrayType->mLength = length;
  687. int chunkId = mTempAlloc.GetChunkedId(constSizedArrayType);
  688. BfIRType retType;
  689. retType.mKind = BfIRTypeData::TypeKind_SizedArray;
  690. retType.mId = chunkId;
  691. return retType;
  692. }
  693. BfIRValue BfIRConstHolder::CreateConst(BfTypeCode typeCode, uint64 val)
  694. {
  695. FixTypeCode(typeCode);
  696. BfConstant* constant = mTempAlloc.Alloc<BfConstant>();
  697. constant->mTypeCode = typeCode;
  698. // Properly sign extend into int64
  699. switch (typeCode)
  700. {
  701. case BfTypeCode_Int8:
  702. constant->mInt64 = (int8)val;
  703. break;
  704. case BfTypeCode_Int16:
  705. constant->mInt64 = (int16)val;
  706. break;
  707. case BfTypeCode_Int32:
  708. constant->mInt64 = (int32)val;
  709. break;
  710. case BfTypeCode_UInt8:
  711. constant->mInt8 = (uint8)val;
  712. break;
  713. case BfTypeCode_UInt16:
  714. constant->mInt64 = (uint16)val;
  715. break;
  716. case BfTypeCode_UInt32:
  717. constant->mInt64 = (uint32)val;
  718. break;
  719. default:
  720. constant->mUInt64 = val;
  721. break;
  722. }
  723. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant));
  724. #ifdef CHECK_CONSTHOLDER
  725. irValue.mHolder = this;
  726. #endif
  727. BF_ASSERT(GetConstant(irValue) == constant);
  728. return irValue;
  729. }
  730. BfIRValue BfIRConstHolder::CreateConst(BfTypeCode typeCode, int val)
  731. {
  732. FixTypeCode(typeCode);
  733. BfConstant* constant = mTempAlloc.Alloc<BfConstant>();
  734. constant->mTypeCode = typeCode;
  735. // Properly sign extend into int64
  736. switch (typeCode)
  737. {
  738. case BfTypeCode_Int8:
  739. constant->mInt64 = (int8)val;
  740. break;
  741. case BfTypeCode_Int16:
  742. constant->mInt64 = (int16)val;
  743. break;
  744. case BfTypeCode_UInt8:
  745. constant->mInt64 = (uint8)val;
  746. break;
  747. case BfTypeCode_UInt16:
  748. constant->mInt64 = (uint16)val;
  749. break;
  750. case BfTypeCode_UInt32:
  751. constant->mInt64 = (uint32)val;
  752. break;
  753. default:
  754. constant->mInt64 = val;
  755. break;
  756. }
  757. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant));
  758. #ifdef CHECK_CONSTHOLDER
  759. irValue.mHolder = this;
  760. #endif
  761. return irValue;
  762. }
  763. BfIRValue BfIRConstHolder::CreateConst(BfTypeCode typeCode, double val)
  764. {
  765. BfConstant* constant = mTempAlloc.Alloc<BfConstant>();
  766. constant->mTypeCode = typeCode;
  767. constant->mDouble = val;
  768. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant));
  769. #ifdef CHECK_CONSTHOLDER
  770. irValue.mHolder = this;
  771. #endif
  772. return irValue;
  773. }
  774. BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* fromHolder)
  775. {
  776. BfConstant* copiedConst = NULL;
  777. int chunkId = -1;
  778. if ((fromConst->mConstType == BfConstType_BitCast) || (fromConst->mConstType == BfConstType_BitCastNull))
  779. {
  780. //HMM- This should never happen? Is that true? We always just store string refs as ints
  781. //BF_FATAL("Bad");
  782. auto fromConstBitCast = (BfConstantBitCast*)fromConst;
  783. BfIRValue copiedTarget;
  784. if (fromConstBitCast->mTarget)
  785. {
  786. auto fromTarget = fromHolder->GetConstantById(fromConstBitCast->mTarget);
  787. copiedTarget = CreateConst(fromTarget, fromHolder);
  788. }
  789. auto ptrToInt = mTempAlloc.Alloc<BfConstantBitCast>();
  790. ptrToInt->mConstType = fromConst->mConstType;
  791. ptrToInt->mTarget = copiedTarget.mId;
  792. ptrToInt->mToType = fromConstBitCast->mToType;
  793. copiedConst = (BfConstant*)ptrToInt;
  794. }
  795. else if (fromConst->mConstType == BfConstType_GlobalVar)
  796. {
  797. auto fromGlobalVar = (BfGlobalVar*)fromConst;
  798. return CreateGlobalVariableConstant(fromGlobalVar->mType, fromGlobalVar->mIsConst, fromGlobalVar->mLinkageType, fromGlobalVar->mInitializer, fromGlobalVar->mName, fromGlobalVar->mIsTLS);
  799. }
  800. else if (fromConst->mConstType == BfConstType_GEP32_2)
  801. {
  802. auto fromConstGEP = (BfConstantGEP32_2*)fromConst;
  803. auto fromTarget = fromHolder->GetConstantById(fromConstGEP->mTarget);
  804. auto copiedTarget = CreateConst(fromTarget, fromHolder);
  805. auto constGEP = mTempAlloc.Alloc<BfConstantGEP32_2>();
  806. constGEP->mConstType = BfConstType_GEP32_2;
  807. constGEP->mTarget = copiedTarget.mId;
  808. constGEP->mIdx0 = fromConstGEP->mIdx0;
  809. constGEP->mIdx1 = fromConstGEP->mIdx1;
  810. copiedConst = (BfConstant*)constGEP;
  811. }
  812. else if (fromConst->mConstType == BfConstType_ExtractValue)
  813. {
  814. auto fromConstGEP = (BfConstantExtractValue*)fromConst;
  815. auto fromTarget = fromHolder->GetConstantById(fromConstGEP->mTarget);
  816. auto copiedTarget = CreateConst(fromTarget, fromHolder);
  817. auto constGEP = mTempAlloc.Alloc<BfConstantExtractValue>();
  818. constGEP->mConstType = BfConstType_ExtractValue;
  819. constGEP->mTarget = copiedTarget.mId;
  820. constGEP->mIdx0 = fromConstGEP->mIdx0;
  821. copiedConst = (BfConstant*)constGEP;
  822. }
  823. else if (fromConst->mConstType == BfConstType_TypeOf)
  824. {
  825. auto typeOf = (BfTypeOf_Const*)fromConst;
  826. return CreateTypeOf(typeOf->mType);
  827. }
  828. else if (fromConst->mConstType == BfConstType_TypeOf_Comptime)
  829. {
  830. auto typeOf = (BfTypeOf_Const*)fromConst;
  831. return CreateTypeOfComptime(typeOf->mType);
  832. }
  833. else if (fromConst->mConstType == BfConstType_TypeOf_WithData)
  834. {
  835. auto typeOf = (BfTypeOf_WithData_Const*)fromConst;
  836. auto dataConstant = fromHolder->GetConstant(typeOf->mTypeData);
  837. return CreateTypeOf(typeOf->mType, CreateConst(dataConstant, fromHolder));
  838. }
  839. else if (fromConst->mConstType == BfConstType_AggZero)
  840. {
  841. auto aggZero = (BfConstant*)fromConst;
  842. return CreateConstAggZero(fromConst->mIRType);
  843. }
  844. else if (fromConst->mConstType == BfConstType_Agg)
  845. {
  846. auto constAgg = (BfConstantAgg*)fromConst;
  847. BfSizedVector<BfIRValue, 8> copiedVals;
  848. copiedVals.reserve(constAgg->mValues.size());
  849. for (auto fromVal : constAgg->mValues)
  850. {
  851. auto elementConst = fromHolder->GetConstant(fromVal);
  852. copiedVals.push_back(CreateConst(elementConst, fromHolder));
  853. }
  854. return CreateConstAgg(constAgg->mType, copiedVals);
  855. }
  856. else if (fromConst->mConstType == BfConstType_Undef)
  857. {
  858. auto constUndef = (BfConstantUndef*)fromConst;
  859. BF_ASSERT(constUndef->mType.mKind != BfIRTypeData::TypeKind_Stream);
  860. if (constUndef->mType.mKind == BfIRTypeData::TypeKind_Stream)
  861. return GetUndefConstValue(BfIRValue());
  862. return GetUndefConstValue(constUndef->mType);
  863. }
  864. else if (fromConst->mConstType == BfConstType_ArrayZero8)
  865. {
  866. return CreateConstArrayZero(fromConst->mInt32);
  867. }
  868. else if (fromConst->mTypeCode == BfTypeCode_None)
  869. {
  870. return CreateConst(fromConst->mTypeCode, 0);
  871. }
  872. else if ((IsInt(fromConst->mTypeCode)) || (fromConst->mTypeCode == BfTypeCode_Boolean) || (fromConst->mTypeCode == BfTypeCode_StringId) || (fromConst->mTypeCode == BfTypeCode_CharPtr))
  873. {
  874. return CreateConst(fromConst->mTypeCode, fromConst->mUInt64);
  875. }
  876. else if ((fromConst->mTypeCode == BfTypeCode_Float) || (fromConst->mTypeCode == BfTypeCode_Double))
  877. {
  878. return CreateConst(fromConst->mTypeCode, fromConst->mDouble);
  879. }
  880. else if (fromConst->mTypeCode == BfTypeCode_NullPtr)
  881. {
  882. if (fromConst->mIRType)
  883. return CreateConstNull(fromConst->mIRType);
  884. else
  885. return CreateConstNull();
  886. }
  887. else if (fromConst->mConstType == BfConstType_PtrToInt)
  888. {
  889. auto fromPtrToInt = (BfConstantPtrToInt*)fromConst;
  890. auto fromTarget = fromHolder->GetConstantById(fromPtrToInt->mTarget);
  891. auto copiedTarget = CreateConst(fromTarget, fromHolder);
  892. auto ptrToInt = mTempAlloc.Alloc<BfConstantPtrToInt>();
  893. ptrToInt->mConstType = BfConstType_PtrToInt;
  894. ptrToInt->mTarget = copiedTarget.mId;
  895. ptrToInt->mToTypeCode = fromPtrToInt->mToTypeCode;
  896. copiedConst = (BfConstant*)ptrToInt;
  897. }
  898. else if (fromConst->mConstType == BfConstType_IntToPtr)
  899. {
  900. auto fromPtrToInt = (BfConstantIntToPtr*)fromConst;
  901. auto fromTarget = fromHolder->GetConstantById(fromPtrToInt->mTarget);
  902. auto copiedTarget = CreateConst(fromTarget, fromHolder);
  903. auto ptrToInt = mTempAlloc.Alloc<BfConstantIntToPtr>();
  904. ptrToInt->mConstType = BfConstType_IntToPtr;
  905. ptrToInt->mTarget = copiedTarget.mId;
  906. ptrToInt->mToType = fromPtrToInt->mToType;
  907. copiedConst = (BfConstant*)ptrToInt;
  908. }
  909. else if (fromConst->mConstType == BfConstType_Box)
  910. {
  911. auto fromBox = (BfConstantBox*)fromConst;
  912. auto fromTarget = fromHolder->GetConstantById(fromBox->mTarget);
  913. auto copiedTarget = CreateConst(fromTarget, fromHolder);
  914. auto box = mTempAlloc.Alloc<BfConstantBox>();
  915. box->mConstType = BfConstType_Box;
  916. box->mTarget = copiedTarget.mId;
  917. box->mToType = fromBox->mToType;
  918. copiedConst = (BfConstant*)box;
  919. }
  920. else
  921. {
  922. BF_FATAL("not handled");
  923. }
  924. BfIRValue retVal;
  925. retVal.mFlags = BfIRValueFlags_Const;
  926. if (chunkId == -1)
  927. chunkId = mTempAlloc.GetChunkedId(copiedConst);
  928. retVal.mId = chunkId;
  929. BF_ASSERT(retVal.mId >= 0);
  930. #ifdef CHECK_CONSTHOLDER
  931. retVal.mHolder = this;
  932. #endif
  933. return retVal;
  934. }
  935. BfIRValue BfIRConstHolder::CreateConstNull()
  936. {
  937. BfConstant* constant = mTempAlloc.Alloc<BfConstant>();
  938. constant->mTypeCode = BfTypeCode_NullPtr;
  939. constant->mIRType = BfIRType();
  940. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant));
  941. #ifdef CHECK_CONSTHOLDER
  942. irValue.mHolder = this;
  943. #endif
  944. return irValue;
  945. }
  946. BfIRValue BfIRConstHolder::CreateConstNull(BfIRType ptrType)
  947. {
  948. BfConstant* constant = mTempAlloc.Alloc<BfConstant>();
  949. constant->mTypeCode = BfTypeCode_NullPtr;
  950. constant->mIRType = ptrType;
  951. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant));
  952. #ifdef CHECK_CONSTHOLDER
  953. irValue.mHolder = this;
  954. #endif
  955. return irValue;
  956. }
  957. BfIRValue BfIRConstHolder::CreateConstAggZero(BfIRType aggType)
  958. {
  959. BfConstant* constant = mTempAlloc.Alloc<BfConstant>();
  960. constant->mConstType = BfConstType_AggZero;
  961. constant->mIRType = aggType;
  962. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant));
  963. #ifdef CHECK_CONSTHOLDER
  964. irValue.mHolder = this;
  965. #endif
  966. return irValue;
  967. }
  968. BfIRValue BfIRConstHolder::CreateConstAgg(BfIRType type, const BfSizedArray<BfIRValue>& values)
  969. {
  970. #ifdef _DEBUG
  971. for (auto& val : values)
  972. {
  973. BF_ASSERT(val);
  974. //BF_ASSERT(val.IsConst());
  975. }
  976. #endif
  977. BfConstantAgg* constant = mTempAlloc.Alloc<BfConstantAgg>();
  978. constant->mConstType = BfConstType_Agg;
  979. constant->mType = type = type;
  980. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant));
  981. constant->mValues.mVals = (BfIRValue*)mTempAlloc.AllocBytes(sizeof(BfIRValue) * values.mSize, 8);
  982. memcpy(constant->mValues.mVals, values.mVals, sizeof(BfIRValue) * values.mSize);
  983. constant->mValues.mSize = values.mSize;
  984. #ifdef CHECK_CONSTHOLDER
  985. irValue.mHolder = this;
  986. #endif
  987. return irValue;
  988. }
  989. BfIRValue BfIRConstHolder::CreateConstAggCE(BfIRType type, addr_ce addr)
  990. {
  991. BfConstantAggCE* constant = mTempAlloc.Alloc<BfConstantAggCE>();
  992. constant->mConstType = BfConstType_AggCE;
  993. constant->mType = type = type;
  994. constant->mCEAddr = addr;
  995. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant));
  996. #ifdef CHECK_CONSTHOLDER
  997. irValue.mHolder = this;
  998. #endif
  999. return irValue;
  1000. }
  1001. BfIRValue BfIRConstHolder::CreateConstArrayZero(BfIRType type, int count)
  1002. {
  1003. BfConstantArrayZero* constant = mTempAlloc.Alloc<BfConstantArrayZero>();
  1004. constant->mConstType = BfConstType_ArrayZero;
  1005. constant->mType = type = type;
  1006. constant->mCount = count;
  1007. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant));
  1008. #ifdef CHECK_CONSTHOLDER
  1009. irValue.mHolder = this;
  1010. #endif
  1011. return irValue;
  1012. }
  1013. BfIRValue BfIRConstHolder::CreateConstArrayZero(int count)
  1014. {
  1015. BfConstant* constant = mTempAlloc.Alloc<BfConstant>();
  1016. constant->mConstType = BfConstType_ArrayZero8;
  1017. constant->mInt64 = count;
  1018. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant));
  1019. #ifdef CHECK_CONSTHOLDER
  1020. irValue.mHolder = this;
  1021. #endif
  1022. return irValue;
  1023. }
  1024. BfIRValue BfIRConstHolder::CreateConstBitCast(BfIRValue val, BfIRType type)
  1025. {
  1026. auto constVal = GetConstant(val);
  1027. auto bitCast = mTempAlloc.Alloc<BfConstantBitCast>();
  1028. if ((constVal == NULL) || (constVal->IsNull()))
  1029. bitCast->mConstType = BfConstType_BitCastNull;
  1030. else
  1031. bitCast->mConstType = BfConstType_BitCast;
  1032. BF_ASSERT(val.mId != -1);
  1033. bitCast->mTarget = val.mId;
  1034. bitCast->mToType = type;
  1035. BfIRValue castedVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(bitCast));
  1036. #ifdef CHECK_CONSTHOLDER
  1037. castedVal.mHolder = this;
  1038. #endif
  1039. BF_ASSERT((void*)GetConstant(castedVal) == (void*)bitCast);
  1040. return castedVal;
  1041. }
  1042. BfIRValue BfIRConstHolder::CreateConstBox(BfIRValue val, BfIRType type)
  1043. {
  1044. auto constVal = GetConstant(val);
  1045. auto box = mTempAlloc.Alloc<BfConstantBox>();
  1046. box->mConstType = BfConstType_Box;
  1047. BF_ASSERT(val.mId != -1);
  1048. box->mTarget = val.mId;
  1049. box->mToType = type;
  1050. BfIRValue castedVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(box));
  1051. #ifdef CHECK_CONSTHOLDER
  1052. castedVal.mHolder = this;
  1053. #endif
  1054. BF_ASSERT((void*)GetConstant(castedVal) == (void*)box);
  1055. return castedVal;
  1056. }
  1057. BfIRValue BfIRConstHolder::CreateTypeOfComptime(BfType* type)
  1058. {
  1059. BfTypeOf_Const* typeOf = mTempAlloc.Alloc<BfTypeOf_Const>();
  1060. typeOf->mConstType = BfConstType_TypeOf_Comptime;
  1061. typeOf->mType = type;
  1062. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(typeOf));
  1063. #ifdef CHECK_CONSTHOLDER
  1064. irValue.mHolder = this;
  1065. #endif
  1066. return irValue;
  1067. }
  1068. BfIRValue BfIRConstHolder::CreateTypeOf(BfType* type)
  1069. {
  1070. BfTypeOf_Const* typeOf = mTempAlloc.Alloc<BfTypeOf_Const>();
  1071. typeOf->mConstType = BfConstType_TypeOf;
  1072. typeOf->mType = type;
  1073. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(typeOf));
  1074. #ifdef CHECK_CONSTHOLDER
  1075. irValue.mHolder = this;
  1076. #endif
  1077. return irValue;
  1078. }
  1079. BfIRValue BfIRConstHolder::CreateTypeOf(BfType* type, BfIRValue typeData)
  1080. {
  1081. BfTypeOf_WithData_Const* typeOf = mTempAlloc.Alloc<BfTypeOf_WithData_Const>();
  1082. typeOf->mConstType = BfConstType_TypeOf_WithData;
  1083. typeOf->mType = type;
  1084. typeOf->mTypeData = typeData;
  1085. auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(typeOf));
  1086. #ifdef CHECK_CONSTHOLDER
  1087. irValue.mHolder = this;
  1088. #endif
  1089. return irValue;
  1090. }
  1091. BfIRValue BfIRConstHolder::GetUndefConstValue(BfIRType irType)
  1092. {
  1093. auto constUndef = mTempAlloc.Alloc<BfConstantUndef>();
  1094. constUndef->mConstType = BfConstType_Undef;
  1095. constUndef->mType = irType;
  1096. BfIRValue undefVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constUndef));
  1097. #ifdef CHECK_CONSTHOLDER
  1098. castedVal.mHolder = this;
  1099. #endif
  1100. BF_ASSERT((void*)GetConstant(undefVal) == (void*)constUndef);
  1101. return undefVal;
  1102. }
  1103. bool BfIRConstHolder::WriteConstant(BfIRValue val, void* ptr, BfType* type)
  1104. {
  1105. auto constant = GetConstant(val);
  1106. if (constant == NULL)
  1107. return false;
  1108. switch (constant->mTypeCode)
  1109. {
  1110. case BfTypeCode_Int8:
  1111. case BfTypeCode_UInt8:
  1112. case BfTypeCode_Boolean:
  1113. case BfTypeCode_Char8:
  1114. *(int8*)ptr = constant->mInt8;
  1115. return true;
  1116. case BfTypeCode_Int16:
  1117. case BfTypeCode_UInt16:
  1118. case BfTypeCode_Char16:
  1119. *(int16*)ptr = constant->mInt16;
  1120. return true;
  1121. case BfTypeCode_Int32:
  1122. case BfTypeCode_UInt32:
  1123. case BfTypeCode_Char32:
  1124. case BfTypeCode_StringId:
  1125. *(int32*)ptr = constant->mInt32;
  1126. return true;
  1127. case BfTypeCode_Int64:
  1128. case BfTypeCode_UInt64:
  1129. *(int64*)ptr = constant->mInt64;
  1130. return true;
  1131. case BfTypeCode_NullPtr:
  1132. if (mModule->mSystem->mPtrSize == 4)
  1133. *(int32*)ptr = 0;
  1134. else
  1135. *(int64*)ptr = 0;
  1136. return true;
  1137. case BfTypeCode_Float:
  1138. *(float*)ptr = (float)constant->mDouble;
  1139. return true;
  1140. case BfTypeCode_Double:
  1141. *(double*)ptr = constant->mDouble;
  1142. return true;
  1143. }
  1144. if (constant->mConstType == BfConstType_Agg)
  1145. {
  1146. auto aggConstant = (BfConstantAgg*)constant;
  1147. if (type->IsSizedArray())
  1148. {
  1149. auto sizedArrayType = (BfSizedArrayType*)type;
  1150. for (int i = 0; i < sizedArrayType->mElementCount; i++)
  1151. {
  1152. if (!WriteConstant(aggConstant->mValues[i], (uint8*)ptr + (i * sizedArrayType->mElementType->GetStride()), sizedArrayType->mElementType))
  1153. return false;
  1154. }
  1155. return true;
  1156. }
  1157. else
  1158. {
  1159. BF_ASSERT(type->IsStruct());
  1160. mModule->PopulateType(type);
  1161. auto typeInst = type->ToTypeInstance();
  1162. int idx = 0;
  1163. if (typeInst->mBaseType != NULL)
  1164. {
  1165. if (!WriteConstant(aggConstant->mValues[0], ptr, typeInst->mBaseType))
  1166. return false;
  1167. }
  1168. if (typeInst->IsUnion())
  1169. {
  1170. auto innerType = typeInst->GetUnionInnerType();
  1171. if (!WriteConstant(aggConstant->mValues[1], (uint8*)ptr, innerType))
  1172. return false;
  1173. }
  1174. if ((!typeInst->IsUnion()) || (typeInst->IsPayloadEnum()))
  1175. {
  1176. for (auto& fieldInstance : typeInst->mFieldInstances)
  1177. {
  1178. if (fieldInstance.mDataOffset < 0)
  1179. continue;
  1180. if (!WriteConstant(aggConstant->mValues[fieldInstance.mDataIdx], (uint8*)ptr + fieldInstance.mDataOffset, fieldInstance.mResolvedType))
  1181. return false;
  1182. }
  1183. }
  1184. }
  1185. return true;
  1186. }
  1187. if (constant->mConstType == BfConstType_AggZero)
  1188. {
  1189. BF_ASSERT(type->IsComposite());
  1190. memset(ptr, 0, type->mSize);
  1191. return true;
  1192. }
  1193. if (constant->mConstType == BfConstType_BitCast)
  1194. {
  1195. auto constBitCast = (BfConstantBitCast*)constant;
  1196. auto constTarget = mModule->mBfIRBuilder->GetConstantById(constBitCast->mTarget);
  1197. return WriteConstant(BfIRValue(BfIRValueFlags_Const, constBitCast->mTarget), ptr, type);
  1198. }
  1199. if (constant->mConstType == BfConstType_GlobalVar)
  1200. {
  1201. auto constGV = (BfGlobalVar*)constant;
  1202. const char* strDataPrefix = "__bfStrData";
  1203. if (strncmp(constGV->mName, strDataPrefix, strlen(strDataPrefix)) == 0)
  1204. {
  1205. *(int32*)ptr = atoi(constGV->mName + strlen(strDataPrefix));
  1206. return true;
  1207. }
  1208. const char* strObjPrefix = "__bfStrObj";
  1209. if (strncmp(constGV->mName, strObjPrefix, strlen(strObjPrefix)) == 0)
  1210. {
  1211. *(int32*)ptr = atoi(constGV->mName + strlen(strObjPrefix));
  1212. return true;
  1213. }
  1214. }
  1215. return false;
  1216. }
  1217. BfIRValue BfIRConstHolder::ReadConstant(void* ptr, BfType* type)
  1218. {
  1219. if (type->IsPrimitiveType())
  1220. {
  1221. auto primType = (BfPrimitiveType*)type;
  1222. switch (primType->mTypeDef->mTypeCode)
  1223. {
  1224. case BfTypeCode_Int8:
  1225. case BfTypeCode_UInt8:
  1226. case BfTypeCode_Boolean:
  1227. case BfTypeCode_Char8:
  1228. return CreateConst(primType->mTypeDef->mTypeCode, *(int8*)ptr);
  1229. case BfTypeCode_Int16:
  1230. case BfTypeCode_UInt16:
  1231. case BfTypeCode_Char16:
  1232. return CreateConst(primType->mTypeDef->mTypeCode, *(int16*)ptr);
  1233. case BfTypeCode_Int32:
  1234. case BfTypeCode_UInt32:
  1235. case BfTypeCode_Char32:
  1236. case BfTypeCode_StringId:
  1237. return CreateConst(primType->mTypeDef->mTypeCode, *(int32*)ptr);
  1238. case BfTypeCode_Int64:
  1239. case BfTypeCode_UInt64:
  1240. return CreateConst(primType->mTypeDef->mTypeCode, *(uint64*)ptr);
  1241. case BfTypeCode_NullPtr:
  1242. return CreateConstNull();
  1243. case BfTypeCode_Float:
  1244. return CreateConst(primType->mTypeDef->mTypeCode, *(float*)ptr);
  1245. case BfTypeCode_Double:
  1246. return CreateConst(primType->mTypeDef->mTypeCode, *(double*)ptr);
  1247. case BfTypeCode_IntPtr:
  1248. case BfTypeCode_UIntPtr:
  1249. if (mModule->mSystem->mPtrSize == 4)
  1250. return CreateConst(primType->mTypeDef->mTypeCode, *(int32*)ptr);
  1251. else
  1252. return CreateConst(primType->mTypeDef->mTypeCode, *(uint64*)ptr);
  1253. default:
  1254. return BfIRValue();
  1255. }
  1256. }
  1257. if (type->IsTypedPrimitive())
  1258. {
  1259. return ReadConstant(ptr, type->GetUnderlyingType());
  1260. }
  1261. if (type->IsSizedArray())
  1262. {
  1263. SizedArray<BfIRValue, 8> irValues;
  1264. auto sizedArrayType = (BfSizedArrayType*)type;
  1265. for (int i = 0; i < sizedArrayType->mElementCount; i++)
  1266. {
  1267. auto val = ReadConstant((uint8*)ptr + (i * sizedArrayType->mElementType->GetStride()), sizedArrayType->mElementType);
  1268. if (!val)
  1269. return BfIRValue();
  1270. irValues.Add(val);
  1271. }
  1272. BfIRType irType;
  1273. irType.mKind = BfIRTypeData::TypeKind_TypeId;
  1274. irType.mId = type->mTypeId;
  1275. return CreateConstAgg(irType, irValues);
  1276. }
  1277. if (type->IsStruct())
  1278. {
  1279. mModule->PopulateType(type);
  1280. auto typeInst = type->ToTypeInstance();
  1281. int idx = 0;
  1282. SizedArray<BfIRValue, 8> irValues;
  1283. if (typeInst->mBaseType != NULL)
  1284. {
  1285. auto val = ReadConstant(ptr, typeInst->mBaseType);
  1286. if (!val)
  1287. return BfIRValue();
  1288. irValues.Add(val);
  1289. }
  1290. if (typeInst->IsUnion())
  1291. {
  1292. auto innerType = typeInst->GetUnionInnerType();
  1293. auto val = ReadConstant(ptr, innerType);
  1294. if (!val)
  1295. return BfIRValue();
  1296. irValues.Add(val);
  1297. }
  1298. if ((!typeInst->IsUnion()) || (typeInst->IsPayloadEnum()))
  1299. {
  1300. for (auto& fieldInstance : typeInst->mFieldInstances)
  1301. {
  1302. if (fieldInstance.mDataOffset < 0)
  1303. continue;
  1304. auto val = ReadConstant((uint8*)ptr + fieldInstance.mDataOffset, fieldInstance.mResolvedType);
  1305. if (!val)
  1306. return BfIRValue();
  1307. irValues.Add(val);
  1308. }
  1309. }
  1310. BfIRType irType;
  1311. irType.mKind = BfIRTypeData::TypeKind_TypeId;
  1312. irType.mId = type->mTypeId;
  1313. return CreateConstAgg(irType, irValues);
  1314. }
  1315. if (type->IsInstanceOf(mModule->mCompiler->mStringTypeDef))
  1316. {
  1317. return CreateConst(BfTypeCode_StringId, *(int32*)ptr);
  1318. }
  1319. if (type->IsPointer())
  1320. {
  1321. bool isZero = false;
  1322. if (mModule->mSystem->mPtrSize == 4)
  1323. isZero = *(int32*)ptr == 0;
  1324. else
  1325. isZero = *(int64*)ptr == 0;
  1326. if (isZero)
  1327. {
  1328. BfIRType irType;
  1329. irType.mKind = BfIRTypeData::TypeKind_TypeId;
  1330. irType.mId = type->mTypeId;
  1331. return CreateConstNull(irType);
  1332. }
  1333. }
  1334. return BfIRValue();
  1335. }
  1336. //////////////////////////////////////////////////////////////////////////
  1337. void BfIRBuilder::OpFailed()
  1338. {
  1339. mOpFailed = true;
  1340. }
  1341. uint8 BfIRBuilder::CheckedAdd(uint8 a, uint8 b)
  1342. {
  1343. uint32 result = (uint32)a + b;
  1344. if (result & 0xFFFFFF00)
  1345. OpFailed();
  1346. return (uint8)result;
  1347. }
  1348. uint16 BfIRBuilder::CheckedAdd(uint16 a, uint16 b)
  1349. {
  1350. uint32 result = (uint32)a + b;
  1351. if (result & 0xFFFF0000)
  1352. OpFailed();
  1353. return (uint16)result;
  1354. }
  1355. uint32 BfIRBuilder::CheckedAdd(uint32 a, uint32 b)
  1356. {
  1357. uint32 result = a + b;
  1358. if (result < a)
  1359. OpFailed();
  1360. return (uint32)result;
  1361. }
  1362. uint64 BfIRBuilder::CheckedAdd(uint64 a, uint64 b)
  1363. {
  1364. uint64 result = a + b;
  1365. if (result < a)
  1366. OpFailed();
  1367. return (uint64)result;
  1368. }
  1369. int8 BfIRBuilder::CheckedAdd(int8 a, int8 b)
  1370. {
  1371. int32 result = (int32)a + b;
  1372. if ((result > 0x7F) || (result < -0x80))
  1373. OpFailed();
  1374. return (int8)result;
  1375. }
  1376. int16 BfIRBuilder::CheckedAdd(int16 a, int16 b)
  1377. {
  1378. int32 result = (int32)a + b;
  1379. if ((result > 0x7FFF) || (result < -0x8000))
  1380. OpFailed();
  1381. return (int16)result;
  1382. }
  1383. int32 BfIRBuilder::CheckedAdd(int32 a, int32 b)
  1384. {
  1385. int32 result = a + b;
  1386. if (b >= 0)
  1387. {
  1388. if (result < a)
  1389. OpFailed();
  1390. }
  1391. else if (result > a)
  1392. OpFailed();
  1393. return (uint32)result;
  1394. }
  1395. int64 BfIRBuilder::CheckedAdd(int64 a, int64 b)
  1396. {
  1397. int64 result = a + b;
  1398. if (b >= 0)
  1399. {
  1400. if (result < a)
  1401. OpFailed();
  1402. }
  1403. else if (result > a)
  1404. OpFailed();
  1405. return (uint64)result;
  1406. }
  1407. ///
  1408. uint8 BfIRBuilder::CheckedSub(uint8 a, uint8 b)
  1409. {
  1410. uint32 result = (uint32)a - b;
  1411. if (result & 0xFFFFFF00)
  1412. OpFailed();
  1413. return (uint8)result;
  1414. }
  1415. uint16 BfIRBuilder::CheckedSub(uint16 a, uint16 b)
  1416. {
  1417. uint32 result = (uint32)a - b;
  1418. if (result & 0xFFFF0000)
  1419. OpFailed();
  1420. return (uint16)result;
  1421. }
  1422. uint32 BfIRBuilder::CheckedSub(uint32 a, uint32 b)
  1423. {
  1424. uint32 result = a - b;
  1425. if (result > a)
  1426. OpFailed();
  1427. return (uint32)result;
  1428. }
  1429. uint64 BfIRBuilder::CheckedSub(uint64 a, uint64 b)
  1430. {
  1431. uint64 result = a - b;
  1432. if (result > a)
  1433. OpFailed();
  1434. return (uint64)result;
  1435. }
  1436. int8 BfIRBuilder::CheckedSub(int8 a, int8 b)
  1437. {
  1438. int32 result = (int32)a - b;
  1439. if ((result > 0x7F) || (result < -0x80))
  1440. OpFailed();
  1441. return (int8)result;
  1442. }
  1443. int16 BfIRBuilder::CheckedSub(int16 a, int16 b)
  1444. {
  1445. int32 result = (int32)a - b;
  1446. if ((result > 0x7FFF) || (result < -0x8000))
  1447. OpFailed();
  1448. return (int16)result;
  1449. }
  1450. int32 BfIRBuilder::CheckedSub(int32 a, int32 b)
  1451. {
  1452. int32 result = a - b;
  1453. if (b >= 0)
  1454. {
  1455. if (result > a)
  1456. OpFailed();
  1457. }
  1458. else if (result < a)
  1459. OpFailed();
  1460. return (uint32)result;
  1461. }
  1462. int64 BfIRBuilder::CheckedSub(int64 a, int64 b)
  1463. {
  1464. int64 result = a - b;
  1465. if (b >= 0)
  1466. {
  1467. if (result > a)
  1468. OpFailed();
  1469. }
  1470. else if (result < a)
  1471. OpFailed();
  1472. return (uint64)result;
  1473. }
  1474. ///
  1475. uint8 BfIRBuilder::CheckedMul(uint8 a, uint8 b)
  1476. {
  1477. int result = (uint32)a * b;
  1478. if (result & 0xFFFFFF00)
  1479. OpFailed();
  1480. return (uint8)result;
  1481. }
  1482. uint16 BfIRBuilder::CheckedMul(uint16 a, uint16 b)
  1483. {
  1484. int result = (uint32)a * b;
  1485. if (result & 0xFFFF0000)
  1486. OpFailed();
  1487. return (uint16)result;
  1488. }
  1489. uint32 BfIRBuilder::CheckedMul(uint32 a, uint32 b)
  1490. {
  1491. uint64 result = (uint64)a * b;
  1492. uint32 upper = (uint32)(result >> 32);
  1493. if ((upper != 0) && (upper != 0xFFFFFFFF))
  1494. OpFailed();
  1495. return (uint32)result;
  1496. }
  1497. uint64 BfIRBuilder::CheckedMul(uint64 a, uint64 b)
  1498. {
  1499. uint32 aHigh;
  1500. uint32 aLow;
  1501. uint32 bHigh;
  1502. uint32 bLow;
  1503. // a*b can be decomposed to
  1504. // (aHigh * bHigh * 2^64) + (aLow * bHigh * 2^32) + (aHigh * bLow * 2^32) + (aLow * bLow)
  1505. aHigh = (uint32)(a >> 32);
  1506. aLow = (uint32)(a);
  1507. bHigh = (uint32)(b >> 32);
  1508. bLow = (uint32)(b);
  1509. uint64 ret = 0;
  1510. if (aHigh == 0)
  1511. {
  1512. if (bHigh != 0)
  1513. ret = (uint64)aLow * (uint64)bHigh;
  1514. }
  1515. else if (bHigh == 0)
  1516. {
  1517. if (aHigh != 0)
  1518. ret = (uint64)aHigh * (uint64)bLow;
  1519. }
  1520. else
  1521. OpFailed();
  1522. if (ret != 0)
  1523. {
  1524. uint64 tmp;
  1525. if((uint32)(ret >> 32) != 0)
  1526. OpFailed();
  1527. ret <<= 32;
  1528. tmp = (uint64)aLow * (uint64)bLow;
  1529. ret += tmp;
  1530. if (ret < tmp)
  1531. OpFailed();
  1532. return ret;
  1533. }
  1534. return (uint64)aLow * (uint64)bLow;
  1535. }
  1536. int8 BfIRBuilder::CheckedMul(int8 a, int8 b)
  1537. {
  1538. int32 result = (int32)a * b;
  1539. if ((result > 0x7F) || (result < -0x80))
  1540. OpFailed();
  1541. return (int8)result;
  1542. }
  1543. int16 BfIRBuilder::CheckedMul(int16 a, int16 b)
  1544. {
  1545. int result = a * b;
  1546. if ((result > 0x7FFF) || (result < -0x8000))
  1547. OpFailed();
  1548. return (int16)result;
  1549. }
  1550. int32 BfIRBuilder::CheckedMul(int32 a, int32 b)
  1551. {
  1552. int64 result = (int64)a * b;
  1553. int32 upper = (int32)(result >> 32);
  1554. if ((upper != 0) && (upper != 0xFFFFFFFF))
  1555. OpFailed();
  1556. return (int32)result;
  1557. }
  1558. int64 BfIRBuilder::CheckedMul(int64 a, int64 b)
  1559. {
  1560. bool aNegative = false;
  1561. int64 aAbs = a;
  1562. if (aAbs < 0)
  1563. {
  1564. aNegative = true;
  1565. aAbs = -aAbs;
  1566. }
  1567. int64 bAbs = b;
  1568. bool bNegative = false;
  1569. if (bAbs < 0)
  1570. {
  1571. bNegative = true;
  1572. bAbs = -bAbs;
  1573. }
  1574. uint64 tmp = CheckedMul((uint64)aAbs, (uint64)bAbs);
  1575. // Don't allow overflow into sign flag
  1576. if (tmp & 0x8000000000000000LL)
  1577. OpFailed();
  1578. if (aNegative ^ bNegative)
  1579. return -(int64)tmp;
  1580. return (int64)tmp;
  1581. }
  1582. ///
  1583. uint8 BfIRBuilder::CheckedShl(uint8 a, uint8 b)
  1584. {
  1585. if ((a != 0) && (b >= 8))
  1586. OpFailed();
  1587. uint32 result = (uint32)a << b;
  1588. if (result & 0xFFFFFF00)
  1589. OpFailed();
  1590. return (uint8)result;
  1591. }
  1592. uint16 BfIRBuilder::CheckedShl(uint16 a, uint16 b)
  1593. {
  1594. if ((a != 0) && (b >= 16))
  1595. OpFailed();
  1596. uint32 result = (uint32)a << b;
  1597. if (result & 0xFFFF0000)
  1598. OpFailed();
  1599. return (uint16)result;
  1600. }
  1601. uint32 BfIRBuilder::CheckedShl(uint32 a, uint32 b)
  1602. {
  1603. if ((a != 0) && (b >= 32))
  1604. OpFailed();
  1605. uint32 result = a << b;
  1606. if (result < a)
  1607. OpFailed();
  1608. return (uint32)result;
  1609. }
  1610. uint64 BfIRBuilder::CheckedShl(uint64 a, uint64 b)
  1611. {
  1612. if ((a != 0) && (b >= 64))
  1613. OpFailed();
  1614. uint64 result = a << b;
  1615. if (result < a)
  1616. OpFailed();
  1617. return (uint64)result;
  1618. }
  1619. int8 BfIRBuilder::CheckedShl(int8 a, int8 b)
  1620. {
  1621. if ((a != 0) && (b >= 8))
  1622. OpFailed();
  1623. int32 result = (int32)a << b;
  1624. if ((result > 0x7F) || (result < -0x80))
  1625. OpFailed();
  1626. return (int8)result;
  1627. }
  1628. int16 BfIRBuilder::CheckedShl(int16 a, int16 b)
  1629. {
  1630. if ((a != 0) && (b >= 16))
  1631. OpFailed();
  1632. int32 result = (int32)a << b;
  1633. if ((result > 0x7FFF) || (result < -0x8000))
  1634. OpFailed();
  1635. return (int16)result;
  1636. }
  1637. int32 BfIRBuilder::CheckedShl(int32 a, int32 b)
  1638. {
  1639. if ((a != 0) && (b >= 32))
  1640. OpFailed();
  1641. int64 result = (int64)a << b;
  1642. if ((result > 0x7FFFFFFFLL) || (result < -0x80000000LL))
  1643. OpFailed();
  1644. return (int32)result;
  1645. }
  1646. int64 BfIRBuilder::CheckedShl(int64 a, int64 b)
  1647. {
  1648. if ((a != 0) && (b >= 64))
  1649. OpFailed();
  1650. int64 result = (int64)a << b;
  1651. if (((a > 0) && (result < a)) ||
  1652. ((a < 0) && (result > a)))
  1653. OpFailed();
  1654. return result;
  1655. }
  1656. //////////////////////////////////////////////////////////////////////////
  1657. BfIRBuilder::BfIRBuilder(BfModule* module) : BfIRConstHolder(module)
  1658. {
  1659. mBlockCount = 0;
  1660. mModule = module;
  1661. mHasDebugLoc = false;
  1662. mHasDebugInfo = false;
  1663. mHasDebugLineInfo = false;
  1664. mIRCodeGen = NULL;
  1665. mBeIRCodeGen = NULL;
  1666. mBfIRCodeGen = NULL;
  1667. mDbgVerifyCodeGen = false;
  1668. mIgnoreWrites = false;
  1669. mCurFakeId = -32;
  1670. mOpFailed = false;
  1671. mHasGlobalDefs = false;
  1672. mNumFunctionsWithBodies = 0;
  1673. mActiveFunctionHasBody = false;
  1674. mHasStarted = false;
  1675. mCmdCount = 0;
  1676. mIsBeefBackend = false;
  1677. }
  1678. bool BfIRBuilder::HasExports()
  1679. {
  1680. return mHasGlobalDefs || (mNumFunctionsWithBodies > 0);
  1681. }
  1682. BfIRBuilder::~BfIRBuilder()
  1683. {
  1684. if (mIRCodeGen != NULL)
  1685. {
  1686. mIRCodeGen->mStream = NULL;
  1687. delete mIRCodeGen;
  1688. }
  1689. BF_ASSERT(mSavedDebugLocs.size() == 0);
  1690. }
  1691. String BfIRBuilder::ToString(BfIRValue irValue)
  1692. {
  1693. if ((irValue.mFlags & BfIRValueFlags_Const) != 0)
  1694. {
  1695. return BfIRConstHolder::ToString(irValue);
  1696. }
  1697. else if ((irValue.mFlags & BfIRValueFlags_Arg) != 0)
  1698. {
  1699. return StrFormat("Arg %d in %s", irValue.mId, ActiveFuncToString().c_str());
  1700. }
  1701. else if (irValue.mFlags != 0)
  1702. {
  1703. if (mBfIRCodeGen != NULL)
  1704. {
  1705. auto val = mBfIRCodeGen->GetLLVMValue(irValue.mId);
  1706. std::string outStr;
  1707. llvm::raw_string_ostream strStream(outStr);
  1708. val->print(strStream);
  1709. strStream << "\n Type: ";
  1710. val->getType()->print(strStream);
  1711. strStream.flush();
  1712. return outStr;
  1713. }
  1714. else if (mBeIRCodeGen != NULL)
  1715. {
  1716. auto val = mBeIRCodeGen->GetBeValue(irValue.mId);
  1717. String str;
  1718. BeDumpContext dc;
  1719. dc.ToString(str, val);
  1720. auto type = val->GetType();
  1721. if (type != NULL)
  1722. {
  1723. str += "\n";
  1724. dc.ToString(str, type);
  1725. }
  1726. return str;
  1727. }
  1728. else
  1729. return "Value???";
  1730. }
  1731. else
  1732. {
  1733. BF_ASSERT(irValue.mId == -1);
  1734. }
  1735. return "empty";
  1736. }
  1737. String BfIRBuilder::ToString(BfIRType irType)
  1738. {
  1739. if (mBfIRCodeGen != NULL)
  1740. {
  1741. llvm::Type* llvmType = NULL;
  1742. if (irType.mKind == BfIRTypeData::TypeKind_Stream)
  1743. {
  1744. llvmType = mBfIRCodeGen->GetLLVMType(irType.mId);
  1745. }
  1746. else if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeCode)
  1747. {
  1748. bool isSigned = false;
  1749. llvmType = mBfIRCodeGen->GetLLVMType((BfTypeCode)irType.mId, isSigned);
  1750. }
  1751. else
  1752. {
  1753. auto& typeEntry = mBfIRCodeGen->GetTypeEntry(irType.mId);
  1754. if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeId)
  1755. llvmType = typeEntry.mType->mLLVMType;
  1756. else if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeInstId)
  1757. llvmType = typeEntry.mInstType->mLLVMType;
  1758. else if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeInstPtrId)
  1759. llvmType = typeEntry.mInstType->mLLVMType->getPointerTo();
  1760. }
  1761. if (llvmType == NULL)
  1762. return "null";
  1763. std::string outStr;
  1764. llvm::raw_string_ostream strStream(outStr);
  1765. llvmType->print(strStream);
  1766. if (auto pointerType = llvm::dyn_cast<llvm::PointerType>(llvmType))
  1767. {
  1768. strStream << "\n ElementType: ";
  1769. //pointerType->getElementType()->print(strStream);
  1770. }
  1771. strStream.flush();
  1772. return outStr;
  1773. }
  1774. else if (mBeIRCodeGen != NULL)
  1775. {
  1776. BeType* beType;
  1777. if (irType.mKind == BfIRTypeData::TypeKind_Stream)
  1778. {
  1779. beType = mBeIRCodeGen->GetBeType(irType.mId);
  1780. }
  1781. else if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeCode)
  1782. {
  1783. bool isSigned = false;
  1784. beType = mBeIRCodeGen->GetBeType((BfTypeCode)irType.mId, isSigned);
  1785. }
  1786. else
  1787. {
  1788. auto& typeEntry = mBeIRCodeGen->GetTypeEntry(irType.mId);
  1789. if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeId)
  1790. beType = typeEntry.mBeType;
  1791. else if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeInstId)
  1792. beType = typeEntry.mBeType;
  1793. else if (irType.mKind == BfIRType::TypeKind::TypeKind_TypeInstPtrId)
  1794. beType = mBeIRCodeGen->mBeContext->GetPointerTo(typeEntry.mInstBeType);
  1795. }
  1796. String str;
  1797. BeDumpContext dc;
  1798. dc.ToString(str, beType);
  1799. return str;
  1800. }
  1801. else if (irType.mKind == BfIRTypeData::TypeKind_TypeId)
  1802. {
  1803. return StrFormat("Type#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str());
  1804. }
  1805. else if (irType.mKind == BfIRTypeData::TypeKind_TypeInstId)
  1806. {
  1807. return StrFormat("TypeInst#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str());
  1808. }
  1809. else if (irType.mKind == BfIRTypeData::TypeKind_TypeInstPtrId)
  1810. {
  1811. return StrFormat("TypeInstPtr#%d:%s", irType.mId, mModule->TypeToString(mModule->mContext->mTypes[irType.mId]).c_str());
  1812. }
  1813. else if (irType.mKind == BfIRTypeData::TypeKind_SizedArray)
  1814. {
  1815. auto sizedArrayType = (BfConstantSizedArrayType*)GetConstantById(irType.mId);
  1816. return StrFormat("%s[%d]", ToString(sizedArrayType->mType).c_str(), (int)sizedArrayType->mLength);
  1817. }
  1818. else
  1819. {
  1820. return "Type ???";
  1821. }
  1822. }
  1823. String BfIRBuilder::ToString(BfIRFunction irFunc)
  1824. {
  1825. if (mBfIRCodeGen != NULL)
  1826. {
  1827. auto val = mBfIRCodeGen->GetLLVMValue(irFunc.mId);
  1828. if (val == NULL)
  1829. return "null";
  1830. std::string outStr;
  1831. llvm::raw_string_ostream strStream(outStr);
  1832. val->print(strStream);
  1833. strStream.flush();
  1834. return outStr;
  1835. }
  1836. else if (mBeIRCodeGen != NULL)
  1837. {
  1838. auto val = mBeIRCodeGen->GetBeValue(irFunc.mId);
  1839. if (val == NULL)
  1840. return "null";
  1841. String str;
  1842. BeDumpContext dc;
  1843. dc.ToString(str, val);
  1844. return str;
  1845. }
  1846. else
  1847. return "???";
  1848. }
  1849. String BfIRBuilder::ToString(BfIRFunctionType irType)
  1850. {
  1851. if (mBfIRCodeGen != NULL)
  1852. {
  1853. auto llvmType = mBfIRCodeGen->GetLLVMType(irType.mId);
  1854. if (llvmType == NULL)
  1855. return "null";
  1856. std::string outStr;
  1857. llvm::raw_string_ostream strStream(outStr);
  1858. llvmType->print(strStream);
  1859. strStream.flush();
  1860. return outStr;
  1861. }
  1862. else
  1863. return "???";
  1864. }
  1865. String BfIRBuilder::ToString(BfIRMDNode irMDNode)
  1866. {
  1867. if (mBfIRCodeGen != NULL)
  1868. {
  1869. auto md = mBfIRCodeGen->GetLLVMMetadata(irMDNode.mId);
  1870. if (md == NULL)
  1871. return "null";
  1872. std::string outStr;
  1873. llvm::raw_string_ostream strStream(outStr);
  1874. md->print(strStream);
  1875. strStream.flush();
  1876. return outStr;
  1877. }
  1878. else if (mBeIRCodeGen != NULL)
  1879. {
  1880. auto md = mBeIRCodeGen->GetBeMetadata(irMDNode.mId);
  1881. if (md == NULL)
  1882. return "null";
  1883. String str;
  1884. BeDumpContext dc;
  1885. dc.ToString(str, md);
  1886. return str;
  1887. }
  1888. else
  1889. return "???";
  1890. }
  1891. String BfIRBuilder::ActiveFuncToString()
  1892. {
  1893. if (mBfIRCodeGen != NULL)
  1894. {
  1895. std::string outStr;
  1896. llvm::raw_string_ostream strStream(outStr);
  1897. mBfIRCodeGen->mActiveFunction->print(strStream);
  1898. return outStr;
  1899. }
  1900. else
  1901. return "???";
  1902. }
  1903. void BfIRBuilder::PrintActiveFunc()
  1904. {
  1905. pv(mActiveFunction);
  1906. }
  1907. void BfIRBuilder::pv(const BfIRValue& irValue)
  1908. {
  1909. OutputDebugStrF("%s\n", ToString(irValue).c_str());
  1910. }
  1911. void BfIRBuilder::pt(const BfIRType& irType)
  1912. {
  1913. OutputDebugStrF("%s\n", ToString(irType).c_str());
  1914. }
  1915. void pt(llvm::Type* t);
  1916. void BfIRBuilder::pbft(BfType* type)
  1917. {
  1918. OutputDebugStrF("%s\n", mModule->TypeToString(type).c_str());
  1919. //auto itr = mTypeMap.find(type);
  1920. //if (itr == mTypeMap.end())
  1921. BfIRPopulateType* populateType = NULL;
  1922. if (!mTypeMap.TryGetValue(type, &populateType))
  1923. {
  1924. OutputDebugStrF("Not in mTypeMap\n");
  1925. return;
  1926. }
  1927. OutputDebugStrF("mTypeMap DefState: %d\n", *populateType);
  1928. if (mBfIRCodeGen != NULL)
  1929. {
  1930. auto llvmType = mBfIRCodeGen->GetLLVMTypeById(type->mTypeId);
  1931. ::pt(llvmType);
  1932. }
  1933. }
  1934. void BfIRBuilder::pt(const BfIRFunction& irFunc)
  1935. {
  1936. OutputDebugStrF("%s\n", ToString(irFunc).c_str());
  1937. }
  1938. void BfIRBuilder::pft(const BfIRFunctionType& irType)
  1939. {
  1940. OutputDebugStrF("%s\n", ToString(irType).c_str());
  1941. }
  1942. void BfIRBuilder::pmd(const BfIRMDNode& irMDNode)
  1943. {
  1944. OutputDebugStrF("%s\n", ToString(irMDNode).c_str());
  1945. }
  1946. void BfIRBuilder::GetBufferData(Array<uint8>& outBuffer)
  1947. {
  1948. if (mStream.GetSize() == 0)
  1949. return;
  1950. outBuffer.ResizeRaw(mStream.GetSize());
  1951. mStream.SetReadPos(0);
  1952. mStream.Read(&outBuffer[0], mStream.GetSize());
  1953. }
  1954. void BfIRBuilder::ClearConstData()
  1955. {
  1956. mTempAlloc.Clear();
  1957. mConstMemMap.Clear();
  1958. mFunctionMap.Clear();
  1959. mGlobalVarMap.Clear();
  1960. BF_ASSERT(mMethodTypeMap.GetCount() == 0);
  1961. BF_ASSERT(mTypeMap.GetCount() == 0);
  1962. BF_ASSERT(mDITemporaryTypes.size() == 0);
  1963. #ifdef BFIR_RENTRY_CHECK
  1964. BF_ASSERT(mDeclReentrySet.size() == 0);
  1965. BF_ASSERT(mDefReentrySet.size() == 0);
  1966. #endif
  1967. BF_ASSERT(mStream.GetSize() == 0);
  1968. }
  1969. void BfIRBuilder::ClearNonConstData()
  1970. {
  1971. mMethodTypeMap.Clear();
  1972. mFunctionMap.Clear();
  1973. mGlobalVarMap.Clear();
  1974. mTypeMap.Clear();
  1975. mConstMemMap.Clear();
  1976. mDITemporaryTypes.Clear();
  1977. mSavedDebugLocs.Clear();
  1978. mDeferredDbgTypeDefs.Clear();
  1979. mActiveFunction = BfIRFunction();
  1980. mInsertBlock = BfIRValue();
  1981. }
  1982. void BfIRBuilder::Start(const StringImpl& moduleName, int ptrSize, bool isOptimized)
  1983. {
  1984. mHasStarted = true;
  1985. WriteCmd(BfIRCmd_Module_Start, moduleName, ptrSize, isOptimized);
  1986. NEW_CMD_INSERTED;
  1987. }
  1988. void BfIRBuilder::SetBackend(bool isBeefBackend)
  1989. {
  1990. mIsBeefBackend = isBeefBackend;
  1991. BF_ASSERT(mIRCodeGen == NULL);
  1992. if (mDbgVerifyCodeGen)
  1993. {
  1994. if (isBeefBackend)
  1995. {
  1996. mBeIRCodeGen = new BeIRCodeGen();
  1997. mBeIRCodeGen->mStream = &mStream;
  1998. mBeIRCodeGen->mBfIRBuilder = this;
  1999. mIRCodeGen = mBeIRCodeGen;
  2000. }
  2001. else
  2002. {
  2003. mBfIRCodeGen = new BfIRCodeGen();
  2004. mBfIRCodeGen->mStream = &mStream;
  2005. mBfIRCodeGen->mBfIRBuilder = this;
  2006. mIRCodeGen = mBfIRCodeGen;
  2007. }
  2008. mIRCodeGen->SetConfigConst(BfIRConfigConst_VirtualMethodOfs, 0);
  2009. mIRCodeGen->SetConfigConst(BfIRConfigConst_DynSlotOfs, 0);
  2010. while (mStream.GetReadPos() < mStream.GetSize())
  2011. mIRCodeGen->HandleNextCmd();
  2012. }
  2013. }
  2014. void BfIRBuilder::RemoveIRCodeGen()
  2015. {
  2016. if (mIRCodeGen != NULL)
  2017. {
  2018. mIRCodeGen->mStream = NULL;
  2019. delete mIRCodeGen;
  2020. mIRCodeGen = NULL;
  2021. }
  2022. }
  2023. void BfIRBuilder::WriteIR(const StringImpl& fileName)
  2024. {
  2025. WriteCmd(BfIRCmd_WriteIR, fileName);
  2026. NEW_CMD_INSERTED;
  2027. }
  2028. void BfIRBuilder::AbortStream()
  2029. {
  2030. WriteCmd(BfIRCmd_Abort);
  2031. NEW_CMD_INSERTED;
  2032. }
  2033. void BfIRBuilder::Module_SetTargetTriple(const StringImpl& targetTriple, const StringImpl& targetCPU)
  2034. {
  2035. WriteCmd(BfIRCmd_Module_SetTargetTriple, targetTriple, targetCPU);
  2036. NEW_CMD_INSERTED;
  2037. }
  2038. void BfIRBuilder::Module_AddModuleFlag(const StringImpl& flag, int val)
  2039. {
  2040. WriteCmd(BfIRCmd_Module_AddModuleFlag, flag, val);
  2041. NEW_CMD_INSERTED;
  2042. }
  2043. #define GET_FROM(ptr, T) *((T*)(ptr += sizeof(T)) - 1)
  2044. void BfIRBuilder::WriteSLEB128(int64 value)
  2045. {
  2046. if ((value >= -0x40) && (value <= 0x3F))
  2047. {
  2048. mStream.Write(((uint8)value) & 0x7F);
  2049. return;
  2050. }
  2051. bool hasMore;
  2052. do
  2053. {
  2054. uint8 curByte = (uint8)(value & 0x7f);
  2055. value >>= 7;
  2056. hasMore = !((((value == 0) && ((curByte & 0x40) == 0)) ||
  2057. ((value == -1) && ((curByte & 0x40) != 0))));
  2058. if (hasMore)
  2059. curByte |= 0x80;
  2060. mStream.Write(curByte);
  2061. }
  2062. while (hasMore);
  2063. }
  2064. void BfIRBuilder::WriteSLEB128(int32 value)
  2065. {
  2066. if (value < 0)
  2067. {
  2068. // if (value >= -0x40)
  2069. // {
  2070. // mStream.Write((uint8)value);
  2071. // return;
  2072. // }
  2073. //
  2074. // if (value >= -0x2000)
  2075. // {
  2076. // uint16 val =
  2077. // (((uint16)(value << 1)) & 0x7F00) |
  2078. // (((uint16)value) & 0x7F) | 0x80;
  2079. // mStream.Write_2(val);
  2080. // return;
  2081. // }
  2082. //
  2083. // if (value >= -0x100000)
  2084. // {
  2085. // uint32 val =
  2086. // (((uint32)(value << 2)) & 0x7F0000) |
  2087. // (((uint32)(value << 1)) & 0x7F00) |
  2088. // (((uint32)value) & 0x7F) | 0x8080;
  2089. // mStream.Write_3(val);
  2090. // return;
  2091. // }
  2092. //
  2093. // if (value >= -0x8000000)
  2094. // {
  2095. // uint32 val =
  2096. // (((uint32)(value << 3)) & 0x7F000000) |
  2097. // (((uint32)(value << 2)) & 0x7F0000) |
  2098. // (((uint32)(value << 1)) & 0x7F00) |
  2099. // (((uint32)value) & 0x7F) | 0x808080;
  2100. // mStream.Write_4(val);
  2101. // return;
  2102. // }
  2103. }
  2104. else
  2105. {
  2106. if (value <= 0x3F)
  2107. {
  2108. mStream.Write((uint8)value);
  2109. return;
  2110. }
  2111. if (value <= 0x1FFF)
  2112. {
  2113. uint16 val =
  2114. (((uint16)(value << 1)) & 0x7F00) |
  2115. (((uint16)value) & 0x7F) | 0x80;
  2116. mStream.Write_2(val);
  2117. return;
  2118. }
  2119. //
  2120. // if (value <= 0x0FFFFF)
  2121. // {
  2122. // uint32 val =
  2123. // (((uint32)(value << 2)) & 0x7F0000) |
  2124. // (((uint32)(value << 1)) & 0x7F00) |
  2125. // (((uint32)value) & 0x7F) | 0x8080;
  2126. // mStream.Write_3(val);
  2127. // return;
  2128. // }
  2129. //
  2130. // if (value <= 0x7FFFFF)
  2131. // {
  2132. // uint32 val =
  2133. // (((uint32)(value << 3)) & 0x7F000000) |
  2134. // (((uint32)(value << 2)) & 0x7F0000) |
  2135. // (((uint32)(value << 1)) & 0x7F00) |
  2136. // (((uint32)value) & 0x7F) | 0x808080;
  2137. // mStream.Write_4(val);
  2138. // return;
  2139. // }
  2140. }
  2141. bool hasMore;
  2142. do
  2143. {
  2144. uint8 curByte = (uint8)(value & 0x7f);
  2145. value >>= 7;
  2146. hasMore = !((((value == 0) && ((curByte & 0x40) == 0)) ||
  2147. ((value == -1) && ((curByte & 0x40) != 0))));
  2148. if (hasMore)
  2149. curByte |= 0x80;
  2150. mStream.Write(curByte);
  2151. } while (hasMore);
  2152. }
  2153. void BfIRBuilder::Write(uint8 val)
  2154. {
  2155. mStream.Write(val);
  2156. }
  2157. void BfIRBuilder::Write(bool val)
  2158. {
  2159. mStream.Write(val ? 1 : 0);
  2160. }
  2161. void BfIRBuilder::Write(int intVal)
  2162. {
  2163. WriteSLEB128(intVal);
  2164. }
  2165. void BfIRBuilder::Write(int64 intVal)
  2166. {
  2167. WriteSLEB128(intVal);
  2168. }
  2169. void BfIRBuilder::Write(Val128 val)
  2170. {
  2171. WriteSLEB128((int64)val.mLow);
  2172. WriteSLEB128((int64)val.mHigh);
  2173. }
  2174. void BfIRBuilder::Write(const StringImpl&str)
  2175. {
  2176. WriteSLEB128((int)str.length());
  2177. mStream.Write(str.c_str(), (int)str.length());
  2178. }
  2179. void BfIRBuilder::Write(const BfIRValue& irValue)
  2180. {
  2181. if ((irValue.mFlags & BfIRValueFlags_Const) != 0)
  2182. {
  2183. auto constant = GetConstantById(irValue.mId);
  2184. mStream.Write(BfIRParamType_Const);
  2185. mStream.Write((uint8)constant->mTypeCode);
  2186. switch ((int)constant->mTypeCode)
  2187. {
  2188. case (int)BfTypeCode_Float:
  2189. {
  2190. float f = (float)constant->mDouble;
  2191. mStream.Write(&f, sizeof(float));
  2192. }
  2193. break;
  2194. case (int)BfTypeCode_Double:
  2195. {
  2196. mStream.Write(&constant->mDouble, sizeof(double));
  2197. }
  2198. break;
  2199. case (int)BfTypeCode_Int8:
  2200. case (int)BfTypeCode_UInt8:
  2201. case (int)BfTypeCode_Int16:
  2202. case (int)BfTypeCode_UInt16:
  2203. case (int)BfTypeCode_Int32:
  2204. case (int)BfTypeCode_UInt32:
  2205. case (int)BfTypeCode_Int64:
  2206. case (int)BfTypeCode_UInt64:
  2207. case (int)BfTypeCode_IntPtr:
  2208. case (int)BfTypeCode_UIntPtr:
  2209. case (int)BfTypeCode_IntUnknown:
  2210. case (int)BfTypeCode_UIntUnknown:
  2211. case (int)BfTypeCode_Char8:
  2212. case (int)BfTypeCode_Char16:
  2213. case (int)BfTypeCode_Char32:
  2214. {
  2215. WriteSLEB128(constant->mInt64);
  2216. }
  2217. break;
  2218. case (int)BfTypeCode_Boolean:
  2219. {
  2220. Write(constant->mBool);
  2221. }
  2222. break;
  2223. case (int)BfTypeCode_NullPtr:
  2224. {
  2225. Write(constant->mIRType);
  2226. }
  2227. break;
  2228. case (int)BfTypeCode_None:
  2229. {
  2230. // No param needed
  2231. }
  2232. break;
  2233. case (int)BfConstType_GlobalVar:
  2234. {
  2235. auto gvConst = (BfGlobalVar*)constant;
  2236. WriteSLEB128(gvConst->mStreamId);
  2237. if (gvConst->mStreamId == -1)
  2238. {
  2239. int streamId = mCmdCount++;
  2240. gvConst->mStreamId = streamId;
  2241. Write(gvConst->mType);
  2242. Write(gvConst->mIsConst);
  2243. Write((uint8)gvConst->mLinkageType);
  2244. Write(gvConst->mInitializer);
  2245. Write(String(gvConst->mName));
  2246. Write(gvConst->mIsTLS);
  2247. }
  2248. }
  2249. break;
  2250. case (int)BfConstType_BitCast:
  2251. case (int)BfConstType_BitCastNull:
  2252. {
  2253. auto bitcast = (BfConstantBitCast*)constant;
  2254. BfIRValue targetConst(BfIRValueFlags_Const, bitcast->mTarget);
  2255. Write(targetConst);
  2256. Write(bitcast->mToType);
  2257. }
  2258. break;
  2259. case (int)BfConstType_GEP32_1:
  2260. {
  2261. auto gepConst = (BfConstantGEP32_1*)constant;
  2262. BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
  2263. Write(targetConst);
  2264. Write(gepConst->mIdx0);
  2265. }
  2266. break;
  2267. case (int)BfConstType_GEP32_2:
  2268. {
  2269. auto gepConst = (BfConstantGEP32_2*)constant;
  2270. BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
  2271. Write(targetConst);
  2272. Write(gepConst->mIdx0);
  2273. Write(gepConst->mIdx1);
  2274. }
  2275. break;
  2276. case (int)BfConstType_ExtractValue:
  2277. {
  2278. auto gepConst = (BfConstantExtractValue*)constant;
  2279. BfIRValue targetConst(BfIRValueFlags_Const, gepConst->mTarget);
  2280. Write(targetConst);
  2281. Write(gepConst->mIdx0);
  2282. }
  2283. break;
  2284. case (int)BfConstType_PtrToInt:
  2285. {
  2286. auto ptrToIntConst = (BfConstantPtrToInt*)constant;
  2287. BfIRValue targetConst(BfIRValueFlags_Const, ptrToIntConst->mTarget);
  2288. Write(targetConst);
  2289. Write(ptrToIntConst->mToTypeCode);
  2290. }
  2291. break;
  2292. case (int)BfConstType_IntToPtr:
  2293. {
  2294. auto intToPtrConst = (BfConstantIntToPtr*)constant;
  2295. BfIRValue targetConst(BfIRValueFlags_Const, intToPtrConst->mTarget);
  2296. Write(targetConst);
  2297. Write(intToPtrConst->mToType);
  2298. }
  2299. break;
  2300. case (int)BfConstType_AggZero:
  2301. {
  2302. Write(constant->mIRType);
  2303. }
  2304. break;
  2305. case (int)BfConstType_Agg:
  2306. {
  2307. auto arrayConst = (BfConstantAgg*)constant;
  2308. Write(arrayConst->mType);
  2309. Write(arrayConst->mValues);
  2310. }
  2311. break;
  2312. case (int)BfConstType_ArrayZero8:
  2313. {
  2314. Write(constant->mInt64);
  2315. }
  2316. break;
  2317. case (int)BfConstType_TypeOf:
  2318. {
  2319. auto typeofConst = (BfTypeOf_Const*)constant;
  2320. Write(MapType(typeofConst->mType, BfIRPopulateType_Identity));
  2321. }
  2322. break;
  2323. case (int)BfConstType_TypeOf_Comptime:
  2324. {
  2325. auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
  2326. auto typeofConst = (BfTypeOf_Const*)constant;
  2327. Write(MapType(typeType, BfIRPopulateType_Identity));
  2328. Write(typeofConst->mType->mTypeId);
  2329. }
  2330. break;
  2331. case (int)BfConstType_Undef:
  2332. {
  2333. auto undefConst = (BfConstantUndef*)constant;
  2334. Write(undefConst->mType);
  2335. }
  2336. break;
  2337. case (int)BfConstType_TypeOf_WithData:
  2338. {
  2339. auto typeofConst = (BfTypeOf_WithData_Const*)constant;
  2340. Write(MapType(typeofConst->mType, BfIRPopulateType_Identity));
  2341. Write(typeofConst->mTypeData);
  2342. }
  2343. break;
  2344. default:
  2345. {
  2346. BF_FATAL("Unhandled");
  2347. }
  2348. break;
  2349. }
  2350. }
  2351. else if ((irValue.mFlags & BfIRValueFlags_Arg) != 0)
  2352. {
  2353. mStream.Write(BfIRParamType_Arg);
  2354. WriteSLEB128(irValue.mId);
  2355. }
  2356. else if (irValue.mFlags != 0)
  2357. {
  2358. BF_ASSERT(irValue.mId >= 0);
  2359. if (irValue.mId < 0x100)
  2360. {
  2361. mStream.Write(BfIRParamType_StreamId_Abs8);
  2362. mStream.Write(irValue.mId);
  2363. }
  2364. else
  2365. {
  2366. int offset = mCmdCount - irValue.mId;
  2367. BF_ASSERT(offset > 0);
  2368. if (offset <= BfIRParamType_StreamId_Back_LAST - BfIRParamType_StreamId_Back1)
  2369. {
  2370. mStream.Write(BfIRParamType_StreamId_Back1 + (offset - 1));
  2371. }
  2372. else
  2373. {
  2374. mStream.Write(BfIRParamType_StreamId_Rel);
  2375. WriteSLEB128(offset);
  2376. }
  2377. }
  2378. }
  2379. else
  2380. {
  2381. BF_ASSERT(irValue.mId == -1);
  2382. mStream.Write(BfIRParamType_None);
  2383. }
  2384. }
  2385. void BfIRBuilder::Write(BfTypeCode typeCode)
  2386. {
  2387. mStream.Write((uint8)typeCode);
  2388. }
  2389. void BfIRBuilder::Write(const BfIRTypeData& type)
  2390. {
  2391. mStream.Write((uint8)type.mKind);
  2392. if (type.mKind == BfIRTypeData::TypeKind_SizedArray)
  2393. {
  2394. auto sizedArrayType = (BfConstantSizedArrayType*)GetConstantById(type.mId);
  2395. Write(sizedArrayType->mType);
  2396. WriteSLEB128((int64)sizedArrayType->mLength);
  2397. }
  2398. else if (type.mKind != BfIRTypeData::TypeKind_None)
  2399. WriteSLEB128(type.mId);
  2400. }
  2401. void BfIRBuilder::Write(BfIRFunctionType funcType)
  2402. {
  2403. WriteSLEB128(funcType.mId);
  2404. }
  2405. void BfIRBuilder::Write(BfIRFunction func)
  2406. {
  2407. //auto funcData = mFunctionVec[func.mId];
  2408. //WriteSLEB128(bufPtr, funcData->mStreamId);
  2409. WriteSLEB128(func.mId);
  2410. }
  2411. void BfIRBuilder::Write(BfIRBlock block)
  2412. {
  2413. WriteSLEB128(block.mId);
  2414. }
  2415. void BfIRBuilder::Write(BfIRMDNode node)
  2416. {
  2417. BF_ASSERT(node.mId >= -1);
  2418. WriteSLEB128(node.mId);
  2419. }
  2420. BfIRValue BfIRBuilder::WriteCmd(BfIRCmd cmd)
  2421. {
  2422. if (mIgnoreWrites)
  2423. return GetFakeVal();
  2424. mStream.Write((uint8)cmd);
  2425. return BfIRValue(BfIRValueFlags_Value, mCmdCount++);
  2426. }
  2427. void BfIRBuilder::NewCmdInserted()
  2428. {
  2429. BF_ASSERT(mIgnoreWrites || mHasStarted);
  2430. if (mIgnoreWrites)
  2431. return;
  2432. if (mIRCodeGen == NULL)
  2433. return;
  2434. // This is for debug only - for checking the stream after each command. Useful when debugging IR generation errors
  2435. BF_ASSERT(mStream.GetReadPos() < mStream.GetSize());
  2436. mIRCodeGen->HandleNextCmd();
  2437. BF_ASSERT(mStream.GetReadPos() == mStream.GetSize());
  2438. }
  2439. BfIRMDNode BfIRBuilder::CreateNamespaceScope(BfType* type, BfIRMDNode fileDIScope)
  2440. {
  2441. BfIRMDNode curDIScope = fileDIScope;
  2442. auto typeInstance = type->ToTypeInstance();
  2443. if (mModule->mCompiler->mOptions.IsCodeView())
  2444. {
  2445. curDIScope = DbgCreateNameSpace(curDIScope, "_bf",
  2446. fileDIScope, 0);
  2447. }
  2448. if (typeInstance != NULL)
  2449. {
  2450. auto typeDef = typeInstance->mTypeDef;
  2451. if (!typeInstance->IsBoxed())
  2452. {
  2453. BfAtomCompositeT<16> curNamespace;
  2454. if (typeInstance->IsArray())
  2455. {
  2456. auto arrayType = (BfArrayType*)typeInstance;
  2457. auto innerTypeInst = arrayType->GetUnderlyingType()->ToTypeInstance();
  2458. if (innerTypeInst != NULL)
  2459. curNamespace = innerTypeInst->mTypeDef->mNamespace;
  2460. }
  2461. else
  2462. curNamespace = typeDef->mNamespace;
  2463. for (int partCount = 0; partCount < curNamespace.GetPartsCount(); partCount++)
  2464. {
  2465. curDIScope = DbgCreateNameSpace(curDIScope, curNamespace.mParts[partCount]->ToString(),
  2466. fileDIScope, 0);
  2467. }
  2468. }
  2469. }
  2470. return curDIScope;
  2471. }
  2472. String BfIRBuilder::GetDebugTypeName(BfTypeInstance* typeInstance, bool includeOuterTypeName)
  2473. {
  2474. BfTypeNameFlags typeNameFlags = BfTypeNameFlag_AddGlobalContainerName;
  2475. if (!typeInstance->IsUnspecializedTypeVariation())
  2476. typeNameFlags = (BfTypeNameFlags)(typeNameFlags | BfTypeNameFlag_ResolveGenericParamNames);
  2477. String typeName;
  2478. if (typeInstance->IsBoxed())
  2479. {
  2480. BfBoxedType* boxedType = (BfBoxedType*)typeInstance;
  2481. typeName = mModule->TypeToString(boxedType->mElementType, (BfTypeNameFlags)(typeNameFlags));
  2482. if (boxedType->IsBoxedStructPtr())
  2483. typeName += "*";
  2484. typeName = "Box<" + typeName + ">";
  2485. }
  2486. else if (includeOuterTypeName)
  2487. {
  2488. typeName = mModule->TypeToString(typeInstance, (BfTypeNameFlags)(typeNameFlags | BfTypeNameFlag_OmitNamespace));
  2489. }
  2490. else
  2491. {
  2492. typeName = mModule->TypeToString(typeInstance, (BfTypeNameFlags)(typeNameFlags | BfTypeNameFlag_OmitNamespace | BfTypeNameFlag_OmitOuterType));
  2493. }
  2494. for (int i = 0; i < (int)typeName.length(); i++)
  2495. {
  2496. if (typeName[i] == '.')
  2497. {
  2498. typeName[i] = ':';
  2499. typeName.Insert(i, ":");
  2500. }
  2501. }
  2502. //DbgAddPrefix(typeName);
  2503. return typeName;
  2504. }
  2505. #ifdef BFIR_RENTRY_CHECK
  2506. struct ReEntryCheck
  2507. {
  2508. public:
  2509. std::set<BfType*>* mSet;
  2510. BfType* mType;
  2511. public:
  2512. ReEntryCheck(std::set<BfType*>* set, BfType* type)
  2513. {
  2514. mSet = set;
  2515. mType = type;
  2516. auto pair = mSet->insert(type);
  2517. BF_ASSERT(pair.second);
  2518. }
  2519. ~ReEntryCheck()
  2520. {
  2521. mSet->erase(mType);
  2522. }
  2523. };
  2524. #endif
  2525. void BfIRBuilder::CreateTypeDeclaration(BfType* type, bool forceDbgDefine)
  2526. {
  2527. auto populateModule = mModule->mContext->mUnreifiedModule;
  2528. auto typeInstance = type->ToTypeInstance();
  2529. if ((typeInstance != NULL) && (typeInstance->mModule != NULL))
  2530. populateModule = typeInstance->mModule;
  2531. bool wantDIData = DbgHasInfo() && (!type->IsUnspecializedType());
  2532. // Types that don't have a proper 'defining module' need to be defined in every module they are used
  2533. bool wantsDIForwardDecl = (type->GetModule() != mModule) && (!type->IsFunction());
  2534. // Forward declarations of valuetypes don't work in LLVM backend for Win32.....
  2535. //TODO: Why was this commented out?
  2536. bool wantsDIPartialDef = false;
  2537. if (wantsDIForwardDecl)
  2538. {
  2539. if ((!mIsBeefBackend) && (type->IsValueType()))
  2540. {
  2541. wantsDIPartialDef = true;
  2542. wantsDIForwardDecl = false;
  2543. }
  2544. }
  2545. if (mModule->mExtensionCount != 0)
  2546. wantsDIForwardDecl = true;
  2547. if (forceDbgDefine)
  2548. wantsDIForwardDecl = false;
  2549. bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive());
  2550. if (!type->IsDeclared())
  2551. populateModule->PopulateType(type, BfPopulateType_Declaration);
  2552. if (!type->IsDeclared())
  2553. {
  2554. AbortStream();
  2555. return;
  2556. }
  2557. #ifdef BFIR_RENTRY_CHECK
  2558. ReEntryCheck reEntryCheck(&mDeclReentrySet, type);
  2559. #endif
  2560. BfIRType irType;
  2561. BfIRMDNode diType;
  2562. bool trackDIType = false;
  2563. BfType* underlyingArrayType = NULL;
  2564. int underlyingArraySize = -1;
  2565. bool underlyingArrayIsVector = false;
  2566. if (typeInstance != NULL)
  2567. typeInstance->GetUnderlyingArray(underlyingArrayType, underlyingArraySize, underlyingArrayIsVector);
  2568. if (type->IsPointer())
  2569. {
  2570. BfPointerType* pointerType = (BfPointerType*)type;
  2571. populateModule->PopulateType(pointerType->mElementType, BfPopulateType_Data);
  2572. if (pointerType->mElementType->IsValuelessNonOpaqueType())
  2573. {
  2574. irType = GetPrimitiveType(BfTypeCode_NullPtr);
  2575. }
  2576. else
  2577. {
  2578. irType = GetPointerTo(MapType(pointerType->mElementType));
  2579. }
  2580. if (wantDIData)
  2581. {
  2582. diType = DbgCreatePointerType(DbgGetType(pointerType->mElementType, BfIRPopulateType_Declaration));
  2583. trackDIType = true;
  2584. }
  2585. }
  2586. else if (type->IsRef())
  2587. {
  2588. BfRefType* refType = (BfRefType*)type;
  2589. if (refType->mElementType->IsValuelessNonOpaqueType())
  2590. irType = GetPrimitiveType(BfTypeCode_NullPtr);
  2591. else
  2592. {
  2593. //mModule->PopulateType(refType->mElementType, BfPopulateType_Declaration);
  2594. irType = GetPointerTo(MapType(refType->mElementType));
  2595. }
  2596. if ((wantDIData) && (!type->IsUnspecializedType()))
  2597. {
  2598. diType = DbgCreateReferenceType(DbgGetType(refType->mElementType));
  2599. trackDIType = true;
  2600. }
  2601. }
  2602. else if ((type->IsGenericParam()) || (type->IsModifiedTypeType()))
  2603. {
  2604. //mModule->PopulateType(mModule->mContext->mBfObjectType, BfPopulateType_Declaration);
  2605. irType = MapType(mModule->mContext->mBfObjectType);
  2606. if (wantDIData)
  2607. diType = DbgGetType(mModule->mContext->mBfObjectType);
  2608. }
  2609. else if (type->IsConcreteInterfaceType())
  2610. {
  2611. BfConcreteInterfaceType* concreteInterfaceType = (BfConcreteInterfaceType*)type;
  2612. irType = MapType(concreteInterfaceType->mInterface);
  2613. if (wantDIData)
  2614. {
  2615. diType = DbgGetType(concreteInterfaceType->mInterface);
  2616. }
  2617. }
  2618. else if (type->IsMethodRef())
  2619. {
  2620. auto methodRefType = (BfMethodRefType*)type;
  2621. BfMethodInstance* methodInstance = methodRefType->mMethodRef;
  2622. String name = "_BF_MethodRef_";
  2623. if (methodInstance != NULL)
  2624. name += BfTypeUtils::HashEncode64(methodInstance->mIdHash).c_str();
  2625. BF_ASSERT(methodInstance != NULL);
  2626. if ((wantDIData) && (methodInstance != NULL))
  2627. {
  2628. auto typeDeclaration = methodInstance->GetOwner()->mTypeDef->mTypeDeclaration;
  2629. BfFileInstance* bfFileInstance;
  2630. if (typeDeclaration != NULL)
  2631. bfFileInstance = mModule->GetFileFromNode(typeDeclaration);
  2632. else
  2633. bfFileInstance = mModule->GetFileFromNode(mModule->mContext->mBfObjectType->mTypeDef->mTypeDeclaration);
  2634. auto namespaceScope = DbgCreateNameSpace(bfFileInstance->mDIFile, "_bf", bfFileInstance->mDIFile, 0);
  2635. StringT<128> mangledName;
  2636. BfMangler::Mangle(mangledName, mModule->mCompiler->GetMangleKind(), methodInstance);
  2637. int captureSize = 0;
  2638. int captureAlign = 0;
  2639. BfIRMDNode derivedFrom;
  2640. Array<BfIRMDNode> elements;
  2641. diType = DbgCreateReplaceableCompositeType(llvm::dwarf::DW_TAG_structure_type, name, namespaceScope, bfFileInstance->mDIFile, 0, captureSize * 8, captureAlign * 8, 0);
  2642. auto int64Type = mModule->GetPrimitiveType(BfTypeCode_Int64);
  2643. auto memberType = DbgCreateMemberType(diType, mangledName, bfFileInstance->mDIFile, 0, 0, 0, -1, 0, DbgGetType(int64Type));
  2644. elements.Add(memberType);
  2645. int offset = 0;
  2646. int implicitParamCount = methodInstance->GetImplicitParamCount();
  2647. for (int paramIdx = methodInstance->HasThis() ? -1 : 0; paramIdx < implicitParamCount; paramIdx++)
  2648. {
  2649. BfType* paramType = methodInstance->GetParamType(paramIdx);
  2650. offset = BF_ALIGN(offset, paramType->mAlign);
  2651. String memberName = methodInstance->GetParamName(paramIdx);
  2652. if (memberName == "this")
  2653. memberName = "__this";
  2654. auto diMember = DbgCreateMemberType(diType, memberName, bfFileInstance->mDIFile, 0, paramType->mSize * 8, paramType->mAlign * 8, offset * 8, 0, DbgGetType(paramType));
  2655. elements.Add(diMember);
  2656. offset += paramType->mSize;
  2657. }
  2658. offset = BF_ALIGN(offset, methodRefType->mAlign);
  2659. BF_ASSERT(offset == methodRefType->mSize);
  2660. DbgMakePermanent(diType, derivedFrom, elements);
  2661. }
  2662. Array<BfIRType> members;
  2663. for (int dataIdx = 0; dataIdx < methodRefType->GetCaptureDataCount(); dataIdx++)
  2664. {
  2665. BfType* paramType = methodRefType->GetCaptureType(dataIdx);
  2666. if (paramType->IsValueType())
  2667. PopulateType(paramType, BfIRPopulateType_Eventually_Full);
  2668. members.Add(MapType(paramType));
  2669. }
  2670. irType = CreateStructType(name);
  2671. StructSetBody(irType, members, type->mSize, type->mAlign, false);
  2672. }
  2673. else if (type->IsSizedArray())
  2674. {
  2675. BfSizedArrayType* arrayType = (BfSizedArrayType*)type;
  2676. auto elementType = arrayType->mElementType;
  2677. BfIRType elementIrType;
  2678. if (elementType->IsValueType())
  2679. {
  2680. //mModule->PopulateType(arrayType->mElementType, BfPopulateType_Data);
  2681. elementIrType = MapType(arrayType->mElementType, BfIRPopulateType_Eventually_Full);
  2682. }
  2683. else
  2684. {
  2685. //mModule->PopulateType(arrayType->mElementType, BfPopulateType_Declaration);
  2686. elementIrType = MapType(arrayType->mElementType);
  2687. }
  2688. if (arrayType->mElementType->IsValuelessType())
  2689. irType = elementIrType;
  2690. else
  2691. irType = GetSizedArrayType(MapType(arrayType->mElementType), BF_MAX(arrayType->mElementCount, 0));
  2692. // else if (arrayType->mElementType->IsSizeAligned())
  2693. // irType = GetSizedArrayType(MapType(arrayType->mElementType), BF_MAX(arrayType->mElementCount, 0));
  2694. // else
  2695. // irType = GetSizedArrayType(MapType(mModule->GetPrimitiveType(BfTypeCode_Int8)), BF_MAX(arrayType->mSize, 0));
  2696. if (wantDIData)
  2697. diType = DbgCreateArrayType((int64)arrayType->mSize * 8, arrayType->mAlign * 8, DbgGetType(arrayType->mElementType), arrayType->mElementCount);
  2698. }
  2699. else if (type->IsPrimitiveType())
  2700. {
  2701. auto primType = (BfPrimitiveType*)type;
  2702. auto typeCode = primType->mTypeDef->mTypeCode;
  2703. if ((typeCode == BfTypeCode_Var) || (typeCode == BfTypeCode_Let) || (typeCode == BfTypeCode_Self))
  2704. {
  2705. //mModule->PopulateType(mModule->mContext->mBfObjectType, BfPopulateType_Declaration);
  2706. irType = MapType(mModule->mContext->mBfObjectType);
  2707. if (wantDIData)
  2708. diType = DbgGetType(mModule->mContext->mBfObjectType);
  2709. }
  2710. else if (typeCode == BfTypeCode_NullPtr)
  2711. {
  2712. irType = GetPrimitiveType(typeCode);
  2713. if (wantDIData)
  2714. {
  2715. auto voidType = DbgGetType(mModule->GetPrimitiveType(BfTypeCode_None));
  2716. diType = DbgCreatePointerType(voidType);
  2717. }
  2718. }
  2719. else
  2720. {
  2721. irType = GetPrimitiveType(typeCode);
  2722. if (wantDIData)
  2723. {
  2724. int dwarfType = 0;
  2725. switch (typeCode)
  2726. {
  2727. case BfTypeCode_None:
  2728. dwarfType = llvm::dwarf::DW_ATE_address;
  2729. break;
  2730. case BfTypeCode_Boolean:
  2731. dwarfType = llvm::dwarf::DW_ATE_boolean;
  2732. break;
  2733. case BfTypeCode_Int8:
  2734. case BfTypeCode_Int16:
  2735. case BfTypeCode_Int32:
  2736. case BfTypeCode_Int64:
  2737. case BfTypeCode_IntPtr:
  2738. dwarfType = llvm::dwarf::DW_ATE_signed;
  2739. break;
  2740. case BfTypeCode_UInt8:
  2741. case BfTypeCode_UInt16:
  2742. case BfTypeCode_UInt32:
  2743. case BfTypeCode_UInt64:
  2744. case BfTypeCode_UIntPtr:
  2745. dwarfType = llvm::dwarf::DW_ATE_unsigned;
  2746. break;
  2747. case BfTypeCode_Char8:
  2748. case BfTypeCode_Char16:
  2749. case BfTypeCode_Char32:
  2750. dwarfType = llvm::dwarf::DW_ATE_unsigned_char;
  2751. break;
  2752. case BfTypeCode_Float:
  2753. case BfTypeCode_Double:
  2754. dwarfType = llvm::dwarf::DW_ATE_float;
  2755. break;
  2756. default:
  2757. BF_FATAL("Unhandled");
  2758. }
  2759. diType = DbgCreateBasicType(primType->mTypeDef->mName->ToString(), primType->mSize * 8, primType->mAlign * 8, dwarfType);
  2760. }
  2761. }
  2762. }
  2763. else if (type->IsTypeInstance())
  2764. {
  2765. auto typeDef = typeInstance->mTypeDef;
  2766. BfIRMDNode diForwardDecl;
  2767. if (wantDIData)
  2768. {
  2769. BfFileInstance* bfFileInstance;
  2770. // Why did we bother setting the actual type declaration location?
  2771. bfFileInstance = mModule->GetFileFromNode(mModule->mContext->mBfObjectType->mTypeDef->mTypeDeclaration);
  2772. BfIRMDNode fileDIScope;
  2773. if (bfFileInstance != NULL)
  2774. fileDIScope = bfFileInstance->mDIFile;
  2775. BfIRMDNode curDIScope;
  2776. auto checkType = type;
  2777. if (checkType->IsArray())
  2778. {
  2779. BfArrayType* arrayType = (BfArrayType*)checkType;
  2780. checkType = arrayType->mGenericTypeInfo->mTypeGenericArguments[0];
  2781. }
  2782. BfTypeInstance* outerType = NULL;
  2783. if (!checkType->IsBoxed())
  2784. outerType = mModule->GetOuterType(checkType);
  2785. if (outerType != NULL)
  2786. curDIScope = DbgGetTypeInst(outerType);
  2787. else if (checkType->IsNullable())
  2788. curDIScope = CreateNamespaceScope(checkType->GetUnderlyingType(), fileDIScope);
  2789. else
  2790. curDIScope = CreateNamespaceScope(checkType, fileDIScope);
  2791. String typeName = GetDebugTypeName(typeInstance, false);
  2792. if (wantsDIForwardDecl)
  2793. {
  2794. if (type->IsInterface())
  2795. {
  2796. int flags = 0;
  2797. diForwardDecl = DbgCreateReplaceableCompositeType(llvm::dwarf::DW_TAG_structure_type,
  2798. typeName, curDIScope, fileDIScope, 0, (int64)0 * 8, (int64)0 * 8, flags);
  2799. auto derivedFrom = DbgGetTypeInst(mModule->mContext->mBfObjectType);
  2800. SizedArray<BfIRMDNode, 8> diFieldTypes;
  2801. auto inheritanceType = DbgCreateInheritance(diForwardDecl, derivedFrom, 0, llvm::DINode::FlagPublic);
  2802. diFieldTypes.push_back(inheritanceType);
  2803. DbgMakePermanent(diForwardDecl, derivedFrom, diFieldTypes);
  2804. }
  2805. else
  2806. {
  2807. diForwardDecl = DbgCreateSizedForwardDecl(llvm::dwarf::DW_TAG_structure_type,
  2808. typeName, curDIScope, fileDIScope, 0, (int64)BF_ALIGN(type->mSize, type->mAlign) * 8, (int64)type->mAlign * 8);
  2809. }
  2810. }
  2811. else
  2812. {
  2813. if (wantsDIPartialDef)
  2814. typeName += "$part$";
  2815. // Will fill in later (during definition phase)
  2816. int flags = 0;
  2817. diForwardDecl = DbgCreateReplaceableCompositeType(llvm::dwarf::DW_TAG_structure_type,
  2818. typeName, curDIScope, fileDIScope, 0, (int64)BF_ALIGN(typeInstance->mInstSize, typeInstance->mInstAlign) * 8, (int64)typeInstance->mInstAlign * 8, flags);
  2819. mDITemporaryTypes.push_back(typeInstance);
  2820. if (!type->IsUnspecializedType())
  2821. {
  2822. BF_ASSERT(!mDeferredDbgTypeDefs.Contains(type));
  2823. mDeferredDbgTypeDefs.Add(type);
  2824. }
  2825. }
  2826. DbgSetInstType(type, diForwardDecl);
  2827. BfIRMDNode diType;
  2828. if (type->IsValueType())
  2829. diType = diForwardDecl;
  2830. else
  2831. diType = DbgCreatePointerType(diForwardDecl);
  2832. DbgSetType(type, diType);
  2833. }
  2834. if (underlyingArraySize != -1)
  2835. {
  2836. if (underlyingArrayIsVector)
  2837. {
  2838. irType = GetVectorType(MapType(underlyingArrayType), underlyingArraySize);
  2839. }
  2840. else
  2841. irType = GetSizedArrayType(MapType(underlyingArrayType), underlyingArraySize);
  2842. SetType(type, irType);
  2843. }
  2844. else if (type->IsTypedPrimitive())
  2845. {
  2846. populateModule->PopulateType(type);
  2847. auto underlyingType = type->GetUnderlyingType();
  2848. irType = MapType(underlyingType);
  2849. SetType(type, irType);
  2850. SetInstType(type, irType);
  2851. }
  2852. else
  2853. {
  2854. String prefix = typeDef->mProject->mName + ".";
  2855. StringT<128> mangledName;
  2856. mangledName += prefix;
  2857. BfMangler::Mangle(mangledName, mModule->mCompiler->GetMangleKind(), typeInstance, typeInstance->mModule);
  2858. BfIRType irStructType = CreateStructType(mangledName);
  2859. if (type->IsObjectOrInterface())
  2860. {
  2861. BfIRType ptrToStructType = GetPointerTo(irStructType);
  2862. SetType(type, ptrToStructType);
  2863. SetInstType(type, irStructType);
  2864. }
  2865. else
  2866. {
  2867. SetType(type, irStructType);
  2868. SetInstType(type, irStructType);
  2869. }
  2870. }
  2871. return;
  2872. }
  2873. else
  2874. {
  2875. irType = GetPrimitiveType(BfTypeCode_None);
  2876. if (wantDIData)
  2877. diType = DbgCreateBasicType("void", 0, 0, llvm::dwarf::DW_ATE_address);
  2878. }
  2879. if (irType)
  2880. SetType(type, irType);
  2881. if (diType)
  2882. {
  2883. DbgSetType(type, diType);
  2884. //if (trackDIType)
  2885. //DbgTrackDITypes(type);
  2886. }
  2887. }
  2888. void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
  2889. {
  2890. BP_ZONE("BfIRBuilder::CreateDbgTypeDefinition");
  2891. auto typeInstance = type->ToTypeInstance();
  2892. bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive());
  2893. auto typeDef = typeInstance->mTypeDef;
  2894. bool wantDIData = true;
  2895. BfModuleOptions moduleOptions = mModule->GetModuleOptions();
  2896. bool isOptimized = (moduleOptions.mOptLevel != BfOptLevel_O0) && (moduleOptions.mOptLevel != BfOptLevel_OgPlus);
  2897. BfIRMDNode fileDIScope;
  2898. if (wantDIData)
  2899. {
  2900. BfFileInstance* bfFileInstance;
  2901. if (typeDef->mTypeDeclaration != NULL)
  2902. bfFileInstance = mModule->GetFileFromNode(typeDef->mTypeDeclaration);
  2903. else
  2904. bfFileInstance = mModule->GetFileFromNode(mModule->mCompiler->mBfObjectTypeDef->mTypeDeclaration);
  2905. if (bfFileInstance != NULL)
  2906. fileDIScope = bfFileInstance->mDIFile;
  2907. }
  2908. #ifdef BFIR_RENTRY_CHECK
  2909. ReEntryCheck reEntryCheck(&mDefReentrySet, type);
  2910. #endif
  2911. //BF_ASSERT(WantsDbgDefinition(type));
  2912. SizedArray<BfIRMDNode, 256> diFieldTypes;
  2913. int packing = 0;
  2914. bool isUnion = false;
  2915. bool isCRepr = false;
  2916. BfType* underlyingArrayType = NULL;
  2917. int underlyingArraySize = -1;
  2918. bool underlyingArrayIsVector = false;
  2919. if (typeInstance->IsBoxed())
  2920. {
  2921. }
  2922. else
  2923. {
  2924. isCRepr = typeInstance->mIsCRepr;
  2925. packing = typeInstance->mPacking;
  2926. isUnion = typeInstance->mIsUnion;
  2927. typeInstance->GetUnderlyingArray(underlyingArrayType, underlyingArraySize, underlyingArrayIsVector);
  2928. // if (underlyingArrayType != NULL)
  2929. // return; // Done
  2930. }
  2931. String typeName = GetDebugTypeName(typeInstance, false);
  2932. bool isGlobalContainer = typeDef->IsGlobalsContainer();
  2933. bool isDefiningModule = ((type->GetModule() == mModule) || (type->IsFunction()));
  2934. auto diForwardDecl = DbgGetTypeInst(typeInstance);
  2935. BfSizedVector<BfFieldInstance*, 8> orderedFields;
  2936. if ((type->IsUnion()) && (!type->IsEnum()))
  2937. {
  2938. int lineNum = 0;
  2939. int flags = llvm::DINode::FlagPublic;
  2940. auto fieldType = typeInstance->GetUnionInnerType();
  2941. auto resolvedFieldDIType = DbgGetType(fieldType);
  2942. String fieldName = "$bfunion";
  2943. auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, lineNum,
  2944. fieldType->mSize * 8, fieldType->mAlign * 8, typeInstance->mBaseType->mInstSize * 8,
  2945. flags, resolvedFieldDIType);
  2946. diFieldTypes.push_back(memberType);
  2947. }
  2948. std::function<void(BfType* type, int depth, int byteOffset)> _AddFields = [&](BfType* type, int depth, int byteOffset)
  2949. {
  2950. typeInstance = type->ToTypeInstance();
  2951. if (typeInstance == NULL)
  2952. return;
  2953. bool isPayloadEnum = (typeInstance->IsEnum()) && (!typeInstance->IsTypedPrimitive());
  2954. for (int fieldIdx = 0; fieldIdx < typeInstance->mFieldInstances.mSize; fieldIdx++)
  2955. {
  2956. auto fieldInstance = &typeInstance->mFieldInstances[fieldIdx];
  2957. if (!fieldInstance->mFieldIncluded)
  2958. continue;
  2959. auto fieldDef = fieldInstance->GetFieldDef();
  2960. if ((fieldInstance->mResolvedType == NULL) || (typeInstance->IsBoxed()))
  2961. continue;
  2962. auto resolvedFieldType = fieldInstance->GetResolvedType();
  2963. mModule->PopulateType(resolvedFieldType, BfPopulateType_Declaration);
  2964. BfIRType resolvedFieldIRType = MapType(resolvedFieldType);
  2965. BfIRMDNode resolvedFieldDIType;
  2966. if ((fieldDef != NULL) && (!fieldDef->mIsStatic) && (resolvedFieldType->IsStruct()))
  2967. PopulateType(resolvedFieldType, BfIRPopulateType_Eventually_Full);
  2968. resolvedFieldDIType = DbgGetType(resolvedFieldType);
  2969. if ((fieldInstance->IsAppendedObject()) && (!fieldDef->mIsStatic))
  2970. resolvedFieldDIType = DbgGetTypeInst(resolvedFieldType->ToTypeInstance());
  2971. if ((fieldDef == NULL) && (typeInstance->IsPayloadEnum()))
  2972. {
  2973. orderedFields.push_back(fieldInstance);
  2974. int lineNum = 0;
  2975. int flags = llvm::DINode::FlagPublic;
  2976. auto fieldType = fieldInstance->mResolvedType;
  2977. String fieldName = "__bftag";
  2978. auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, lineNum,
  2979. resolvedFieldType->mSize * 8, resolvedFieldType->mAlign * 8, fieldInstance->mDataOffset * 8,
  2980. flags, resolvedFieldDIType);
  2981. diFieldTypes.push_back(memberType);
  2982. }
  2983. if ((!typeInstance->IsBoxed()) && (fieldDef != NULL))
  2984. {
  2985. if (fieldDef->mIsConst)
  2986. {
  2987. if ((isDefiningModule) && (depth == 0))
  2988. {
  2989. if ((isPayloadEnum) && (fieldDef->IsEnumCaseEntry()))
  2990. {
  2991. auto payloadType = fieldInstance->mResolvedType;
  2992. if (payloadType == NULL)
  2993. payloadType = mModule->CreateTupleType(BfTypeVector(), Array<String>());
  2994. String fieldName = StrFormat("_%d_%s", -fieldInstance->mDataIdx - 1, fieldDef->mName.c_str());
  2995. int flags = 0;
  2996. auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, 0,
  2997. BF_ALIGN(payloadType->mSize, payloadType->mAlign) * 8, payloadType->mAlign * 8, 0,
  2998. flags, DbgGetType(payloadType));
  2999. diFieldTypes.push_back(memberType);
  3000. }
  3001. else
  3002. {
  3003. BfConstant* constant = NULL;
  3004. BfIRValue staticValue;
  3005. if (fieldInstance->mConstIdx != -1)
  3006. {
  3007. constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
  3008. if (!resolvedFieldType->IsValuelessType())
  3009. staticValue = mModule->ConstantToCurrent(constant, typeInstance->mConstHolder, resolvedFieldType);
  3010. }
  3011. if (fieldInstance->mResolvedType->IsComposite())
  3012. PopulateType(fieldInstance->mResolvedType);
  3013. BfIRMDNode constDIType = DbgCreateConstType(resolvedFieldDIType);
  3014. if ((fieldDef->mIsExtern) && (resolvedFieldType->IsPointer()))
  3015. {
  3016. auto underlyingType = resolvedFieldType->GetUnderlyingType();
  3017. auto staticTypedValue = mModule->ReferenceStaticField(fieldInstance);
  3018. staticValue = staticTypedValue.mValue;
  3019. int flags = 0;
  3020. auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldDef->mName, fileDIScope, 0,
  3021. constDIType, flags, CreateConst(BfTypeCode_Int32, 0));
  3022. diFieldTypes.push_back(memberType);
  3023. StringT<128> staticVarName;
  3024. BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
  3025. if (!staticVarName.StartsWith("#"))
  3026. {
  3027. String fieldName = DbgGetStaticFieldName(fieldInstance);
  3028. DbgCreateGlobalVariable(diForwardDecl, fieldName, staticVarName, fileDIScope, 0,
  3029. constDIType, false, staticValue, memberType);
  3030. }
  3031. }
  3032. else if (resolvedFieldType->IsValuelessType())
  3033. {
  3034. // Do nothing
  3035. }
  3036. else if ((resolvedFieldType->IsObjectOrInterface()) || (resolvedFieldType->IsPointer()) || (resolvedFieldType->IsSizedArray()))
  3037. {
  3038. bool useIntConstant = false;
  3039. bool wasMadeAddr = false;
  3040. StringT<128> staticVarName;
  3041. BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
  3042. String fieldName = fieldDef->mName;
  3043. BfIRValue intConstant;
  3044. if (constant != NULL)
  3045. {
  3046. // This constant debug info causes linking errors on Linux
  3047. if (isOptimized)
  3048. continue;
  3049. if ((constant->mConstType == BfConstType_Agg) ||
  3050. (constant->mConstType == BfConstType_AggZero) ||
  3051. (constant->mTypeCode == BfTypeCode_NullPtr))
  3052. {
  3053. staticValue = ConstToMemory(staticValue);
  3054. wasMadeAddr = true;
  3055. }
  3056. else if (constant->mTypeCode == BfTypeCode_StringId)
  3057. {
  3058. int stringId = constant->mInt32;
  3059. const StringImpl& str = mModule->mContext->mStringObjectIdMap[stringId].mString;
  3060. if (resolvedFieldType->IsPointer())
  3061. staticValue = mModule->GetStringCharPtr(str);
  3062. else
  3063. staticValue = mModule->GetStringObjectValue(str);
  3064. }
  3065. else
  3066. {
  3067. // Ignore other types (for now)
  3068. continue;
  3069. }
  3070. }
  3071. if (!useIntConstant)
  3072. {
  3073. auto useType = resolvedFieldType;
  3074. if (wasMadeAddr)
  3075. useType = mModule->CreatePointerType(useType);
  3076. staticValue = CreateGlobalVariable(mModule->mBfIRBuilder->MapType(useType), true, BfIRLinkageType_Internal, staticValue, staticVarName);
  3077. GlobalVar_SetAlignment(staticValue, useType->mAlign);
  3078. }
  3079. BfIRMDNode memberType;
  3080. int flags = 0;
  3081. if (!fieldDef->mName.IsEmpty())
  3082. {
  3083. memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0,
  3084. constDIType, flags, useIntConstant ? intConstant : BfIRValue());
  3085. diFieldTypes.push_back(memberType);
  3086. }
  3087. if (fieldDef->mUsingProtection != BfProtection_Hidden)
  3088. {
  3089. auto memberType = DbgCreateStaticMemberType(diForwardDecl, "$using$" + fieldName, fileDIScope, 0,
  3090. constDIType, flags, useIntConstant ? intConstant : BfIRValue());
  3091. diFieldTypes.push_back(memberType);
  3092. }
  3093. if ((staticValue) && (!fieldDef->mName.IsEmpty()))
  3094. {
  3095. String qualifiedName = DbgGetStaticFieldName(fieldInstance);
  3096. DbgCreateGlobalVariable(diForwardDecl, qualifiedName, staticVarName, fileDIScope, 0,
  3097. constDIType, false, staticValue, memberType);
  3098. }
  3099. }
  3100. else if (mModule->mCompiler->mOptions.IsCodeView())
  3101. {
  3102. int flags = 0;
  3103. String fieldName = fieldDef->mName;
  3104. if ((constant != NULL) &&
  3105. ((IsIntable(constant->mTypeCode)) || (IsFloat(constant->mTypeCode))))
  3106. {
  3107. int64 writeVal = constant->mInt64;
  3108. if (constant->mTypeCode == BfTypeCode_Float)
  3109. {
  3110. // We need to do this because Singles are stored in mDouble, so we need to reduce here
  3111. float floatVal = (float)constant->mDouble;
  3112. writeVal = *(uint32*)&floatVal;
  3113. }
  3114. if (writeVal < 0)
  3115. fieldName += StrFormat("$_%llu", -writeVal);
  3116. else
  3117. fieldName += StrFormat("$%llu", writeVal);
  3118. }
  3119. auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0,
  3120. constDIType, flags, staticValue);
  3121. diFieldTypes.push_back(memberType);
  3122. }
  3123. else
  3124. {
  3125. int flags = 0;
  3126. String fieldName = DbgGetStaticFieldName(fieldInstance);
  3127. auto memberType = DbgCreateStaticMemberType(diForwardDecl, fieldName, fileDIScope, 0,
  3128. constDIType, flags, staticValue);
  3129. diFieldTypes.push_back(memberType);
  3130. }
  3131. }
  3132. }
  3133. }
  3134. else if (fieldDef->mIsStatic)
  3135. {
  3136. if ((isDefiningModule) && (depth == 0))
  3137. {
  3138. BfIRMDNode memberType;
  3139. int flags = 0;
  3140. if (!fieldDef->mName.IsEmpty())
  3141. {
  3142. memberType = DbgCreateStaticMemberType(diForwardDecl, fieldDef->mName, fileDIScope, 0,
  3143. resolvedFieldDIType, flags, BfIRValue());
  3144. diFieldTypes.push_back(memberType);
  3145. }
  3146. if (fieldDef->mUsingProtection != BfProtection_Hidden)
  3147. {
  3148. auto memberType = DbgCreateStaticMemberType(diForwardDecl, "$using$" + fieldDef->mName, fileDIScope, 0,
  3149. resolvedFieldDIType, flags, BfIRValue());
  3150. diFieldTypes.push_back(memberType);
  3151. }
  3152. StringT<128> staticVarName;
  3153. BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
  3154. if ((!staticVarName.StartsWith('#')) && (!fieldDef->mName.IsEmpty()))
  3155. {
  3156. auto staticValue = mModule->ReferenceStaticField(fieldInstance);
  3157. if (staticValue.mValue)
  3158. {
  3159. String fieldName = DbgGetStaticFieldName(fieldInstance);
  3160. DbgCreateGlobalVariable(diForwardDecl, fieldName, staticVarName, fileDIScope, 0,
  3161. resolvedFieldDIType, false, staticValue.mValue, memberType);
  3162. }
  3163. }
  3164. }
  3165. }
  3166. else
  3167. {
  3168. bool useForUnion = false;
  3169. BF_ASSERT(!fieldInstance->mIsEnumPayloadCase);
  3170. if (wantDIData)
  3171. {
  3172. if ((fieldDef->mUsingProtection != BfProtection_Hidden) && (depth < 10))
  3173. {
  3174. _AddFields(fieldInstance->mResolvedType, depth + 1, byteOffset + fieldInstance->mDataOffset);
  3175. }
  3176. int lineNum = 0;
  3177. int flags = 0;
  3178. String fieldName = fieldDef->mName;
  3179. if (!fieldDef->mName.IsEmpty())
  3180. {
  3181. if (fieldDef->mHasMultiDefs)
  3182. fieldName += "$" + fieldDef->mDeclaringType->mProject->mName;
  3183. auto memberType = DbgCreateMemberType(diForwardDecl, fieldName, fileDIScope, lineNum,
  3184. fieldInstance->mDataSize * 8, resolvedFieldType->mAlign * 8, (byteOffset + fieldInstance->mDataOffset) * 8,
  3185. flags, resolvedFieldDIType);
  3186. diFieldTypes.push_back(memberType);
  3187. }
  3188. }
  3189. }
  3190. }
  3191. }
  3192. };
  3193. _AddFields(typeInstance, 0, 0);
  3194. int dataPos = 0;
  3195. if (typeInstance->mBaseType != NULL)
  3196. dataPos = typeInstance->mBaseType->mInstSize;
  3197. int unionSize = 0;
  3198. if (typeInstance->mIsUnion)
  3199. {
  3200. auto unionInnerType = typeInstance->GetUnionInnerType();
  3201. unionSize = unionInnerType->mSize;
  3202. dataPos += unionSize;
  3203. }
  3204. bool wantsMethods = true;
  3205. // We can't directly call boxed methods from the debugger
  3206. if (type->IsBoxed())
  3207. wantsMethods = false;
  3208. if (!isDefiningModule)
  3209. wantsMethods = false;
  3210. if (wantsMethods)
  3211. {
  3212. for (int methodIdx = 0; methodIdx < (int)typeInstance->mMethodInstanceGroups.size(); methodIdx++)
  3213. {
  3214. auto& methodGroup = typeInstance->mMethodInstanceGroups[methodIdx];
  3215. auto methodInstance = methodGroup.mDefault;
  3216. // We're only adding non-generic methods at the moment
  3217. if ((methodInstance == NULL) || (methodInstance->mIsUnspecialized))
  3218. continue;
  3219. if (type->IsGenericTypeInstance())
  3220. {
  3221. // We don't force method declarations for generic type instances, so don't add any unreified methods here
  3222. // for the purpose of keeping debug type info the same between rebuilds
  3223. if (!methodInstance->mIsReified)
  3224. continue;
  3225. }
  3226. auto methodDef = methodInstance->mMethodDef;
  3227. if ((methodDef->mMethodType == BfMethodType_Operator) || (methodDef->mMethodType == BfMethodType_Mixin) || (methodDef->mMethodType == BfMethodType_Ignore))
  3228. continue;
  3229. if (methodDef->mIsOverride)
  3230. continue;
  3231. BfIRMDNode diFuncType = DbgCreateSubroutineType(methodInstance);
  3232. int defLine = 0;
  3233. StringT<128> mangledName;
  3234. int flags = 0;
  3235. BfMangler::Mangle(mangledName, mModule->mCompiler->GetMangleKind(), methodInstance);
  3236. BfIRMDNode funcScope = diForwardDecl;
  3237. if (methodDef->mProtection == BfProtection_Public)
  3238. flags = llvm::DINode::FlagPublic;
  3239. else if (methodDef->mProtection == BfProtection_Protected)
  3240. flags = llvm::DINode::FlagProtected;
  3241. else
  3242. flags = llvm::DINode::FlagPrivate;
  3243. if (methodDef->mIsOverride)
  3244. {
  3245. //flags |= llvm::DINode::FlagVirtual;
  3246. }
  3247. else if (methodDef->mIsVirtual)
  3248. flags |= llvm::DINode::FlagIntroducedVirtual;
  3249. if ((methodDef->mIsStatic) || (methodDef->mMethodType == BfMethodType_Mixin))
  3250. flags |= llvm::DINode::FlagStaticMember;
  3251. else
  3252. {
  3253. if (typeInstance->IsValuelessType())
  3254. flags |= llvm::DINode::FlagStaticMember;
  3255. }
  3256. flags |= llvm::DINode::FlagPrototyped;
  3257. if (methodDef->mMethodType == BfMethodType_Ctor)
  3258. {
  3259. flags |= llvm::DINode::FlagArtificial;
  3260. }
  3261. String methodName = methodDef->mName;
  3262. SizedArray<BfIRMDNode, 1> genericArgs;
  3263. SizedArray<BfIRValue, 1> genericConstValueArgs;
  3264. auto diFunction = DbgCreateMethod(funcScope, methodName, mangledName, fileDIScope,
  3265. defLine + 1, diFuncType, false, false,
  3266. (methodInstance->mVirtualTableIdx != -1) ? 1 : 0,
  3267. (methodInstance->mVirtualTableIdx != -1) ? methodInstance->DbgGetVirtualMethodNum() : 0,
  3268. funcScope, flags, /*IsOptimized()*/false, BfIRValue(), genericArgs, genericConstValueArgs);
  3269. diFieldTypes.push_back(diFunction);
  3270. if (methodInstance->mVirtualTableIdx != -1)
  3271. {
  3272. BF_ASSERT(mModule->mCompiler->mMaxInterfaceSlots != -1);
  3273. }
  3274. }
  3275. }
  3276. BfType* declaredBaseType = typeInstance->mBaseType;
  3277. if (typeInstance->IsTypedPrimitive())
  3278. declaredBaseType = typeInstance->GetUnderlyingType();
  3279. /*if (isPrimEnum)
  3280. {
  3281. // Handled below
  3282. }
  3283. else*/ if (type->IsBoxed())
  3284. {
  3285. auto underlyingType = ((BfBoxedType*)type)->GetModifiedElementType();
  3286. if (!underlyingType->IsValuelessType())
  3287. {
  3288. auto fieldInstance = &typeInstance->mFieldInstances.back();
  3289. auto resolvedFieldType = fieldInstance->GetResolvedType();
  3290. auto inheritanceType = DbgCreateInheritance(diForwardDecl, DbgGetTypeInst(mModule->mContext->mBfObjectType), 0, llvm::DINode::FlagPublic);
  3291. diFieldTypes.push_back(inheritanceType);
  3292. int lineNum = 0;
  3293. int flags = llvm::DINode::FlagPublic;
  3294. auto memberType = DbgCreateMemberType(fileDIScope, "val", fileDIScope, lineNum,
  3295. resolvedFieldType->mSize * 8, resolvedFieldType->mAlign * 8, fieldInstance->mDataOffset * 8,
  3296. flags, DbgGetType(underlyingType));
  3297. diFieldTypes.push_back(memberType);
  3298. }
  3299. }
  3300. else
  3301. {
  3302. auto baseType = typeInstance->mBaseType;
  3303. if (baseType != NULL)
  3304. {
  3305. auto baseTypeInst = baseType->ToTypeInstance();
  3306. BfIRMDNode inheritanceType;
  3307. if (baseTypeInst != NULL)
  3308. inheritanceType = DbgCreateInheritance(diForwardDecl, DbgGetTypeInst(baseTypeInst), 0, llvm::DINode::FlagPublic);
  3309. else
  3310. inheritanceType = DbgCreateInheritance(diForwardDecl, DbgGetType(baseType), 0, llvm::DINode::FlagPublic);
  3311. diFieldTypes.push_back(inheritanceType);
  3312. }
  3313. // Typed primitives are expressed as multiple inheritance
  3314. if ((typeInstance->IsTypedPrimitive()) && (typeInstance->mBaseType != NULL) && (!typeInstance->mBaseType->IsTypedPrimitive()))
  3315. {
  3316. auto underlyingType = typeInstance->GetUnderlyingType();
  3317. // auto inheritanceType = DbgCreateInheritance(diForwardDecl, DbgGetType(underlyingType), 0, llvm::DINode::FlagPublic);
  3318. // diFieldTypes.push_back(inheritanceType);
  3319. int lineNum = 0;
  3320. int flags = llvm::DINode::FlagPublic;
  3321. auto memberType = DbgCreateMemberType(fileDIScope, "$prim", fileDIScope, lineNum,
  3322. underlyingType->mSize * 8, underlyingType->mAlign * 8, 0,
  3323. flags, DbgGetType(underlyingType));
  3324. diFieldTypes.push_back(memberType);
  3325. }
  3326. }
  3327. BfIRMDNode derivedFrom;
  3328. if (typeInstance->IsInterface())
  3329. {
  3330. derivedFrom = DbgGetTypeInst(mModule->mContext->mBfObjectType);
  3331. auto inheritanceType = DbgCreateInheritance(diForwardDecl, derivedFrom, 0, llvm::DINode::FlagPublic);
  3332. diFieldTypes.push_back(inheritanceType);
  3333. }
  3334. else if (typeInstance->mBaseType != NULL)
  3335. {
  3336. derivedFrom = DbgGetTypeInst(typeInstance->mBaseType);
  3337. }
  3338. BfIRMDNode curDIScope;
  3339. BfTypeInstance* outerType = NULL;
  3340. if (!type->IsBoxed())
  3341. outerType = mModule->GetOuterType(type);
  3342. if (outerType != NULL)
  3343. curDIScope = DbgGetTypeInst(outerType);
  3344. else if (type->IsNullable())
  3345. curDIScope = CreateNamespaceScope(type->GetUnderlyingType(), fileDIScope);
  3346. else
  3347. curDIScope = CreateNamespaceScope(type, fileDIScope);
  3348. //TODO: Set DI Flags
  3349. int diFlags = 0;
  3350. BfIRMDNode diType;
  3351. /*if ((typeInstance->IsEnum()) && (typeInstance->IsTypedPrimitive()))
  3352. {
  3353. llvm::SmallVector<BfIRMDNode, 8> diEnumValues;
  3354. for (auto& fieldInst : typeInstance->mFieldInstances)
  3355. {
  3356. if (!fieldInst.mFieldIncluded)
  3357. continue;
  3358. auto fieldDef = fieldInst.GetFieldDef();
  3359. if ((fieldInst.mConstIdx != -1) && (fieldDef->IsEnumCaseEntry()))
  3360. {
  3361. auto constant = typeInstance->mConstHolder->GetConstantById(fieldInst.mConstIdx);
  3362. auto enumValue = DbgCreateEnumerator(fieldInst.GetFieldDef()->mName, constant->mInt64);
  3363. diEnumValues.push_back(enumValue);
  3364. }
  3365. }
  3366. diType = DbgMakePermanent(diForwardDecl, DbgGetType(declaredBaseType), diEnumValues);
  3367. DbgSetType(type, diType);
  3368. DbgSetInstType(type, diType);
  3369. }
  3370. else*/
  3371. {
  3372. BfIRMDNode diCompositeType = DbgMakePermanent(diForwardDecl, BfIRMDNode(), diFieldTypes);
  3373. diType = diCompositeType;
  3374. }
  3375. }
  3376. bool BfIRBuilder::WantsDbgDefinition(BfType* type)
  3377. {
  3378. if ((type->GetModule() == mModule) || (type->IsFunction()))
  3379. return true;
  3380. // Forward declarations of valuetypes doesn't work in LLVM backend
  3381. // if ((!mIsBeefBackend) && (type->IsValueType()))
  3382. // return true;
  3383. return false;
  3384. }
  3385. void BfIRBuilder::CreateTypeDefinition_Data(BfModule* populateModule, BfTypeInstance* typeInstance, bool forceDbgDefine)
  3386. {
  3387. auto typeDef = typeInstance->mTypeDef;
  3388. #ifdef BFIR_RENTRY_CHECK
  3389. ReEntryCheck reEntryCheck(&mDefReentrySet, type);
  3390. #endif
  3391. bool isGlobalContainer = typeDef->IsGlobalsContainer();
  3392. auto diForwardDecl = DbgGetTypeInst(typeInstance);
  3393. SizedArray<BfIRType, 256> irFieldTypes;
  3394. if ((!typeInstance->IsTypedPrimitive()) && (typeInstance->mBaseType != NULL))
  3395. {
  3396. if (typeInstance->mBaseType->IsValuelessCReprType())
  3397. {
  3398. // Fake an empty type to avoid having a one-byte base type
  3399. auto valueTypeType = mModule->ResolveTypeDef(mModule->mCompiler->mValueTypeTypeDef);
  3400. irFieldTypes.push_back(MapType(valueTypeType, BfIRPopulateType_Eventually_Full));
  3401. }
  3402. else
  3403. irFieldTypes.push_back(MapTypeInst(typeInstance->mBaseType, BfIRPopulateType_Eventually_Full));
  3404. }
  3405. SizedArray<BfIRMDNode, 256> diFieldTypes;
  3406. int packing = 0;
  3407. bool isUnion = false;
  3408. bool isCRepr = false;
  3409. if (typeInstance->IsBoxed())
  3410. {
  3411. auto boxedType = (BfBoxedType*)typeInstance;
  3412. BF_ASSERT(!boxedType->mFieldInstances.IsEmpty());
  3413. auto& fieldInst = boxedType->mFieldInstances.back();
  3414. auto elementType = fieldInst.mResolvedType;
  3415. populateModule->PopulateType(elementType, BfPopulateType_Data);
  3416. if (!elementType->IsValuelessType())
  3417. {
  3418. irFieldTypes.Add(MapType(elementType, elementType->IsValueType() ? BfIRPopulateType_Eventually_Full : BfIRPopulateType_Declaration));
  3419. }
  3420. }
  3421. else
  3422. {
  3423. isCRepr = typeInstance->mIsCRepr;
  3424. packing = typeInstance->mPacking;
  3425. isUnion = typeInstance->mIsUnion;
  3426. }
  3427. BfSizedVector<BfFieldInstance*, 8> orderedFields;
  3428. bool isPayloadEnum = (typeInstance->IsEnum()) && (!typeInstance->IsTypedPrimitive());
  3429. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  3430. {
  3431. auto fieldInstance = &fieldInstanceRef;
  3432. if (!fieldInstance->mFieldIncluded)
  3433. continue;
  3434. auto fieldDef = fieldInstance->GetFieldDef();
  3435. if ((fieldInstance->mResolvedType == NULL) || (typeInstance->IsBoxed()))
  3436. continue;
  3437. if ((fieldDef != NULL) && (fieldDef->mIsStatic))
  3438. continue; // Just create type first - we may contain a static reference to ourselves, creating an dependency loop
  3439. auto resolvedFieldType = fieldInstance->GetResolvedType();
  3440. mModule->PopulateType(resolvedFieldType, BfPopulateType_Declaration);
  3441. BfIRType resolvedFieldIRType = MapType(resolvedFieldType);
  3442. BfIRMDNode resolvedFieldDIType;
  3443. if ((fieldDef != NULL) && (resolvedFieldType->IsStruct()))
  3444. PopulateType(resolvedFieldType, BfIRPopulateType_Eventually_Full);
  3445. if (fieldInstance->IsAppendedObject())
  3446. PopulateType(resolvedFieldType, BfIRPopulateType_Eventually_Full);
  3447. if ((fieldDef == NULL) && (typeInstance->IsPayloadEnum()))
  3448. {
  3449. orderedFields.push_back(fieldInstance);
  3450. }
  3451. if ((!typeInstance->IsBoxed()) && (fieldDef != NULL))
  3452. {
  3453. bool useForUnion = false;
  3454. BF_ASSERT(!fieldInstance->mIsEnumPayloadCase);
  3455. if ((!fieldDef->mIsStatic) && (!resolvedFieldType->IsValuelessType()))
  3456. {
  3457. if (!isUnion)
  3458. {
  3459. BF_ASSERT(resolvedFieldIRType.mId != -1);
  3460. //irFieldTypes.push_back(resolvedFieldIRType);
  3461. if (fieldInstance->mDataIdx != -1)
  3462. {
  3463. while (fieldInstance->mDataIdx >= (int)orderedFields.size())
  3464. orderedFields.push_back(NULL);
  3465. orderedFields[fieldInstance->mDataIdx] = fieldInstance;
  3466. }
  3467. }
  3468. }
  3469. }
  3470. }
  3471. int dataPos = 0;
  3472. if (typeInstance->mBaseType != NULL)
  3473. dataPos = typeInstance->mBaseType->mInstSize;
  3474. int unionSize = 0;
  3475. if (typeInstance->mIsUnion)
  3476. {
  3477. auto unionInnerType = typeInstance->GetUnionInnerType();
  3478. irFieldTypes.push_back(MapType(unionInnerType, unionInnerType->IsValueType() ? BfIRPopulateType_Eventually_Full : BfIRPopulateType_Declaration));
  3479. unionSize = unionInnerType->mSize;
  3480. dataPos += unionSize;
  3481. }
  3482. for (int fieldIdx = 0; fieldIdx < (int)orderedFields.size(); fieldIdx++)
  3483. {
  3484. auto fieldInstance = orderedFields[fieldIdx];
  3485. if (fieldInstance == NULL)
  3486. continue;
  3487. auto fieldDef = fieldInstance->GetFieldDef();
  3488. auto resolvedFieldType = fieldInstance->GetResolvedType();
  3489. BfIRType resolvedFieldIRType = MapType(resolvedFieldType);
  3490. if (fieldInstance->IsAppendedObject())
  3491. {
  3492. auto fieldTypeInst = fieldInstance->mResolvedType->ToTypeInstance();
  3493. if (fieldInstance->mDataSize > fieldTypeInst->mInstSize)
  3494. {
  3495. SizedArray<BfIRType, 2> types;
  3496. types.push_back(MapTypeInst(fieldTypeInst));
  3497. types.push_back(GetSizedArrayType(GetPrimitiveType(BfTypeCode_Int8), fieldInstance->mDataSize - fieldTypeInst->mInstSize));
  3498. resolvedFieldIRType = CreateStructType(types);
  3499. }
  3500. else
  3501. resolvedFieldIRType = MapTypeInst(fieldTypeInst);
  3502. }
  3503. if (fieldInstance->mDataOffset > dataPos)
  3504. {
  3505. int fillSize = fieldInstance->mDataOffset - dataPos;
  3506. auto byteType = mModule->GetPrimitiveType(BfTypeCode_Int8);
  3507. auto arrType = GetSizedArrayType(MapType(byteType), fillSize);
  3508. irFieldTypes.push_back(arrType);
  3509. dataPos = fieldInstance->mDataOffset;
  3510. }
  3511. dataPos += fieldInstance->mDataSize;
  3512. BF_ASSERT((int)irFieldTypes.size() == fieldInstance->mDataIdx);
  3513. irFieldTypes.push_back(resolvedFieldIRType);
  3514. }
  3515. if (isCRepr)
  3516. {
  3517. // Add explicit padding at end to enforce the "aligned size"
  3518. int endPad = typeInstance->mInstSize - dataPos;
  3519. if (endPad > 0)
  3520. {
  3521. auto byteType = mModule->GetPrimitiveType(BfTypeCode_Int8);
  3522. auto arrType = GetSizedArrayType(MapType(byteType), endPad);
  3523. irFieldTypes.push_back(arrType);
  3524. dataPos += endPad;
  3525. }
  3526. }
  3527. if (typeInstance->mIsUnion)
  3528. {
  3529. }
  3530. else if ((typeInstance->IsEnum()) && (typeInstance->IsStruct()))
  3531. {
  3532. BF_FATAL("Shouldn't happen");
  3533. // Just an empty placeholder
  3534. auto byteType = GetPrimitiveType(BfTypeCode_UInt8);
  3535. auto rawDataType = GetSizedArrayType(byteType, 0);
  3536. irFieldTypes.push_back(rawDataType);
  3537. }
  3538. if (!typeInstance->IsTypedPrimitive())
  3539. StructSetBody(MapTypeInst(typeInstance), irFieldTypes, typeInstance->mInstSize, typeInstance->mInstAlign, true);
  3540. if (typeInstance->IsNullable())
  3541. {
  3542. BF_ASSERT(irFieldTypes.size() <= 3);
  3543. }
  3544. }
  3545. void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDbgDefine)
  3546. {
  3547. auto populateModule = mModule->mContext->mUnreifiedModule;
  3548. auto typeInstance = type->ToTypeInstance();
  3549. if (typeInstance != NULL)
  3550. populateModule = typeInstance->mModule;
  3551. // This PopulateType is generally NOT needed, but here is a scenario in which it is:
  3552. // ClassB derives from ClassA. ClassC uses ClassB. A method inside ClassA gets modified,
  3553. // marking ClassA as incomplete, and then ClassC rebuilds and calls MapType on ClassB.
  3554. // "ClassB" itself is still populated, but its base class (ClassA) is not -- until we call
  3555. // this PopulateType below.
  3556. if (type->IsDataIncomplete())
  3557. populateModule->PopulateType(type, BfPopulateType_Data);
  3558. bool isDefiningModule = ((type->GetModule() == mModule) || (type->IsFunction()));
  3559. if (mModule->mExtensionCount != 0)
  3560. isDefiningModule = false;
  3561. // if (mModule->mModuleName == "vdata")
  3562. // isDefiningModule = true;
  3563. if ((isDefiningModule) || (type->IsValueType()))
  3564. {
  3565. if ((typeInstance != NULL) && (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotting))
  3566. {
  3567. // Don't re-enter
  3568. BfLogSys(mModule->mSystem, "BfIRBuilder::CreateTypeDefinition avoided PopulateType BfPopulateType_DataAndMethods re-entry typeInst: %p\n", typeInstance);
  3569. }
  3570. else
  3571. populateModule->PopulateType(type, BfPopulateType_DataAndMethods);
  3572. }
  3573. if ((!isDefiningModule) && (!type->IsUnspecializedType()) && (type->IsValueType()) && (mHasDebugInfo))
  3574. {
  3575. DbgSetTypeSize(DbgGetType(type), BF_ALIGN(type->mSize, type->mAlign) * 8, type->mAlign * 8);
  3576. }
  3577. bool isPrimEnum = (type->IsEnum()) && (type->IsTypedPrimitive());
  3578. if (typeInstance == NULL)
  3579. return;
  3580. BfType* underlyingArrayType = NULL;
  3581. int underlyingArraySize = -1;
  3582. bool underlyingIsVector = false;
  3583. typeInstance->GetUnderlyingArray(underlyingArrayType, underlyingArraySize, underlyingIsVector);
  3584. if (underlyingArraySize > 0)
  3585. {
  3586. // Don't populate data
  3587. }
  3588. else
  3589. {
  3590. CreateTypeDefinition_Data(populateModule, typeInstance, forceDbgDefine);
  3591. }
  3592. for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
  3593. {
  3594. auto fieldInstance = &fieldInstanceRef;
  3595. if (!fieldInstance->mFieldIncluded)
  3596. continue;
  3597. auto fieldDef = fieldInstance->GetFieldDef();
  3598. if ((fieldInstance->mResolvedType == NULL) || (typeInstance->IsBoxed()))
  3599. continue;
  3600. if ((fieldDef == NULL) || (!fieldDef->mIsStatic))
  3601. continue; // Already handled non-statics
  3602. auto resolvedFieldType = fieldInstance->GetResolvedType();
  3603. mModule->PopulateType(resolvedFieldType, BfPopulateType_Declaration);
  3604. BfIRType resolvedFieldIRType = MapType(resolvedFieldType);
  3605. BfIRMDNode resolvedFieldDIType;
  3606. //if ((fieldDef != NULL) && (!fieldDef->mIsStatic) && (resolvedFieldType->IsStruct()))
  3607. //PopulateType(resolvedFieldType, BfIRPopulateType_Eventually_Full);
  3608. if ((!typeInstance->IsBoxed()) && (fieldDef != NULL))
  3609. {
  3610. if (fieldDef->mIsConst)
  3611. {
  3612. if ((isDefiningModule) && (fieldDef->mIsExtern) && (resolvedFieldType->IsPointer()))
  3613. {
  3614. if (!resolvedFieldType->IsVoid())
  3615. mModule->CreateStaticField(fieldInstance);
  3616. }
  3617. }
  3618. else if (fieldDef->mIsStatic)
  3619. {
  3620. if (isDefiningModule)
  3621. {
  3622. bool isThreadLocal = mModule->IsThreadLocal(fieldInstance);
  3623. if (!resolvedFieldType->IsVoid())
  3624. mModule->CreateStaticField(fieldInstance, isThreadLocal);
  3625. }
  3626. }
  3627. }
  3628. }
  3629. }
  3630. void BfIRBuilder::ReplaceDITemporaryTypes()
  3631. {
  3632. //for (auto typeInstance : mDITemporaryTypes)
  3633. for (int i = 0; i < (int)mDITemporaryTypes.size(); i++)
  3634. {
  3635. auto typeInstance = mDITemporaryTypes[i];
  3636. auto populateType = mTypeMap[typeInstance];
  3637. if (populateType == BfIRPopulateType_Full)
  3638. continue;
  3639. mTypeMap[typeInstance] = BfIRPopulateType_Eventually_Full;
  3640. CreateTypeDefinition(typeInstance, false);
  3641. mTypeMap[typeInstance] = BfIRPopulateType_Full;
  3642. }
  3643. mDITemporaryTypes.Clear();
  3644. }
  3645. void BfIRBuilder::PushDbgLoc(BfTypeInstance* typeInst)
  3646. {
  3647. }
  3648. BfIRPopulateType BfIRBuilder::GetPopulateTypeState(BfType* type)
  3649. {
  3650. BfIRPopulateType* populateTypePtr = NULL;
  3651. if (mTypeMap.TryGetValue(type, &populateTypePtr))
  3652. return *populateTypePtr;
  3653. return BfIRPopulateType_Identity;
  3654. }
  3655. void BfIRBuilder::PopulateType(BfType* type, BfIRPopulateType populateType)
  3656. {
  3657. if (mIgnoreWrites)
  3658. return;
  3659. BF_ASSERT(!mModule->mIsScratchModule);
  3660. if (populateType == BfIRPopulateType_Identity)
  3661. return;
  3662. auto curPopulateType = BfIRPopulateType_Identity;
  3663. BfIRPopulateType* populateTypePtr = NULL;
  3664. if (mTypeMap.TryGetValue(type, &populateTypePtr))
  3665. curPopulateType = *populateTypePtr;
  3666. if (curPopulateType >= populateType)
  3667. return;
  3668. if (curPopulateType == BfIRPopulateType_Full)
  3669. return;
  3670. auto typeInst = type->ToTypeInstance();
  3671. if ((curPopulateType < BfIRPopulateType_Declaration) && (populateType >= BfIRPopulateType_Declaration))
  3672. {
  3673. CreateTypeDeclaration(type, populateType == BfIRPopulateType_Full_ForceDefinition);
  3674. mTypeMap[type] = BfIRPopulateType_Declaration;
  3675. }
  3676. if ((curPopulateType < populateType) && (populateType >= BfIRPopulateType_Eventually_Full))
  3677. {
  3678. mTypeMap[type] = BfIRPopulateType_Eventually_Full;
  3679. CreateTypeDefinition(type, populateType == BfIRPopulateType_Full_ForceDefinition);
  3680. mTypeMap[type] = BfIRPopulateType_Full;
  3681. }
  3682. }
  3683. void BfIRBuilder::SetType(BfType* type, BfIRType irType)
  3684. {
  3685. WriteCmd(BfIRCmd_SetType, type->mTypeId, irType);
  3686. NEW_CMD_INSERTED;
  3687. }
  3688. void BfIRBuilder::SetInstType(BfType* type, BfIRType irType)
  3689. {
  3690. WriteCmd(BfIRCmd_SetInstType, type->mTypeId, irType);
  3691. NEW_CMD_INSERTED;
  3692. }
  3693. int BfIRBuilder::GetFakeId()
  3694. {
  3695. int fakeId = mCurFakeId;
  3696. mCurFakeId--;
  3697. if (mCurFakeId >= 0)
  3698. mCurFakeId = -2;
  3699. return fakeId;
  3700. }
  3701. BfIRValue BfIRBuilder::GetFakeVal()
  3702. {
  3703. BfIRValue irValue;
  3704. irValue.mFlags = BfIRValueFlags_Value;
  3705. irValue.mId = GetFakeId();
  3706. return irValue;
  3707. }
  3708. BfIRValue BfIRBuilder::GetFakeConst()
  3709. {
  3710. BfIRValue irValue;
  3711. irValue.mFlags = BfIRValueFlags_Const;
  3712. irValue.mId = GetFakeId();
  3713. return irValue;
  3714. }
  3715. BfIRType BfIRBuilder::GetFakeType()
  3716. {
  3717. BfIRType type;
  3718. type.mId = GetFakeId();
  3719. return type;
  3720. }
  3721. BfIRType BfIRBuilder::GetFakeBlock()
  3722. {
  3723. BfIRBlock block;
  3724. block.mFlags = BfIRValueFlags_Block;
  3725. block.mId = GetFakeId();
  3726. return block;
  3727. }
  3728. BfIRFunctionType BfIRBuilder::GetFakeFunctionType()
  3729. {
  3730. BfIRFunctionType funcType;
  3731. funcType.mId = GetFakeId();
  3732. return funcType;
  3733. }
  3734. BfIRFunction BfIRBuilder::GetFakeFunction()
  3735. {
  3736. BfIRFunction func;
  3737. //func.mFlags = BfIRValueFlags_Func;
  3738. func.mId = GetFakeId();
  3739. return func;
  3740. }
  3741. BfIRType BfIRBuilder::GetPrimitiveType(BfTypeCode typeCode)
  3742. {
  3743. FixTypeCode(typeCode);
  3744. BfIRType irType;
  3745. irType.mKind = BfIRTypeData::TypeKind_TypeCode;
  3746. irType.mId = (int)typeCode;
  3747. return irType;
  3748. }
  3749. BfIRType BfIRBuilder::CreateStructType(const StringImpl& name)
  3750. {
  3751. BfIRType retType = WriteCmd(BfIRCmd_CreateStruct, name);
  3752. NEW_CMD_INSERTED_IRTYPE;
  3753. return retType;
  3754. }
  3755. BfIRType BfIRBuilder::CreateStructType(const BfSizedArray<BfIRType>& memberTypes)
  3756. {
  3757. BfIRType retType = WriteCmd(BfIRCmd_CreateAnonymousStruct, memberTypes);
  3758. NEW_CMD_INSERTED_IRTYPE;
  3759. return retType;
  3760. }
  3761. void BfIRBuilder::StructSetBody(BfIRType type, const BfSizedArray<BfIRType>& memberTypes, int size, int align, bool isPacked)
  3762. {
  3763. WriteCmd(BfIRCmd_StructSetBody, type, memberTypes, size, align, isPacked);
  3764. NEW_CMD_INSERTED;
  3765. }
  3766. BfIRType BfIRBuilder::MapType(BfType* type, BfIRPopulateType populateType)
  3767. {
  3768. if (!mIgnoreWrites)
  3769. {
  3770. PopulateType(type, populateType);
  3771. }
  3772. BF_ASSERT(type->mTypeId > 0);
  3773. BfIRType retType;
  3774. retType.mKind = BfIRType::TypeKind_TypeId;
  3775. retType.mId = type->mTypeId;
  3776. return retType;
  3777. }
  3778. BfIRType BfIRBuilder::MapTypeInst(BfTypeInstance* typeInst, BfIRPopulateType populateType)
  3779. {
  3780. if (!mIgnoreWrites)
  3781. {
  3782. PopulateType(typeInst, populateType);
  3783. }
  3784. if ((!mIgnoreWrites) && (populateType != BfIRPopulateType_Identity))
  3785. BF_ASSERT(mTypeMap.ContainsKey(typeInst));
  3786. BfIRType retType;
  3787. retType.mKind = BfIRType::TypeKind_TypeInstId;
  3788. retType.mId = typeInst->mTypeId;
  3789. return retType;
  3790. }
  3791. BfIRType BfIRBuilder::MapTypeInstPtr(BfTypeInstance* typeInst)
  3792. {
  3793. if (!mIgnoreWrites)
  3794. {
  3795. PopulateType(typeInst, BfIRPopulateType_Declaration);
  3796. }
  3797. BfIRType retType;
  3798. retType.mKind = BfIRType::TypeKind_TypeInstPtrId;
  3799. retType.mId = typeInst->mTypeId;
  3800. return retType;
  3801. }
  3802. BfIRType BfIRBuilder::GetType(BfIRValue val)
  3803. {
  3804. if (mIgnoreWrites)
  3805. return GetFakeType();
  3806. BfIRType retType = WriteCmd(BfIRCmd_GetType, val);
  3807. NEW_CMD_INSERTED_IRTYPE;
  3808. return retType;
  3809. }
  3810. BfIRType BfIRBuilder::GetPointerTo(BfIRFunctionType funcType)
  3811. {
  3812. BfIRType retType = WriteCmd(BfIRCmd_GetPointerToFuncType, funcType);
  3813. NEW_CMD_INSERTED_IRTYPE;
  3814. return retType;
  3815. }
  3816. BfIRType BfIRBuilder::GetPointerTo(BfIRType type)
  3817. {
  3818. BfIRType retType = WriteCmd(BfIRCmd_GetPointerToType, type);
  3819. NEW_CMD_INSERTED_IRTYPE;
  3820. return retType;
  3821. }
  3822. BfIRType BfIRBuilder::GetSizedArrayType(BfIRType elementType, int length)
  3823. {
  3824. BF_ASSERT(length >= 0);
  3825. if (mIgnoreWrites)
  3826. {
  3827. auto constSizedArrayType = mTempAlloc.Alloc<BfConstantSizedArrayType>();
  3828. constSizedArrayType->mConstType = BfConstType_SizedArrayType;
  3829. constSizedArrayType->mType = elementType;
  3830. constSizedArrayType->mLength = length;
  3831. int chunkId = mTempAlloc.GetChunkedId(constSizedArrayType);
  3832. BfIRType retType;
  3833. retType.mKind = BfIRTypeData::TypeKind_SizedArray;
  3834. retType.mId = chunkId;
  3835. return retType;
  3836. }
  3837. else
  3838. {
  3839. BfIRType retType = WriteCmd(BfIRCmd_GetSizedArrayType, elementType, length);
  3840. NEW_CMD_INSERTED_IRTYPE;
  3841. return retType;
  3842. }
  3843. }
  3844. BfIRType BfIRBuilder::GetVectorType(BfIRType elementType, int length)
  3845. {
  3846. BfIRType retType = WriteCmd(BfIRCmd_GetVectorType, elementType, length);
  3847. NEW_CMD_INSERTED_IRTYPE;
  3848. return retType;
  3849. }
  3850. BfIRValue BfIRBuilder::CreateConstAgg_Value(BfIRType type, const BfSizedArray<BfIRValue>& values)
  3851. {
  3852. BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstAgg, type, values);
  3853. NEW_CMD_INSERTED_IRVALUE;
  3854. return retVal;
  3855. }
  3856. BfIRValue BfIRBuilder::CreateConstString(const StringImpl& str)
  3857. {
  3858. BfIRValue retVal = WriteCmd(BfIRCmd_CreateConstString, str);
  3859. NEW_CMD_INSERTED_IRVALUE;
  3860. return retVal;
  3861. }
  3862. BfIRValue BfIRBuilder::ConstToMemory(BfIRValue constVal)
  3863. {
  3864. auto constant = GetConstant(constVal);
  3865. BfIRValue* value = NULL;
  3866. if (mConstMemMap.TryGetValue(constVal.mId, &value))
  3867. return *value;
  3868. BfIRType constType;
  3869. if (constant->mConstType == BfConstType_Agg)
  3870. constType = ((BfConstantAgg*)constant)->mType;
  3871. else if (constant->mConstType == BfConstType_AggZero)
  3872. constType = constant->mIRType;
  3873. else if (constant->mTypeCode == BfTypeCode_NullPtr)
  3874. constType = constant->mIRType;
  3875. else
  3876. BF_FATAL("Invalid const type for ConstToMemory");
  3877. auto memVal = CreateGlobalVariable(constType, true, BfIRLinkageType_Internal, constVal, StrFormat("__constMem%d", constVal.mId));
  3878. mConstMemMap[constVal.mId] = memVal;
  3879. return memVal;
  3880. }
  3881. BfIRValue BfIRBuilder::GetConfigConst(BfIRConfigConst constType, BfTypeCode typeCode)
  3882. {
  3883. BfIRValue retVal = WriteCmd(BfIRCmd_ConfigConst, (int)constType, typeCode);
  3884. NEW_CMD_INSERTED_IRVALUE;
  3885. return retVal;
  3886. }
  3887. BfIRValue BfIRBuilder::GetArgument(int argIdx)
  3888. {
  3889. BfIRValue retVal(BfIRValueFlags_Arg, argIdx);
  3890. return retVal;
  3891. }
  3892. void BfIRBuilder::SetName(BfIRValue val, const StringImpl& name)
  3893. {
  3894. WriteCmd(BfIRCmd_SetName, val, name);
  3895. NEW_CMD_INSERTED;
  3896. }
  3897. BfIRValue BfIRBuilder::CreateUndefValue(BfIRType type)
  3898. {
  3899. BfIRValue retVal = WriteCmd(BfIRCmd_CreateUndefValue, type);
  3900. NEW_CMD_INSERTED_IRVALUE;
  3901. return retVal;
  3902. }
  3903. BfIRValue BfIRBuilder::CreateNumericCast(BfIRValue val, bool valIsSigned, BfTypeCode typeCode)
  3904. {
  3905. FixTypeCode(typeCode);
  3906. if (val.IsConst())
  3907. {
  3908. auto constVal = GetConstantById(val.mId);
  3909. if (constVal->mConstType == BfConstType_Undef)
  3910. return GetUndefConstValue(GetPrimitiveType(typeCode));
  3911. if (constVal->mTypeCode < BfTypeCode_Length)
  3912. {
  3913. // ? -> Int
  3914. if (IsInt(typeCode))
  3915. {
  3916. uint64 val = 0;
  3917. if ((typeCode == BfTypeCode_IntPtr) || (typeCode == BfTypeCode_UIntPtr))
  3918. {
  3919. if (mModule->mSystem->mPtrSize == 4)
  3920. typeCode = (typeCode == BfTypeCode_IntPtr) ? BfTypeCode_Int32 : BfTypeCode_UInt32;
  3921. else
  3922. typeCode = (typeCode == BfTypeCode_IntPtr) ? BfTypeCode_Int64 : BfTypeCode_UInt64;
  3923. }
  3924. // Int -> Int
  3925. if (IsInt(constVal->mTypeCode))
  3926. {
  3927. switch (typeCode)
  3928. {
  3929. case BfTypeCode_Int8: val = (int8)constVal->mInt64; break;
  3930. case BfTypeCode_Char8:
  3931. case BfTypeCode_UInt8: val = (uint8)constVal->mInt64; break;
  3932. case BfTypeCode_Int16: val = (int16)constVal->mInt64; break;
  3933. case BfTypeCode_Char16:
  3934. case BfTypeCode_UInt16: val = (uint16)constVal->mInt64; break;
  3935. case BfTypeCode_Int32: val = (int32)constVal->mInt64; break;
  3936. case BfTypeCode_Char32:
  3937. case BfTypeCode_UInt32: val = (uint32)constVal->mInt64; break;
  3938. case BfTypeCode_Int64: val = (uint64)(int64)constVal->mInt64; break;
  3939. case BfTypeCode_UInt64: val = (uint64)constVal->mUInt64; break;
  3940. default: break;
  3941. }
  3942. }
  3943. else // Float -> Int
  3944. {
  3945. switch (typeCode)
  3946. {
  3947. case BfTypeCode_Int8: val = (int8)constVal->mDouble; break;
  3948. case BfTypeCode_Char8:
  3949. case BfTypeCode_UInt8: val = (uint8)constVal->mDouble; break;
  3950. case BfTypeCode_Int16: val = (int16)constVal->mDouble; break;
  3951. case BfTypeCode_Char16:
  3952. case BfTypeCode_UInt16: val = (uint16)constVal->mDouble; break;
  3953. case BfTypeCode_Int32: val = (int32)constVal->mDouble; break;
  3954. case BfTypeCode_Char32:
  3955. case BfTypeCode_UInt32: val = (uint32)constVal->mDouble; break;
  3956. case BfTypeCode_Int64: val = (uint64)(int64)constVal->mDouble; break;
  3957. case BfTypeCode_UInt64: val = (uint64)constVal->mDouble; break;
  3958. default: break;
  3959. }
  3960. }
  3961. return CreateConst(typeCode, val);
  3962. }
  3963. // Int -> Float
  3964. if (IsInt(constVal->mTypeCode))
  3965. {
  3966. double val = 0;
  3967. if (IsSigned(constVal->mTypeCode))
  3968. val = (double)constVal->mInt64;
  3969. else
  3970. val = (double)constVal->mUInt64;
  3971. return CreateConst(typeCode, val);
  3972. }
  3973. // Float -> Float
  3974. return CreateConst(typeCode, constVal->mDouble);
  3975. }
  3976. }
  3977. auto retVal = WriteCmd(BfIRCmd_NumericCast, val, valIsSigned, typeCode);
  3978. NEW_CMD_INSERTED_IRVALUE;
  3979. return retVal;
  3980. }
  3981. BfIRValue BfIRBuilder::CreateCmpEQ(BfIRValue lhs, BfIRValue rhs)
  3982. {
  3983. if ((lhs.IsConst()) && (rhs.IsConst()))
  3984. {
  3985. CMP_APPLY(lhs, rhs, ==);
  3986. int eqVal = CheckConstEquality(lhs, rhs);
  3987. if (eqVal != -1)
  3988. return CreateConst(BfTypeCode_Boolean, (eqVal == 1) ? (uint64)1 : (uint64)0);
  3989. }
  3990. auto retVal = WriteCmd(BfIRCmd_CmpEQ, lhs, rhs);
  3991. NEW_CMD_INSERTED_IRVALUE;
  3992. return retVal;
  3993. }
  3994. BfIRValue BfIRBuilder::CreateCmpNE(BfIRValue lhs, BfIRValue rhs)
  3995. {
  3996. if ((lhs.IsConst()) && (rhs.IsConst()))
  3997. {
  3998. CMP_APPLY(lhs, rhs, !=);
  3999. int eqVal = CheckConstEquality(lhs, rhs);
  4000. if (eqVal != -1)
  4001. return CreateConst(BfTypeCode_Boolean, (eqVal == 0) ? (uint64)1 : (uint64)0);
  4002. }
  4003. auto retVal = WriteCmd(BfIRCmd_CmpNE, lhs, rhs);
  4004. NEW_CMD_INSERTED_IRVALUE;
  4005. return retVal;
  4006. }
  4007. BfIRValue BfIRBuilder::CreateCmpLT(BfIRValue lhs, BfIRValue rhs, bool isSigned)
  4008. {
  4009. if ((lhs.IsConst()) && (rhs.IsConst()))
  4010. {
  4011. CMP_APPLY(lhs, rhs, <);
  4012. }
  4013. else if ((!isSigned) && (rhs.IsConst()))
  4014. {
  4015. // "unsigned < 0" is always false
  4016. auto constant = GetConstant(rhs);
  4017. if ((IsInt(constant->mTypeCode)) && (constant->mUInt64 == 0))
  4018. return CreateConst(BfTypeCode_Boolean, 0);
  4019. }
  4020. auto retVal = WriteCmd(isSigned ? BfIRCmd_CmpSLT : BfIRCmd_CmpULT, lhs, rhs);
  4021. NEW_CMD_INSERTED_IRVALUE;
  4022. return retVal;
  4023. }
  4024. BfIRValue BfIRBuilder::CreateCmpLTE(BfIRValue lhs, BfIRValue rhs, bool isSigned)
  4025. {
  4026. if ((lhs.IsConst()) && (rhs.IsConst()))
  4027. {
  4028. CMP_APPLY(lhs, rhs, <=);
  4029. }
  4030. auto retVal = WriteCmd(isSigned ? BfIRCmd_CmpSLE : BfIRCmd_CmpULE, lhs, rhs);
  4031. NEW_CMD_INSERTED;
  4032. return retVal;
  4033. }
  4034. BfIRValue BfIRBuilder::CreateCmpGT(BfIRValue lhs, BfIRValue rhs, bool isSigned)
  4035. {
  4036. if ((lhs.IsConst()) && (rhs.IsConst()))
  4037. {
  4038. CMP_APPLY(lhs, rhs, >);
  4039. }
  4040. auto retVal = WriteCmd(isSigned ? BfIRCmd_CmpSGT : BfIRCmd_CmpUGT, lhs, rhs);
  4041. NEW_CMD_INSERTED_IRVALUE;
  4042. return retVal;
  4043. }
  4044. BfIRValue BfIRBuilder::CreateCmpGTE(BfIRValue lhs, BfIRValue rhs, bool isSigned)
  4045. {
  4046. if ((lhs.IsConst()) && (rhs.IsConst()))
  4047. {
  4048. CMP_APPLY(lhs, rhs, >=);
  4049. }
  4050. else if ((!isSigned) && (lhs.IsConst()))
  4051. {
  4052. // "0 >= unsigned" is always true
  4053. auto constant = GetConstant(lhs);
  4054. if ((IsInt(constant->mTypeCode)) && (constant->mUInt64 == 0))
  4055. return CreateConst(BfTypeCode_Boolean, 1);
  4056. }
  4057. auto retVal = WriteCmd(isSigned ? BfIRCmd_CmpSGE : BfIRCmd_CmpUGE, lhs, rhs);
  4058. NEW_CMD_INSERTED_IRVALUE;
  4059. return retVal;
  4060. }
  4061. BfIRValue BfIRBuilder::CreateAdd(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKind overflowCheckKind)
  4062. {
  4063. mOpFailed = false;
  4064. if ((lhs.IsConst()) && (rhs.IsConst()))
  4065. {
  4066. auto constLHS = GetConstantById(lhs.mId);
  4067. if (constLHS->mConstType != BfConstType_PtrToInt)
  4068. {
  4069. BINOPFUNC_APPLY(lhs, rhs, CheckedAdd);
  4070. }
  4071. }
  4072. auto retVal = WriteCmd(BfIRCmd_Add, lhs, rhs, overflowCheckKind);
  4073. NEW_CMD_INSERTED_IRVALUE;
  4074. if ((overflowCheckKind != BfOverflowCheckKind_None) && (!mIgnoreWrites))
  4075. {
  4076. mInsertBlock = mActualInsertBlock = WriteCmd(BfIRCmd_GetInsertBlock);
  4077. NEW_CMD_INSERTED_IRVALUE;
  4078. }
  4079. return retVal;
  4080. }
  4081. BfIRValue BfIRBuilder::CreateSub(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKind overflowCheckKind)
  4082. {
  4083. mOpFailed = false;
  4084. if ((lhs.IsConst()) && (rhs.IsConst()))
  4085. {
  4086. BINOPFUNC_APPLY(lhs, rhs, CheckedSub);
  4087. }
  4088. auto retVal = WriteCmd(BfIRCmd_Sub, lhs, rhs, overflowCheckKind);
  4089. NEW_CMD_INSERTED;
  4090. if ((overflowCheckKind != BfOverflowCheckKind_None) && (!mIgnoreWrites))
  4091. {
  4092. mInsertBlock = mActualInsertBlock = WriteCmd(BfIRCmd_GetInsertBlock);
  4093. NEW_CMD_INSERTED_IRVALUE;
  4094. }
  4095. return retVal;
  4096. }
  4097. BfIRValue BfIRBuilder::CreateMul(BfIRValue lhs, BfIRValue rhs, BfOverflowCheckKind overflowCheckKind)
  4098. {
  4099. mOpFailed = false;
  4100. if ((lhs.IsConst()) && (rhs.IsConst()))
  4101. {
  4102. BINOPFUNC_APPLY(lhs, rhs, CheckedMul);
  4103. }
  4104. auto retVal = WriteCmd(BfIRCmd_Mul, lhs, rhs, overflowCheckKind);
  4105. NEW_CMD_INSERTED_IRVALUE;
  4106. if ((overflowCheckKind != BfOverflowCheckKind_None) && (!mIgnoreWrites))
  4107. {
  4108. mInsertBlock = mActualInsertBlock = WriteCmd(BfIRCmd_GetInsertBlock);
  4109. NEW_CMD_INSERTED_IRVALUE;
  4110. }
  4111. return retVal;
  4112. }
  4113. BfIRValue BfIRBuilder::CreateDiv(BfIRValue lhs, BfIRValue rhs, bool isSigned)
  4114. {
  4115. if ((lhs.IsConst()) && (rhs.IsConst()))
  4116. {
  4117. auto constLHS = GetConstantById(lhs.mId);
  4118. auto constRHS = GetConstantById(rhs.mId);
  4119. if ((constLHS->mTypeCode == BfTypeCode_Float) || (constLHS->mTypeCode == BfTypeCode_Double))
  4120. {
  4121. double fVal = constLHS->mDouble / constRHS->mDouble;
  4122. return CreateConst(constLHS->mTypeCode, fVal);
  4123. }
  4124. if (constRHS->mInt64 != 0)
  4125. {
  4126. INT_BINOP_APPLY(constLHS, constRHS, /);
  4127. }
  4128. }
  4129. auto retVal = WriteCmd(isSigned ? BfIRCmd_SDiv : BfIRCmd_UDiv, lhs, rhs);
  4130. NEW_CMD_INSERTED_IRVALUE;
  4131. return retVal;
  4132. }
  4133. BfIRValue BfIRBuilder::CreateRem(BfIRValue lhs, BfIRValue rhs, bool isSigned)
  4134. {
  4135. if ((lhs.IsConst()) && (rhs.IsConst()))
  4136. {
  4137. auto constLHS = GetConstantById(lhs.mId);
  4138. auto constRHS = GetConstantById(rhs.mId);
  4139. if ((constLHS->mTypeCode == BfTypeCode_Float) || (constLHS->mTypeCode == BfTypeCode_Double))
  4140. {
  4141. double fVal = fmod(constLHS->mDouble, constRHS->mDouble);
  4142. return CreateConst(constLHS->mTypeCode, fVal);
  4143. }
  4144. if (constRHS->mInt64 != 0)
  4145. {
  4146. INT_BINOP_APPLY(constLHS, constRHS, %);
  4147. }
  4148. }
  4149. auto retVal = WriteCmd(isSigned ? BfIRCmd_SRem : BfIRCmd_URem, lhs, rhs);
  4150. NEW_CMD_INSERTED_IRVALUE;
  4151. return retVal;
  4152. }
  4153. BfIRValue BfIRBuilder::CreateAnd(BfIRValue lhs, BfIRValue rhs)
  4154. {
  4155. if ((lhs.IsConst()) && (rhs.IsConst()))
  4156. {
  4157. auto constLHS = GetConstantById(lhs.mId);
  4158. auto constRHS = GetConstantById(rhs.mId);
  4159. INT_BINOP_APPLY(constLHS, constRHS, &);
  4160. }
  4161. auto retVal = WriteCmd(BfIRCmd_And, lhs, rhs);
  4162. NEW_CMD_INSERTED_IRVALUE;
  4163. return retVal;
  4164. }
  4165. BfIRValue BfIRBuilder::CreateOr(BfIRValue lhs, BfIRValue rhs)
  4166. {
  4167. if ((lhs.IsConst()) && (rhs.IsConst()))
  4168. {
  4169. auto constLHS = GetConstantById(lhs.mId);
  4170. auto constRHS = GetConstantById(rhs.mId);
  4171. INT_BINOP_APPLY(constLHS, constRHS, |);
  4172. }
  4173. auto retVal = WriteCmd(BfIRCmd_Or, lhs, rhs);
  4174. NEW_CMD_INSERTED_IRVALUE;
  4175. return retVal;
  4176. }
  4177. BfIRValue BfIRBuilder::CreateXor(BfIRValue lhs, BfIRValue rhs)
  4178. {
  4179. if ((lhs.IsConst()) && (rhs.IsConst()))
  4180. {
  4181. auto constLHS = GetConstantById(lhs.mId);
  4182. auto constRHS = GetConstantById(rhs.mId);
  4183. INT_BINOP_APPLY(constLHS, constRHS, ^);
  4184. }
  4185. auto retVal = WriteCmd(BfIRCmd_Xor, lhs, rhs);
  4186. NEW_CMD_INSERTED_IRVALUE;
  4187. return retVal;
  4188. }
  4189. BfIRValue BfIRBuilder::CreateShl(BfIRValue lhs, BfIRValue rhs)
  4190. {
  4191. mOpFailed = false;
  4192. if ((lhs.IsConst()) && (rhs.IsConst()))
  4193. {
  4194. INT_BINOPFUNC_APPLY(lhs, rhs, CheckedShl);
  4195. }
  4196. auto retVal = WriteCmd(BfIRCmd_Shl, lhs, rhs);
  4197. NEW_CMD_INSERTED_IRVALUE;
  4198. return retVal;
  4199. }
  4200. BfIRValue BfIRBuilder::CreateShr(BfIRValue lhs, BfIRValue rhs, bool isSigned)
  4201. {
  4202. if ((lhs.IsConst()) && (rhs.IsConst()))
  4203. {
  4204. auto constLHS = GetConstantById(lhs.mId);
  4205. auto constRHS = GetConstantById(rhs.mId);
  4206. uint64 val;
  4207. if (isSigned)
  4208. val = (uint64)(constLHS->mInt64 >> constRHS->mInt32);
  4209. else
  4210. val = constLHS->mUInt64 >> constRHS->mInt32;
  4211. return CreateConst(constLHS->mTypeCode, val);
  4212. }
  4213. auto retVal = WriteCmd(isSigned ? BfIRCmd_AShr : BfIRCmd_LShr, lhs, rhs);
  4214. NEW_CMD_INSERTED_IRVALUE;
  4215. return retVal;
  4216. }
  4217. BfIRValue BfIRBuilder::CreateNeg(BfIRValue val)
  4218. {
  4219. if (val.IsConst())
  4220. {
  4221. UNARYOP_APPLY(val, -);
  4222. }
  4223. auto retVal = WriteCmd(BfIRCmd_Neg, val);
  4224. NEW_CMD_INSERTED_IRVALUE;
  4225. return retVal;
  4226. }
  4227. BfIRValue BfIRBuilder::CreateNot(BfIRValue val)
  4228. {
  4229. if (val.IsConst())
  4230. {
  4231. auto constVal = GetConstantById(val.mId);
  4232. uint64 newVal = 0;
  4233. if (constVal->mTypeCode == BfTypeCode_Boolean)
  4234. newVal = constVal->mBool ? 0 : 1;
  4235. else
  4236. newVal = ~constVal->mUInt64;
  4237. return CreateConst(constVal->mTypeCode, newVal);
  4238. }
  4239. auto retVal = WriteCmd(BfIRCmd_Not, val);
  4240. NEW_CMD_INSERTED_IRVALUE;
  4241. return retVal;
  4242. }
  4243. BfIRValue BfIRBuilder::CreateBitCast(BfIRValue val, BfIRType type)
  4244. {
  4245. if (val.IsConst())
  4246. return CreateConstBitCast(val, type);
  4247. auto retVal = WriteCmd(BfIRCmd_BitCast, val, type);
  4248. NEW_CMD_INSERTED_IRVALUE;
  4249. return retVal;
  4250. }
  4251. BfIRValue BfIRBuilder::CreatePtrToInt(BfIRValue val, BfTypeCode typeCode)
  4252. {
  4253. FixTypeCode(typeCode);
  4254. if (val.IsConst())
  4255. {
  4256. auto ptrToInt = mTempAlloc.Alloc<BfConstantPtrToInt>();
  4257. ptrToInt->mConstType = BfConstType_PtrToInt;
  4258. ptrToInt->mTarget = val.mId;
  4259. ptrToInt->mToTypeCode = typeCode;
  4260. BfIRValue castedVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(ptrToInt));
  4261. #ifdef CHECK_CONSTHOLDER
  4262. castedVal.mHolder = this;
  4263. #endif
  4264. return castedVal;
  4265. }
  4266. auto retVal = WriteCmd(BfIRCmd_PtrToInt, val, typeCode);
  4267. NEW_CMD_INSERTED_IRVALUE;
  4268. return retVal;
  4269. }
  4270. BfIRValue BfIRBuilder::CreateIntToPtr(BfIRValue val, BfIRType type)
  4271. {
  4272. if (val.IsConst())
  4273. {
  4274. auto ptrToInt = mTempAlloc.Alloc<BfConstantIntToPtr>();
  4275. ptrToInt->mConstType = BfConstType_IntToPtr;
  4276. ptrToInt->mTarget = val.mId;
  4277. ptrToInt->mToType = type;
  4278. BfIRValue castedVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(ptrToInt));
  4279. #ifdef CHECK_CONSTHOLDER
  4280. castedVal.mHolder = this;
  4281. #endif
  4282. return castedVal;
  4283. }
  4284. BfIRValue retVal = WriteCmd(BfIRCmd_IntToPtr, val, type);
  4285. NEW_CMD_INSERTED_IRVALUE;
  4286. return retVal;
  4287. }
  4288. BfIRValue BfIRBuilder::CreateIntToPtr(uint64 val, BfIRType type)
  4289. {
  4290. return CreateIntToPtr(CreateConst(BfTypeCode_IntPtr, val), type);
  4291. }
  4292. BfIRValue BfIRBuilder::CreateInBoundsGEP(BfIRValue val, int idx0)
  4293. {
  4294. if (val.IsConst())
  4295. {
  4296. auto constGEP = mTempAlloc.Alloc<BfConstantGEP32_1>();
  4297. constGEP->mConstType = BfConstType_GEP32_1;
  4298. constGEP->mTarget = val.mId;
  4299. constGEP->mIdx0 = idx0;
  4300. BfIRValue retVal;
  4301. retVal.mFlags = BfIRValueFlags_Const;
  4302. retVal.mId = mTempAlloc.GetChunkedId(constGEP);
  4303. #ifdef CHECK_CONSTHOLDER
  4304. retVal.mHolder = this;
  4305. #endif
  4306. return retVal;
  4307. }
  4308. BfIRValue retVal = WriteCmd(BfIRCmd_InboundsGEP1_32, val, idx0);
  4309. NEW_CMD_INSERTED_IRVALUE;
  4310. return retVal;
  4311. }
  4312. BfIRValue BfIRBuilder::CreateInBoundsGEP(BfIRValue val, int idx0, int idx1)
  4313. {
  4314. if (val.IsConst())
  4315. {
  4316. #ifdef _DEBUG
  4317. auto targetConstant = GetConstant(val);
  4318. BF_ASSERT((mBfIRCodeGen == NULL) ||
  4319. ((targetConstant->mTypeCode != BfTypeCode_NullPtr) && (targetConstant->mConstType != BfConstType_BitCastNull)));
  4320. #endif
  4321. auto constGEP = mTempAlloc.Alloc<BfConstantGEP32_2>();
  4322. constGEP->mConstType = BfConstType_GEP32_2;
  4323. constGEP->mTarget = val.mId;
  4324. constGEP->mIdx0 = idx0;
  4325. constGEP->mIdx1 = idx1;
  4326. BfIRValue retVal;
  4327. retVal.mFlags = BfIRValueFlags_Const;
  4328. retVal.mId = mTempAlloc.GetChunkedId(constGEP);
  4329. #ifdef CHECK_CONSTHOLDER
  4330. retVal.mHolder = this;
  4331. #endif
  4332. return retVal;
  4333. }
  4334. auto retVal = WriteCmd(BfIRCmd_InboundsGEP2_32, val, idx0, idx1);
  4335. NEW_CMD_INSERTED_IRVALUE;
  4336. return retVal;
  4337. }
  4338. BfIRValue BfIRBuilder::CreateInBoundsGEP(BfIRValue val, BfIRValue idx0)
  4339. {
  4340. auto constant = GetConstant(val);
  4341. if (constant != NULL)
  4342. {
  4343. #ifdef _DEBUG
  4344. //BF_ASSERT((constant->mTypeCode != BfTypeCode_NullPtr) && (constant->mConstType != BfConstType_BitCastNull));
  4345. #endif
  4346. if (constant->mConstType == BfConstType_IntToPtr)
  4347. {
  4348. auto fromPtrToInt = (BfConstantIntToPtr*)constant;
  4349. auto fromTarget = GetConstantById(fromPtrToInt->mTarget);
  4350. if (IsInt(fromTarget->mTypeCode))
  4351. {
  4352. if (fromPtrToInt->mToType.mKind == BfIRTypeData::TypeKind_TypeId)
  4353. {
  4354. auto type = mModule->mContext->mTypes[fromPtrToInt->mToType.mId];
  4355. if (type->IsPointer())
  4356. {
  4357. auto elementType = type->GetUnderlyingType();
  4358. auto addConstant = GetConstant(idx0);
  4359. if ((addConstant != NULL) && (IsInt(addConstant->mTypeCode)))
  4360. {
  4361. return CreateIntToPtr(CreateConst(fromTarget->mTypeCode, (uint64)(fromTarget->mInt64 + addConstant->mInt64 * elementType->GetStride())),
  4362. fromPtrToInt->mToType);
  4363. }
  4364. }
  4365. }
  4366. }
  4367. }
  4368. if (auto idxConstant = GetConstant(idx0))
  4369. {
  4370. if (IsInt(idxConstant->mTypeCode))
  4371. return CreateInBoundsGEP(val, idxConstant->mInt32);
  4372. }
  4373. }
  4374. BfIRValue retVal = WriteCmd(BfIRCmd_InBoundsGEP1, val, idx0);
  4375. NEW_CMD_INSERTED_IRVALUE;
  4376. return retVal;
  4377. }
  4378. BfIRValue BfIRBuilder::CreateInBoundsGEP(BfIRValue val, BfIRValue idx0, BfIRValue idx1)
  4379. {
  4380. if ((val.IsConst()) && (idx0.IsConst()) && (idx1.IsConst()))
  4381. {
  4382. auto idx0Constant = GetConstant(idx0);
  4383. auto idx1Constant = GetConstant(idx1);
  4384. if ((IsInt(idx0Constant->mTypeCode)) && (IsInt(idx1Constant->mTypeCode)))
  4385. return CreateInBoundsGEP(val, idx0Constant->mInt32, idx1Constant->mInt32);
  4386. }
  4387. BfIRValue retVal = WriteCmd(BfIRCmd_InBoundsGEP2, val, idx0, idx1);
  4388. NEW_CMD_INSERTED_IRVALUE;
  4389. return retVal;
  4390. }
  4391. BfIRValue BfIRBuilder::CreateIsNull(BfIRValue val)
  4392. {
  4393. auto constant = GetConstant(val);
  4394. if (constant != NULL)
  4395. {
  4396. if (constant->mTypeCode == BfTypeCode_NullPtr)
  4397. return CreateConst(BfTypeCode_Boolean, 1);
  4398. if (constant->mConstType == BfConstType_BitCastNull)
  4399. return CreateConst(BfTypeCode_Boolean, 1);
  4400. if (constant->mConstType == BfConstType_GlobalVar)
  4401. return CreateConst(BfTypeCode_Boolean, 0);
  4402. }
  4403. BfIRValue retVal = WriteCmd(BfIRCmd_IsNull, val);
  4404. NEW_CMD_INSERTED_IRVALUE;
  4405. return retVal;
  4406. }
  4407. BfIRValue BfIRBuilder::CreateIsNotNull(BfIRValue val)
  4408. {
  4409. auto constant = GetConstant(val);
  4410. if (constant != NULL)
  4411. {
  4412. if (constant->mTypeCode == BfTypeCode_NullPtr)
  4413. return CreateConst(BfTypeCode_Boolean, 0);
  4414. if (constant->mConstType == BfConstType_BitCastNull)
  4415. return CreateConst(BfTypeCode_Boolean, 0);
  4416. if (constant->mConstType == BfConstType_GlobalVar)
  4417. return CreateConst(BfTypeCode_Boolean, 1);
  4418. }
  4419. BfIRValue retVal = WriteCmd(BfIRCmd_IsNotNull, val);
  4420. NEW_CMD_INSERTED_IRVALUE;
  4421. return retVal;
  4422. }
  4423. BfIRValue BfIRBuilder::CreateExtractValue(BfIRValue val, int idx)
  4424. {
  4425. auto aggConstant = GetConstant(val);
  4426. if (aggConstant != NULL)
  4427. {
  4428. if (aggConstant->mConstType == BfConstType_Agg)
  4429. {
  4430. auto arrayConstant = (BfConstantAgg*)aggConstant;
  4431. return arrayConstant->mValues[idx];
  4432. }
  4433. auto constGEP = mTempAlloc.Alloc<BfConstantExtractValue>();
  4434. constGEP->mConstType = BfConstType_ExtractValue;
  4435. constGEP->mTarget = val.mId;
  4436. constGEP->mIdx0 = idx;
  4437. BfIRValue retVal;
  4438. retVal.mFlags = BfIRValueFlags_Const;
  4439. retVal.mId = mTempAlloc.GetChunkedId(constGEP);
  4440. #ifdef CHECK_CONSTHOLDER
  4441. retVal.mHolder = this;
  4442. #endif
  4443. return retVal;
  4444. }
  4445. BfIRValue retVal = WriteCmd(BfIRCmd_ExtractValue, val, idx);
  4446. NEW_CMD_INSERTED_IRVALUE;
  4447. return retVal;
  4448. }
  4449. BfIRValue BfIRBuilder::CreateExtractValue(BfIRValue val, BfIRValue idx)
  4450. {
  4451. auto idxConst = GetConstant(idx);
  4452. if (idxConst != NULL)
  4453. {
  4454. BF_ASSERT(IsInt(idxConst->mTypeCode));
  4455. return CreateExtractValue(val, idxConst->mInt32);
  4456. }
  4457. if (mIgnoreWrites)
  4458. return GetFakeVal();
  4459. // We allow looking up into a const array with a non-const index by creating memory backing for the array
  4460. auto arrConst = GetConstant(val);
  4461. if (arrConst != NULL)
  4462. {
  4463. if ((arrConst->mConstType == BfConstType_Agg) || (arrConst->mConstType == BfConstType_AggZero))
  4464. {
  4465. BfIRValue arrMemVal = ConstToMemory(val);
  4466. auto valAddr = CreateInBoundsGEP(arrMemVal, CreateConst(BfTypeCode_IntPtr, 0), idx);
  4467. return CreateLoad(valAddr);
  4468. }
  4469. }
  4470. BF_FATAL("Invalid extract value");
  4471. return BfIRValue();
  4472. }
  4473. BfIRValue BfIRBuilder::CreateInsertValue(BfIRValue agg, BfIRValue val, int idx)
  4474. {
  4475. BfIRValue retVal = WriteCmd(BfIRCmd_InsertValue, agg, val, idx);
  4476. NEW_CMD_INSERTED_IRVALUE;
  4477. return retVal;
  4478. }
  4479. BfIRValue BfIRBuilder::CreateAlloca(BfIRType type)
  4480. {
  4481. BfIRValue retVal = WriteCmd(BfIRCmd_Alloca, type);
  4482. NEW_CMD_INSERTED_IRVALUE;
  4483. return retVal;
  4484. }
  4485. BfIRValue BfIRBuilder::CreateAlloca(BfIRType type, BfIRValue arraySize)
  4486. {
  4487. BfIRValue retVal = WriteCmd(BfIRCmd_AllocaArray, type, arraySize);
  4488. NEW_CMD_INSERTED_IRVALUE;
  4489. return retVal;
  4490. }
  4491. void BfIRBuilder::SetAllocaAlignment(BfIRValue val, int alignment)
  4492. {
  4493. BfIRValue retVal = WriteCmd(BfIRCmd_SetAllocaAlignment, val, alignment);
  4494. NEW_CMD_INSERTED;
  4495. }
  4496. void BfIRBuilder::SetAllocaNoChkStkHint(BfIRValue val)
  4497. {
  4498. BfIRValue retVal = WriteCmd(BfIRCmd_SetAllocaNoChkStkHint, val);
  4499. NEW_CMD_INSERTED;
  4500. }
  4501. void BfIRBuilder::SetAllocaForceMem(BfIRValue val)
  4502. {
  4503. BfIRValue retVal = WriteCmd(BfIRCmd_SetAllocaForceMem, val);
  4504. NEW_CMD_INSERTED;
  4505. }
  4506. BfIRValue BfIRBuilder::CreateAliasValue(BfIRValue val)
  4507. {
  4508. BfIRValue retVal = WriteCmd(BfIRCmd_AliasValue, val);
  4509. NEW_CMD_INSERTED;
  4510. return retVal;
  4511. }
  4512. BfIRValue BfIRBuilder::CreateLifetimeStart(BfIRValue val)
  4513. {
  4514. BfIRValue retVal = WriteCmd(BfIRCmd_LifetimeStart, val);
  4515. NEW_CMD_INSERTED;
  4516. return retVal;
  4517. }
  4518. BfIRValue BfIRBuilder::CreateLifetimeEnd(BfIRValue val)
  4519. {
  4520. BfIRValue retVal = WriteCmd(BfIRCmd_LifetimeEnd, val);
  4521. NEW_CMD_INSERTED;
  4522. return retVal;
  4523. }
  4524. BfIRValue BfIRBuilder::CreateLifetimeSoftEnd(BfIRValue val)
  4525. {
  4526. BfIRValue retVal = WriteCmd(BfIRCmd_LifetimeSoftEnd, val);
  4527. NEW_CMD_INSERTED;
  4528. return retVal;
  4529. }
  4530. BfIRValue BfIRBuilder::CreateLifetimeExtend(BfIRValue val)
  4531. {
  4532. BfIRValue retVal = WriteCmd(BfIRCmd_LifetimeExtend, val);
  4533. NEW_CMD_INSERTED;
  4534. return retVal;
  4535. }
  4536. BfIRValue BfIRBuilder::CreateValueScopeStart()
  4537. {
  4538. BfIRValue retVal = WriteCmd(BfIRCmd_ValueScopeStart);
  4539. NEW_CMD_INSERTED;
  4540. return retVal;
  4541. }
  4542. void BfIRBuilder::CreateValueScopeRetain(BfIRValue val)
  4543. {
  4544. BfIRValue retVal = WriteCmd(BfIRCmd_ValueScopeRetain, val);
  4545. NEW_CMD_INSERTED;
  4546. }
  4547. void BfIRBuilder::CreateValueScopeSoftEnd(BfIRValue scopeStart)
  4548. {
  4549. BfIRValue retVal = WriteCmd(BfIRCmd_ValueScopeSoftEnd, scopeStart);
  4550. NEW_CMD_INSERTED;
  4551. }
  4552. void BfIRBuilder::CreateValueScopeHardEnd(BfIRValue scopeStart)
  4553. {
  4554. BfIRValue retVal = WriteCmd(BfIRCmd_ValueScopeHardEnd, scopeStart);
  4555. NEW_CMD_INSERTED;
  4556. }
  4557. BfIRValue BfIRBuilder::CreateLoad(BfIRValue val, bool isVolatile)
  4558. {
  4559. #ifdef _DEBUG
  4560. // auto targetConstant = GetConstant(val);
  4561. // if (targetConstant != NULL)
  4562. // BF_ASSERT((targetConstant->mTypeCode != BfTypeCode_NullPtr) && (targetConstant->mConstType != BfConstType_BitCastNull));
  4563. #endif
  4564. BfIRValue retVal = WriteCmd(BfIRCmd_Load, val, isVolatile);
  4565. NEW_CMD_INSERTED_IRVALUE;
  4566. return retVal;
  4567. }
  4568. BfIRValue BfIRBuilder::CreateAlignedLoad(BfIRValue val, int align, bool isVolatile)
  4569. {
  4570. #ifdef _DEBUG
  4571. // auto targetConstant = GetConstant(val);
  4572. // if (targetConstant != NULL)
  4573. // BF_ASSERT((targetConstant->mTypeCode != BfTypeCode_NullPtr) && (targetConstant->mConstType != BfConstType_BitCastNull));
  4574. #endif
  4575. BfIRValue retVal = WriteCmd(BfIRCmd_AlignedLoad, val, align, isVolatile);
  4576. NEW_CMD_INSERTED_IRVALUE;
  4577. return retVal;
  4578. }
  4579. BfIRValue BfIRBuilder::CreateStore(BfIRValue val, BfIRValue ptr, bool isVolatile)
  4580. {
  4581. BfIRValue retVal = WriteCmd(BfIRCmd_Store, val, ptr, isVolatile);
  4582. NEW_CMD_INSERTED_IRVALUE;
  4583. return retVal;
  4584. }
  4585. BfIRValue BfIRBuilder::CreateAlignedStore(BfIRValue val, BfIRValue ptr, int align, bool isVolatile)
  4586. {
  4587. BfIRValue retVal = WriteCmd(BfIRCmd_AlignedStore, val, ptr, align, isVolatile);
  4588. NEW_CMD_INSERTED_IRVALUE;
  4589. return retVal;
  4590. }
  4591. BfIRValue BfIRBuilder::CreateMemSet(BfIRValue addr, BfIRValue val, BfIRValue size, int align)
  4592. {
  4593. BfIRValue retVal = WriteCmd(BfIRCmd_MemSet, addr, val, size, align);
  4594. NEW_CMD_INSERTED_IRVALUE;
  4595. return retVal;
  4596. }
  4597. void BfIRBuilder::CreateFence(BfIRFenceType fenceType)
  4598. {
  4599. BfIRValue retVal = WriteCmd(BfIRCmd_Fence, (uint8)fenceType);
  4600. NEW_CMD_INSERTED;
  4601. }
  4602. BfIRValue BfIRBuilder::CreateStackSave()
  4603. {
  4604. BfIRValue retVal = WriteCmd(BfIRCmd_StackSave);
  4605. NEW_CMD_INSERTED;
  4606. return retVal;
  4607. }
  4608. BfIRValue BfIRBuilder::CreateStackRestore(BfIRValue stackVal)
  4609. {
  4610. BfIRValue retVal = WriteCmd(BfIRCmd_StackRestore, stackVal);
  4611. NEW_CMD_INSERTED;
  4612. return retVal;
  4613. }
  4614. void BfIRBuilder::CreateGlobalVariable(BfIRValue irValue)
  4615. {
  4616. auto globalVar = (BfGlobalVar*)GetConstant(irValue);
  4617. if ((!mIgnoreWrites) && (globalVar->mStreamId == -1))
  4618. {
  4619. if (globalVar->mInitializer)
  4620. mHasGlobalDefs = true;
  4621. BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVariable, globalVar->mType, globalVar->mIsConst, (uint8)globalVar->mLinkageType, String(globalVar->mName), globalVar->mIsTLS, globalVar->mInitializer);
  4622. globalVar->mStreamId = retVal.mId;
  4623. NEW_CMD_INSERTED_IRVALUE;
  4624. }
  4625. }
  4626. BfIRValue BfIRConstHolder::CreateGlobalVariableConstant(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS)
  4627. {
  4628. BfIRValue* valuePtr = NULL;
  4629. if ((!mGlobalVarMap.TryAdd(name, NULL, &valuePtr)) && (!initializer))
  4630. {
  4631. return *valuePtr;
  4632. }
  4633. BF_ASSERT(varType);
  4634. auto constGV = mTempAlloc.Alloc<BfGlobalVar>();
  4635. int chunkId = mTempAlloc.GetChunkedId(constGV);
  4636. constGV->mStreamId = -1;
  4637. constGV->mConstType = BfConstType_GlobalVar;
  4638. constGV->mType = varType;
  4639. constGV->mIsConst = isConstant;
  4640. constGV->mLinkageType = linkageType;
  4641. constGV->mInitializer = initializer;
  4642. constGV->mName = AllocStr(name);
  4643. constGV->mIsTLS = isTLS;
  4644. auto irValue = BfIRValue(BfIRValueFlags_Const, chunkId);;
  4645. *valuePtr = irValue;
  4646. return irValue;
  4647. }
  4648. BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS)
  4649. {
  4650. auto irValue = CreateGlobalVariableConstant(varType, isConstant, linkageType, initializer, name, isTLS);
  4651. CreateGlobalVariable(irValue);
  4652. return irValue;
  4653. }
  4654. void BfIRBuilder::GlobalVar_SetUnnamedAddr(BfIRValue val, bool unnamedAddr)
  4655. {
  4656. BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVar_SetUnnamedAddr, val, unnamedAddr);
  4657. NEW_CMD_INSERTED;
  4658. }
  4659. void BfIRBuilder::GlobalVar_SetInitializer(BfIRValue globalVar, BfIRValue initVal)
  4660. {
  4661. BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVar_SetInitializer, globalVar, initVal);
  4662. NEW_CMD_INSERTED;
  4663. }
  4664. void BfIRBuilder::GlobalVar_SetAlignment(BfIRValue globalVar, int alignment)
  4665. {
  4666. BF_ASSERT(alignment != -1);
  4667. BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVar_SetAlignment, globalVar, alignment);
  4668. NEW_CMD_INSERTED;
  4669. }
  4670. void BfIRBuilder::GlobalVar_SetStorageKind(BfIRValue globalVar, BfIRStorageKind storageKind)
  4671. {
  4672. BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVar_SetStorageKind, globalVar, (int)storageKind);
  4673. NEW_CMD_INSERTED;
  4674. }
  4675. BfIRValue BfIRBuilder::CreateGlobalStringPtr(const StringImpl& str)
  4676. {
  4677. BfIRValue retVal = WriteCmd(BfIRCmd_GlobalStringPtr, str);
  4678. NEW_CMD_INSERTED_IRVALUE;
  4679. return retVal;
  4680. }
  4681. void BfIRBuilder::SetReflectTypeData(BfIRType type, BfIRValue globalVar)
  4682. {
  4683. BfIRValue retVal = WriteCmd(BfIRCmd_SetReflectTypeData, type, globalVar);
  4684. NEW_CMD_INSERTED_IRVALUE;
  4685. }
  4686. BfIRBlock BfIRBuilder::CreateBlock(const StringImpl& name, bool addNow)
  4687. {
  4688. if (addNow)
  4689. mActiveFunctionHasBody = true;
  4690. mBlockCount++;
  4691. BfIRBlock retBlock = WriteCmd(BfIRCmd_CreateBlock, name, addNow);
  4692. NEW_CMD_INSERTED_IRBLOCK;
  4693. return retBlock;
  4694. }
  4695. BfIRBlock BfIRBuilder::MaybeChainNewBlock(const StringImpl& name)
  4696. {
  4697. BfIRBlock retBlock = WriteCmd(BfIRCmd_MaybeChainNewBlock, name);
  4698. NEW_CMD_INSERTED_IRBLOCK;
  4699. if (!mIgnoreWrites)
  4700. {
  4701. BF_ASSERT(!retBlock.IsFake());
  4702. mActualInsertBlock = retBlock;
  4703. }
  4704. mInsertBlock = retBlock;
  4705. return retBlock;
  4706. }
  4707. void BfIRBuilder::AddBlock(BfIRBlock block)
  4708. {
  4709. mActiveFunctionHasBody = true;
  4710. BfIRValue retVal = WriteCmd(BfIRCmd_AddBlock, block);
  4711. NEW_CMD_INSERTED;
  4712. }
  4713. void BfIRBuilder::DropBlocks(BfIRBlock startingBlock)
  4714. {
  4715. WriteCmd(BfIRCmd_DropBlocks, startingBlock);
  4716. NEW_CMD_INSERTED;
  4717. }
  4718. void BfIRBuilder::MergeBlockDown(BfIRBlock fromBlock, BfIRBlock intoBlock)
  4719. {
  4720. WriteCmd(BfIRCmd_MergeBlockDown, fromBlock, intoBlock);
  4721. NEW_CMD_INSERTED;
  4722. }
  4723. void BfIRBuilder::SetInsertPoint(BfIRValue value)
  4724. {
  4725. BfIRValue retVal = WriteCmd(BfIRCmd_SetInsertPoint, value);
  4726. NEW_CMD_INSERTED;
  4727. }
  4728. void BfIRBuilder::SetInsertPoint(BfIRBlock block)
  4729. {
  4730. BfIRValue retVal = WriteCmd(BfIRCmd_SetInsertPoint, block);
  4731. if (!mIgnoreWrites)
  4732. {
  4733. BF_ASSERT(!block.IsFake());
  4734. mActualInsertBlock = block;
  4735. }
  4736. mInsertBlock = block;
  4737. NEW_CMD_INSERTED;
  4738. }
  4739. void BfIRBuilder::SetInsertPointAtStart(BfIRBlock block)
  4740. {
  4741. BfIRValue retVal = WriteCmd(BfIRCmd_SetInsertPointAtStart, block);
  4742. if (!mIgnoreWrites)
  4743. {
  4744. BF_ASSERT(!block.IsFake());
  4745. mActualInsertBlock = block;
  4746. }
  4747. mInsertBlock = block;
  4748. NEW_CMD_INSERTED;
  4749. }
  4750. void BfIRBuilder::EraseFromParent(BfIRBlock block)
  4751. {
  4752. BfIRValue retVal = WriteCmd(BfIRCmd_EraseFromParent, block);
  4753. NEW_CMD_INSERTED;
  4754. }
  4755. void BfIRBuilder::DeleteBlock(BfIRBlock block)
  4756. {
  4757. BfIRValue retVal = WriteCmd(BfIRCmd_DeleteBlock, block);
  4758. NEW_CMD_INSERTED;
  4759. }
  4760. void BfIRBuilder::EraseInstFromParent(BfIRValue val)
  4761. {
  4762. BfIRValue retVal = WriteCmd(BfIRCmd_EraseInstFromParent, val);
  4763. NEW_CMD_INSERTED;
  4764. }
  4765. BfIRValue BfIRBuilder::CreateBr(BfIRBlock block)
  4766. {
  4767. BfIRValue retVal = WriteCmd(BfIRCmd_CreateBr, block);
  4768. NEW_CMD_INSERTED;
  4769. return retVal;
  4770. }
  4771. BfIRValue BfIRBuilder::CreateBr_Fake(BfIRBlock block)
  4772. {
  4773. BfIRValue retVal = WriteCmd(BfIRCmd_CreateBr_Fake, block);
  4774. NEW_CMD_INSERTED;
  4775. return retVal;
  4776. }
  4777. BfIRValue BfIRBuilder::CreateBr_NoCollapse(BfIRBlock block)
  4778. {
  4779. BfIRValue retVal = WriteCmd(BfIRCmd_CreateBr_NoCollapse, block);
  4780. NEW_CMD_INSERTED;
  4781. return retVal;
  4782. }
  4783. void BfIRBuilder::CreateCondBr(BfIRValue val, BfIRBlock trueBlock, BfIRBlock falseBlock)
  4784. {
  4785. BfIRValue retVal = WriteCmd(BfIRCmd_CreateCondBr, val, trueBlock, falseBlock);
  4786. NEW_CMD_INSERTED;
  4787. }
  4788. BfIRBlock BfIRBuilder::GetInsertBlock()
  4789. {
  4790. if (!mIgnoreWrites)
  4791. {
  4792. BF_ASSERT(!mActualInsertBlock.IsFake());
  4793. return mActualInsertBlock;
  4794. }
  4795. return mInsertBlock;
  4796. }
  4797. void BfIRBuilder::MoveBlockToEnd(BfIRBlock block)
  4798. {
  4799. BfIRValue retVal = WriteCmd(BfIRCmd_MoveBlockToEnd, block);
  4800. NEW_CMD_INSERTED;
  4801. }
  4802. BfIRValue BfIRBuilder::CreateSwitch(BfIRValue value, BfIRBlock dest, int numCases)
  4803. {
  4804. BfIRValue retVal = WriteCmd(BfIRCmd_CreateSwitch, value, dest, numCases);
  4805. NEW_CMD_INSERTED_IRVALUE;
  4806. return retVal;
  4807. }
  4808. BfIRValue BfIRBuilder::AddSwitchCase(BfIRValue switchVal, BfIRValue caseVal, BfIRBlock caseBlock)
  4809. {
  4810. BfIRValue retVal = WriteCmd(BfIRCmd_AddSwitchCase, switchVal, caseVal, caseBlock);
  4811. BF_ASSERT(caseVal.IsConst());
  4812. NEW_CMD_INSERTED;
  4813. return retVal;
  4814. }
  4815. void BfIRBuilder::SetSwitchDefaultDest(BfIRValue switchVal, BfIRBlock caseBlock)
  4816. {
  4817. WriteCmd(BfIRCmd_SetSwitchDefaultDest, switchVal, caseBlock);
  4818. NEW_CMD_INSERTED;
  4819. }
  4820. BfIRValue BfIRBuilder::CreatePhi(BfIRType type, int incomingCount)
  4821. {
  4822. BfIRValue retVal = WriteCmd(BfIRCmd_CreatePhi, type, incomingCount);
  4823. NEW_CMD_INSERTED_IRVALUE;
  4824. return retVal;
  4825. }
  4826. void BfIRBuilder::AddPhiIncoming(BfIRValue phi, BfIRValue value, BfIRBlock comingFrom)
  4827. {
  4828. BfIRValue retVal = WriteCmd(BfIRCmd_AddPhiIncoming, phi, value, comingFrom);
  4829. NEW_CMD_INSERTED;
  4830. }
  4831. BfIRFunction BfIRBuilder::GetIntrinsic(String intrinName, int intrinId, BfIRType returnType, const BfSizedArray<BfIRType>& paramTypes)
  4832. {
  4833. BfIRValue retVal = WriteCmd(BfIRCmd_GetIntrinsic, intrinName, intrinId, returnType, paramTypes);
  4834. NEW_CMD_INSERTED;
  4835. return retVal;
  4836. }
  4837. BfIRFunctionType BfIRBuilder::MapMethod(BfMethodInstance* methodInstance)
  4838. {
  4839. if (mIgnoreWrites)
  4840. return GetFakeFunctionType();
  4841. bool useCache = (!mModule->mIsSpecialModule) && (methodInstance->mMethodDef->mIdx >= 0);
  4842. if (useCache)
  4843. {
  4844. BfIRFunctionType* funcType = NULL;
  4845. if (mMethodTypeMap.TryGetValue(methodInstance, &funcType))
  4846. return *funcType;
  4847. }
  4848. BfIRType retType;
  4849. SizedArray<BfIRType, 8> paramTypes;
  4850. methodInstance->GetIRFunctionInfo(mModule, retType, paramTypes);
  4851. auto funcType = CreateFunctionType(retType, paramTypes, methodInstance->IsVarArgs());
  4852. if (useCache)
  4853. mMethodTypeMap[methodInstance] = funcType;
  4854. return funcType;
  4855. }
  4856. BfIRFunctionType BfIRBuilder::CreateFunctionType(BfIRType resultType, const BfSizedArray<BfIRType>& paramTypes, bool isVarArg)
  4857. {
  4858. BfIRFunctionType retType = WriteCmd(BfIRCmd_CreateFunctionType, resultType, paramTypes, isVarArg);
  4859. NEW_CMD_INSERTED_IRFUNCTYPE;
  4860. return retType;
  4861. }
  4862. BfIRFunction BfIRBuilder::CreateFunction(BfIRFunctionType funcType, BfIRLinkageType linkageType, const StringImpl& name)
  4863. {
  4864. if (mIgnoreWrites)
  4865. {
  4866. auto fakeVal = GetFakeVal();
  4867. return fakeVal;
  4868. }
  4869. BF_ASSERT(mModule->mIsModuleMutable);
  4870. BfIRFunction retVal = WriteCmd(BfIRCmd_CreateFunction, funcType, (uint8)linkageType, name);
  4871. NEW_CMD_INSERTED_IRVALUE;
  4872. StringView nameSV = StringView(AllocStr(name), name.mLength);
  4873. mFunctionMap[nameSV] = retVal;
  4874. //BfLogSys(mModule->mSystem, "BfIRBuilder::CreateFunction: %d %s Module:%p\n", retVal.mId, name.c_str(), mModule);
  4875. return retVal;
  4876. }
  4877. void BfIRBuilder::SetFunctionName(BfIRValue func, const StringImpl& name)
  4878. {
  4879. WriteCmd(BfIRCmd_SetFunctionName, func, name);
  4880. NEW_CMD_INSERTED_IRVALUE;
  4881. }
  4882. void BfIRBuilder::EnsureFunctionPatchable()
  4883. {
  4884. BfIRValue retVal = WriteCmd(BfIRCmd_EnsureFunctionPatchable);
  4885. NEW_CMD_INSERTED_IRVALUE;
  4886. }
  4887. BfIRValue BfIRBuilder::RemapBindFunction(BfIRValue func)
  4888. {
  4889. BfIRValue retVal = WriteCmd(BfIRCmd_RemapBindFunction, func);
  4890. NEW_CMD_INSERTED_IRVALUE;
  4891. return retVal;
  4892. }
  4893. void BfIRBuilder::SetActiveFunction(BfIRFunction func)
  4894. {
  4895. //BfLogSys(mModule->mSystem, "BfIRBuilder::SetActiveFunction: %d\n", func.mId);
  4896. if (mActiveFunctionHasBody)
  4897. mNumFunctionsWithBodies++;
  4898. mActiveFunction = func;
  4899. mActiveFunctionHasBody = false;
  4900. if (!func.IsFake())
  4901. {
  4902. WriteCmd(BfIRCmd_SetActiveFunction, func);
  4903. NEW_CMD_INSERTED;
  4904. }
  4905. }
  4906. BfIRFunction BfIRBuilder::GetActiveFunction()
  4907. {
  4908. return mActiveFunction;
  4909. }
  4910. BfIRFunction BfIRBuilder::GetFunction(const StringImpl& name)
  4911. {
  4912. BfIRFunction* funcPtr = NULL;
  4913. if (mFunctionMap.TryGetValue(name, &funcPtr))
  4914. return *funcPtr;
  4915. return BfIRFunction();
  4916. }
  4917. BfIRValue BfIRBuilder::CreateCall(BfIRValue func, const BfSizedArray<BfIRValue>& args)
  4918. {
  4919. BfIRValue retVal = WriteCmd(BfIRCmd_CreateCall, func, args);
  4920. NEW_CMD_INSERTED_IRVALUE;
  4921. return retVal;
  4922. }
  4923. void BfIRBuilder::SetCallCallingConv(BfIRValue callInst, BfIRCallingConv callingConv)
  4924. {
  4925. if (callingConv == BfIRCallingConv_CDecl)
  4926. return;
  4927. WriteCmd(BfIRCmd_SetCallCallingConv, callInst, (uint8)callingConv);
  4928. NEW_CMD_INSERTED;
  4929. }
  4930. void BfIRBuilder::SetFuncCallingConv(BfIRFunction func, BfIRCallingConv callingConv)
  4931. {
  4932. if (callingConv == BfIRCallingConv_CDecl)
  4933. return;
  4934. WriteCmd(BfIRCmd_SetFuncCallingConv, func, (uint8)callingConv);
  4935. NEW_CMD_INSERTED;
  4936. }
  4937. void BfIRBuilder::SetTailCall(BfIRValue callInst)
  4938. {
  4939. WriteCmd(BfIRCmd_SetTailCall, callInst);
  4940. NEW_CMD_INSERTED;
  4941. }
  4942. void BfIRBuilder::SetCallAttribute(BfIRValue callInst, int paramIdx, BfIRAttribute attribute)
  4943. {
  4944. WriteCmd(BfIRCmd_SetCallAttribute, callInst, paramIdx, attribute);
  4945. NEW_CMD_INSERTED;
  4946. }
  4947. BfIRValue BfIRBuilder::CreateRet(BfIRValue val)
  4948. {
  4949. BfIRValue retVal = WriteCmd(BfIRCmd_CreateRet, val);
  4950. NEW_CMD_INSERTED;
  4951. return retVal;
  4952. }
  4953. BfIRValue BfIRBuilder::CreateSetRet(BfIRValue val, int returnTypeId)
  4954. {
  4955. BfIRValue retVal = WriteCmd(BfIRCmd_CreateSetRet, val, returnTypeId);
  4956. NEW_CMD_INSERTED;
  4957. return retVal;
  4958. }
  4959. void BfIRBuilder::CreateRetVoid()
  4960. {
  4961. WriteCmd(BfIRCmd_CreateRetVoid);
  4962. NEW_CMD_INSERTED;
  4963. }
  4964. void BfIRBuilder::CreateUnreachable()
  4965. {
  4966. WriteCmd(BfIRCmd_CreateUnreachable);
  4967. NEW_CMD_INSERTED;
  4968. }
  4969. void BfIRBuilder::Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr)
  4970. {
  4971. WriteCmd(BfIRCmd_Call_AddAttribute, callInst, argIdx, attr);
  4972. NEW_CMD_INSERTED;
  4973. }
  4974. void BfIRBuilder::Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr, int arg)
  4975. {
  4976. WriteCmd(BfIRCmd_Call_AddAttribute1, callInst, argIdx, attr, arg);
  4977. NEW_CMD_INSERTED;
  4978. }
  4979. void BfIRBuilder::Func_AddAttribute(BfIRFunction func, int argIdx, BfIRAttribute attr)
  4980. {
  4981. WriteCmd(BfIRCmd_Func_AddAttribute, func, argIdx, attr);
  4982. NEW_CMD_INSERTED;
  4983. }
  4984. void BfIRBuilder::Func_AddAttribute(BfIRFunction func, int argIdx, BfIRAttribute attr, int arg)
  4985. {
  4986. WriteCmd(BfIRCmd_Func_AddAttribute1, func, argIdx, attr, arg);
  4987. NEW_CMD_INSERTED;
  4988. }
  4989. void BfIRBuilder::Func_SetParamName(BfIRFunction func, int argIdx, const StringImpl& name)
  4990. {
  4991. WriteCmd(BfIRCmd_Func_SetParamName, func, argIdx, name);
  4992. NEW_CMD_INSERTED;
  4993. }
  4994. void BfIRBuilder::Func_DeleteBody(BfIRFunction func)
  4995. {
  4996. if (mActiveFunction == func)
  4997. mActiveFunctionHasBody = false;
  4998. WriteCmd(BfIRCmd_Func_DeleteBody, func);
  4999. NEW_CMD_INSERTED;
  5000. }
  5001. void BfIRBuilder::Func_SafeRename(BfIRFunction func)
  5002. {
  5003. WriteCmd(BfIRCmd_Func_SafeRename, func);
  5004. // We don't actually remove it from the named map. It doesn't matter for us.
  5005. // {
  5006. // auto llvmFunc = llvm::dyn_cast<llvm::Function>(func.mLLVMValue);
  5007. // llvmFunc->eraseFromParent();
  5008. // }
  5009. NEW_CMD_INSERTED;
  5010. }
  5011. void BfIRBuilder::Func_SafeRenameFrom(BfIRFunction func, const StringImpl& prevName)
  5012. {
  5013. WriteCmd(BfIRCmd_Func_SafeRenameFrom, func, prevName);
  5014. NEW_CMD_INSERTED;
  5015. }
  5016. void BfIRBuilder::Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage)
  5017. {
  5018. WriteCmd(BfIRCmd_Func_SetLinkage, func, (uint8)linkage);
  5019. NEW_CMD_INSERTED;
  5020. }
  5021. void BfIRBuilder::Comptime_Error(int errorKind)
  5022. {
  5023. BfIRValue retVal = WriteCmd(BfIRCmd_Comptime_Error, errorKind);
  5024. NEW_CMD_INSERTED;
  5025. }
  5026. BfIRValue BfIRBuilder::Comptime_GetBfType(int typeId, BfIRType resultType)
  5027. {
  5028. BfIRValue retVal = WriteCmd(BfIRCmd_Comptime_GetBfType, typeId, resultType);
  5029. NEW_CMD_INSERTED;
  5030. return retVal;
  5031. }
  5032. BfIRValue BfIRBuilder::Comptime_GetReflectType(int typeId, BfIRType resultType)
  5033. {
  5034. BfIRValue retVal = WriteCmd(BfIRCmd_Comptime_GetReflectType, typeId, resultType);
  5035. NEW_CMD_INSERTED;
  5036. return retVal;
  5037. }
  5038. BfIRValue BfIRBuilder::Comptime_DynamicCastCheck(BfIRValue value, int typeId, BfIRType resultType)
  5039. {
  5040. BfIRValue retVal = WriteCmd(BfIRCmd_Comptime_DynamicCastCheck, value, typeId, resultType);
  5041. NEW_CMD_INSERTED;
  5042. return retVal;
  5043. }
  5044. BfIRValue BfIRBuilder::Comptime_GetVirtualFunc(BfIRValue value, int virtualTableId, BfIRType resultType)
  5045. {
  5046. BfIRValue retVal = WriteCmd(BfIRCmd_Comptime_GetVirtualFunc, value, virtualTableId, resultType);
  5047. NEW_CMD_INSERTED;
  5048. return retVal;
  5049. }
  5050. BfIRValue BfIRBuilder::Comptime_GetInterfaceFunc(BfIRValue value, int typeId, int methodIdx, BfIRType resultType)
  5051. {
  5052. BfIRValue retVal = WriteCmd(BfIRCmd_Comptime_GetInterfaceFunc, value, typeId, methodIdx, resultType);
  5053. NEW_CMD_INSERTED;
  5054. return retVal;
  5055. }
  5056. void BfIRBuilder::SaveDebugLocation()
  5057. {
  5058. if (!mIgnoreWrites)
  5059. {
  5060. mSavedDebugLocs.push_back(mModule->mCurFilePosition);
  5061. WriteCmd(BfIRCmd_SaveDebugLocation);
  5062. NEW_CMD_INSERTED;
  5063. }
  5064. }
  5065. void BfIRBuilder::RestoreDebugLocation()
  5066. {
  5067. if (!mIgnoreWrites)
  5068. {
  5069. mModule->mCurFilePosition = mSavedDebugLocs.back();
  5070. mSavedDebugLocs.pop_back();
  5071. WriteCmd(BfIRCmd_RestoreDebugLocation);
  5072. mHasDebugLoc = true;
  5073. NEW_CMD_INSERTED;
  5074. }
  5075. }
  5076. void BfIRBuilder::DupDebugLocation()
  5077. {
  5078. WriteCmd(BfIRCmd_DupDebugLocation);
  5079. NEW_CMD_INSERTED;
  5080. }
  5081. bool BfIRBuilder::HasDebugLocation()
  5082. {
  5083. return mHasDebugLoc;
  5084. }
  5085. void BfIRBuilder::ClearDebugLocation()
  5086. {
  5087. WriteCmd(BfIRCmd_ClearDebugLocation);
  5088. mHasDebugLoc = false;
  5089. NEW_CMD_INSERTED;
  5090. }
  5091. void BfIRBuilder::ClearDebugLocation(BfIRValue inst)
  5092. {
  5093. WriteCmd(BfIRCmd_ClearDebugLocationInst, inst);
  5094. NEW_CMD_INSERTED;
  5095. }
  5096. void BfIRBuilder::ClearDebugLocation_Last()
  5097. {
  5098. WriteCmd(BfIRCmd_ClearDebugLocationInstLast);
  5099. NEW_CMD_INSERTED;
  5100. }
  5101. void BfIRBuilder::UpdateDebugLocation(BfIRValue inst)
  5102. {
  5103. WriteCmd(BfIRCmd_UpdateDebugLocation, inst);
  5104. NEW_CMD_INSERTED;
  5105. }
  5106. void BfIRBuilder::SetCurrentDebugLocation(int line, int column, BfIRMDNode diScope, BfIRMDNode diInlinedAt)
  5107. {
  5108. BF_ASSERT(diScope);
  5109. if (mDbgVerifyCodeGen && gDebugDbgLoc)
  5110. {
  5111. OutputDebugStrF("SetCurrentDebugLocation %d %d:%d\n", diScope.mId, line, column);
  5112. }
  5113. WriteCmd(BfIRCmd_SetCurrentDebugLocation, line, column, diScope, diInlinedAt);
  5114. mHasDebugLoc = true;
  5115. NEW_CMD_INSERTED;
  5116. }
  5117. void BfIRBuilder::CreateNop()
  5118. {
  5119. WriteCmd(BfIRCmd_Nop);
  5120. NEW_CMD_INSERTED;
  5121. }
  5122. void BfIRBuilder::CreateEnsureInstructionAt()
  5123. {
  5124. WriteCmd(BfIRCmd_EnsureInstructionAt);
  5125. NEW_CMD_INSERTED;
  5126. }
  5127. void BfIRBuilder::CreateStatementStart()
  5128. {
  5129. WriteCmd(BfIRCmd_StatementStart);
  5130. NEW_CMD_INSERTED;
  5131. }
  5132. void BfIRBuilder::CreateObjectAccessCheck(BfIRValue value, bool useAsm)
  5133. {
  5134. auto retBlock = WriteCmd(BfIRCmd_ObjectAccessCheck, value, useAsm);
  5135. NEW_CMD_INSERTED_IRBLOCK;
  5136. if (!mIgnoreWrites)
  5137. {
  5138. BF_ASSERT(!retBlock.IsFake());
  5139. mActualInsertBlock = retBlock;
  5140. }
  5141. mInsertBlock = retBlock;
  5142. }
  5143. void BfIRBuilder::DbgInit()
  5144. {
  5145. mHasDebugInfo = true;
  5146. mHasDebugLineInfo = true;
  5147. WriteCmd(BfIRCmd_DbgInit);
  5148. NEW_CMD_INSERTED;
  5149. }
  5150. void BfIRBuilder::DbgFinalize()
  5151. {
  5152. while ((!mDeferredDbgTypeDefs.IsEmpty()) || (!mDITemporaryTypes.IsEmpty()))
  5153. {
  5154. //for (auto deferredType : mDeferredDbgTypeDefs)
  5155. for (int i = 0; i < (int)mDeferredDbgTypeDefs.size(); i++)
  5156. CreateDbgTypeDefinition(mDeferredDbgTypeDefs[i]);
  5157. mDeferredDbgTypeDefs.Clear();
  5158. ReplaceDITemporaryTypes();
  5159. }
  5160. WriteCmd(BfIRCmd_DbgFinalize);
  5161. NEW_CMD_INSERTED;
  5162. }
  5163. bool BfIRBuilder::DbgHasInfo()
  5164. {
  5165. return mHasDebugInfo;
  5166. }
  5167. bool BfIRBuilder::DbgHasLineInfo()
  5168. {
  5169. return mHasDebugLineInfo;
  5170. }
  5171. String BfIRBuilder::DbgGetStaticFieldName(BfFieldInstance* fieldInstance)
  5172. {
  5173. String fieldName;
  5174. auto fieldDef = fieldInstance->GetFieldDef();
  5175. auto typeInstance = fieldInstance->mOwner;
  5176. auto typeDef = typeInstance->mTypeDef;
  5177. if (mModule->mCompiler->mOptions.IsCodeView())
  5178. {
  5179. fieldName += "_bf";
  5180. for (int partIdx = 0; partIdx < typeInstance->mTypeDef->mNamespace.GetPartsCount(); partIdx++)
  5181. {
  5182. auto atom = typeInstance->mTypeDef->mNamespace.mParts[partIdx];
  5183. if (!fieldName.empty())
  5184. fieldName += "::";
  5185. fieldName += atom->ToString();
  5186. }
  5187. if (!fieldName.empty())
  5188. fieldName += "::";
  5189. fieldName += GetDebugTypeName(typeInstance, true);
  5190. fieldName += "::";
  5191. fieldName += fieldDef->mName;
  5192. }
  5193. else
  5194. {
  5195. fieldName += fieldDef->mName;
  5196. }
  5197. return fieldName;
  5198. }
  5199. void BfIRBuilder::DbgAddPrefix(String & name)
  5200. {
  5201. if (mModule->mCompiler->mOptions.IsCodeView())
  5202. name.Insert(0, "bf__");
  5203. }
  5204. BfIRMDNode BfIRBuilder::DbgCreateCompileUnit(int lang, const StringImpl& fileName, const StringImpl& directory, const StringImpl& producer, bool isOptimized, const StringImpl& flags, int runtimeVer, bool linesOnly)
  5205. {
  5206. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateCompileUnit, lang, fileName, directory, producer, isOptimized, flags, runtimeVer, linesOnly);
  5207. NEW_CMD_INSERTED_IRMD;
  5208. return retVal;
  5209. }
  5210. BfIRMDNode BfIRBuilder::DbgCreateFile(const StringImpl& fileName, const StringImpl& directory, const Val128& md5Hash)
  5211. {
  5212. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateFile, fileName, directory, md5Hash);
  5213. NEW_CMD_INSERTED_IRMD;
  5214. if (mDbgVerifyCodeGen && gDebugDbgLoc)
  5215. {
  5216. OutputDebugStrF("DbgCreateFile %s %d\n", fileName.c_str(), retVal.mId);
  5217. }
  5218. return retVal;
  5219. }
  5220. BfIRMDNode BfIRBuilder::DbgGetCurrentLocation()
  5221. {
  5222. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgGetCurrentLocation);
  5223. NEW_CMD_INSERTED_IRMD;
  5224. return retVal;
  5225. }
  5226. void BfIRBuilder::DbgSetType(BfType* type, BfIRMDNode diType)
  5227. {
  5228. WriteCmd(BfIRCmd_DbgSetType, type->mTypeId, diType);
  5229. NEW_CMD_INSERTED;
  5230. }
  5231. void BfIRBuilder::DbgSetInstType(BfType* type, BfIRMDNode diType)
  5232. {
  5233. WriteCmd(BfIRCmd_DbgSetInstType, type->mTypeId, diType);
  5234. NEW_CMD_INSERTED;
  5235. }
  5236. BfIRMDNode BfIRBuilder::DbgCreateConstValue(int64 val)
  5237. {
  5238. auto retVal = WriteCmd(BfIRCmd_ConstValueI64, val);
  5239. NEW_CMD_INSERTED;
  5240. return retVal;
  5241. }
  5242. BfIRMDNode BfIRBuilder::DbgGetType(BfType* type, BfIRPopulateType populateType)
  5243. {
  5244. if (mIgnoreWrites)
  5245. return BfIRMDNode();
  5246. PopulateType(type, populateType);
  5247. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgGetType, type->mTypeId);
  5248. NEW_CMD_INSERTED_IRMD;
  5249. return retVal;
  5250. }
  5251. BfIRMDNode BfIRBuilder::DbgGetTypeInst(BfTypeInstance* typeInst, BfIRPopulateType populateType)
  5252. {
  5253. if (mIgnoreWrites)
  5254. return BfIRMDNode();
  5255. PopulateType(typeInst, populateType);
  5256. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgGetTypeInst, typeInst->mTypeId);
  5257. NEW_CMD_INSERTED_IRMD;
  5258. return retVal;
  5259. }
  5260. void BfIRBuilder::DbgTrackDITypes(BfType* type)
  5261. {
  5262. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgTrackDITypes, type->mTypeId);
  5263. NEW_CMD_INSERTED;
  5264. }
  5265. BfIRMDNode BfIRBuilder::DbgCreateNameSpace(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNum)
  5266. {
  5267. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateNamespace, scope, name, file, lineNum);
  5268. NEW_CMD_INSERTED_IRMD;
  5269. return retVal;
  5270. }
  5271. BfIRMDNode BfIRBuilder::DbgCreateImportedModule(BfIRMDNode context, BfIRMDNode namespaceNode, int line)
  5272. {
  5273. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateImportedModule, context, namespaceNode, line);
  5274. NEW_CMD_INSERTED_IRMD;
  5275. return retVal;
  5276. }
  5277. BfIRMDNode BfIRBuilder::DbgCreateBasicType(const StringImpl& name, int64 sizeInBits, int64 alignInBits, int encoding)
  5278. {
  5279. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateBasicType, name, (int32)sizeInBits, (int32)alignInBits, encoding);
  5280. NEW_CMD_INSERTED_IRMD;
  5281. return retVal;
  5282. }
  5283. BfIRMDNode BfIRBuilder::DbgCreateStructType(BfIRMDNode context, const StringImpl& name, BfIRMDNode file, int lineNum, int64 sizeInBits, int64 alignInBits, int flags, BfIRMDNode derivedFrom, const BfSizedArray<BfIRMDNode>& elements)
  5284. {
  5285. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateStructType, context, name, file, lineNum, (int32)sizeInBits, (int32)alignInBits, flags, derivedFrom, elements);
  5286. NEW_CMD_INSERTED_IRMD;
  5287. return retVal;
  5288. }
  5289. BfIRMDNode BfIRBuilder::DbgCreateEnumerationType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 sizeInBits, int64 alignInBits, const BfSizedArray<BfIRMDNode>& elements, BfIRMDNode underlyingType)
  5290. {
  5291. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateEnumerationType, scope, name, file, lineNumber, (int32)sizeInBits, (int32)alignInBits, elements, underlyingType);
  5292. NEW_CMD_INSERTED_IRMD;
  5293. return retVal;
  5294. }
  5295. BfIRMDNode BfIRBuilder::DbgCreatePointerType(BfIRMDNode diType)
  5296. {
  5297. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreatePointerType, diType);
  5298. NEW_CMD_INSERTED_IRMD;
  5299. return retVal;
  5300. }
  5301. BfIRMDNode BfIRBuilder::DbgCreateReferenceType(BfIRMDNode diType)
  5302. {
  5303. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateReferenceType, diType);
  5304. NEW_CMD_INSERTED_IRMD;
  5305. return retVal;
  5306. }
  5307. BfIRMDNode BfIRBuilder::DbgCreateConstType(BfIRMDNode diType)
  5308. {
  5309. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateConstType, diType);
  5310. NEW_CMD_INSERTED_IRMD;
  5311. return retVal;
  5312. }
  5313. BfIRMDNode BfIRBuilder::DbgCreateArtificialType(BfIRMDNode diType)
  5314. {
  5315. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateArtificialType, diType);
  5316. NEW_CMD_INSERTED_IRMD;
  5317. return retVal;
  5318. }
  5319. BfIRMDNode BfIRBuilder::DbgCreateArrayType(int64 sizeInBits, int64 alignInBits, BfIRMDNode elementType, int64 numElements)
  5320. {
  5321. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateArrayType, sizeInBits, alignInBits, elementType, numElements);
  5322. NEW_CMD_INSERTED_IRMD;
  5323. return retVal;
  5324. }
  5325. BfIRMDNode BfIRBuilder::DbgCreateReplaceableCompositeType(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode file, int line, int64 sizeInBits, int64 alignInBits, int flags)
  5326. {
  5327. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateReplaceableCompositeType, tag, name, scope, file, line, (int32)sizeInBits, (int32)alignInBits, flags);
  5328. NEW_CMD_INSERTED_IRMD;
  5329. return retVal;
  5330. }
  5331. void BfIRBuilder::DbgSetTypeSize(BfIRMDNode diType, int64 sizeInBits, int alignInBits)
  5332. {
  5333. BF_ASSERT(diType);
  5334. BfIRMDNode retVal = WriteCmd(BeIRCmd_DbgSetTypeSize, diType, sizeInBits, alignInBits);
  5335. NEW_CMD_INSERTED_IRMD;
  5336. }
  5337. BfIRMDNode BfIRBuilder::DbgCreateForwardDecl(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode file, int line)
  5338. {
  5339. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateForwardDecl, tag, name, scope, file, line);
  5340. NEW_CMD_INSERTED_IRMD;
  5341. return retVal;
  5342. }
  5343. BfIRMDNode BfIRBuilder::DbgCreateSizedForwardDecl(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode file, int line, int64 sizeInBits, int64 alignInBits)
  5344. {
  5345. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateSizedForwardDecl, tag, name, scope, file, line, (int32)sizeInBits, (int32)alignInBits);
  5346. NEW_CMD_INSERTED_IRMD;
  5347. return retVal;
  5348. }
  5349. BfIRMDNode BfIRBuilder::DbgReplaceAllUses(BfIRMDNode diPrevNode, BfIRMDNode diNewNode)
  5350. {
  5351. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgReplaceAllUses, diPrevNode, diNewNode);
  5352. NEW_CMD_INSERTED;
  5353. return retVal;
  5354. }
  5355. void BfIRBuilder::DbgDeleteTemporary(BfIRMDNode diNode)
  5356. {
  5357. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgDeleteTemporary, diNode);
  5358. NEW_CMD_INSERTED;
  5359. }
  5360. BfIRMDNode BfIRBuilder::DbgMakePermanent(BfIRMDNode diNode, BfIRMDNode diBaseType, const BfSizedArray<BfIRMDNode>& elements)
  5361. {
  5362. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgMakePermanent, diNode, diBaseType, elements);
  5363. NEW_CMD_INSERTED;
  5364. return retVal;
  5365. }
  5366. BfIRMDNode BfIRBuilder::DbgCreateEnumerator(const StringImpl& name, int64 val)
  5367. {
  5368. BfIRMDNode retVal = WriteCmd(BfIRCmd_CreateEnumerator, name, val);
  5369. NEW_CMD_INSERTED;
  5370. return retVal;
  5371. }
  5372. BfIRMDNode BfIRBuilder::DbgCreateMemberType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 sizeInBits, int64 alignInBits, int64 offsetInBits, int flags, BfIRMDNode type)
  5373. {
  5374. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateMemberType, scope, name, file, lineNumber, (int32)sizeInBits, (int32)alignInBits, (int32)offsetInBits, flags, type);
  5375. NEW_CMD_INSERTED_IRMD;
  5376. return retVal;
  5377. }
  5378. BfIRMDNode BfIRBuilder::DbgCreateStaticMemberType(BfIRMDNode scope, const StringImpl&name, BfIRMDNode file, int lineNumber, BfIRMDNode type, int flags, BfIRValue val)
  5379. {
  5380. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgStaticCreateMemberType, scope, name, file, lineNumber, type, flags, val);
  5381. NEW_CMD_INSERTED_IRMD;
  5382. return retVal;
  5383. }
  5384. BfIRMDNode BfIRBuilder::DbgCreateInheritance(BfIRMDNode type, BfIRMDNode baseType, int64 baseOffset, int flags)
  5385. {
  5386. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateInheritance, type, baseType, (int32)baseOffset, flags);
  5387. NEW_CMD_INSERTED_IRMD;
  5388. return retVal;
  5389. }
  5390. BfIRMDNode BfIRBuilder::DbgCreateMethod(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNum, BfIRMDNode type, bool isLocalToUnit, bool isDefinition, int vk, int vIndex, BfIRMDNode vTableHolder, int flags,
  5391. bool isOptimized, BfIRValue fn, const BfSizedArray<BfIRMDNode>& genericArgs, const BfSizedArray<BfIRValue>& genericConstValueArgs)
  5392. {
  5393. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateMethod, context, name, linkageName, file, lineNum, type, isLocalToUnit, isDefinition, vk, vIndex, vTableHolder, flags, isOptimized, fn, genericArgs, genericConstValueArgs);
  5394. NEW_CMD_INSERTED_IRMD;
  5395. // if (mDbgVerifyCodeGen && gDebugDbgLoc)
  5396. // {
  5397. // OutputDebugStrF("DbgCreateFunction Context:%d name:%s = %d\n", context.mId, name.c_str(), retVal.mId);
  5398. // }
  5399. return retVal;
  5400. }
  5401. BfIRMDNode BfIRBuilder::DbgCreateFunction(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNum, BfIRMDNode type, bool isLocalToUnit, bool isDefinition, int scopeLine, int flags, bool isOptimized, BfIRValue fn)
  5402. {
  5403. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateFunction, context, name, linkageName, file, lineNum, type, isLocalToUnit, isDefinition, scopeLine, flags, isOptimized, fn);
  5404. NEW_CMD_INSERTED_IRMD;
  5405. // if (mDbgVerifyCodeGen && gDebugDbgLoc)
  5406. // {
  5407. // OutputDebugStrF("DbgCreateFunction Context:%d name:%s = %d\n", context.mId, name.c_str(), retVal.mId);
  5408. // }
  5409. return retVal;
  5410. }
  5411. BfIRMDNode BfIRBuilder::DbgCreateParameterVariable(BfIRMDNode scope, const StringImpl& name, int argNo, BfIRMDNode file, int lineNum, BfIRMDNode type, bool alwaysPreserve, int flags)
  5412. {
  5413. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateParameterVariable, scope, name, argNo, file, lineNum, type, alwaysPreserve, flags);
  5414. NEW_CMD_INSERTED_IRMD;
  5415. return retVal;
  5416. }
  5417. BfIRMDNode BfIRBuilder::DbgCreateSubroutineType(BfMethodInstance* methodInstance)
  5418. {
  5419. auto methodDef = methodInstance->mMethodDef;
  5420. auto typeInstance = methodInstance->GetOwner();
  5421. SizedArray<BfIRMDNode, 32> diParams;
  5422. diParams.push_back(DbgGetType(methodInstance->mReturnType));
  5423. BfType* thisType = NULL;
  5424. if (!methodDef->mIsStatic)
  5425. {
  5426. BfType* thisType;
  5427. thisType = typeInstance;
  5428. if (!thisType->IsValuelessType())
  5429. {
  5430. BfType* thisPtrType = thisType;
  5431. auto diType = DbgGetType(thisPtrType);
  5432. if ((thisType->IsComposite()) && (!methodInstance->GetParamIsSplat(-1)))
  5433. {
  5434. diType = DbgCreatePointerType(diType);
  5435. diType = DbgCreateArtificialType(diType);
  5436. }
  5437. diParams.push_back(diType);
  5438. }
  5439. }
  5440. for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
  5441. {
  5442. bool isParamSkipped = methodInstance->IsParamSkipped(paramIdx);
  5443. if (!isParamSkipped)
  5444. {
  5445. auto resolvedType = methodInstance->GetParamType(paramIdx);
  5446. diParams.push_back(DbgGetType(resolvedType));
  5447. }
  5448. }
  5449. return DbgCreateSubroutineType(diParams);
  5450. }
  5451. BfIRMDNode BfIRBuilder::DbgCreateSubroutineType(const BfSizedArray<BfIRMDNode>& elements)
  5452. {
  5453. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateSubroutineType, elements);
  5454. NEW_CMD_INSERTED_IRMD;
  5455. return retVal;
  5456. }
  5457. BfIRMDNode BfIRBuilder::DbgCreateAutoVariable(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNo, BfIRMDNode type, BfIRInitType initType)
  5458. {
  5459. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateAutoVariable, scope, name, file, lineNo, type, (int)initType);
  5460. NEW_CMD_INSERTED_IRMD;
  5461. return retVal;
  5462. }
  5463. BfIRValue BfIRBuilder::DbgInsertValueIntrinsic(BfIRValue val, BfIRMDNode varInfo)
  5464. {
  5465. BfIRValue retVal = WriteCmd(BfIRCmd_DbgInsertValueIntrinsic, val, varInfo);
  5466. NEW_CMD_INSERTED;
  5467. return retVal;
  5468. }
  5469. BfIRValue BfIRBuilder::DbgInsertDeclare(BfIRValue val, BfIRMDNode varInfo, BfIRValue declareBefore)
  5470. {
  5471. BfIRValue retVal = WriteCmd(BfIRCmd_DbgInsertDeclare, val, varInfo, declareBefore);
  5472. NEW_CMD_INSERTED_IRVALUE;
  5473. return retVal;
  5474. }
  5475. BfIRValue BfIRBuilder::DbgLifetimeEnd(BfIRMDNode varInfo)
  5476. {
  5477. BfIRValue retVal = WriteCmd(BfIRCmd_DbgLifetimeEnd, varInfo);
  5478. NEW_CMD_INSERTED_IRVALUE;
  5479. return retVal;
  5480. }
  5481. void BfIRBuilder::DbgCreateGlobalVariable(BfIRMDNode context, const StringImpl& name, const StringImpl& linkageName, BfIRMDNode file, int lineNumber, BfIRMDNode type, bool isLocalToUnit, BfIRValue val, BfIRMDNode decl)
  5482. {
  5483. WriteCmd(BfIRCmd_DbgCreateGlobalVariable, context, name, linkageName, file, lineNumber, type, isLocalToUnit, val, decl);
  5484. NEW_CMD_INSERTED;
  5485. }
  5486. BfIRMDNode BfIRBuilder::DbgCreateLexicalBlock(BfIRMDNode scope, BfIRMDNode file, int line, int col)
  5487. {
  5488. BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateLexicalBlock, scope, file, line, col);
  5489. NEW_CMD_INSERTED;
  5490. if (mDbgVerifyCodeGen && gDebugDbgLoc)
  5491. {
  5492. OutputDebugStrF("DbgCreateLexicalBlock Scope:%d File:%d = %d\n", scope.mId, file.mId, retVal.mId);
  5493. }
  5494. return retVal;
  5495. }
  5496. void BfIRBuilder::DbgCreateAnnotation(BfIRMDNode scope, const StringImpl& name, BfIRValue value)
  5497. {
  5498. WriteCmd(BfIRCmd_DbgCreateAnnotation, scope, name, value);
  5499. NEW_CMD_INSERTED;
  5500. }
  5501. BfIRState BfIRBuilder::GetState()
  5502. {
  5503. BfIRState state;
  5504. state.mActualInsertBlock = mActualInsertBlock;
  5505. state.mInsertBlock = mInsertBlock;
  5506. state.mActiveFunction = mActiveFunction;
  5507. state.mActiveFunctionHasBody = mActiveFunctionHasBody;
  5508. state.mSavedDebugLocs = mSavedDebugLocs;
  5509. return state;
  5510. }
  5511. void BfIRBuilder::SetState(const BfIRState& state)
  5512. {
  5513. mActualInsertBlock = state.mActualInsertBlock;
  5514. mInsertBlock = state.mInsertBlock;
  5515. mActiveFunction = state.mActiveFunction;
  5516. mActiveFunctionHasBody = state.mActiveFunctionHasBody;
  5517. mSavedDebugLocs = state.mSavedDebugLocs;
  5518. }