BfIRCodeGen.cpp 160 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161
  1. #include "BfIRCodeGen.h"
  2. #include "BfModule.h"
  3. #include "BeefySysLib/util/BeefPerf.h"
  4. #include "BeefySysLib/util/Hash.h"
  5. #ifdef BF_PLATFORM_WINDOWS
  6. #include <io.h>
  7. #endif
  8. #pragma warning(push)
  9. #pragma warning(disable:4141)
  10. #pragma warning(disable:4146)
  11. #pragma warning(disable:4291)
  12. #pragma warning(disable:4244)
  13. #pragma warning(disable:4267)
  14. #pragma warning(disable:4624)
  15. #pragma warning(disable:4800)
  16. #pragma warning(disable:4996)
  17. #include "llvm/IR/Module.h"
  18. #include "llvm/IR/Constants.h"
  19. #include "llvm/IR/GlobalValue.h"
  20. #include "llvm/IR/GlobalVariable.h"
  21. #include "llvm/ADT/ArrayRef.h"
  22. #include "llvm/IR/InlineAsm.h"
  23. #include "llvm/IR/Attributes.h"
  24. #include "llvm/Support/FileSystem.h"
  25. //#include "llvm/Support/Dwarf.h"
  26. #include "llvm/IR/DIBuilder.h"
  27. #include "llvm/ADT/Triple.h"
  28. //#include "llvm/CodeGen/CommandFlags.h"
  29. #include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
  30. #include "llvm/CodeGen/LinkAllCodegenComponents.h"
  31. #include "llvm/IR/DataLayout.h"
  32. #include "llvm/IR/IRPrintingPasses.h"
  33. #include "llvm/IR/LLVMContext.h"
  34. #include "llvm/IR/Module.h"
  35. #include "llvm/IRReader/IRReader.h"
  36. #include "llvm/MC/SubtargetFeature.h"
  37. #include "llvm/MC/MCObjectWriter.h"
  38. #include "llvm/Pass.h"
  39. #include "llvm/Transforms/IPO/PassManagerBuilder.h"
  40. #include "llvm/Transforms/Utils.h"
  41. #include "llvm/Transforms/Scalar/InstSimplifyPass.h"
  42. #include "llvm/IR/LegacyPassManager.h"
  43. #include "llvm/Support/CommandLine.h"
  44. #include "llvm/Support/Debug.h"
  45. #include "llvm/Support/FileSystem.h"
  46. #include "llvm/Support/FormattedStream.h"
  47. #include "llvm/Support/Host.h"
  48. #include "llvm/Support/ManagedStatic.h"
  49. #include "llvm/Support/PluginLoader.h"
  50. #include "llvm/Support/PrettyStackTrace.h"
  51. #include "llvm/Support/Signals.h"
  52. #include "llvm/Support/SourceMgr.h"
  53. #include "llvm/Support/TargetRegistry.h"
  54. #include "llvm/Support/TargetSelect.h"
  55. #include "llvm/Support/ToolOutputFile.h"
  56. //#include "llvm/Target/TargetLibraryInfo.h"
  57. #include "llvm/Target/TargetMachine.h"
  58. //#include "llvm/Target/TargetSubtargetInfo.h"
  59. #include "llvm/Transforms/IPO/PassManagerBuilder.h"
  60. #include "llvm-c/Transforms/PassManagerBuilder.h"
  61. #include "llvm/ADT/SmallVector.h"
  62. #include "llvm/Analysis/Passes.h"
  63. #include "llvm/IR/DataLayout.h"
  64. #include "llvm/IR/Verifier.h"
  65. #include "llvm/IR/LegacyPassManager.h"
  66. #include "llvm/Support/CommandLine.h"
  67. #include "llvm/Support/ManagedStatic.h"
  68. #include "llvm/Analysis/BasicAliasAnalysis.h"
  69. //#include "llvm/Analysis/CFLAliasAnalysis.h"
  70. #include "llvm/Analysis/CFLAndersAliasAnalysis.h"
  71. #include "llvm/Analysis/CFLSteensAliasAnalysis.h"
  72. #include "llvm/Analysis/GlobalsModRef.h"
  73. #include "llvm/Analysis/ScopedNoAliasAA.h"
  74. #include "llvm/Analysis/TargetLibraryInfo.h"
  75. #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
  76. #include "llvm/Target/TargetMachine.h"
  77. #include "llvm/Transforms/IPO.h"
  78. #include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
  79. #include "llvm/Transforms/IPO/FunctionAttrs.h"
  80. #include "llvm/Transforms/IPO/InferFunctionAttrs.h"
  81. #include "llvm/Transforms/IPO/AlwaysInliner.h"
  82. #include "llvm/Transforms/Instrumentation.h"
  83. #include "llvm/Transforms/Scalar.h"
  84. #include "llvm/Transforms/Scalar/GVN.h"
  85. #include "llvm/Transforms/Vectorize.h"
  86. #include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"
  87. #include "llvm/Transforms/InstCombine/InstCombine.h"
  88. #include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h"
  89. //#include "llvm/Bitcode/ReaderWriter.h"
  90. #include "llvm/Analysis/Passes.h"
  91. #include "llvm/Transforms/IPO.h"
  92. #include "llvm/Transforms/Scalar.h"
  93. #include "llvm/Transforms/Vectorize.h"
  94. #include "llvm/Pass.h"
  95. #include "llvm/CodeGen/MachineFunctionPass.h"
  96. #include "llvm/Support/raw_ostream.h"
  97. #include "llvm/MC/MCAsmBackend.h"
  98. #include "llvm/MC/MCCodeEmitter.h"
  99. #include "llvm/Support/TargetRegistry.h"
  100. #include "llvm/LTO/LTOBackend.h"
  101. #include "llvm/Bitcode/BitcodeWriter.h"
  102. #include "llvm/Bitcode/BitcodeReader.h"
  103. #include "llvm/Bitcode/BitcodeWriterPass.h"
  104. #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
  105. #include "llvm/Transforms/IPO/AlwaysInliner.h"
  106. #include "llvm/Transforms/IPO.h"
  107. #include "../LLVMUtils.h"
  108. #pragma warning(pop)
  109. USING_NS_BF;
  110. #pragma warning(disable:4146)
  111. #pragma warning(disable:4996)
  112. struct BuiltinEntry
  113. {
  114. const char* mName;
  115. bool operator<(const StringImpl& rhs) const
  116. {
  117. return strcmp(mName, rhs.c_str()) < 0;
  118. }
  119. };
  120. static const BuiltinEntry gIntrinEntries[] =
  121. {
  122. {":PLATFORM"},
  123. {"abs"},
  124. {"add"},
  125. {"and"},
  126. {"atomic_add"},
  127. {"atomic_and"},
  128. {"atomic_cmpstore"},
  129. {"atomic_cmpstore_weak"},
  130. {"atomic_cmpxchg"},
  131. {"atomic_fence"},
  132. {"atomic_load"},
  133. {"atomic_max"},
  134. {"atomic_min"},
  135. {"atomic_nand"},
  136. {"atomic_or"},
  137. {"atomic_store"},
  138. {"atomic_sub"},
  139. {"atomic_umax"},
  140. {"atomic_umin"},
  141. {"atomic_xchg"},
  142. {"atomic_xor"},
  143. {"bswap"},
  144. {"cast"},
  145. {"cos"},
  146. {"debugtrap"},
  147. {"div"},
  148. {"eq"},
  149. {"floor"},
  150. {"free"},
  151. {"gt"},
  152. {"gte"},
  153. ("index"),
  154. {"log"},
  155. {"log10"},
  156. {"log2"},
  157. {"lt"},
  158. {"lte"},
  159. {"malloc"},
  160. {"memcpy"},
  161. {"memmove"},
  162. {"memset"},
  163. {"mod"},
  164. {"mul"},
  165. {"neq"},
  166. {"not"},
  167. {"or"},
  168. {"pow"},
  169. {"powi"},
  170. {"round"},
  171. {"sar"},
  172. {"shl"},
  173. {"shr"},
  174. {"shuffle"},
  175. {"sin"},
  176. {"sqrt"},
  177. {"sub"},
  178. {"xor"},
  179. };
  180. #define CMD_PARAM(ty, name) ty name; Read(name);
  181. BF_STATIC_ASSERT(BF_ARRAY_COUNT(gIntrinEntries) == BfIRIntrinsic_COUNT);
  182. template <typename T>
  183. class CmdParamVec : public llvm::SmallVector<T, 8>
  184. {};
  185. static int GetLLVMCallingConv(BfIRCallingConv callingConv)
  186. {
  187. int llvmCallingConv = llvm::CallingConv::C;
  188. if (callingConv == BfIRCallingConv_ThisCall)
  189. llvmCallingConv = llvm::CallingConv::X86_ThisCall;
  190. else if (callingConv == BfIRCallingConv_StdCall)
  191. llvmCallingConv = llvm::CallingConv::X86_StdCall;
  192. else if (callingConv == BfIRCallingConv_FastCall)
  193. llvmCallingConv = llvm::CallingConv::X86_FastCall;
  194. else if (callingConv == BfIRCallingConv_CDecl)
  195. llvmCallingConv = llvm::CallingConv::C;
  196. return llvmCallingConv;
  197. }
  198. static llvm::GlobalValue::LinkageTypes LLVMMapLinkageType(BfIRLinkageType linkageType)
  199. {
  200. llvm::GlobalValue::LinkageTypes llvmLinkageType;
  201. if (linkageType == BfIRLinkageType_Internal)
  202. llvmLinkageType = llvm::GlobalValue::InternalLinkage;
  203. else
  204. llvmLinkageType = llvm::GlobalValue::ExternalLinkage;
  205. return llvmLinkageType;
  206. }
  207. static llvm::Attribute::AttrKind LLVMMapAttribute(BfIRAttribute attr)
  208. {
  209. switch (attr)
  210. {
  211. case BfIRAttribute_NoReturn: return llvm::Attribute::NoReturn;
  212. case BfIRAttribute_NoAlias: return llvm::Attribute::NoAlias;
  213. case BfIRAttribute_NoCapture: return llvm::Attribute::NoCapture;
  214. case BfIRAttribute_StructRet: return llvm::Attribute::StructRet;
  215. case BfIRAttribute_ZExt: return llvm::Attribute::ZExt;
  216. case BFIRAttribute_NoUnwind: return llvm::Attribute::NoUnwind;
  217. case BFIRAttribute_UWTable: return llvm::Attribute::UWTable;
  218. case BFIRAttribute_AlwaysInline: return llvm::Attribute::AlwaysInline;
  219. case BFIRAttribute_NoRecurse: return llvm::Attribute::NoRecurse;
  220. default: break;
  221. }
  222. return llvm::Attribute::None;
  223. }
  224. #ifdef BF_PLATFORM_WINDOWS
  225. struct BfTempFile
  226. {
  227. String mContents;
  228. String mFilePath;
  229. CritSect mCritSect;
  230. FILE* mFP;
  231. BfTempFile()
  232. {
  233. mFP = NULL;
  234. }
  235. ~BfTempFile()
  236. {
  237. if (mFP != NULL)
  238. fclose(mFP);
  239. if (!mFilePath.IsEmpty())
  240. ::DeleteFileW(UTF8Decode(mFilePath).c_str());
  241. }
  242. bool Create()
  243. {
  244. AutoCrit autoCrit(mCritSect);
  245. if (mFP != NULL)
  246. return false;
  247. WCHAR wPath[4096];
  248. wPath[0] = 0;
  249. ::GetTempPathW(4096, wPath);
  250. WCHAR wFilePath[4096];
  251. wFilePath[0] = 0;
  252. GetTempFileNameW(wPath, L"bftmp", 0, wFilePath);
  253. mFilePath = UTF8Encode(wFilePath);
  254. mFP = _wfopen(wFilePath, L"w+D");
  255. return mFP != NULL;
  256. }
  257. String GetContents()
  258. {
  259. AutoCrit autoCrit(mCritSect);
  260. if (mFP != NULL)
  261. {
  262. fseek(mFP, 0, SEEK_END);
  263. int size = (int)ftell(mFP);
  264. fseek(mFP, 0, SEEK_SET);
  265. char* str = new char[size];
  266. int readSize = (int)fread(str, 1, size, mFP);
  267. mContents.Append(str, readSize);
  268. delete [] str;
  269. fclose(mFP);
  270. mFP = NULL;
  271. ::DeleteFileW(UTF8Decode(mFilePath).c_str());
  272. }
  273. return mContents;
  274. }
  275. };
  276. static BfTempFile gTempFile;
  277. static void AddStdErrCrashInfo()
  278. {
  279. String tempContents = gTempFile.GetContents();
  280. if (!tempContents.IsEmpty())
  281. BfpSystem_AddCrashInfo(tempContents.c_str());
  282. }
  283. #endif
  284. ///
  285. BfIRCodeGen::BfIRCodeGen()
  286. {
  287. mStream = NULL;
  288. mBfIRBuilder = NULL;
  289. mLLVMTargetMachine = NULL;
  290. mNopInlineAsm = NULL;
  291. mAsmObjectCheckAsm = NULL;
  292. mHasDebugLoc = false;
  293. mAttrSet = NULL;
  294. mIRBuilder = NULL;
  295. mDIBuilder = NULL;
  296. mDICompileUnit = NULL;
  297. mActiveFunction = NULL;
  298. mLLVMContext = new llvm::LLVMContext();
  299. mLLVMModule = NULL;
  300. mIsCodeView = false;
  301. mConstValIdx = 0;
  302. mCmdCount = 0;
  303. #ifdef BF_PLATFORM_WINDOWS
  304. if (::GetStdHandle(STD_ERROR_HANDLE) == 0)
  305. {
  306. if (gTempFile.Create())
  307. {
  308. _dup2(fileno(gTempFile.mFP), 2);
  309. BfpSystem_AddCrashInfoFunc(AddStdErrCrashInfo);
  310. }
  311. }
  312. #endif
  313. }
  314. BfIRCodeGen::~BfIRCodeGen()
  315. {
  316. mDebugLoc = llvm::DebugLoc();
  317. mSavedDebugLocs.Clear();
  318. delete mStream;
  319. delete mIRBuilder;
  320. delete mDIBuilder;
  321. delete mLLVMTargetMachine;
  322. delete mLLVMModule;
  323. delete mLLVMContext;
  324. }
  325. void BfIRCodeGen::FatalError(const StringImpl &err)
  326. {
  327. String failStr = "Fatal Error in Module: ";
  328. failStr += mModuleName;
  329. failStr += "\n";
  330. if (mLLVMModule != NULL)
  331. {
  332. if (mActiveFunction != NULL)
  333. {
  334. failStr += "Function: ";
  335. failStr += mActiveFunction->getName().str();
  336. failStr += "\n";
  337. }
  338. auto loc = mIRBuilder->getCurrentDebugLocation();
  339. auto dbgLoc = loc.getAsMDNode();
  340. if (dbgLoc != NULL)
  341. {
  342. std::string str;
  343. llvm::raw_string_ostream os(str);
  344. dbgLoc->print(os);
  345. failStr += "DbgLoc: ";
  346. failStr += str;
  347. failStr += "\n";
  348. llvm::MDNode* scope = loc.getScope();
  349. if (scope != NULL)
  350. {
  351. std::string str;
  352. llvm::raw_string_ostream os(str);
  353. scope->print(os);
  354. failStr += "Scope: ";
  355. failStr += str;
  356. failStr += "\n";
  357. }
  358. }
  359. }
  360. failStr += err;
  361. BF_FATAL(failStr);
  362. }
  363. void BfIRCodeGen::Fail(const StringImpl& error)
  364. {
  365. if (mFailed)
  366. return;
  367. if (mHasDebugLoc)
  368. {
  369. auto dbgLoc = mIRBuilder->getCurrentDebugLocation();
  370. if (dbgLoc)
  371. {
  372. llvm::DIFile* file = NULL;
  373. if (llvm::DIScope* scope = llvm::dyn_cast<llvm::DIScope>(dbgLoc.getScope()))
  374. {
  375. BfIRCodeGenBase::Fail(StrFormat("%s at line %d:%d in %s/%s", error.c_str(), dbgLoc.getLine(), dbgLoc.getCol(), scope->getDirectory().data(), scope->getFilename().data()));
  376. return;
  377. }
  378. }
  379. }
  380. BfIRCodeGenBase::Fail(error);
  381. }
  382. void BfIRCodeGen::PrintModule()
  383. {
  384. Beefy::debug_ostream os;
  385. mLLVMModule->print(os, NULL, false, true);
  386. os << "\n";
  387. os.flush();
  388. }
  389. void BfIRCodeGen::PrintFunction()
  390. {
  391. Beefy::debug_ostream os;
  392. mActiveFunction->print(os);
  393. os << "\n";
  394. os.flush();
  395. }
  396. void BfIRCodeGen::FixValues(llvm::StructType* structType, llvm::SmallVector<llvm::Value*, 8>& values)
  397. {
  398. if (values.size() >= structType->getNumElements())
  399. return;
  400. int readIdx = (int)values.size() - 1;
  401. values.resize(structType->getNumElements());
  402. for (int i = (int)values.size() - 1; i >= 0; i--)
  403. {
  404. if (values[readIdx]->getType() == structType->getElementType(i))
  405. {
  406. values[i] = values[readIdx];
  407. readIdx--;
  408. }
  409. else if (structType->getElementType(i)->isArrayTy())
  410. {
  411. values[i] = llvm::ConstantAggregateZero::get(structType->getElementType(i));
  412. }
  413. else
  414. {
  415. BF_FATAL("Malformed structure values");
  416. }
  417. }
  418. }
  419. BfTypeCode BfIRCodeGen::GetTypeCode(llvm::Type* type, bool isSigned)
  420. {
  421. if (type->isIntegerTy())
  422. {
  423. switch (type->getIntegerBitWidth())
  424. {
  425. case 1:
  426. return BfTypeCode_Boolean;
  427. case 8:
  428. return isSigned ? BfTypeCode_Int8 : BfTypeCode_UInt8;
  429. case 16:
  430. return isSigned ? BfTypeCode_Int16 : BfTypeCode_UInt16;
  431. case 32:
  432. return isSigned ? BfTypeCode_Int32 : BfTypeCode_UInt32;
  433. case 64:
  434. return isSigned ? BfTypeCode_Int64 : BfTypeCode_UInt64;
  435. }
  436. }
  437. if (type->isFloatingPointTy())
  438. return BfTypeCode_Float;
  439. if (type->isDoubleTy())
  440. return BfTypeCode_Double;
  441. return BfTypeCode_None;
  442. }
  443. llvm::Type* BfIRCodeGen::GetLLVMType(BfTypeCode typeCode, bool& isSigned)
  444. {
  445. if ((typeCode == BfTypeCode_IntPtr) || (typeCode == BfTypeCode_UIntPtr))
  446. {
  447. /*isSigned = typeCode == BfTypeCode_IntPtr;
  448. if (mModule->mSystem->mPtrSize == 4)
  449. return llvm::Type::getInt32Ty(*mLLVMContext);
  450. else
  451. return llvm::Type::getInt64Ty(*mLLVMContext);*/
  452. BF_FATAL("Unsupported");
  453. }
  454. isSigned = false;
  455. switch (typeCode)
  456. {
  457. case BfTypeCode_None:
  458. return llvm::Type::getVoidTy(*mLLVMContext);
  459. case BfTypeCode_NullPtr:
  460. return llvm::Type::getInt8PtrTy(*mLLVMContext);
  461. case BfTypeCode_Boolean:
  462. return llvm::Type::getInt1Ty(*mLLVMContext);
  463. case BfTypeCode_Int8:
  464. isSigned = true;
  465. return llvm::Type::getInt8Ty(*mLLVMContext);
  466. case BfTypeCode_UInt8:
  467. case BfTypeCode_Char8:
  468. return llvm::Type::getInt8Ty(*mLLVMContext);
  469. case BfTypeCode_Int16:
  470. isSigned = true;
  471. return llvm::Type::getInt16Ty(*mLLVMContext);
  472. case BfTypeCode_UInt16:
  473. case BfTypeCode_Char16:
  474. return llvm::Type::getInt16Ty(*mLLVMContext);
  475. case BfTypeCode_Int24:
  476. isSigned = true;
  477. return llvm::Type::getIntNTy(*mLLVMContext, 24);
  478. case BfTypeCode_UInt24:
  479. return llvm::Type::getIntNTy(*mLLVMContext, 24);
  480. case BfTypeCode_Int32:
  481. isSigned = true;
  482. return llvm::Type::getInt32Ty(*mLLVMContext);
  483. case BfTypeCode_UInt32:
  484. case BfTypeCode_Char32:
  485. return llvm::Type::getInt32Ty(*mLLVMContext);
  486. case BfTypeCode_Int40:
  487. isSigned = true;
  488. return llvm::Type::getIntNTy(*mLLVMContext, 40);
  489. case BfTypeCode_UInt40:
  490. return llvm::Type::getIntNTy(*mLLVMContext, 40);
  491. case BfTypeCode_Int48:
  492. isSigned = true;
  493. return llvm::Type::getIntNTy(*mLLVMContext, 48);
  494. case BfTypeCode_UInt48:
  495. return llvm::Type::getIntNTy(*mLLVMContext, 48);
  496. case BfTypeCode_Int56:
  497. isSigned = true;
  498. return llvm::Type::getIntNTy(*mLLVMContext, 56);
  499. case BfTypeCode_UInt56:
  500. return llvm::Type::getIntNTy(*mLLVMContext, 56);
  501. case BfTypeCode_Int64:
  502. isSigned = true;
  503. return llvm::Type::getInt64Ty(*mLLVMContext);
  504. case BfTypeCode_UInt64:
  505. return llvm::Type::getInt64Ty(*mLLVMContext);
  506. case BfTypeCode_Int128:
  507. isSigned = true;
  508. return llvm::Type::getInt128Ty(*mLLVMContext);
  509. case BfTypeCode_UInt128:
  510. return llvm::Type::getInt128Ty(*mLLVMContext);
  511. case BfTypeCode_IntPtr:
  512. BF_FATAL("Illegal");
  513. /*isSigned = true;
  514. if (mModule->mSystem->mPtrSize == 4)
  515. return llvm::Type::getInt32Ty(*mLLVMContext);
  516. else
  517. return llvm::Type::getInt64Ty(*mLLVMContext);*/
  518. case BfTypeCode_UIntPtr:
  519. BF_FATAL("Illegal");
  520. /*if (mModule->mSystem->mPtrSize == 4)
  521. return llvm::Type::getInt32Ty(*mLLVMContext);
  522. else
  523. return llvm::Type::getInt64Ty(*mLLVMContext);*/
  524. case BfTypeCode_Float:
  525. return llvm::Type::getFloatTy(*mLLVMContext);
  526. case BfTypeCode_Double:
  527. return llvm::Type::getDoubleTy(*mLLVMContext);
  528. case BfTypeCode_Float2:
  529. return llvm::VectorType::get(llvm::Type::getFloatTy(*mLLVMContext), 2);
  530. default: break;
  531. }
  532. return NULL;
  533. }
  534. BfIRTypeEntry& BfIRCodeGen::GetTypeEntry(int typeId)
  535. {
  536. BfIRTypeEntry& typeEntry = mTypes[typeId];
  537. if (typeEntry.mTypeId == -1)
  538. typeEntry.mTypeId = typeId;
  539. return typeEntry;
  540. }
  541. void BfIRCodeGen::SetResult(int id, llvm::Value* value)
  542. {
  543. BfIRCodeGenEntry entry;
  544. entry.mKind = BfIRCodeGenEntryKind_LLVMValue;
  545. entry.mLLVMValue = value;
  546. mResults.TryAdd(id, entry);
  547. }
  548. void BfIRCodeGen::SetResult(int id, llvm::Type* type)
  549. {
  550. BfIRCodeGenEntry entry;
  551. entry.mKind = BfIRCodeGenEntryKind_LLVMType;
  552. entry.mLLVMType = type;
  553. mResults.TryAdd(id, entry);
  554. }
  555. void BfIRCodeGen::SetResult(int id, llvm::BasicBlock * value)
  556. {
  557. BfIRCodeGenEntry entry;
  558. entry.mKind = BfIRCodeGenEntryKind_LLVMBasicBlock;
  559. entry.mLLVMBlock = value;
  560. mResults.TryAdd(id, entry);
  561. }
  562. void BfIRCodeGen::SetResult(int id, llvm::MDNode* md)
  563. {
  564. BfIRCodeGenEntry entry;
  565. entry.mKind = BfIRCodeGenEntryKind_LLVMMetadata;
  566. entry.mLLVMMetadata = md;
  567. mResults.TryAdd(id, entry);
  568. }
  569. void BfIRCodeGen::ProcessBfIRData(const BfSizedArray<uint8>& buffer)
  570. {
  571. struct InlineAsmErrorHook
  572. {
  573. static void StaticHandler(const llvm::SMDiagnostic& diag, void *context, unsigned locCookie)
  574. {
  575. if (diag.getKind() == llvm::SourceMgr::DK_Error)
  576. {
  577. BfIRCodeGen* irCodeGen = (BfIRCodeGen*)context;
  578. if (!irCodeGen->mErrorMsg.empty())
  579. irCodeGen->mErrorMsg += "\n";
  580. irCodeGen->mErrorMsg += StrFormat("Inline assembly error: \"%s\" : %s", diag.getMessage().data(), diag.getLineContents().data());
  581. }
  582. }
  583. };
  584. mLLVMContext->setInlineAsmDiagnosticHandler(InlineAsmErrorHook::StaticHandler, this);
  585. BF_ASSERT(mStream == NULL);
  586. mStream = new ChunkedDataBuffer();
  587. mStream->InitFlatRef(buffer.mVals, buffer.mSize);
  588. while (mStream->GetReadPos() < buffer.mSize)
  589. {
  590. if (mFailed)
  591. break;
  592. HandleNextCmd();
  593. }
  594. BF_ASSERT((mFailed) || (mStream->GetReadPos() == buffer.mSize));
  595. }
  596. int64 BfIRCodeGen::ReadSLEB128()
  597. {
  598. int64 val = 0;
  599. int64 shift = 0;
  600. uint8 byteVal;
  601. do
  602. {
  603. byteVal = mStream->Read();
  604. val |= ((int64)(byteVal & 0x7f)) << shift;
  605. shift += 7;
  606. } while (byteVal >= 128);
  607. // Sign extend negative numbers.
  608. if ((byteVal & 0x40) && (shift < 64))
  609. val |= (-1ULL) << shift;
  610. return val;
  611. }
  612. void BfIRCodeGen::Read(StringImpl& str)
  613. {
  614. int len = (int)ReadSLEB128();
  615. str.Append('?', len);
  616. mStream->Read((void*)str.c_str(), len);
  617. }
  618. void BfIRCodeGen::Read(int& i)
  619. {
  620. i = (int)ReadSLEB128();
  621. }
  622. void BfIRCodeGen::Read(int64& i)
  623. {
  624. i = ReadSLEB128();
  625. }
  626. void BfIRCodeGen::Read(Val128& i)
  627. {
  628. i.mLow = (uint64)ReadSLEB128();
  629. i.mHigh = (uint64)ReadSLEB128();
  630. }
  631. void BfIRCodeGen::Read(bool& val)
  632. {
  633. val = mStream->Read() != 0;
  634. }
  635. void BfIRCodeGen::Read(BfIRTypeEntry*& type)
  636. {
  637. int typeId = (int)ReadSLEB128();
  638. type = &GetTypeEntry(typeId);
  639. }
  640. void BfIRCodeGen::Read(llvm::Type*& llvmType)
  641. {
  642. BfIRType::TypeKind typeKind = (BfIRType::TypeKind)mStream->Read();
  643. if (typeKind == BfIRType::TypeKind::TypeKind_None)
  644. {
  645. llvmType = NULL;
  646. return;
  647. }
  648. if (typeKind == BfIRType::TypeKind::TypeKind_Stream)
  649. {
  650. int streamId = (int)ReadSLEB128();
  651. if (streamId == -1)
  652. {
  653. llvmType = NULL;
  654. return;
  655. }
  656. auto& result = mResults[streamId];
  657. BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMType);
  658. llvmType = result.mLLVMType;
  659. return;
  660. }
  661. if (typeKind == BfIRType::TypeKind::TypeKind_SizedArray)
  662. {
  663. CMD_PARAM(llvm::Type*, elementType);
  664. CMD_PARAM(int, length);
  665. llvmType = llvm::ArrayType::get(elementType, length);
  666. return;
  667. }
  668. int typeId = (int)ReadSLEB128();
  669. auto& typeEntry = GetTypeEntry(typeId);
  670. if (typeKind == BfIRType::TypeKind::TypeKind_TypeId)
  671. llvmType = typeEntry.mLLVMType;
  672. else if (typeKind == BfIRType::TypeKind::TypeKind_TypeInstId)
  673. llvmType = typeEntry.mInstLLVMType;
  674. else if (typeKind == BfIRType::TypeKind::TypeKind_TypeInstPtrId)
  675. llvmType = typeEntry.mInstLLVMType->getPointerTo();
  676. }
  677. void BfIRCodeGen::Read(llvm::FunctionType*& llvmType)
  678. {
  679. int streamId = (int)ReadSLEB128();
  680. auto& result = mResults[streamId];
  681. BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMType);
  682. llvmType = (llvm::FunctionType*)result.mLLVMType;
  683. }
  684. void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry)
  685. {
  686. BfIRParamType paramType = (BfIRParamType)mStream->Read();
  687. if (paramType == BfIRParamType_None)
  688. {
  689. llvmValue = NULL;
  690. }
  691. else if (paramType == BfIRParamType_Const)
  692. {
  693. BfTypeCode typeCode = (BfTypeCode)mStream->Read();
  694. BfConstType constType = (BfConstType)typeCode;
  695. if (constType == BfConstType_GlobalVar)
  696. {
  697. CMD_PARAM(int, streamId);
  698. if (streamId == -1)
  699. {
  700. int streamId = mCmdCount++;
  701. CMD_PARAM(llvm::Type*, varType);
  702. CMD_PARAM(bool, isConstant);
  703. BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
  704. CMD_PARAM(llvm::Constant*, initializer);
  705. CMD_PARAM(String, name);
  706. CMD_PARAM(bool, isTLS);
  707. llvm::GlobalVariable* globalVariable = mLLVMModule->getGlobalVariable(name.c_str(), true);
  708. if (globalVariable == NULL)
  709. {
  710. globalVariable = new llvm::GlobalVariable(
  711. *mLLVMModule,
  712. varType,
  713. isConstant,
  714. LLVMMapLinkageType(linkageType),
  715. initializer,
  716. name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
  717. }
  718. llvmValue = globalVariable;
  719. SetResult(streamId, globalVariable);
  720. }
  721. else
  722. llvmValue = GetLLVMValue(streamId);
  723. return;
  724. }
  725. /*else if (constType == BfConstType_GlobalVar_TypeInst)
  726. {
  727. CMD_PARAM(int, streamId);
  728. if (streamId == -1)
  729. {
  730. int streamId = mStream->GetReadPos();
  731. CMD_PARAM(int, varTypeId);
  732. auto& typeEntry = GetTypeEntry(varTypeId);
  733. auto varType = typeEntry.mInstLLVMType;
  734. CMD_PARAM(bool, isConstant);
  735. BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
  736. CMD_PARAM(llvm::Constant*, initializer);
  737. CMD_PARAM(String, name);
  738. CMD_PARAM(bool, isTLS);
  739. auto globalVariable = new llvm::GlobalVariable(
  740. *mLLVMModule,
  741. varType,
  742. isConstant,
  743. LLVMMapLinkageType(linkageType),
  744. initializer,
  745. name, NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
  746. llvmValue = globalVariable;
  747. SetResult(streamId, globalVariable);
  748. }
  749. else
  750. llvmValue = GetLLVMValue(streamId);
  751. return;
  752. }*/
  753. else if ((constType == BfConstType_BitCast) || (constType == BfConstType_BitCastNull))
  754. {
  755. CMD_PARAM(llvm::Constant*, target);
  756. CMD_PARAM(llvm::Type*, toType);
  757. if ((constType == BfConstType_BitCastNull) && (toType->isIntegerTy()))
  758. {
  759. llvmValue = llvm::ConstantInt::getNullValue(toType);
  760. }
  761. else if (target->getType()->isIntegerTy())
  762. llvmValue = llvm::ConstantExpr::getIntToPtr(target, toType);
  763. else
  764. llvmValue = llvm::ConstantExpr::getBitCast(target, toType);
  765. return;
  766. }
  767. else if (constType == BfConstType_GEP32_2)
  768. {
  769. CMD_PARAM(llvm::Constant*, target);
  770. CMD_PARAM(int, idx0);
  771. CMD_PARAM(int, idx1);
  772. llvm::Value* gepArgs[] = {
  773. llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), idx0),
  774. llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), idx1)};
  775. llvmValue = llvm::ConstantExpr::getInBoundsGetElementPtr(NULL, target, gepArgs);
  776. return;
  777. }
  778. else if (constType == BfConstType_ExtractValue)
  779. {
  780. CMD_PARAM(llvm::Constant*, target);
  781. CMD_PARAM(int, idx0);
  782. unsigned int gepArgs[] = {
  783. (unsigned int)idx0 };
  784. llvmValue = llvm::ConstantExpr::getExtractValue(target, gepArgs);
  785. return;
  786. }
  787. else if (constType == BfConstType_PtrToInt)
  788. {
  789. CMD_PARAM(llvm::Constant*, target);
  790. BfTypeCode toTypeCode = (BfTypeCode)mStream->Read();
  791. bool isSigned;
  792. llvm::Type* llvmToType = GetLLVMType(toTypeCode, isSigned);
  793. llvmValue = llvm::ConstantExpr::getPtrToInt(target, llvmToType);
  794. return;
  795. }
  796. else if (constType == BfConstType_AggZero)
  797. {
  798. CMD_PARAM(llvm::Type*, type);
  799. llvmValue = llvm::ConstantAggregateZero::get(type);
  800. return;
  801. }
  802. else if (constType == BfConstType_Array)
  803. {
  804. CMD_PARAM(llvm::Type*, type);
  805. CMD_PARAM(CmdParamVec<llvm::Constant*>, values);
  806. auto arrayType = (llvm::ArrayType*)type;
  807. int fillCount = (int)(arrayType->getNumElements() - values.size());
  808. if (fillCount > 0)
  809. {
  810. auto lastValue = values.back();
  811. for (int i = 0; i < fillCount; i++)
  812. values.push_back(lastValue);
  813. }
  814. llvmValue = llvm::ConstantArray::get((llvm::ArrayType*)type, values);
  815. return;
  816. }
  817. bool isSigned;
  818. llvm::Type* llvmConstType = GetLLVMType(typeCode, isSigned);
  819. if (typeCode == BfTypeCode_Float)
  820. {
  821. float f;
  822. mStream->Read(&f, sizeof(float));
  823. llvmValue = llvm::ConstantFP::get(llvmConstType, f);
  824. }
  825. else if (typeCode == BfTypeCode_Double)
  826. {
  827. double d;
  828. mStream->Read(&d, sizeof(double));
  829. llvmValue = llvm::ConstantFP::get(llvmConstType, d);
  830. }
  831. else if (typeCode == BfTypeCode_Boolean)
  832. {
  833. CMD_PARAM(bool, boolVal);
  834. llvmValue = llvm::ConstantInt::get(llvmConstType, boolVal ? 1 : 0);
  835. }
  836. else if (typeCode == BfTypeCode_None)
  837. {
  838. llvmValue = NULL;
  839. }
  840. else if (typeCode == BfTypeCode_NullPtr)
  841. {
  842. CMD_PARAM(llvm::Type*, nullType);
  843. if (nullType != NULL)
  844. llvmValue = llvm::ConstantPointerNull::get((llvm::PointerType*)nullType);
  845. else
  846. llvmValue = llvm::ConstantPointerNull::get((llvm::PointerType*)llvmConstType);
  847. }
  848. else if (BfIRBuilder::IsInt(typeCode))
  849. {
  850. int64 intVal = ReadSLEB128();
  851. auto constVal = llvm::ConstantInt::get(llvmConstType, intVal);
  852. auto constInt = (llvm::ConstantInt*)constVal;
  853. llvmValue = constInt;
  854. }
  855. else
  856. {
  857. BF_FATAL("Unhandled");
  858. }
  859. }
  860. else if (paramType == BfIRParamType_Arg)
  861. {
  862. int argIdx = mStream->Read();
  863. if (argIdx >= mActiveFunction->arg_size())
  864. {
  865. FatalError(StrFormat("ARG out of bounds %d", argIdx));
  866. }
  867. BF_ASSERT(argIdx < mActiveFunction->arg_size());
  868. auto argItr = mActiveFunction->arg_begin();
  869. for (int i = 0; i < argIdx; i++)
  870. argItr++;
  871. llvmValue = &(*argItr);
  872. }
  873. else
  874. {
  875. int cmdId = -1;
  876. if (paramType == BfIRParamType_StreamId_Abs8)
  877. {
  878. cmdId = mStream->Read();
  879. }
  880. else if (paramType == BfIRParamType_StreamId_Rel)
  881. {
  882. cmdId = mCmdCount - (int)ReadSLEB128();
  883. }
  884. else
  885. {
  886. cmdId = mCmdCount - (paramType - BfIRParamType_StreamId_Back1) - 1;
  887. }
  888. auto& result = mResults[cmdId];
  889. if (result.mKind != BfIRCodeGenEntryKind_LLVMValue)
  890. {
  891. if ((codeGenEntry != NULL) && (result.mKind != BfIRCodeGenEntryKind_None))
  892. {
  893. *codeGenEntry = &result;
  894. return;
  895. }
  896. }
  897. BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue);
  898. llvmValue = result.mLLVMValue;
  899. }
  900. }
  901. void BfIRCodeGen::Read(llvm::Constant*& llvmConstant)
  902. {
  903. llvm::Value* value;
  904. Read(value);
  905. if (value == NULL)
  906. {
  907. llvmConstant = NULL;
  908. }
  909. else
  910. {
  911. BF_ASSERT(llvm::isa<llvm::Constant>(value));
  912. llvmConstant = (llvm::Constant*)value;
  913. }
  914. }
  915. void BfIRCodeGen::Read(llvm::Function*& llvmFunc)
  916. {
  917. int streamId = (int)ReadSLEB128();
  918. if (streamId == -1)
  919. {
  920. llvmFunc = NULL;
  921. return;
  922. }
  923. auto& result = mResults[streamId];
  924. BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue);
  925. BF_ASSERT(llvm::isa<llvm::Function>(result.mLLVMValue));
  926. llvmFunc = (llvm::Function*)result.mLLVMValue;
  927. }
  928. void BfIRCodeGen::Read(llvm::BasicBlock*& llvmBlock)
  929. {
  930. int streamId = (int)ReadSLEB128();
  931. auto& result = mResults[streamId];
  932. BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMBasicBlock);
  933. llvmBlock = (llvm::BasicBlock*)result.mLLVMType;
  934. }
  935. void BfIRCodeGen::Read(llvm::MDNode*& llvmMD)
  936. {
  937. int streamId = (int)ReadSLEB128();
  938. if (streamId == -1)
  939. {
  940. llvmMD = NULL;
  941. return;
  942. }
  943. auto& result = mResults[streamId];
  944. BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMMetadata);
  945. llvmMD = result.mLLVMMetadata;
  946. }
  947. void BfIRCodeGen::Read(llvm::Metadata*& llvmMD)
  948. {
  949. int streamId = (int)ReadSLEB128();
  950. if (streamId == -1)
  951. {
  952. llvmMD = NULL;
  953. return;
  954. }
  955. auto& result = mResults[streamId];
  956. BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMMetadata);
  957. llvmMD = result.mLLVMMetadata;
  958. }
  959. void BfIRCodeGen::AddNop()
  960. {
  961. if ((mTargetTriple.GetMachineType() != BfMachineType_x86) && (mTargetTriple.GetMachineType() != BfMachineType_x64))
  962. return;
  963. if (mNopInlineAsm == NULL)
  964. {
  965. llvm::SmallVector<llvm::Type*, 8> paramTypes;
  966. llvm::FunctionType* funcType = llvm::FunctionType::get(llvm::Type::getVoidTy(*mLLVMContext), paramTypes, false);
  967. mNopInlineAsm = llvm::InlineAsm::get(funcType,
  968. "nop", "", true, false, llvm::InlineAsm::AD_ATT);
  969. }
  970. llvm::CallInst* callInst = mIRBuilder->CreateCall(mNopInlineAsm);
  971. callInst->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoUnwind);
  972. }
  973. llvm::Value* BfIRCodeGen::TryToVector(llvm::Value* value)
  974. {
  975. auto valueType = value->getType();
  976. if (llvm::isa<llvm::VectorType>(valueType))
  977. return value;
  978. if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(valueType))
  979. {
  980. auto ptrElemType = ptrType->getElementType();
  981. if (auto arrType = llvm::dyn_cast<llvm::ArrayType>(ptrElemType))
  982. {
  983. auto vecType = llvm::VectorType::get(arrType->getArrayElementType(), (uint)arrType->getArrayNumElements());
  984. auto vecPtrType = vecType->getPointerTo();
  985. auto ptrVal0 = mIRBuilder->CreateBitCast(value, vecPtrType);
  986. return mIRBuilder->CreateAlignedLoad(ptrVal0, 1);
  987. }
  988. if (auto vecType = llvm::dyn_cast<llvm::VectorType>(ptrElemType))
  989. {
  990. return mIRBuilder->CreateAlignedLoad(value, 1);
  991. }
  992. }
  993. return NULL;
  994. }
  995. llvm::Value* BfIRCodeGen::TryToVector(llvm::Value* value, llvm::Type* elemType)
  996. {
  997. auto valueType = value->getType();
  998. if (auto vecType = llvm::dyn_cast<llvm::VectorType>(valueType))
  999. {
  1000. if (vecType->getElementType() == elemType)
  1001. return value;
  1002. //TODO: We need an alloca....
  1003. FatalError("Failed to get vector");
  1004. return value;
  1005. }
  1006. if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(valueType))
  1007. {
  1008. auto ptrElemType = ptrType->getElementType();
  1009. if (auto arrType = llvm::dyn_cast<llvm::ArrayType>(ptrElemType))
  1010. {
  1011. auto vecType = llvm::VectorType::get(arrType->getArrayElementType(), (uint)arrType->getArrayNumElements());
  1012. auto vecPtrType = vecType->getPointerTo();
  1013. auto ptrVal0 = mIRBuilder->CreateBitCast(value, vecPtrType);
  1014. return mIRBuilder->CreateAlignedLoad(ptrVal0, 1);
  1015. }
  1016. if (auto vecType = llvm::dyn_cast<llvm::VectorType>(ptrElemType))
  1017. {
  1018. if (vecType->getElementType() == elemType)
  1019. return mIRBuilder->CreateAlignedLoad(value, 1);
  1020. auto dataLayout = llvm::DataLayout(mLLVMModule);
  1021. int wantNumElements = (int)vecType->getNumElements() * (int)dataLayout.getTypeSizeInBits(vecType->getElementType()) / (int)dataLayout.getTypeSizeInBits(elemType);
  1022. auto newVecType = llvm::VectorType::get(elemType, wantNumElements);
  1023. auto vecPtrType = newVecType->getPointerTo();
  1024. auto ptrVal0 = mIRBuilder->CreateBitCast(value, vecPtrType);
  1025. return mIRBuilder->CreateAlignedLoad(ptrVal0, 1);
  1026. }
  1027. }
  1028. return NULL;
  1029. }
  1030. llvm::Type* BfIRCodeGen::GetElemType(llvm::Value* value)
  1031. {
  1032. auto valueType = value->getType();
  1033. if (auto vecType = llvm::dyn_cast<llvm::VectorType>(valueType))
  1034. return vecType->getElementType();
  1035. if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(valueType))
  1036. {
  1037. auto ptrElemType = ptrType->getElementType();
  1038. if (auto arrType = llvm::dyn_cast<llvm::ArrayType>(ptrElemType))
  1039. return arrType->getArrayElementType();
  1040. if (auto vecType = llvm::dyn_cast<llvm::VectorType>(ptrElemType))
  1041. return vecType->getElementType();
  1042. }
  1043. return NULL;
  1044. }
  1045. bool BfIRCodeGen::TryMemCpy(llvm::Value* ptr, llvm::Value* val)
  1046. {
  1047. auto valType = val->getType();
  1048. auto dataLayout = llvm::DataLayout(mLLVMModule);
  1049. int arrayBytes = (int)dataLayout.getTypeSizeInBits(valType) / 8;
  1050. // LLVM has perf issues with large aggregates - it treats each element as a unique value,
  1051. // which is great for optimizing small data but is a perf killer for large data.
  1052. if (arrayBytes < 256)
  1053. return false;
  1054. auto int8Ty = llvm::Type::getInt8Ty(*mLLVMContext);
  1055. auto int32Ty = llvm::Type::getInt32Ty(*mLLVMContext);
  1056. auto int8PtrTy = int8Ty->getPointerTo();
  1057. if (auto loadInst = llvm::dyn_cast<llvm::LoadInst>(val))
  1058. {
  1059. mIRBuilder->CreateMemCpy(
  1060. mIRBuilder->CreateBitCast(ptr, int8PtrTy),
  1061. llvm::MaybeAlign(1),
  1062. mIRBuilder->CreateBitCast(loadInst->getPointerOperand(), int8PtrTy),
  1063. llvm::MaybeAlign(1),
  1064. llvm::ConstantInt::get(int32Ty, arrayBytes));
  1065. return true;
  1066. }
  1067. auto constVal = llvm::dyn_cast<llvm::Constant>(val);
  1068. if (constVal == NULL)
  1069. return false;
  1070. if (llvm::isa<llvm::ConstantAggregateZero>(constVal))
  1071. {
  1072. mIRBuilder->CreateMemSet(
  1073. mIRBuilder->CreateBitCast(ptr, int8PtrTy),
  1074. llvm::ConstantInt::get(int8Ty, 0),
  1075. llvm::ConstantInt::get(int32Ty, arrayBytes),
  1076. llvm::MaybeAlign(1));
  1077. return true;
  1078. }
  1079. auto globalVariable = new llvm::GlobalVariable(
  1080. *mLLVMModule,
  1081. valType,
  1082. true,
  1083. llvm::GlobalValue::InternalLinkage,
  1084. constVal,
  1085. StrFormat("__ConstVal__%d", mConstValIdx++).c_str(),
  1086. NULL,
  1087. llvm::GlobalValue::NotThreadLocal);
  1088. mIRBuilder->CreateMemCpy(
  1089. mIRBuilder->CreateBitCast(ptr, int8PtrTy),
  1090. llvm::MaybeAlign(1),
  1091. mIRBuilder->CreateBitCast(globalVariable, int8PtrTy),
  1092. llvm::MaybeAlign(1),
  1093. llvm::ConstantInt::get(int32Ty, arrayBytes));
  1094. return true;
  1095. }
  1096. bool BfIRCodeGen::TryVectorCpy(llvm::Value* ptr, llvm::Value* val)
  1097. {
  1098. if (ptr->getType()->getPointerElementType() == val->getType())
  1099. return false;
  1100. if (!llvm::isa<llvm::VectorType>(val->getType()))
  1101. {
  1102. return false;
  1103. }
  1104. auto usePtr = mIRBuilder->CreateBitCast(ptr, val->getType()->getPointerTo());
  1105. mIRBuilder->CreateAlignedStore(val, usePtr, 1);
  1106. // auto valType = val->getType();
  1107. // auto vecType = llvm::dyn_cast<llvm::VectorType>(valType);
  1108. // if (vecType == NULL)
  1109. // return false;
  1110. //
  1111. // for (int i = 0; i < (int)vecType->getVectorNumElements(); i++)
  1112. // {
  1113. // auto extract = mIRBuilder->CreateExtractElement(val, i);
  1114. //
  1115. // llvm::Value* gepArgs[] = {
  1116. // llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0),
  1117. // llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), i) };
  1118. // auto gep = mIRBuilder->CreateInBoundsGEP(ptr, llvm::makeArrayRef(gepArgs));
  1119. //
  1120. // mIRBuilder->CreateStore(extract, gep);
  1121. // }
  1122. return true;
  1123. }
  1124. void BfIRCodeGen::CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile)
  1125. {
  1126. auto sizeConst = llvm::dyn_cast<llvm::ConstantInt>(size);
  1127. auto valConst = llvm::dyn_cast<llvm::ConstantInt>(val);
  1128. if ((!mIsOptimized) && (sizeConst != NULL) && (valConst != NULL))
  1129. {
  1130. int64 sizeVal = sizeConst->getSExtValue();
  1131. uint8 setVal = (uint8)valConst->getSExtValue();
  1132. if (sizeVal <= 128)
  1133. {
  1134. //llvm::Value* intVal = mIRBuilder->CreatePtrToInt(addr, llvm::Type::getInt32Ty(*mLLVMContext))
  1135. int curOffset = 0;
  1136. int sizeLeft = (int)sizeVal;
  1137. llvm::Value* headVal;
  1138. if (mPtrSize >= 8)
  1139. {
  1140. headVal = NULL;
  1141. auto intTy = llvm::Type::getInt64Ty(*mLLVMContext);
  1142. auto constVal = llvm::ConstantInt::get(intTy,
  1143. ((int64)setVal << 56) | ((int64)setVal << 48) | ((int64)setVal << 40) | ((int64)setVal << 32) |
  1144. ((int64)setVal << 24) | ((int64)setVal << 16) | ((int64)setVal << 8) | ((int64)setVal));
  1145. while (sizeLeft >= 8)
  1146. {
  1147. if (headVal == NULL)
  1148. headVal = mIRBuilder->CreateBitCast(addr, intTy->getPointerTo());
  1149. llvm::Value* ptrVal = headVal;
  1150. if (curOffset != 0)
  1151. ptrVal = mIRBuilder->CreateConstInBoundsGEP1_32(NULL, headVal, curOffset / 8);
  1152. mIRBuilder->CreateStore(constVal, ptrVal, isVolatile);
  1153. curOffset += 8;
  1154. sizeLeft -= 8;
  1155. }
  1156. }
  1157. if (sizeLeft >= 4)
  1158. {
  1159. headVal = NULL;
  1160. auto intTy = llvm::Type::getInt32Ty(*mLLVMContext);
  1161. auto constVal = llvm::ConstantInt::get(intTy, ((int)setVal << 24) | ((int)setVal << 16) | ((int)setVal << 8) | ((int)setVal));
  1162. while (sizeLeft >= 4)
  1163. {
  1164. if (headVal == NULL)
  1165. headVal = mIRBuilder->CreateBitCast(addr, intTy->getPointerTo());
  1166. llvm::Value* ptrVal = headVal;
  1167. if (curOffset != 0)
  1168. ptrVal = mIRBuilder->CreateConstInBoundsGEP1_32(NULL, headVal, curOffset / 4);
  1169. mIRBuilder->CreateStore(constVal, ptrVal, isVolatile);
  1170. curOffset += 4;
  1171. sizeLeft -= 4;
  1172. }
  1173. }
  1174. if (sizeLeft >= 2)
  1175. {
  1176. headVal = NULL;
  1177. auto intTy = llvm::Type::getInt16Ty(*mLLVMContext);
  1178. auto constVal = llvm::ConstantInt::get(intTy, ((int)setVal << 8) | ((int)setVal));
  1179. while (sizeLeft >= 2)
  1180. {
  1181. if (headVal == NULL)
  1182. headVal = mIRBuilder->CreateBitCast(addr, intTy->getPointerTo());
  1183. llvm::Value* ptrVal = headVal;
  1184. if (curOffset != 0)
  1185. ptrVal = mIRBuilder->CreateConstInBoundsGEP1_32(NULL, headVal, curOffset / 2);
  1186. mIRBuilder->CreateStore(constVal, ptrVal, isVolatile);
  1187. curOffset += 2;
  1188. sizeLeft -= 2;
  1189. }
  1190. }
  1191. if (sizeLeft >= 1)
  1192. {
  1193. headVal = NULL;
  1194. auto intTy = llvm::Type::getInt8Ty(*mLLVMContext);
  1195. auto constVal = llvm::ConstantInt::get(intTy, ((int)setVal));
  1196. while (sizeLeft >= 1)
  1197. {
  1198. if (headVal == NULL)
  1199. headVal = mIRBuilder->CreateBitCast(addr, intTy->getPointerTo());
  1200. llvm::Value* ptrVal = headVal;
  1201. if (curOffset != 0)
  1202. ptrVal = mIRBuilder->CreateConstInBoundsGEP1_32(NULL, headVal, curOffset / 1);
  1203. mIRBuilder->CreateStore(constVal, ptrVal, isVolatile);
  1204. curOffset += 1;
  1205. sizeLeft -= 1;
  1206. }
  1207. }
  1208. return;
  1209. }
  1210. }
  1211. mIRBuilder->CreateMemSet(addr, val, size, llvm::MaybeAlign(alignment), isVolatile);
  1212. }
  1213. void BfIRCodeGen::InitTarget()
  1214. {
  1215. llvm::SMDiagnostic Err;
  1216. llvm::Triple theTriple = llvm::Triple(mLLVMModule->getTargetTriple());
  1217. llvm::CodeGenOpt::Level optLvl = llvm::CodeGenOpt::None;
  1218. String cpuName = "";
  1219. String arch = "";
  1220. // Get the target specific parser.
  1221. std::string Error;
  1222. const llvm::Target *theTarget = llvm::TargetRegistry::lookupTarget(arch.c_str(), theTriple, Error);
  1223. if (!theTarget)
  1224. {
  1225. Fail(StrFormat("Failed to create LLVM Target: %s", Error.c_str()));
  1226. return;
  1227. }
  1228. llvm::TargetOptions Options = llvm::TargetOptions(); // InitTargetOptionsFromCodeGenFlags();
  1229. String featuresStr;
  1230. if (mCodeGenOptions.mOptLevel == BfOptLevel_O1)
  1231. {
  1232. //optLvl = CodeGenOpt::Less;
  1233. }
  1234. else if (mCodeGenOptions.mOptLevel == BfOptLevel_O2)
  1235. optLvl = llvm::CodeGenOpt::Default;
  1236. else if (mCodeGenOptions.mOptLevel == BfOptLevel_O3)
  1237. optLvl = llvm::CodeGenOpt::Aggressive;
  1238. if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_SSE)
  1239. featuresStr = "+sse";
  1240. else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_SSE2)
  1241. featuresStr = "+sse2";
  1242. else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_SSE3)
  1243. featuresStr = "+sse3";
  1244. else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_SSE4)
  1245. featuresStr = "+sse4";
  1246. else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_SSE41)
  1247. featuresStr = "+sse4.1";
  1248. else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_AVX)
  1249. featuresStr = "+avx";
  1250. else if (mCodeGenOptions.mSIMDSetting == BfSIMDSetting_AVX2)
  1251. featuresStr = "+avx2";
  1252. llvm::Optional<llvm::Reloc::Model> relocModel;
  1253. llvm::CodeModel::Model cmModel = llvm::CodeModel::Small;
  1254. switch (mCodeGenOptions.mRelocType)
  1255. {
  1256. case BfRelocType_Static:
  1257. relocModel = llvm::Reloc::Model::DynamicNoPIC;
  1258. break;
  1259. case BfRelocType_PIC:
  1260. relocModel = llvm::Reloc::Model::PIC_;
  1261. break;
  1262. case BfRelocType_DynamicNoPIC:
  1263. relocModel = llvm::Reloc::Model::DynamicNoPIC;
  1264. break;
  1265. case BfRelocType_ROPI:
  1266. relocModel = llvm::Reloc::Model::ROPI;
  1267. break;
  1268. case BfRelocType_RWPI:
  1269. relocModel = llvm::Reloc::Model::RWPI;
  1270. break;
  1271. case BfRelocType_ROPI_RWPI:
  1272. relocModel = llvm::Reloc::Model::ROPI_RWPI;
  1273. break;
  1274. default: break;
  1275. }
  1276. switch (mCodeGenOptions.mPICLevel)
  1277. {
  1278. case BfPICLevel_Not:
  1279. mLLVMModule->setPICLevel(llvm::PICLevel::Level::NotPIC);
  1280. break;
  1281. case BfPICLevel_Small:
  1282. mLLVMModule->setPICLevel(llvm::PICLevel::Level::SmallPIC);
  1283. break;
  1284. case BfPICLevel_Big:
  1285. mLLVMModule->setPICLevel(llvm::PICLevel::Level::BigPIC);
  1286. break;
  1287. default: break;
  1288. }
  1289. mLLVMTargetMachine =
  1290. theTarget->createTargetMachine(theTriple.getTriple(), cpuName.c_str(), featuresStr.c_str(),
  1291. Options, relocModel, cmModel, optLvl);
  1292. mLLVMModule->setDataLayout(mLLVMTargetMachine->createDataLayout());
  1293. }
  1294. void BfIRCodeGen::HandleNextCmd()
  1295. {
  1296. int curId = mCmdCount;
  1297. BfIRCmd cmd = (BfIRCmd)mStream->Read();
  1298. mCmdCount++;
  1299. switch (cmd)
  1300. {
  1301. case BfIRCmd_Module_Start:
  1302. {
  1303. CMD_PARAM(String, moduleName);
  1304. CMD_PARAM(int, ptrSize);
  1305. CMD_PARAM(bool, isOptimized);
  1306. BF_ASSERT(mLLVMModule == NULL);
  1307. mModuleName = moduleName;
  1308. mPtrSize = ptrSize;
  1309. mIsOptimized = isOptimized;
  1310. mLLVMModule = new llvm::Module(moduleName.c_str(), *mLLVMContext);
  1311. mIRBuilder = new llvm::IRBuilder<>(*mLLVMContext);
  1312. //OutputDebugStrF("-------- Starting Module %s --------\n", moduleName.c_str());
  1313. }
  1314. break;
  1315. case BfIRCmd_Module_SetTargetTriple:
  1316. {
  1317. CMD_PARAM(String, targetTriple);
  1318. mTargetTriple.Set(targetTriple);
  1319. if (targetTriple.IsEmpty())
  1320. mLLVMModule->setTargetTriple(llvm::sys::getDefaultTargetTriple());
  1321. else
  1322. mLLVMModule->setTargetTriple(targetTriple.c_str());
  1323. InitTarget();
  1324. }
  1325. break;
  1326. case BfIRCmd_Module_AddModuleFlag:
  1327. {
  1328. CMD_PARAM(String, flag);
  1329. CMD_PARAM(int, val);
  1330. mLLVMModule->addModuleFlag(llvm::Module::Warning, flag.c_str(), val);
  1331. if (flag == "CodeView")
  1332. mIsCodeView = true;
  1333. }
  1334. break;
  1335. case BfIRCmd_WriteIR:
  1336. {
  1337. CMD_PARAM(String, fileName);
  1338. std::error_code ec;
  1339. llvm::raw_fd_ostream outStream(fileName.c_str(), ec, llvm::sys::fs::OpenFlags::F_Text);
  1340. if (ec)
  1341. {
  1342. Fail("Failed writing IR '" + fileName + "': " + ec.message());
  1343. }
  1344. else
  1345. mLLVMModule->print(outStream, NULL);
  1346. }
  1347. break;
  1348. case BfIRCmd_SetType:
  1349. {
  1350. CMD_PARAM(int, typeId);
  1351. CMD_PARAM(llvm::Type*, type);
  1352. auto& typeEntry = GetTypeEntry(typeId);
  1353. typeEntry.mLLVMType = type;
  1354. if (typeEntry.mInstLLVMType == NULL)
  1355. typeEntry.mInstLLVMType = type;
  1356. }
  1357. break;
  1358. case BfIRCmd_SetInstType:
  1359. {
  1360. CMD_PARAM(int, typeId);
  1361. CMD_PARAM(llvm::Type*, type);
  1362. GetTypeEntry(typeId).mInstLLVMType = type;
  1363. }
  1364. break;
  1365. case BfIRCmd_PrimitiveType:
  1366. {
  1367. BfTypeCode typeCode = (BfTypeCode)mStream->Read();
  1368. bool isSigned;
  1369. SetResult(curId, GetLLVMType(typeCode, isSigned));
  1370. }
  1371. break;
  1372. case BfIRCmd_CreateAnonymousStruct:
  1373. {
  1374. CMD_PARAM(CmdParamVec<llvm::Type*>, members);
  1375. llvm::StructType* structType = llvm::StructType::get(*mLLVMContext, members);
  1376. SetResult(curId, structType);
  1377. }
  1378. break;
  1379. case BfIRCmd_CreateStruct:
  1380. {
  1381. CMD_PARAM(String, typeName);
  1382. SetResult(curId, llvm::StructType::create(*mLLVMContext, typeName.c_str()));
  1383. }
  1384. break;
  1385. case BfIRCmd_StructSetBody:
  1386. {
  1387. CMD_PARAM(llvm::Type*, type);
  1388. CMD_PARAM(CmdParamVec<llvm::Type*>, members);
  1389. CMD_PARAM(bool, isPacked);
  1390. BF_ASSERT(llvm::isa<llvm::StructType>(type));
  1391. auto structType = (llvm::StructType*)type;
  1392. if (structType->isOpaque())
  1393. structType->setBody(members, isPacked);
  1394. }
  1395. break;
  1396. case BfIRCmd_Type:
  1397. {
  1398. CMD_PARAM(BfIRTypeEntry*, typeEntry);
  1399. auto type = typeEntry->mLLVMType;
  1400. SetResult(curId, type);
  1401. }
  1402. break;
  1403. case BfIRCmd_TypeInst:
  1404. {
  1405. CMD_PARAM(BfIRTypeEntry*, typeEntry);
  1406. SetResult(curId, typeEntry->mInstLLVMType);
  1407. }
  1408. break;
  1409. case BfIRCmd_TypeInstPtr:
  1410. {
  1411. CMD_PARAM(BfIRTypeEntry*, typeEntry);
  1412. SetResult(curId, typeEntry->mInstLLVMType->getPointerTo());
  1413. }
  1414. break;
  1415. case BfIRCmd_GetType:
  1416. {
  1417. CMD_PARAM(llvm::Value*, value);
  1418. auto type = value->getType();
  1419. SetResult(curId, type);
  1420. }
  1421. break;
  1422. case BfIRCmd_GetPointerToFuncType:
  1423. {
  1424. CMD_PARAM(llvm::FunctionType*, funcType);
  1425. SetResult(curId, funcType->getPointerTo());
  1426. }
  1427. break;
  1428. case BfIRCmd_GetPointerToType:
  1429. {
  1430. CMD_PARAM(llvm::Type*, type);
  1431. SetResult(curId, type->getPointerTo());
  1432. }
  1433. break;
  1434. case BfIRCmd_GetSizedArrayType:
  1435. {
  1436. CMD_PARAM(llvm::Type*, elementType);
  1437. CMD_PARAM(int, length);
  1438. SetResult(curId, llvm::ArrayType::get(elementType, length));
  1439. }
  1440. break;
  1441. case BfIRCmd_GetVectorType:
  1442. {
  1443. CMD_PARAM(llvm::Type*, elementType);
  1444. CMD_PARAM(int, length);
  1445. SetResult(curId, llvm::VectorType::get(elementType, length));
  1446. }
  1447. break;
  1448. case BfIRCmd_CreateConstStruct:
  1449. {
  1450. CMD_PARAM(llvm::Type*, type);
  1451. CMD_PARAM(CmdParamVec<llvm::Value*>, values)
  1452. llvm::SmallVector<llvm::Constant*, 8> copyValues;
  1453. FixValues((llvm::StructType*)type, values);
  1454. for (auto val : values)
  1455. {
  1456. auto constValue = llvm::dyn_cast<llvm::Constant>(val);
  1457. BF_ASSERT(constValue != NULL);
  1458. copyValues.push_back(constValue);
  1459. }
  1460. SetResult(curId, llvm::ConstantStruct::get((llvm::StructType*)type, copyValues));
  1461. }
  1462. break;
  1463. case BfIRCmd_CreateConstStructZero:
  1464. {
  1465. CMD_PARAM(llvm::Type*, type);
  1466. SetResult(curId, llvm::ConstantAggregateZero::get(type));
  1467. }
  1468. break;
  1469. case BfIRCmd_CreateConstArray:
  1470. {
  1471. CMD_PARAM(llvm::Type*, type);
  1472. CMD_PARAM(CmdParamVec<llvm::Constant*>, values);
  1473. SetResult(curId, llvm::ConstantArray::get((llvm::ArrayType*)type, values));
  1474. }
  1475. break;
  1476. case BfIRCmd_CreateConstString:
  1477. {
  1478. CMD_PARAM(String, str);
  1479. SetResult(curId, llvm::ConstantDataArray::getString(*mLLVMContext, llvm::StringRef(str.c_str(), str.length())));
  1480. }
  1481. break;
  1482. case BfIRCmd_ConfigConst:
  1483. {
  1484. CMD_PARAM(int, constIdx);
  1485. BfTypeCode typeCode = (BfTypeCode)mStream->Read();
  1486. if (typeCode == BfTypeCode_IntPtr)
  1487. typeCode = (mPtrSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64;
  1488. llvm::Constant* constVal = (typeCode == BfTypeCode_Int32) ?
  1489. mConfigConsts32[constIdx] :
  1490. mConfigConsts64[constIdx];
  1491. SetResult(curId, constVal);
  1492. }
  1493. break;
  1494. case BfIRCmd_SetName:
  1495. {
  1496. CMD_PARAM(llvm::Value*, val);
  1497. CMD_PARAM(String, name);
  1498. val->setName(name.c_str());
  1499. }
  1500. break;
  1501. case BfIRCmd_CreateUndefValue:
  1502. {
  1503. CMD_PARAM(llvm::Type*, type);
  1504. SetResult(curId, llvm::UndefValue::get(type));
  1505. }
  1506. break;
  1507. case BfIRCmd_NumericCast:
  1508. {
  1509. CMD_PARAM(llvm::Value*, val);
  1510. CMD_PARAM(bool, valIsSigned);
  1511. BfTypeCode typeCode = (BfTypeCode)mStream->Read();
  1512. BfTypeCode valTypeCode = GetTypeCode(val->getType(), valIsSigned);
  1513. bool toSigned;
  1514. auto toLLVMType = GetLLVMType(typeCode, toSigned);
  1515. llvm::Value* retVal = NULL;
  1516. if (BfIRBuilder::IsInt(typeCode))
  1517. {
  1518. // Int -> Int
  1519. if ((BfIRBuilder::IsInt(valTypeCode)) || (valTypeCode == BfTypeCode_Boolean))
  1520. {
  1521. retVal = mIRBuilder->CreateIntCast(val, toLLVMType, toSigned && valIsSigned);
  1522. }
  1523. else // Float -> Int
  1524. {
  1525. if (BfIRBuilder::IsSigned(typeCode))
  1526. retVal = mIRBuilder->CreateFPToSI(val, toLLVMType);
  1527. else
  1528. retVal = mIRBuilder->CreateFPToUI(val, toLLVMType);
  1529. }
  1530. }
  1531. else
  1532. {
  1533. // Int -> Float
  1534. if ((BfIRBuilder::IsInt(valTypeCode)) || (valTypeCode == BfTypeCode_Boolean))
  1535. {
  1536. if (BfIRBuilder::IsSigned(valTypeCode))
  1537. retVal = mIRBuilder->CreateSIToFP(val, toLLVMType);
  1538. else
  1539. retVal = mIRBuilder->CreateUIToFP(val, toLLVMType);
  1540. }
  1541. else // Float -> Float
  1542. {
  1543. retVal = mIRBuilder->CreateFPCast(val, toLLVMType);
  1544. }
  1545. }
  1546. SetResult(curId, retVal);
  1547. }
  1548. break;
  1549. case BfIRCmd_CmpEQ:
  1550. {
  1551. CMD_PARAM(llvm::Value*, lhs);
  1552. CMD_PARAM(llvm::Value*, rhs);
  1553. if (lhs->getType()->isFloatingPointTy())
  1554. SetResult(curId, mIRBuilder->CreateFCmpOEQ(lhs, rhs));
  1555. else
  1556. SetResult(curId, mIRBuilder->CreateICmpEQ(lhs, rhs));
  1557. }
  1558. break;
  1559. case BfIRCmd_CmpNE:
  1560. {
  1561. CMD_PARAM(llvm::Value*, lhs);
  1562. CMD_PARAM(llvm::Value*, rhs);
  1563. if (lhs->getType()->isFloatingPointTy())
  1564. SetResult(curId, mIRBuilder->CreateFCmpONE(lhs, rhs));
  1565. else
  1566. SetResult(curId, mIRBuilder->CreateICmpNE(lhs, rhs));
  1567. }
  1568. break;
  1569. case BfIRCmd_CmpSLT:
  1570. {
  1571. CMD_PARAM(llvm::Value*, lhs);
  1572. CMD_PARAM(llvm::Value*, rhs);
  1573. if (lhs->getType()->isFloatingPointTy())
  1574. SetResult(curId, mIRBuilder->CreateFCmpOLT(lhs, rhs));
  1575. else
  1576. SetResult(curId, mIRBuilder->CreateICmpSLT(lhs, rhs));
  1577. }
  1578. break;
  1579. case BfIRCmd_CmpULT:
  1580. {
  1581. CMD_PARAM(llvm::Value*, lhs);
  1582. CMD_PARAM(llvm::Value*, rhs);
  1583. if (lhs->getType()->isFloatingPointTy())
  1584. SetResult(curId, mIRBuilder->CreateFCmpOLT(lhs, rhs));
  1585. else
  1586. SetResult(curId, mIRBuilder->CreateICmpULT(lhs, rhs));
  1587. }
  1588. break;
  1589. case BfIRCmd_CmpSLE:
  1590. {
  1591. CMD_PARAM(llvm::Value*, lhs);
  1592. CMD_PARAM(llvm::Value*, rhs);
  1593. if (lhs->getType()->isFloatingPointTy())
  1594. SetResult(curId, mIRBuilder->CreateFCmpOLE(lhs, rhs));
  1595. else
  1596. SetResult(curId, mIRBuilder->CreateICmpSLE(lhs, rhs));
  1597. }
  1598. break;
  1599. case BfIRCmd_CmpULE:
  1600. {
  1601. CMD_PARAM(llvm::Value*, lhs);
  1602. CMD_PARAM(llvm::Value*, rhs);
  1603. if (lhs->getType()->isFloatingPointTy())
  1604. SetResult(curId, mIRBuilder->CreateFCmpOLE(lhs, rhs));
  1605. else
  1606. SetResult(curId, mIRBuilder->CreateICmpULE(lhs, rhs));
  1607. }
  1608. break;
  1609. case BfIRCmd_CmpSGT:
  1610. {
  1611. CMD_PARAM(llvm::Value*, lhs);
  1612. CMD_PARAM(llvm::Value*, rhs);
  1613. if (lhs->getType()->isFloatingPointTy())
  1614. SetResult(curId, mIRBuilder->CreateFCmpUGT(lhs, rhs));
  1615. else
  1616. SetResult(curId, mIRBuilder->CreateICmpSGT(lhs, rhs));
  1617. }
  1618. break;
  1619. case BfIRCmd_CmpUGT:
  1620. {
  1621. CMD_PARAM(llvm::Value*, lhs);
  1622. CMD_PARAM(llvm::Value*, rhs);
  1623. if (lhs->getType()->isFloatingPointTy())
  1624. SetResult(curId, mIRBuilder->CreateFCmpOGT(lhs, rhs));
  1625. else
  1626. SetResult(curId, mIRBuilder->CreateICmpUGT(lhs, rhs));
  1627. }
  1628. break;
  1629. case BfIRCmd_CmpSGE:
  1630. {
  1631. CMD_PARAM(llvm::Value*, lhs);
  1632. CMD_PARAM(llvm::Value*, rhs);
  1633. if (lhs->getType()->isFloatingPointTy())
  1634. SetResult(curId, mIRBuilder->CreateFCmpOGE(lhs, rhs));
  1635. else
  1636. SetResult(curId, mIRBuilder->CreateICmpSGE(lhs, rhs));
  1637. }
  1638. break;
  1639. case BfIRCmd_CmpUGE:
  1640. {
  1641. CMD_PARAM(llvm::Value*, lhs);
  1642. CMD_PARAM(llvm::Value*, rhs);
  1643. if (lhs->getType()->isFloatingPointTy())
  1644. SetResult(curId, mIRBuilder->CreateFCmpOGE(lhs, rhs));
  1645. else
  1646. SetResult(curId, mIRBuilder->CreateICmpUGE(lhs, rhs));
  1647. }
  1648. break;
  1649. case BfIRCmd_Add:
  1650. {
  1651. CMD_PARAM(llvm::Value*, lhs);
  1652. CMD_PARAM(llvm::Value*, rhs);
  1653. if (lhs->getType()->isFloatingPointTy())
  1654. SetResult(curId, mIRBuilder->CreateFAdd(lhs, rhs));
  1655. else
  1656. SetResult(curId, mIRBuilder->CreateAdd(lhs, rhs));
  1657. }
  1658. break;
  1659. case BfIRCmd_Sub:
  1660. {
  1661. CMD_PARAM(llvm::Value*, lhs);
  1662. CMD_PARAM(llvm::Value*, rhs);
  1663. if (lhs->getType()->isFloatingPointTy())
  1664. SetResult(curId, mIRBuilder->CreateFSub(lhs, rhs));
  1665. else
  1666. SetResult(curId, mIRBuilder->CreateSub(lhs, rhs));
  1667. }
  1668. break;
  1669. case BfIRCmd_Mul:
  1670. {
  1671. CMD_PARAM(llvm::Value*, lhs);
  1672. CMD_PARAM(llvm::Value*, rhs);
  1673. if (lhs->getType()->isFloatingPointTy())
  1674. SetResult(curId, mIRBuilder->CreateFMul(lhs, rhs));
  1675. else
  1676. SetResult(curId, mIRBuilder->CreateMul(lhs, rhs));
  1677. }
  1678. break;
  1679. case BfIRCmd_SDiv:
  1680. {
  1681. CMD_PARAM(llvm::Value*, lhs);
  1682. CMD_PARAM(llvm::Value*, rhs);
  1683. if (lhs->getType()->isFloatingPointTy())
  1684. SetResult(curId, mIRBuilder->CreateFDiv(lhs, rhs));
  1685. else
  1686. SetResult(curId, mIRBuilder->CreateSDiv(lhs, rhs));
  1687. }
  1688. break;
  1689. case BfIRCmd_UDiv:
  1690. {
  1691. CMD_PARAM(llvm::Value*, lhs);
  1692. CMD_PARAM(llvm::Value*, rhs);
  1693. SetResult(curId, mIRBuilder->CreateUDiv(lhs, rhs));
  1694. }
  1695. break;
  1696. case BfIRCmd_SRem:
  1697. {
  1698. CMD_PARAM(llvm::Value*, lhs);
  1699. CMD_PARAM(llvm::Value*, rhs);
  1700. if (lhs->getType()->isFloatingPointTy())
  1701. SetResult(curId, mIRBuilder->CreateFRem(lhs, rhs));
  1702. else
  1703. SetResult(curId, mIRBuilder->CreateSRem(lhs, rhs));
  1704. }
  1705. break;
  1706. case BfIRCmd_URem:
  1707. {
  1708. CMD_PARAM(llvm::Value*, lhs);
  1709. CMD_PARAM(llvm::Value*, rhs);
  1710. SetResult(curId, mIRBuilder->CreateURem(lhs, rhs));
  1711. }
  1712. break;
  1713. case BfIRCmd_And:
  1714. {
  1715. CMD_PARAM(llvm::Value*, lhs);
  1716. CMD_PARAM(llvm::Value*, rhs);
  1717. SetResult(curId, mIRBuilder->CreateAnd(lhs, rhs));
  1718. }
  1719. break;
  1720. case BfIRCmd_Or:
  1721. {
  1722. CMD_PARAM(llvm::Value*, lhs);
  1723. CMD_PARAM(llvm::Value*, rhs);
  1724. SetResult(curId, mIRBuilder->CreateOr(lhs, rhs));
  1725. }
  1726. break;
  1727. case BfIRCmd_Xor:
  1728. {
  1729. CMD_PARAM(llvm::Value*, lhs);
  1730. CMD_PARAM(llvm::Value*, rhs);
  1731. SetResult(curId, mIRBuilder->CreateXor(lhs, rhs));
  1732. }
  1733. break;
  1734. case BfIRCmd_Shl:
  1735. {
  1736. CMD_PARAM(llvm::Value*, lhs);
  1737. CMD_PARAM(llvm::Value*, rhs);
  1738. SetResult(curId, mIRBuilder->CreateShl(lhs, rhs));
  1739. }
  1740. break;
  1741. case BfIRCmd_AShr:
  1742. {
  1743. CMD_PARAM(llvm::Value*, lhs);
  1744. CMD_PARAM(llvm::Value*, rhs);
  1745. SetResult(curId, mIRBuilder->CreateAShr(lhs, rhs));
  1746. }
  1747. break;
  1748. case BfIRCmd_LShr:
  1749. {
  1750. CMD_PARAM(llvm::Value*, lhs);
  1751. CMD_PARAM(llvm::Value*, rhs);
  1752. SetResult(curId, mIRBuilder->CreateLShr(lhs, rhs));
  1753. }
  1754. break;
  1755. case BfIRCmd_Neg:
  1756. {
  1757. CMD_PARAM(llvm::Value*, val);
  1758. if (val->getType()->isFloatingPointTy())
  1759. SetResult(curId, mIRBuilder->CreateFNeg(val));
  1760. else
  1761. SetResult(curId, mIRBuilder->CreateNeg(val));
  1762. }
  1763. break;
  1764. case BfIRCmd_Not:
  1765. {
  1766. CMD_PARAM(llvm::Value*, val);
  1767. SetResult(curId, mIRBuilder->CreateNot(val));
  1768. }
  1769. break;
  1770. case BfIRCmd_BitCast:
  1771. {
  1772. CMD_PARAM(llvm::Value*, val);
  1773. CMD_PARAM(llvm::Type*, toType);
  1774. auto fromType = val->getType();
  1775. if ((!fromType->isPointerTy()) || (!toType->isPointerTy()))
  1776. {
  1777. if (fromType->isIntegerTy())
  1778. {
  1779. SetResult(curId, mIRBuilder->CreateIntToPtr(val, toType));
  1780. break;
  1781. }
  1782. SetResult(curId, mIRBuilder->CreatePtrToInt(val, toType));
  1783. break;
  1784. }
  1785. SetResult(curId, mIRBuilder->CreateBitCast(val, toType));
  1786. }
  1787. break;
  1788. case BfIRCmd_PtrToInt:
  1789. {
  1790. CMD_PARAM(llvm::Value*, val);
  1791. auto typeCode = (BfTypeCode)mStream->Read();
  1792. bool isSigned;
  1793. auto llvmType = GetLLVMType(typeCode, isSigned);
  1794. SetResult(curId, mIRBuilder->CreatePtrToInt(val, llvmType));
  1795. }
  1796. break;
  1797. case BfIRCmd_IntToPtr:
  1798. {
  1799. CMD_PARAM(llvm::Value*, val);
  1800. CMD_PARAM(llvm::Type*, toType);
  1801. SetResult(curId, mIRBuilder->CreateIntToPtr(val, toType));
  1802. }
  1803. break;
  1804. case BfIRCmd_InboundsGEP1_32:
  1805. {
  1806. CMD_PARAM(llvm::Value*, val);
  1807. CMD_PARAM(int, idx0);
  1808. SetResult(curId, mIRBuilder->CreateConstInBoundsGEP1_32(NULL, val, idx0));
  1809. }
  1810. break;
  1811. case BfIRCmd_InboundsGEP2_32:
  1812. {
  1813. CMD_PARAM(llvm::Value*, val);
  1814. CMD_PARAM(int, idx0);
  1815. CMD_PARAM(int, idx1);
  1816. SetResult(curId, mIRBuilder->CreateConstInBoundsGEP2_32(NULL, val, idx0, idx1));
  1817. }
  1818. break;
  1819. case BfIRCmd_InBoundsGEP1:
  1820. {
  1821. CMD_PARAM(llvm::Value*, val);
  1822. CMD_PARAM(llvm::Value*, idx0);
  1823. SetResult(curId, mIRBuilder->CreateInBoundsGEP(val, idx0));
  1824. }
  1825. break;
  1826. case BfIRCmd_InBoundsGEP2:
  1827. {
  1828. CMD_PARAM(llvm::Value*, val);
  1829. CMD_PARAM(llvm::Value*, idx0);
  1830. CMD_PARAM(llvm::Value*, idx1);
  1831. llvm::Value* indices[2] = { idx0, idx1 };
  1832. SetResult(curId, mIRBuilder->CreateInBoundsGEP(val, llvm::makeArrayRef(indices)));
  1833. }
  1834. break;
  1835. case BfIRCmd_IsNull:
  1836. {
  1837. CMD_PARAM(llvm::Value*, val);
  1838. SetResult(curId, mIRBuilder->CreateIsNull(val));
  1839. }
  1840. break;
  1841. case BfIRCmd_IsNotNull:
  1842. {
  1843. CMD_PARAM(llvm::Value*, val);
  1844. SetResult(curId, mIRBuilder->CreateIsNotNull(val));
  1845. }
  1846. break;
  1847. case BfIRCmd_ExtractValue:
  1848. {
  1849. CMD_PARAM(llvm::Value*, val);
  1850. CMD_PARAM(int, idx);
  1851. SetResult(curId, mIRBuilder->CreateExtractValue(val, llvm::makeArrayRef((unsigned)idx)));
  1852. }
  1853. break;
  1854. case BfIRCmd_InsertValue:
  1855. {
  1856. CMD_PARAM(llvm::Value*, agg);
  1857. CMD_PARAM(llvm::Value*, val);
  1858. CMD_PARAM(int, idx);
  1859. /*if (idx < 0)
  1860. {
  1861. idx = -idx;
  1862. auto elementType = ((llvm::StructType*)agg->getType())->getElementType(idx);
  1863. val = mIRBuilder->CreateBitCast(val, elementType);
  1864. }*/
  1865. SetResult(curId, mIRBuilder->CreateInsertValue(agg, val, llvm::makeArrayRef((unsigned)idx)));
  1866. }
  1867. break;
  1868. case BfIRCmd_Alloca:
  1869. {
  1870. CMD_PARAM(llvm::Type*, type);
  1871. if (type->isStructTy())
  1872. {
  1873. BF_ASSERT(!((llvm::StructType*)type)->isOpaque());
  1874. }
  1875. SetResult(curId, mIRBuilder->CreateAlloca(type));
  1876. }
  1877. break;
  1878. case BfIRCmd_AllocaArray:
  1879. {
  1880. CMD_PARAM(llvm::Type*, type);
  1881. CMD_PARAM(llvm::Value*, arraySize);
  1882. SetResult(curId, mIRBuilder->CreateAlloca(type, arraySize));
  1883. }
  1884. break;
  1885. case BfIRCmd_SetAllocaAlignment:
  1886. {
  1887. CMD_PARAM(llvm::Value*, val);
  1888. CMD_PARAM(int, alignment);
  1889. auto inst = llvm::dyn_cast<llvm::AllocaInst>(val);
  1890. inst->setAlignment(llvm::Align(alignment));
  1891. }
  1892. break;
  1893. case BfIRCmd_SetAllocaNoChkStkHint:
  1894. {
  1895. CMD_PARAM(llvm::Value*, val);
  1896. // LLVM does not support this
  1897. }
  1898. break;
  1899. case BfIRCmd_LifetimeStart:
  1900. {
  1901. CMD_PARAM(llvm::Value*, val);
  1902. SetResult(curId, mIRBuilder->CreateLifetimeStart(val));
  1903. }
  1904. break;
  1905. case BfIRCmd_LifetimeEnd:
  1906. {
  1907. CMD_PARAM(llvm::Value*, val);
  1908. SetResult(curId, mIRBuilder->CreateLifetimeEnd(val));
  1909. }
  1910. break;
  1911. case BfIRCmd_LifetimeExtend:
  1912. {
  1913. CMD_PARAM(llvm::Value*, val);
  1914. }
  1915. break;
  1916. case BfIRCmd_Load:
  1917. {
  1918. CMD_PARAM(llvm::Value*, val);
  1919. CMD_PARAM(bool, isVolatile);
  1920. SetResult(curId, mIRBuilder->CreateLoad(val, isVolatile));
  1921. }
  1922. break;
  1923. case BfIRCmd_AlignedLoad:
  1924. {
  1925. CMD_PARAM(llvm::Value*, val);
  1926. CMD_PARAM(int, alignment);
  1927. CMD_PARAM(bool, isVolatile);
  1928. SetResult(curId, mIRBuilder->CreateAlignedLoad(val, alignment, isVolatile));
  1929. }
  1930. break;
  1931. case BfIRCmd_Store:
  1932. {
  1933. CMD_PARAM(llvm::Value*, val);
  1934. CMD_PARAM(llvm::Value*, ptr);
  1935. CMD_PARAM(bool, isVolatile);
  1936. if ((!TryMemCpy(ptr, val)) &&
  1937. (!TryVectorCpy(ptr, val)))
  1938. SetResult(curId, mIRBuilder->CreateStore(val, ptr, isVolatile));
  1939. }
  1940. break;
  1941. case BfIRCmd_AlignedStore:
  1942. {
  1943. CMD_PARAM(llvm::Value*, val);
  1944. CMD_PARAM(llvm::Value*, ptr);
  1945. CMD_PARAM(int, alignment);
  1946. CMD_PARAM(bool, isVolatile);
  1947. if ((!TryMemCpy(ptr, val)) &&
  1948. (!TryVectorCpy(ptr, val)))
  1949. SetResult(curId, mIRBuilder->CreateAlignedStore(val, ptr, alignment, isVolatile));
  1950. }
  1951. break;
  1952. case BfIRCmd_MemSet:
  1953. {
  1954. CMD_PARAM(llvm::Value*, addr);
  1955. CMD_PARAM(llvm::Value*, val);
  1956. CMD_PARAM(llvm::Value*, size);
  1957. CMD_PARAM(int, alignment);
  1958. CreateMemSet(addr, val, size, alignment);
  1959. }
  1960. break;
  1961. case BfIRCmd_Fence:
  1962. {
  1963. BfIRFenceType fenceType = (BfIRFenceType)mStream->Read();
  1964. if (fenceType == BfIRFenceType_AcquireRelease)
  1965. mIRBuilder->CreateFence(llvm::AtomicOrdering::AcquireRelease);
  1966. }
  1967. break;
  1968. case BfIRCmd_StackSave:
  1969. {
  1970. auto intrin = llvm::Intrinsic::getDeclaration(mLLVMModule, llvm::Intrinsic::stacksave);
  1971. auto callInst = mIRBuilder->CreateCall(intrin);
  1972. SetResult(curId, callInst);
  1973. }
  1974. break;
  1975. case BfIRCmd_StackRestore:
  1976. {
  1977. CMD_PARAM(llvm::Value*, stackVal);
  1978. auto intrin = llvm::Intrinsic::getDeclaration(mLLVMModule, llvm::Intrinsic::stackrestore);
  1979. auto callInst = mIRBuilder->CreateCall(intrin, llvm::SmallVector<llvm::Value*, 1> {stackVal });
  1980. SetResult(curId, callInst);
  1981. }
  1982. break;
  1983. case BfIRCmd_GlobalVariable:
  1984. {
  1985. CMD_PARAM(llvm::Type*, varType);
  1986. CMD_PARAM(bool, isConstant);
  1987. BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
  1988. CMD_PARAM(String, name);
  1989. CMD_PARAM(bool, isTLS);
  1990. CMD_PARAM(llvm::Constant*, initializer);
  1991. auto globalVariable = new llvm::GlobalVariable(
  1992. *mLLVMModule,
  1993. varType,
  1994. isConstant,
  1995. LLVMMapLinkageType(linkageType),
  1996. initializer,
  1997. name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
  1998. SetResult(curId, globalVariable);
  1999. }
  2000. break;
  2001. case BfIRCmd_GlobalVar_SetUnnamedAddr:
  2002. {
  2003. CMD_PARAM(llvm::Value*, val);
  2004. CMD_PARAM(bool, unnamedAddr);
  2005. ((llvm::GlobalVariable*)val)->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
  2006. }
  2007. break;
  2008. case BfIRCmd_GlobalVar_SetInitializer:
  2009. {
  2010. CMD_PARAM(llvm::Value*, val);
  2011. CMD_PARAM(llvm::Constant*, initializer);
  2012. ((llvm::GlobalVariable*)val)->setInitializer(initializer);
  2013. }
  2014. break;
  2015. case BfIRCmd_GlobalVar_SetAlignment:
  2016. {
  2017. CMD_PARAM(llvm::Value*, val);
  2018. CMD_PARAM(int, alignment);
  2019. ((llvm::GlobalVariable*)val)->setAlignment(llvm::Align(alignment));
  2020. }
  2021. break;
  2022. case BfIRCmd_GlobalVar_SetStorageKind:
  2023. {
  2024. CMD_PARAM(llvm::Value*, val);
  2025. CMD_PARAM(int, storageKind);
  2026. ((llvm::GlobalVariable*)val)->setDLLStorageClass((llvm::GlobalValue::DLLStorageClassTypes)storageKind);
  2027. }
  2028. break;
  2029. case BfIRCmd_GlobalStringPtr:
  2030. {
  2031. CMD_PARAM(String, str);
  2032. SetResult(curId, mIRBuilder->CreateGlobalStringPtr(llvm::StringRef(str.c_str(), str.length())));
  2033. }
  2034. break;
  2035. case BfIRCmd_CreateBlock:
  2036. {
  2037. CMD_PARAM(String, name);
  2038. CMD_PARAM(bool, addNow);
  2039. auto block = llvm::BasicBlock::Create(*mLLVMContext, name.c_str());
  2040. if (addNow)
  2041. mActiveFunction->getBasicBlockList().push_back(block);
  2042. SetResult(curId, block);
  2043. }
  2044. break;
  2045. case BfIRCmd_MaybeChainNewBlock:
  2046. {
  2047. CMD_PARAM(String, name);
  2048. auto newBlock = mIRBuilder->GetInsertBlock();
  2049. if (!newBlock->empty())
  2050. {
  2051. auto bb = llvm::BasicBlock::Create(*mLLVMContext, name.c_str());
  2052. mIRBuilder->CreateBr(bb);
  2053. mActiveFunction->getBasicBlockList().push_back(bb);
  2054. mIRBuilder->SetInsertPoint(bb);
  2055. newBlock = bb;
  2056. }
  2057. SetResult(curId, newBlock);
  2058. }
  2059. break;
  2060. case BfIRCmd_AddBlock:
  2061. {
  2062. CMD_PARAM(llvm::BasicBlock*, block);
  2063. mActiveFunction->getBasicBlockList().push_back(block);
  2064. }
  2065. break;
  2066. case BfIRCmd_DropBlocks:
  2067. {
  2068. CMD_PARAM(llvm::BasicBlock*, startingBlock);
  2069. auto& basicBlockList = mActiveFunction->getBasicBlockList();
  2070. int postExitBlockIdx = -1;
  2071. auto itr = basicBlockList.rbegin();
  2072. int blockIdx = (int)basicBlockList.size() - 1;
  2073. while (itr != basicBlockList.rend())
  2074. {
  2075. auto& block = *itr++;
  2076. block.dropAllReferences();
  2077. if (&block == startingBlock)
  2078. {
  2079. postExitBlockIdx = blockIdx;
  2080. break;
  2081. }
  2082. blockIdx--;
  2083. }
  2084. while ((int)basicBlockList.size() > postExitBlockIdx)
  2085. {
  2086. auto& block = basicBlockList.back();
  2087. block.eraseFromParent();
  2088. }
  2089. }
  2090. break;
  2091. case BfIRCmd_MergeBlockDown:
  2092. {
  2093. CMD_PARAM(llvm::BasicBlock*, fromBlock);
  2094. CMD_PARAM(llvm::BasicBlock*, intoBlock);
  2095. llvm::BasicBlock::InstListType& fromInstList = fromBlock->getInstList();
  2096. llvm::BasicBlock::InstListType& intoInstList = intoBlock->getInstList();
  2097. intoInstList.splice(intoInstList.begin(), fromInstList, fromInstList.begin(), fromInstList.end());
  2098. fromBlock->eraseFromParent();
  2099. }
  2100. break;
  2101. case BfIRCmd_SetInsertPoint:
  2102. {
  2103. CMD_PARAM(llvm::BasicBlock*, block);
  2104. mIRBuilder->SetInsertPoint(block);
  2105. }
  2106. break;
  2107. case BfIRCmd_SetInsertPointAtStart:
  2108. {
  2109. CMD_PARAM(llvm::BasicBlock*, block);
  2110. mIRBuilder->SetInsertPoint(block, block->begin());
  2111. }
  2112. break;
  2113. case BfIRCmd_EraseFromParent:
  2114. {
  2115. CMD_PARAM(llvm::BasicBlock*, block);
  2116. block->eraseFromParent();
  2117. }
  2118. break;
  2119. case BfIRCmd_DeleteBlock:
  2120. {
  2121. CMD_PARAM(llvm::BasicBlock*, block);
  2122. delete block;
  2123. }
  2124. break;
  2125. case BfIRCmd_EraseInstFromParent:
  2126. {
  2127. CMD_PARAM(llvm::Value*, instVal);
  2128. BF_ASSERT(llvm::isa<llvm::Instruction>(instVal));
  2129. ((llvm::Instruction*)instVal)->eraseFromParent();
  2130. }
  2131. break;
  2132. case BfIRCmd_CreateBr:
  2133. case BfIRCmd_CreateBr_NoCollapse:
  2134. {
  2135. CMD_PARAM(llvm::BasicBlock*, block);
  2136. mIRBuilder->CreateBr(block);
  2137. }
  2138. break;
  2139. case BfIRCmd_CreateBr_Fake:
  2140. {
  2141. CMD_PARAM(llvm::BasicBlock*, block);
  2142. // Do nothing
  2143. }
  2144. break;
  2145. case BfIRCmd_CreateCondBr:
  2146. {
  2147. CMD_PARAM(llvm::Value*, condVal);
  2148. CMD_PARAM(llvm::BasicBlock*, trueBlock);
  2149. CMD_PARAM(llvm::BasicBlock*, falseBlock);
  2150. mIRBuilder->CreateCondBr(condVal, trueBlock, falseBlock);
  2151. }
  2152. break;
  2153. case BfIRCmd_MoveBlockToEnd:
  2154. {
  2155. CMD_PARAM(llvm::BasicBlock*, block);
  2156. block->moveAfter(&block->getParent()->getBasicBlockList().back());
  2157. }
  2158. break;
  2159. case BfIRCmd_CreateSwitch:
  2160. {
  2161. CMD_PARAM(llvm::Value*, val);
  2162. CMD_PARAM(llvm::BasicBlock*, dest);
  2163. CMD_PARAM(int, numCases);
  2164. SetResult(curId, mIRBuilder->CreateSwitch(val, dest, numCases));
  2165. }
  2166. break;
  2167. case BfIRCmd_AddSwitchCase:
  2168. {
  2169. CMD_PARAM(llvm::Value*, switchVal);
  2170. CMD_PARAM(llvm::Value*, caseVal);
  2171. CMD_PARAM(llvm::BasicBlock*, caseBlock);
  2172. BF_ASSERT(llvm::isa<llvm::SwitchInst>(switchVal));
  2173. BF_ASSERT(llvm::isa<llvm::ConstantInt>(caseVal));
  2174. ((llvm::SwitchInst*)switchVal)->addCase((llvm::ConstantInt*)caseVal, caseBlock);
  2175. }
  2176. break;
  2177. case BfIRCmd_SetSwitchDefaultDest:
  2178. {
  2179. CMD_PARAM(llvm::Value*, switchVal);
  2180. CMD_PARAM(llvm::BasicBlock*, caseBlock);
  2181. ((llvm::SwitchInst*)switchVal)->setDefaultDest(caseBlock);
  2182. }
  2183. break;
  2184. case BfIRCmd_CreatePhi:
  2185. {
  2186. CMD_PARAM(llvm::Type*, type);
  2187. CMD_PARAM(int, incomingCount);
  2188. SetResult(curId, mIRBuilder->CreatePHI(type, incomingCount));
  2189. }
  2190. break;
  2191. case BfIRCmd_AddPhiIncoming:
  2192. {
  2193. CMD_PARAM(llvm::Value*, phiValue);
  2194. CMD_PARAM(llvm::Value*, value);
  2195. CMD_PARAM(llvm::BasicBlock*, comingFrom);
  2196. BF_ASSERT(llvm::isa<llvm::PHINode>(phiValue));
  2197. ((llvm::PHINode*)phiValue)->addIncoming(value, comingFrom);
  2198. }
  2199. break;
  2200. case BfIRCmd_GetIntrinsic:
  2201. {
  2202. CMD_PARAM(String, intrinName);
  2203. CMD_PARAM(int, intrinId);
  2204. CMD_PARAM(llvm::Type*, returnType);
  2205. CMD_PARAM(CmdParamVec<llvm::Type*>, paramTypes);
  2206. llvm::Function* func = NULL;
  2207. struct _Intrinsics
  2208. {
  2209. llvm::Intrinsic::ID mID;
  2210. int mArg0;
  2211. int mArg1;
  2212. int mArg2;
  2213. };
  2214. static _Intrinsics intrinsics[] =
  2215. {
  2216. { (llvm::Intrinsic::ID)-1, -1}, // PLATFORM,
  2217. { llvm::Intrinsic::fabs, 0, -1},
  2218. { (llvm::Intrinsic::ID)-2, -1}, // add,
  2219. { (llvm::Intrinsic::ID)-2, -1}, // and,
  2220. { (llvm::Intrinsic::ID)-2, -1}, // AtomicAdd,
  2221. { (llvm::Intrinsic::ID)-2, -1}, // AtomicAnd,
  2222. { (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpStore,
  2223. { (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpStore_Weak,
  2224. { (llvm::Intrinsic::ID)-2, -1}, // AtomicCmpXChg,
  2225. { (llvm::Intrinsic::ID)-2, -1}, // AtomicFence,
  2226. { (llvm::Intrinsic::ID)-2, -1}, // AtomicLoad,
  2227. { (llvm::Intrinsic::ID)-2, -1}, // AtomicMax,
  2228. { (llvm::Intrinsic::ID)-2, -1}, // AtomicMin,
  2229. { (llvm::Intrinsic::ID)-2, -1}, // AtomicNAnd,
  2230. { (llvm::Intrinsic::ID)-2, -1}, // AtomicOr,
  2231. { (llvm::Intrinsic::ID)-2, -1}, // AtomicStore,
  2232. { (llvm::Intrinsic::ID)-2, -1}, // AtomicSub,
  2233. { (llvm::Intrinsic::ID)-2, -1}, // AtomicUMax,
  2234. { (llvm::Intrinsic::ID)-2, -1}, // AtomicUMin,
  2235. { (llvm::Intrinsic::ID)-2, -1}, // AtomicXChg,
  2236. { (llvm::Intrinsic::ID)-2, -1}, // AtomicXor,
  2237. { llvm::Intrinsic::bswap, -1},
  2238. { (llvm::Intrinsic::ID)-2, -1}, // cast,
  2239. { llvm::Intrinsic::cos, 0, -1},
  2240. { llvm::Intrinsic::debugtrap, -1}, // debugtrap,
  2241. { (llvm::Intrinsic::ID)-2, -1}, // div
  2242. { (llvm::Intrinsic::ID)-2, -1}, // eq
  2243. { llvm::Intrinsic::floor, 0, -1},
  2244. { (llvm::Intrinsic::ID)-2, -1}, // free
  2245. { (llvm::Intrinsic::ID)-2, -1}, // gt
  2246. { (llvm::Intrinsic::ID)-2, -1}, // gte
  2247. { (llvm::Intrinsic::ID)-2, -1}, // index
  2248. { llvm::Intrinsic::log, 0, -1},
  2249. { llvm::Intrinsic::log10, 0, -1},
  2250. { llvm::Intrinsic::log2, 0, -1},
  2251. { (llvm::Intrinsic::ID)-2, -1}, // lt
  2252. { (llvm::Intrinsic::ID)-2, -1}, // lte
  2253. { (llvm::Intrinsic::ID)-2}, // memset
  2254. { llvm::Intrinsic::memcpy, 0, 1, 2},
  2255. { llvm::Intrinsic::memmove, 0, 2},
  2256. { llvm::Intrinsic::memset, 0, 2},
  2257. { (llvm::Intrinsic::ID)-2, -1}, // mod
  2258. { (llvm::Intrinsic::ID)-2, -1}, // mul
  2259. { (llvm::Intrinsic::ID)-2, -1}, // neq
  2260. { (llvm::Intrinsic::ID)-2, -1}, // not
  2261. { (llvm::Intrinsic::ID)-2, -1}, // or
  2262. { llvm::Intrinsic::pow, 0, -1},
  2263. { llvm::Intrinsic::powi, 0, -1},
  2264. { llvm::Intrinsic::round, 0, -1},
  2265. { (llvm::Intrinsic::ID)-2, -1}, // sar
  2266. { (llvm::Intrinsic::ID)-2, -1}, // shl
  2267. { (llvm::Intrinsic::ID)-2, -1}, // shr
  2268. { (llvm::Intrinsic::ID)-2, -1}, // shuffle
  2269. { llvm::Intrinsic::sin, 0, -1},
  2270. { llvm::Intrinsic::sqrt, 0, -1},
  2271. { (llvm::Intrinsic::ID)-2, -1}, // sub,
  2272. { (llvm::Intrinsic::ID)-2, -1}, // xor
  2273. };
  2274. BF_STATIC_ASSERT(BF_ARRAY_COUNT(intrinsics) == BfIRIntrinsic_COUNT);
  2275. CmdParamVec<llvm::Type*> useParams;
  2276. if (intrinsics[intrinId].mArg0 != -1)
  2277. {
  2278. useParams.push_back(paramTypes[0]);
  2279. if (intrinsics[intrinId].mArg1 != -1)
  2280. {
  2281. useParams.push_back(paramTypes[1]);
  2282. if (intrinsics[intrinId].mArg2 != -1)
  2283. {
  2284. useParams.push_back(paramTypes[2]);
  2285. }
  2286. }
  2287. }
  2288. bool isFakeIntrinsic = (int)intrinsics[intrinId].mID == -2;
  2289. if (isFakeIntrinsic)
  2290. {
  2291. auto intrinsicData = mAlloc.Alloc<BfIRIntrinsicData>();
  2292. intrinsicData->mName = intrinName;
  2293. intrinsicData->mIntrinsic = (BfIRIntrinsic)intrinId;
  2294. intrinsicData->mReturnType = returnType;
  2295. BfIRCodeGenEntry entry;
  2296. entry.mKind = BfIRCodeGenEntryKind_IntrinsicData;
  2297. entry.mIntrinsicData = intrinsicData;
  2298. mResults.TryAdd(curId, entry);
  2299. break;
  2300. }
  2301. if (intrinId == BfIRIntrinsic__PLATFORM)
  2302. {
  2303. int colonPos = (int)intrinName.IndexOf(':');
  2304. String platName = intrinName.Substring(0, colonPos);
  2305. String platIntrinName = intrinName.Substring(colonPos + 1);
  2306. if (platName.IsEmpty())
  2307. {
  2308. auto intrinsicData = mAlloc.Alloc<BfIRIntrinsicData>();
  2309. intrinsicData->mName = platIntrinName;
  2310. intrinsicData->mIntrinsic = BfIRIntrinsic__PLATFORM;
  2311. intrinsicData->mReturnType = returnType;
  2312. BfIRCodeGenEntry entry;
  2313. entry.mKind = BfIRCodeGenEntryKind_IntrinsicData;
  2314. entry.mIntrinsicData = intrinsicData;
  2315. mResults.TryAdd(curId, entry);
  2316. break;
  2317. }
  2318. llvm::Intrinsic::ID intrin = llvm::Intrinsic::getIntrinsicForGCCBuiltin(platName.c_str(), platIntrinName.c_str());
  2319. if ((int)intrin <= 0)
  2320. FatalError(StrFormat("Unable to find intrinsic '%s'", intrinName.c_str()));
  2321. else
  2322. func = llvm::Intrinsic::getDeclaration(mLLVMModule, intrinsics[intrinId].mID, useParams);
  2323. }
  2324. else
  2325. {
  2326. BF_ASSERT(intrinsics[intrinId].mID != (llvm::Intrinsic::ID)-1);
  2327. func = llvm::Intrinsic::getDeclaration(mLLVMModule, intrinsics[intrinId].mID, useParams);
  2328. }
  2329. mIntrinsicReverseMap[func] = intrinId;
  2330. SetResult(curId, func);
  2331. }
  2332. break;
  2333. case BfIRCmd_CreateFunctionType:
  2334. {
  2335. CMD_PARAM(llvm::Type*, resultType);
  2336. CMD_PARAM(CmdParamVec<llvm::Type*>, paramTypes);
  2337. CMD_PARAM(bool, isVarArg);
  2338. SetResult(curId, llvm::FunctionType::get(resultType, paramTypes, isVarArg));
  2339. }
  2340. break;
  2341. case BfIRCmd_CreateFunction:
  2342. {
  2343. CMD_PARAM(llvm::FunctionType*, type);
  2344. BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
  2345. CMD_PARAM(String, name);
  2346. auto func = mLLVMModule->getFunction(name.c_str());
  2347. if ((func == NULL) || (func->getFunctionType() != type))
  2348. func = llvm::Function::Create(type, LLVMMapLinkageType(linkageType), name.c_str(), mLLVMModule);
  2349. SetResult(curId, func);
  2350. }
  2351. break;
  2352. case BfIRCmd_EnsureFunctionPatchable:
  2353. {
  2354. int minPatchSize = 5;
  2355. int guessInstBytes = 1; // ret
  2356. guessInstBytes += mActiveFunction->getFunctionType()->getNumParams() * 4;
  2357. if (guessInstBytes < 5)
  2358. {
  2359. for (auto& block : mActiveFunction->getBasicBlockList())
  2360. {
  2361. for (auto& inst : block)
  2362. {
  2363. if (auto loadInst = llvm::dyn_cast<llvm::LoadInst>(&inst))
  2364. guessInstBytes += 2;
  2365. else if (auto storeInst = llvm::dyn_cast<llvm::StoreInst>(&inst))
  2366. guessInstBytes += 2;
  2367. else if (auto callInst = llvm::dyn_cast<llvm::CallInst>(&inst))
  2368. {
  2369. auto calledValue = callInst->getCalledOperand();
  2370. if (calledValue == mNopInlineAsm)
  2371. guessInstBytes += 1;
  2372. else if (auto func = llvm::dyn_cast<llvm::Function>(calledValue))
  2373. {
  2374. if (!func->isIntrinsic())
  2375. guessInstBytes += 4;
  2376. }
  2377. else
  2378. guessInstBytes += 4;
  2379. }
  2380. if (guessInstBytes >= minPatchSize)
  2381. break;
  2382. }
  2383. }
  2384. }
  2385. for (int i = guessInstBytes; i < minPatchSize; i++)
  2386. AddNop();
  2387. }
  2388. break;
  2389. case BfIRCmd_RemapBindFunction:
  2390. {
  2391. CMD_PARAM(llvm::Value*, func);
  2392. // We need to store this value to a data segment so we get a symbol we can remap during hot swap
  2393. // We actually do this to ensure that we don't bind to the NEW method but rather the old one- so
  2394. // delegate equality checks still work
  2395. llvm::Function* llvmFunc = llvm::dyn_cast<llvm::Function>(func);
  2396. if (llvmFunc != NULL)
  2397. {
  2398. // I don't know why we mixed in HSPreserveIdx - that causes bound address to change after reloading, basically totally breaking
  2399. // the whole point of this.
  2400. //String funcName = StrFormat("bf_hs_preserve@%d@%s", mModule->mCompiler->mHSPreserveIdx++, func->getName());
  2401. String funcName = StrFormat("bf_hs_preserve@%s_%s", llvmFunc->getName().data(), mLLVMModule->getName().data());
  2402. llvm::GlobalVariable* globalVariable = mLLVMModule->getGlobalVariable(funcName.c_str());
  2403. if (globalVariable == NULL)
  2404. {
  2405. globalVariable = new llvm::GlobalVariable(*mLLVMModule, func->getType(), true, llvm::GlobalValue::ExternalLinkage, (llvm::Constant*)func, funcName.c_str());
  2406. }
  2407. SetResult(curId, mIRBuilder->CreateLoad(globalVariable));
  2408. }
  2409. else
  2410. SetResult(curId, func);
  2411. }
  2412. break;
  2413. case BfIRCmd_SetActiveFunction:
  2414. {
  2415. CMD_PARAM(llvm::Function*, func);
  2416. mActiveFunction = func;
  2417. }
  2418. break;
  2419. case BfIRCmd_CreateCall:
  2420. {
  2421. llvm::Value* func = NULL;
  2422. BfIRCodeGenEntry* codeGenEntry = NULL;
  2423. Read(func, &codeGenEntry);
  2424. CMD_PARAM(CmdParamVec<llvm::Value*>, args);
  2425. if ((func == NULL) && (codeGenEntry != NULL) && (codeGenEntry->mKind == BfIRCodeGenEntryKind_IntrinsicData))
  2426. {
  2427. auto intrinsicData = codeGenEntry->mIntrinsicData;
  2428. switch (intrinsicData->mIntrinsic)
  2429. {
  2430. case BfIRIntrinsic__PLATFORM:
  2431. {
  2432. if (intrinsicData->mName == "add_ps")
  2433. {
  2434. auto val0 = TryToVector(args[0], llvm::Type::getFloatTy(*mLLVMContext));
  2435. auto val1 = TryToVector(args[0], llvm::Type::getFloatTy(*mLLVMContext));
  2436. //SetResult(curId, TryToVector(mIRBuilder->CreateFAdd(val0, val1), GetElemType(args[0])));
  2437. SetResult(curId, mIRBuilder->CreateFAdd(val0, val1));
  2438. }
  2439. else
  2440. {
  2441. FatalError(StrFormat("Unable to find intrinsic '%s'", intrinsicData->mName.c_str()));
  2442. }
  2443. }
  2444. break;
  2445. case BfIRIntrinsic_Add:
  2446. case BfIRIntrinsic_And:
  2447. case BfIRIntrinsic_Div:
  2448. case BfIRIntrinsic_Eq:
  2449. case BfIRIntrinsic_Gt:
  2450. case BfIRIntrinsic_GtE:
  2451. case BfIRIntrinsic_Lt:
  2452. case BfIRIntrinsic_LtE:
  2453. case BfIRIntrinsic_Mod:
  2454. case BfIRIntrinsic_Mul:
  2455. case BfIRIntrinsic_Neq:
  2456. case BfIRIntrinsic_Or:
  2457. case BfIRIntrinsic_Sub:
  2458. case BfIRIntrinsic_Xor:
  2459. {
  2460. auto val0 = TryToVector(args[0]);
  2461. if (val0 != NULL)
  2462. {
  2463. auto vecType = llvm::dyn_cast<llvm::VectorType>(val0->getType());
  2464. auto elemType = vecType->getElementType();
  2465. bool isFP = elemType->isFloatTy();
  2466. llvm::Value* val1;
  2467. if (args.size() < 2)
  2468. {
  2469. llvm::Value* val;
  2470. if (isFP)
  2471. val = llvm::ConstantFP::get(elemType, 1);
  2472. else
  2473. val = llvm::ConstantInt::get(elemType, 1);
  2474. val1 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), val, (uint64)0);
  2475. val1 = mIRBuilder->CreateInsertElement(val1, val, (uint64)1);
  2476. val1 = mIRBuilder->CreateInsertElement(val1, val, (uint64)2);
  2477. val1 = mIRBuilder->CreateInsertElement(val1, val, (uint64)3);
  2478. }
  2479. else if (args[1]->getType()->isPointerTy())
  2480. {
  2481. auto ptrVal1 = mIRBuilder->CreateBitCast(args[1], vecType->getPointerTo());
  2482. val1 = mIRBuilder->CreateAlignedLoad(ptrVal1, 1);
  2483. }
  2484. else if (args[1]->getType()->isVectorTy())
  2485. {
  2486. val1 = args[1];
  2487. }
  2488. else
  2489. {
  2490. val1 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), args[1], (uint64)0);
  2491. val1 = mIRBuilder->CreateInsertElement(val1, args[1], (uint64)1);
  2492. val1 = mIRBuilder->CreateInsertElement(val1, args[1], (uint64)2);
  2493. val1 = mIRBuilder->CreateInsertElement(val1, args[1], (uint64)3);
  2494. }
  2495. if (isFP)
  2496. {
  2497. llvm::Value* result = NULL;
  2498. switch (intrinsicData->mIntrinsic)
  2499. {
  2500. case BfIRIntrinsic_Add:
  2501. result = mIRBuilder->CreateFAdd(val0, val1);
  2502. break;
  2503. case BfIRIntrinsic_Div:
  2504. result = mIRBuilder->CreateFDiv(val0, val1);
  2505. break;
  2506. case BfIRIntrinsic_Eq:
  2507. result = mIRBuilder->CreateFCmpOEQ(val0, val1);
  2508. break;
  2509. case BfIRIntrinsic_Gt:
  2510. result = mIRBuilder->CreateFCmpOGT(val0, val1);
  2511. break;
  2512. case BfIRIntrinsic_GtE:
  2513. result = mIRBuilder->CreateFCmpOGE(val0, val1);
  2514. break;
  2515. case BfIRIntrinsic_Lt:
  2516. result = mIRBuilder->CreateFCmpOLT(val0, val1);
  2517. break;
  2518. case BfIRIntrinsic_LtE:
  2519. result = mIRBuilder->CreateFCmpOLE(val0, val1);
  2520. break;
  2521. case BfIRIntrinsic_Mod:
  2522. result = mIRBuilder->CreateFRem(val0, val1);
  2523. break;
  2524. case BfIRIntrinsic_Mul:
  2525. result = mIRBuilder->CreateFMul(val0, val1);
  2526. break;
  2527. case BfIRIntrinsic_Neq:
  2528. result = mIRBuilder->CreateFCmpONE(val0, val1);
  2529. break;
  2530. case BfIRIntrinsic_Sub:
  2531. result = mIRBuilder->CreateFSub(val0, val1);
  2532. break;
  2533. default:
  2534. FatalError("Intrinsic argument error");
  2535. }
  2536. if (result != NULL)
  2537. {
  2538. if (auto vecType = llvm::dyn_cast<llvm::VectorType>(result->getType()))
  2539. {
  2540. if (auto intType = llvm::dyn_cast<llvm::IntegerType>(vecType->getElementType()))
  2541. {
  2542. if (intType->getBitWidth() == 1)
  2543. {
  2544. auto toType = llvm::VectorType::get(llvm::IntegerType::get(*mLLVMContext, 8), vecType->getNumElements());
  2545. result = mIRBuilder->CreateZExt(result, toType);
  2546. }
  2547. }
  2548. }
  2549. SetResult(curId, result);
  2550. }
  2551. }
  2552. else
  2553. {
  2554. llvm::Value* result = NULL;
  2555. switch (intrinsicData->mIntrinsic)
  2556. {
  2557. case BfIRIntrinsic_And:
  2558. result = mIRBuilder->CreateAnd(val0, val1);
  2559. break;
  2560. case BfIRIntrinsic_Add:
  2561. result = mIRBuilder->CreateAdd(val0, val1);
  2562. break;
  2563. case BfIRIntrinsic_Div:
  2564. result = mIRBuilder->CreateSDiv(val0, val1);
  2565. break;
  2566. case BfIRIntrinsic_Eq:
  2567. result = mIRBuilder->CreateICmpEQ(val0, val1);
  2568. break;
  2569. case BfIRIntrinsic_Gt:
  2570. result = mIRBuilder->CreateICmpSGT(val0, val1);
  2571. break;
  2572. case BfIRIntrinsic_GtE:
  2573. result = mIRBuilder->CreateICmpSGE(val0, val1);
  2574. break;
  2575. case BfIRIntrinsic_Lt:
  2576. result = mIRBuilder->CreateICmpSLT(val0, val1);
  2577. break;
  2578. case BfIRIntrinsic_LtE:
  2579. result = mIRBuilder->CreateICmpSLE(val0, val1);
  2580. break;
  2581. case BfIRIntrinsic_Mod:
  2582. result = mIRBuilder->CreateSRem(val0, val1);
  2583. break;
  2584. case BfIRIntrinsic_Mul:
  2585. result = mIRBuilder->CreateMul(val0, val1);
  2586. break;
  2587. case BfIRIntrinsic_Neq:
  2588. result = mIRBuilder->CreateICmpNE(val0, val1);
  2589. break;
  2590. case BfIRIntrinsic_Or:
  2591. result = mIRBuilder->CreateOr(val0, val1);
  2592. break;
  2593. case BfIRIntrinsic_Sub:
  2594. result = mIRBuilder->CreateSub(val0, val1);
  2595. break;
  2596. case BfIRIntrinsic_Xor:
  2597. result = mIRBuilder->CreateXor(val0, val1);
  2598. break;
  2599. default:
  2600. FatalError("Intrinsic argument error");
  2601. }
  2602. if (result != NULL)
  2603. {
  2604. if (auto vecType = llvm::dyn_cast<llvm::VectorType>(result->getType()))
  2605. {
  2606. if (auto intType = llvm::dyn_cast<llvm::IntegerType>(vecType->getElementType()))
  2607. {
  2608. if (intType->getBitWidth() == 1)
  2609. {
  2610. auto toType = llvm::VectorType::get(llvm::IntegerType::get(*mLLVMContext, 8), vecType->getNumElements());
  2611. result = mIRBuilder->CreateZExt(result, toType);
  2612. }
  2613. }
  2614. }
  2615. SetResult(curId, result);
  2616. }
  2617. }
  2618. }
  2619. else if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(args[1]->getType()))
  2620. {
  2621. auto ptrElemType = ptrType->getElementType();
  2622. if (auto arrType = llvm::dyn_cast<llvm::ArrayType>(ptrElemType))
  2623. {
  2624. auto vecType = llvm::VectorType::get(arrType->getArrayElementType(), (uint)arrType->getArrayNumElements());
  2625. auto vecPtrType = vecType->getPointerTo();
  2626. llvm::Value* val0;
  2627. val0 = mIRBuilder->CreateInsertElement(llvm::UndefValue::get(vecType), args[0], (uint64)0);
  2628. val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)1);
  2629. val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)2);
  2630. val0 = mIRBuilder->CreateInsertElement(val0, args[0], (uint64)3);
  2631. auto ptrVal1 = mIRBuilder->CreateBitCast(args[1], vecPtrType);
  2632. auto val1 = mIRBuilder->CreateAlignedLoad(ptrVal1, 1);
  2633. switch (intrinsicData->mIntrinsic)
  2634. {
  2635. case BfIRIntrinsic_Div:
  2636. SetResult(curId, mIRBuilder->CreateFDiv(val0, val1));
  2637. break;
  2638. case BfIRIntrinsic_Mod:
  2639. SetResult(curId, mIRBuilder->CreateFRem(val0, val1));
  2640. break;
  2641. default:
  2642. FatalError("Intrinsic argument error");
  2643. }
  2644. }
  2645. }
  2646. else
  2647. {
  2648. FatalError("Intrinsic argument error");
  2649. }
  2650. }
  2651. break;
  2652. case BfIRIntrinsic_Not:
  2653. {
  2654. auto val0 = TryToVector(args[0]);
  2655. SetResult(curId, mIRBuilder->CreateNot(val0));
  2656. }
  2657. break;
  2658. case BfIRIntrinsic_Shuffle:
  2659. {
  2660. llvm::SmallVector<uint, 8> intMask;
  2661. for (int i = 7; i < (int)intrinsicData->mName.length(); i++)
  2662. intMask.push_back((uint)(intrinsicData->mName[i] - '0'));
  2663. auto val0 = TryToVector(args[0]);
  2664. if (val0 != NULL)
  2665. {
  2666. SetResult(curId, mIRBuilder->CreateShuffleVector(val0, val0, intMask));
  2667. }
  2668. else
  2669. {
  2670. FatalError("Intrinsic argument error");
  2671. }
  2672. }
  2673. break;
  2674. case BfIRIntrinsic_Index:
  2675. {
  2676. llvm::Value* gepArgs[] = {
  2677. llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0),
  2678. args[1] };
  2679. auto gep = mIRBuilder->CreateInBoundsGEP(args[0], llvm::makeArrayRef(gepArgs));
  2680. if (args.size() >= 3)
  2681. mIRBuilder->CreateStore(args[2], gep);
  2682. else
  2683. SetResult(curId, mIRBuilder->CreateLoad(gep));
  2684. }
  2685. break;
  2686. case BfIRIntrinsic_AtomicCmpStore:
  2687. case BfIRIntrinsic_AtomicCmpStore_Weak:
  2688. case BfIRIntrinsic_AtomicCmpXChg:
  2689. {
  2690. auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[3]);
  2691. if (memoryKindConst == NULL)
  2692. {
  2693. FatalError("Non-constant success ordering on Atomic_CmpXChg");
  2694. break;
  2695. }
  2696. auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
  2697. auto successOrdering = llvm::AtomicOrdering::Unordered;
  2698. auto failOrdering = llvm::AtomicOrdering::Unordered;
  2699. switch (memoryKind & BfIRAtomicOrdering_ORDERMASK)
  2700. {
  2701. case BfIRAtomicOrdering_Acquire:
  2702. successOrdering = llvm::AtomicOrdering::Acquire;
  2703. failOrdering = llvm::AtomicOrdering::Acquire;
  2704. break;
  2705. case BfIRAtomicOrdering_AcqRel:
  2706. successOrdering = llvm::AtomicOrdering::AcquireRelease;
  2707. failOrdering = llvm::AtomicOrdering::Acquire;
  2708. break;
  2709. case BfIRAtomicOrdering_Relaxed:
  2710. successOrdering = llvm::AtomicOrdering::Monotonic;
  2711. failOrdering = llvm::AtomicOrdering::Monotonic;
  2712. break;
  2713. case BfIRAtomicOrdering_Release:
  2714. successOrdering = llvm::AtomicOrdering::Release;
  2715. failOrdering = llvm::AtomicOrdering::Monotonic;
  2716. break;
  2717. case BfIRAtomicOrdering_SeqCst:
  2718. successOrdering = llvm::AtomicOrdering::SequentiallyConsistent;
  2719. failOrdering = llvm::AtomicOrdering::SequentiallyConsistent;
  2720. break;
  2721. default:
  2722. Fail("Invalid success ordering on Atomic_CmpXChg");
  2723. break;
  2724. }
  2725. if (args.size() >= 5)
  2726. {
  2727. auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[4]);
  2728. if (memoryKindConst == NULL)
  2729. {
  2730. FatalError("Non-constant fail ordering on Atomic_CmpXChg");
  2731. break;
  2732. }
  2733. auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
  2734. switch (memoryKind & BfIRAtomicOrdering_ORDERMASK)
  2735. {
  2736. case BfIRAtomicOrdering_Acquire:
  2737. failOrdering = llvm::AtomicOrdering::Acquire;
  2738. break;
  2739. case BfIRAtomicOrdering_Relaxed:
  2740. failOrdering = llvm::AtomicOrdering::Monotonic;
  2741. break;
  2742. case BfIRAtomicOrdering_SeqCst:
  2743. failOrdering = llvm::AtomicOrdering::SequentiallyConsistent;
  2744. break;
  2745. default:
  2746. FatalError("Invalid fail ordering on Atomic_CmpXChg");
  2747. break;
  2748. }
  2749. }
  2750. auto inst = mIRBuilder->CreateAtomicCmpXchg(args[0], args[1], args[2], successOrdering, failOrdering);
  2751. if (intrinsicData->mIntrinsic == BfIRIntrinsic_AtomicCmpStore_Weak)
  2752. inst->setWeak(true);
  2753. if ((memoryKind & BfIRAtomicOrdering_Volatile) != 0)
  2754. inst->setVolatile(true);
  2755. if (intrinsicData->mIntrinsic == BfIRIntrinsic_AtomicCmpXChg)
  2756. {
  2757. auto prevVal = mIRBuilder->CreateExtractValue(inst, 0);
  2758. SetResult(curId, prevVal);
  2759. }
  2760. else
  2761. {
  2762. auto successVal = mIRBuilder->CreateExtractValue(inst, 1);
  2763. SetResult(curId, successVal);
  2764. }
  2765. }
  2766. break;
  2767. case BfIRIntrinsic_AtomicFence:
  2768. {
  2769. if (args.size() == 0)
  2770. {
  2771. if ((mTargetTriple.GetMachineType() != BfMachineType_x86) && (mTargetTriple.GetMachineType() != BfMachineType_x64))
  2772. {
  2773. Fail("Unable to create compiler barrier on this platform");
  2774. }
  2775. else
  2776. {
  2777. // Compiler barrier
  2778. llvm::SmallVector<llvm::Type*, 8> paramTypes;
  2779. llvm::FunctionType* funcType = llvm::FunctionType::get(llvm::Type::getVoidTy(*mLLVMContext), paramTypes, false);
  2780. auto fenceFunc = llvm::InlineAsm::get(funcType,
  2781. "", "~{memory},~{dirflag},~{fpsr},~{flags}", true, false, llvm::InlineAsm::AD_ATT);
  2782. mIRBuilder->CreateCall(fenceFunc);
  2783. }
  2784. break;
  2785. }
  2786. auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[0]);
  2787. if (memoryKindConst == NULL)
  2788. {
  2789. FatalError("Non-constant success ordering on AtomicFence");
  2790. break;
  2791. }
  2792. auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
  2793. auto ordering = llvm::AtomicOrdering::SequentiallyConsistent;
  2794. switch (memoryKind & BfIRAtomicOrdering_ORDERMASK)
  2795. {
  2796. case BfIRAtomicOrdering_Acquire:
  2797. ordering = llvm::AtomicOrdering::Acquire;
  2798. break;
  2799. case BfIRAtomicOrdering_AcqRel:
  2800. ordering = llvm::AtomicOrdering::AcquireRelease;
  2801. break;
  2802. case BfIRAtomicOrdering_Release:
  2803. ordering = llvm::AtomicOrdering::Release;
  2804. break;
  2805. case BfIRAtomicOrdering_SeqCst:
  2806. ordering = llvm::AtomicOrdering::SequentiallyConsistent;
  2807. break;
  2808. default:
  2809. Fail("Invalid ordering on atomic operation");
  2810. break;
  2811. }
  2812. mIRBuilder->CreateFence(ordering);
  2813. }
  2814. break;
  2815. case BfIRIntrinsic_AtomicLoad:
  2816. {
  2817. auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[1]);
  2818. if (memoryKindConst == NULL)
  2819. {
  2820. FatalError("Non-constant success ordering on AtomicLoad");
  2821. break;
  2822. }
  2823. auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
  2824. auto ptrType = llvm::dyn_cast<llvm::PointerType>(args[0]->getType());
  2825. auto loadInst = mIRBuilder->CreateAlignedLoad(args[0], (uint)ptrType->getElementType()->getPrimitiveSizeInBits() / 8);
  2826. switch (memoryKind & BfIRAtomicOrdering_ORDERMASK)
  2827. {
  2828. case BfIRAtomicOrdering_Acquire:
  2829. loadInst->setAtomic(llvm::AtomicOrdering::Acquire);
  2830. break;
  2831. case BfIRAtomicOrdering_Relaxed:
  2832. loadInst->setAtomic(llvm::AtomicOrdering::Monotonic);
  2833. break;
  2834. case BfIRAtomicOrdering_SeqCst:
  2835. loadInst->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
  2836. break;
  2837. default:
  2838. BF_FATAL("BadAtomic");
  2839. }
  2840. if ((memoryKind & BfIRAtomicOrdering_Volatile) != 0)
  2841. loadInst->setVolatile(true);
  2842. SetResult(curId, loadInst);
  2843. }
  2844. break;
  2845. case BfIRIntrinsic_AtomicStore:
  2846. {
  2847. auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[1]);
  2848. if (memoryKindConst == NULL)
  2849. {
  2850. FatalError("Non-constant success ordering on AtomicLoad");
  2851. break;
  2852. }
  2853. auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
  2854. auto storeInst = mIRBuilder->CreateAlignedStore(args[1], args[0], (uint)args[1]->getType()->getPrimitiveSizeInBits() / 8);
  2855. switch (memoryKind & BfIRAtomicOrdering_ORDERMASK)
  2856. {
  2857. case BfIRAtomicOrdering_Relaxed:
  2858. storeInst->setAtomic(llvm::AtomicOrdering::Monotonic);
  2859. break;
  2860. case BfIRAtomicOrdering_Release:
  2861. storeInst->setAtomic(llvm::AtomicOrdering::Release);
  2862. break;
  2863. case BfIRAtomicOrdering_SeqCst:
  2864. storeInst->setAtomic(llvm::AtomicOrdering::SequentiallyConsistent);
  2865. break;
  2866. }
  2867. if ((memoryKind & BfIRAtomicOrdering_Volatile) != 0)
  2868. storeInst->setVolatile(true);
  2869. SetResult(curId, storeInst);
  2870. }
  2871. break;
  2872. case BfIRIntrinsic_AtomicAdd:
  2873. case BfIRIntrinsic_AtomicAnd:
  2874. case BfIRIntrinsic_AtomicMax:
  2875. case BfIRIntrinsic_AtomicMin:
  2876. case BfIRIntrinsic_AtomicNAnd:
  2877. case BfIRIntrinsic_AtomicOr:
  2878. case BfIRIntrinsic_AtomicSub:
  2879. case BfIRIntrinsic_AtomicUMax:
  2880. case BfIRIntrinsic_AtomicUMin:
  2881. case BfIRIntrinsic_AtomicXChg:
  2882. case BfIRIntrinsic_AtomicXor:
  2883. {
  2884. bool isFloat = args[1]->getType()->isFloatingPointTy();
  2885. auto op = llvm::AtomicRMWInst::BinOp::Add;
  2886. switch (intrinsicData->mIntrinsic)
  2887. {
  2888. case BfIRIntrinsic_AtomicAdd:
  2889. op = llvm::AtomicRMWInst::BinOp::Add;
  2890. break;
  2891. case BfIRIntrinsic_AtomicAnd:
  2892. op = llvm::AtomicRMWInst::BinOp::And;
  2893. break;
  2894. case BfIRIntrinsic_AtomicMax:
  2895. op = llvm::AtomicRMWInst::BinOp::Max;
  2896. break;
  2897. case BfIRIntrinsic_AtomicMin:
  2898. op = llvm::AtomicRMWInst::BinOp::Min;
  2899. break;
  2900. case BfIRIntrinsic_AtomicNAnd:
  2901. op = llvm::AtomicRMWInst::BinOp::Nand;
  2902. break;
  2903. case BfIRIntrinsic_AtomicOr:
  2904. op = llvm::AtomicRMWInst::BinOp::Or;
  2905. break;
  2906. case BfIRIntrinsic_AtomicSub:
  2907. op = llvm::AtomicRMWInst::BinOp::Sub;
  2908. break;
  2909. case BfIRIntrinsic_AtomicUMax:
  2910. op = llvm::AtomicRMWInst::BinOp::UMax;
  2911. break;
  2912. case BfIRIntrinsic_AtomicUMin:
  2913. op = llvm::AtomicRMWInst::BinOp::UMin;
  2914. break;
  2915. case BfIRIntrinsic_AtomicXChg:
  2916. op = llvm::AtomicRMWInst::BinOp::Xchg;
  2917. break;
  2918. case BfIRIntrinsic_AtomicXor:
  2919. op = llvm::AtomicRMWInst::BinOp::Xor;
  2920. break;
  2921. default: break;
  2922. }
  2923. auto memoryKindConst = llvm::dyn_cast<llvm::ConstantInt>(args[2]);
  2924. if (memoryKindConst == NULL)
  2925. {
  2926. FatalError("Non-constant ordering on atomic operation");
  2927. break;
  2928. }
  2929. auto memoryKind = (BfIRAtomicOrdering)memoryKindConst->getSExtValue();
  2930. auto ordering = llvm::AtomicOrdering::Unordered;
  2931. switch (memoryKind & BfIRAtomicOrdering_ORDERMASK)
  2932. {
  2933. case BfIRAtomicOrdering_Acquire:
  2934. ordering = llvm::AtomicOrdering::Acquire;
  2935. break;
  2936. case BfIRAtomicOrdering_AcqRel:
  2937. ordering = llvm::AtomicOrdering::AcquireRelease;
  2938. break;
  2939. case BfIRAtomicOrdering_Relaxed:
  2940. ordering = llvm::AtomicOrdering::Monotonic;
  2941. break;
  2942. case BfIRAtomicOrdering_Release:
  2943. ordering = llvm::AtomicOrdering::Release;
  2944. break;
  2945. case BfIRAtomicOrdering_SeqCst:
  2946. ordering = llvm::AtomicOrdering::SequentiallyConsistent;
  2947. break;
  2948. default:
  2949. Fail("Invalid ordering on atomic operation");
  2950. break;
  2951. }
  2952. auto atomicRMW = mIRBuilder->CreateAtomicRMW(op, args[0], args[1], ordering);
  2953. if ((memoryKind & BfIRAtomicOrdering_Volatile) != 0)
  2954. atomicRMW->setVolatile(true);
  2955. llvm::Value* result = atomicRMW;
  2956. if ((memoryKind & BfIRAtomicOrdering_ReturnModified) != 0)
  2957. {
  2958. switch (intrinsicData->mIntrinsic)
  2959. {
  2960. case BfIRIntrinsic_AtomicAdd:
  2961. if (isFloat)
  2962. result = mIRBuilder->CreateFAdd(atomicRMW, args[1]);
  2963. else
  2964. result = mIRBuilder->CreateAdd(atomicRMW, args[1]);
  2965. break;
  2966. case BfIRIntrinsic_AtomicAnd:
  2967. result = mIRBuilder->CreateAnd(atomicRMW, args[1]);
  2968. break;
  2969. case BfIRIntrinsic_AtomicMax:
  2970. case BfIRIntrinsic_AtomicMin:
  2971. case BfIRIntrinsic_AtomicUMax:
  2972. case BfIRIntrinsic_AtomicUMin:
  2973. {
  2974. llvm::Value* cmpVal = NULL;
  2975. switch (intrinsicData->mIntrinsic)
  2976. {
  2977. case BfIRIntrinsic_AtomicMax:
  2978. if (isFloat)
  2979. cmpVal = mIRBuilder->CreateFCmpOGE(atomicRMW, args[1]);
  2980. else
  2981. cmpVal = mIRBuilder->CreateICmpSGE(atomicRMW, args[1]);
  2982. break;
  2983. case BfIRIntrinsic_AtomicMin:
  2984. if (isFloat)
  2985. cmpVal = mIRBuilder->CreateFCmpOLE(atomicRMW, args[1]);
  2986. else
  2987. cmpVal = mIRBuilder->CreateICmpSLE(atomicRMW, args[1]);
  2988. break;
  2989. case BfIRIntrinsic_AtomicUMax:
  2990. cmpVal = mIRBuilder->CreateICmpUGE(atomicRMW, args[1]);
  2991. break;
  2992. case BfIRIntrinsic_AtomicUMin:
  2993. cmpVal = mIRBuilder->CreateICmpULE(atomicRMW, args[1]);
  2994. break;
  2995. default: break;
  2996. }
  2997. result = mIRBuilder->CreateSelect(cmpVal, atomicRMW, args[1]);
  2998. }
  2999. break;
  3000. case BfIRIntrinsic_AtomicNAnd:
  3001. result = mIRBuilder->CreateAnd(atomicRMW, args[1]);
  3002. result = mIRBuilder->CreateNot(result);
  3003. break;
  3004. case BfIRIntrinsic_AtomicOr:
  3005. result = mIRBuilder->CreateOr(atomicRMW, args[1]);
  3006. break;
  3007. case BfIRIntrinsic_AtomicSub:
  3008. if (isFloat)
  3009. result = mIRBuilder->CreateFSub(atomicRMW, args[1]);
  3010. else
  3011. result = mIRBuilder->CreateSub(atomicRMW, args[1]);
  3012. break;
  3013. case BfIRIntrinsic_AtomicXor:
  3014. result = mIRBuilder->CreateXor(atomicRMW, args[1]);
  3015. break;
  3016. case BfIRIntrinsic_AtomicXChg:
  3017. result = args[1];
  3018. break;
  3019. default: break;
  3020. }
  3021. }
  3022. SetResult(curId, result);
  3023. }
  3024. break;
  3025. case BfIRIntrinsic_Cast:
  3026. {
  3027. auto arg0Type = args[0]->getType();
  3028. if (arg0Type->isPointerTy())
  3029. {
  3030. if (intrinsicData->mReturnType->isPointerTy())
  3031. {
  3032. SetResult(curId, mIRBuilder->CreateBitCast(args[0], intrinsicData->mReturnType));
  3033. }
  3034. else
  3035. {
  3036. auto castedRes = mIRBuilder->CreateBitCast(args[0], intrinsicData->mReturnType->getPointerTo());
  3037. SetResult(curId, mIRBuilder->CreateAlignedLoad(castedRes, 1));
  3038. }
  3039. }
  3040. else
  3041. {
  3042. FatalError("Expected address");
  3043. }
  3044. }
  3045. break;
  3046. default:
  3047. FatalError("Unhandled intrinsic");
  3048. }
  3049. break;
  3050. }
  3051. if (auto funcPtr = llvm::dyn_cast<llvm::Function>(func))
  3052. {
  3053. // if (funcPtr->getName() == "__FAILCALL")
  3054. // {
  3055. // FatalError("__FAILCALL");
  3056. // }
  3057. int intrinId = -1;
  3058. if (mIntrinsicReverseMap.TryGetValue(funcPtr, &intrinId))
  3059. {
  3060. if (intrinId == BfIRIntrinsic__PLATFORM)
  3061. {
  3062. NOP;
  3063. }
  3064. if (intrinId == BfIRIntrinsic_MemSet)
  3065. {
  3066. int align = 1;
  3067. BF_ASSERT(args.size() == 5);
  3068. auto alignConst = llvm::dyn_cast<llvm::ConstantInt>(args[3]);
  3069. if (alignConst != NULL)
  3070. align = (int)alignConst->getSExtValue();
  3071. bool isVolatile = false;
  3072. auto volatileConst = llvm::dyn_cast<llvm::ConstantInt>(args[4]);
  3073. if ((volatileConst != NULL) && (volatileConst->getSExtValue() != 0))
  3074. isVolatile = true;
  3075. CreateMemSet(args[0], args[1], args[2], align, isVolatile);
  3076. break;
  3077. }
  3078. else if ((intrinId == BfIRIntrinsic_MemCpy) || (intrinId == BfIRIntrinsic_MemMove))
  3079. {
  3080. int align = 1;
  3081. BF_ASSERT(args.size() == 5);
  3082. auto alignConst = llvm::dyn_cast<llvm::ConstantInt>(args[3]);
  3083. if (alignConst != NULL)
  3084. align = (int)alignConst->getSExtValue();
  3085. bool isVolatile = false;
  3086. auto volatileConst = llvm::dyn_cast<llvm::ConstantInt>(args[4]);
  3087. if ((volatileConst != NULL) && (volatileConst->getSExtValue() != 0))
  3088. isVolatile = true;
  3089. if (intrinId == BfIRIntrinsic_MemCpy)
  3090. mIRBuilder->CreateMemCpy(args[0], llvm::MaybeAlign(align), args[1], llvm::MaybeAlign(align), args[2], isVolatile);
  3091. else
  3092. mIRBuilder->CreateMemMove(args[0], llvm::MaybeAlign(align), args[1], llvm::MaybeAlign(align), args[2], isVolatile);
  3093. break;
  3094. }
  3095. }
  3096. }
  3097. llvm::Value* val0 = NULL;
  3098. llvm::Value* val1 = NULL;
  3099. if (args.size() > 0)
  3100. {
  3101. val0 = args[0];
  3102. }
  3103. if (args.size() > 1)
  3104. {
  3105. val1 = args[1];
  3106. }
  3107. llvm::FunctionType* funcType = NULL;
  3108. if (auto ptrType = llvm::dyn_cast<llvm::PointerType>(func->getType()))
  3109. funcType = llvm::dyn_cast<llvm::FunctionType>(ptrType->getElementType());
  3110. SetResult(curId, mIRBuilder->CreateCall(funcType, func, args));
  3111. }
  3112. break;
  3113. case BfIRCmd_SetCallCallingConv:
  3114. {
  3115. CMD_PARAM(llvm::Value*, callInst);
  3116. BfIRCallingConv callingConv = (BfIRCallingConv)mStream->Read();
  3117. BF_ASSERT(llvm::isa<llvm::CallInst>(callInst));
  3118. ((llvm::CallInst*)callInst)->setCallingConv(GetLLVMCallingConv(callingConv));
  3119. }
  3120. break;
  3121. case BfIRCmd_SetFuncCallingConv:
  3122. {
  3123. CMD_PARAM(llvm::Function*, func);
  3124. BfIRCallingConv callingConv = (BfIRCallingConv)mStream->Read();
  3125. ((llvm::Function*)func)->setCallingConv(GetLLVMCallingConv(callingConv));
  3126. }
  3127. break;
  3128. case BfIRCmd_SetTailCall:
  3129. {
  3130. CMD_PARAM(llvm::Value*, callInst);
  3131. BF_ASSERT(llvm::isa<llvm::CallInst>(callInst));
  3132. ((llvm::CallInst*)callInst)->setTailCall();
  3133. }
  3134. break;
  3135. case BfIRCmd_SetCallAttribute:
  3136. {
  3137. CMD_PARAM(llvm::Value*, callInst);
  3138. CMD_PARAM(int, paramIdx);
  3139. BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
  3140. BF_ASSERT(llvm::isa<llvm::CallInst>(callInst));
  3141. llvm::Attribute::AttrKind attr = llvm::Attribute::None;
  3142. if (attribute == BfIRAttribute_NoReturn)
  3143. attr = llvm::Attribute::NoReturn;
  3144. ((llvm::CallInst*)callInst)->addAttribute(paramIdx, attr);
  3145. }
  3146. break;
  3147. case BfIRCmd_CreateRet:
  3148. {
  3149. CMD_PARAM(llvm::Value*, val);
  3150. SetResult(curId, mIRBuilder->CreateRet(val));
  3151. }
  3152. break;
  3153. case BfIRCmd_CreateRetVoid:
  3154. {
  3155. mIRBuilder->CreateRetVoid();
  3156. }
  3157. break;
  3158. case BfIRCmd_CreateUnreachable:
  3159. {
  3160. mIRBuilder->CreateUnreachable();
  3161. }
  3162. break;
  3163. case BfIRCmd_Call_AddAttribute:
  3164. {
  3165. CMD_PARAM(llvm::Value*, callInst);
  3166. CMD_PARAM(int, argIdx);
  3167. BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
  3168. BF_ASSERT(llvm::isa<llvm::CallInst>(callInst));
  3169. ((llvm::CallInst*)callInst)->addAttribute(argIdx, LLVMMapAttribute(attribute));
  3170. }
  3171. break;
  3172. case BfIRCmd_Call_AddAttribute1:
  3173. {
  3174. CMD_PARAM(llvm::Value*, inst);
  3175. CMD_PARAM(int, argIdx);
  3176. BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
  3177. CMD_PARAM(int, arg);
  3178. auto callInst = llvm::dyn_cast<llvm::CallInst>(inst);
  3179. if (callInst != NULL)
  3180. {
  3181. if (attribute == BfIRAttribute_Dereferencable)
  3182. {
  3183. ((llvm::CallInst*)callInst)->addDereferenceableAttr(argIdx, arg);
  3184. }
  3185. else if (attribute == BfIRAttribute_ByVal)
  3186. {
  3187. llvm::AttrBuilder B;
  3188. B.addAttribute(llvm::Attribute::ByVal);
  3189. B.addAlignmentAttr(arg);
  3190. auto attrList = ((llvm::CallInst*)callInst)->getAttributes();
  3191. attrList = attrList.addAttributes(*mLLVMContext, argIdx, B);
  3192. ((llvm::CallInst*)callInst)->setAttributes(attrList);
  3193. }
  3194. }
  3195. }
  3196. break;
  3197. case BfIRCmd_Func_AddAttribute:
  3198. {
  3199. CMD_PARAM(llvm::Function*, func);
  3200. CMD_PARAM(int, argIdx);
  3201. BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
  3202. if (attribute == BFIRAttribute_DllImport)
  3203. {
  3204. func->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
  3205. }
  3206. else if (attribute == BFIRAttribute_DllExport)
  3207. {
  3208. func->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
  3209. }
  3210. else if (attribute == BFIRAttribute_NoFramePointerElim)
  3211. {
  3212. func->addFnAttr("no-frame-pointer-elim", "true");
  3213. }
  3214. else if ((attribute == BFIRAttribute_Constructor) || (attribute == BFIRAttribute_Destructor))
  3215. {
  3216. CmdParamVec<llvm::Type*> members;
  3217. members.push_back(llvm::Type::getInt32Ty(*mLLVMContext));
  3218. members.push_back(func->getType());
  3219. members.push_back(llvm::Type::getInt8PtrTy(*mLLVMContext));
  3220. llvm::StructType* structType = llvm::StructType::get(*mLLVMContext, members);
  3221. CmdParamVec<llvm::Constant*> structVals;
  3222. structVals.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0x7FFFFF00));
  3223. structVals.push_back(func);
  3224. structVals.push_back(llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(*mLLVMContext)));
  3225. auto constStruct = llvm::ConstantStruct::get(structType, structVals);
  3226. CmdParamVec<llvm::Constant*> structArrVals;
  3227. structArrVals.push_back(constStruct);
  3228. auto arrTy = llvm::ArrayType::get(structType, 1);
  3229. auto constArr = llvm::ConstantArray::get(arrTy, structArrVals);
  3230. auto globalVariable = new llvm::GlobalVariable(
  3231. *mLLVMModule,
  3232. arrTy,
  3233. false,
  3234. llvm::GlobalValue::AppendingLinkage,
  3235. constArr,
  3236. (attribute == BFIRAttribute_Constructor) ? "llvm.global_ctors" : "llvm.global_dtors",
  3237. NULL, llvm::GlobalValue::NotThreadLocal);
  3238. }
  3239. else
  3240. func->addAttribute(argIdx, LLVMMapAttribute(attribute));
  3241. }
  3242. break;
  3243. case BfIRCmd_Func_AddAttribute1:
  3244. {
  3245. CMD_PARAM(llvm::Function*, func);
  3246. CMD_PARAM(int, argIdx);
  3247. BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
  3248. CMD_PARAM(int, arg);
  3249. if (attribute == BfIRAttribute_Dereferencable)
  3250. {
  3251. ((llvm::Function*)func)->addDereferenceableAttr(argIdx, arg);
  3252. }
  3253. else if (attribute == BfIRAttribute_ByVal)
  3254. {
  3255. llvm::AttrBuilder B;
  3256. B.addAttribute(llvm::Attribute::ByVal);
  3257. B.addAlignmentAttr(arg);
  3258. auto attrList = ((llvm::Function*)func)->getAttributes();
  3259. attrList = attrList.addAttributes(*mLLVMContext, argIdx, B);
  3260. ((llvm::Function*)func)->setAttributes(attrList);
  3261. }
  3262. }
  3263. break;
  3264. case BfIRCmd_Func_SetParamName:
  3265. {
  3266. CMD_PARAM(llvm::Function*, func);
  3267. CMD_PARAM(int, argIdx);
  3268. CMD_PARAM(String, name);
  3269. auto argItr = ((llvm::Function*)func)->arg_begin();
  3270. for (int i = 1; i < argIdx; i++)
  3271. ++argItr;
  3272. argItr->setName(name.c_str());
  3273. }
  3274. break;
  3275. case BfIRCmd_Func_DeleteBody:
  3276. {
  3277. CMD_PARAM(llvm::Function*, func);
  3278. BF_ASSERT(llvm::isa<llvm::Function>(func));
  3279. ((llvm::Function*)func)->deleteBody();
  3280. }
  3281. break;
  3282. case BfIRCmd_Func_SafeRename:
  3283. {
  3284. CMD_PARAM(llvm::Function*, func);
  3285. func->setName(llvm::Twine((Beefy::String(func->getName().data()) + StrFormat("__RENAME%d", curId)).c_str()));
  3286. }
  3287. break;
  3288. case BfIRCmd_Func_SetLinkage:
  3289. {
  3290. CMD_PARAM(llvm::Function*, func);
  3291. BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
  3292. ((llvm::Function*)func)->setLinkage(LLVMMapLinkageType(linkageType));
  3293. }
  3294. break;
  3295. case BfIRCmd_SaveDebugLocation:
  3296. {
  3297. mSavedDebugLocs.push_back(mIRBuilder->getCurrentDebugLocation());
  3298. }
  3299. break;
  3300. case BfIRCmd_RestoreDebugLocation:
  3301. {
  3302. mDebugLoc = mSavedDebugLocs[mSavedDebugLocs.size() - 1];
  3303. mIRBuilder->SetCurrentDebugLocation(mDebugLoc);
  3304. mSavedDebugLocs.pop_back();
  3305. }
  3306. break;
  3307. case BfIRCmd_DupDebugLocation:
  3308. break;
  3309. case BfIRCmd_ClearDebugLocation:
  3310. {
  3311. mDebugLoc = llvm::DebugLoc();
  3312. mIRBuilder->SetCurrentDebugLocation(llvm::DebugLoc());
  3313. }
  3314. break;
  3315. case BfIRCmd_ClearDebugLocationInst:
  3316. {
  3317. CMD_PARAM(llvm::Value*, instValue);
  3318. BF_ASSERT(llvm::isa<llvm::Instruction>(instValue));
  3319. ((llvm::Instruction*)instValue)->setDebugLoc(llvm::DebugLoc());
  3320. }
  3321. break;
  3322. case BfIRCmd_ClearDebugLocationInstLast:
  3323. {
  3324. llvm::BasicBlock* bb = mIRBuilder->GetInsertBlock();
  3325. if (bb != NULL)
  3326. {
  3327. auto& instList = bb->getInstList();
  3328. if (!instList.empty())
  3329. {
  3330. auto& inst = instList.back();
  3331. inst.setDebugLoc(llvm::DebugLoc());
  3332. }
  3333. }
  3334. }
  3335. break;
  3336. case BfIRCmd_UpdateDebugLocation:
  3337. {
  3338. CMD_PARAM(llvm::Value*, instValue);
  3339. BF_ASSERT(llvm::isa<llvm::Instruction>(instValue));
  3340. ((llvm::Instruction*)instValue)->setDebugLoc(mIRBuilder->getCurrentDebugLocation());
  3341. }
  3342. break;
  3343. case BfIRCmd_SetCurrentDebugLocation:
  3344. {
  3345. CMD_PARAM(int, line);
  3346. CMD_PARAM(int, column);
  3347. CMD_PARAM(llvm::MDNode*, diScope);
  3348. CMD_PARAM(llvm::MDNode*, diInlinedAt);
  3349. mDebugLoc = llvm::DebugLoc::get(line, column, diScope, diInlinedAt);
  3350. }
  3351. break;
  3352. case BfIRCmd_Nop:
  3353. case BfIRCmd_EnsureInstructionAt:
  3354. AddNop();
  3355. break;
  3356. case BfIRCmd_StatementStart:
  3357. // We only commit the debug loc for statement starts
  3358. mIRBuilder->SetCurrentDebugLocation(mDebugLoc);
  3359. mHasDebugLoc = true;
  3360. break;
  3361. case BfIRCmd_ObjectAccessCheck:
  3362. {
  3363. CMD_PARAM(llvm::Value*, val);
  3364. CMD_PARAM(bool, useAsm);
  3365. auto curLLVMFunc = mActiveFunction;
  3366. auto irBuilder = mIRBuilder;
  3367. if ((mTargetTriple.GetMachineType() != BfMachineType_x86) && (mTargetTriple.GetMachineType() != BfMachineType_x64))
  3368. useAsm = false;
  3369. if (!useAsm)
  3370. {
  3371. // This is generates slower code than the inline asm in debug mode, but can optimize well in release
  3372. auto int8Ty = llvm::Type::getInt8Ty(*mLLVMContext);
  3373. auto int8Ptr = irBuilder->CreateBitCast(val, int8Ty->getPointerTo());
  3374. auto int8Val = irBuilder->CreateLoad(int8Ptr);
  3375. auto cmpResult = irBuilder->CreateICmpUGE(int8Val, llvm::ConstantInt::get(int8Ty, 0x80));
  3376. auto failBB = llvm::BasicBlock::Create(*mLLVMContext, "access.fail");
  3377. auto passBB = llvm::BasicBlock::Create(*mLLVMContext, "access.pass");
  3378. irBuilder->CreateCondBr(cmpResult, failBB, passBB);
  3379. curLLVMFunc->getBasicBlockList().push_back(failBB);
  3380. irBuilder->SetInsertPoint(failBB);
  3381. auto trapDecl = llvm::Intrinsic::getDeclaration(mLLVMModule, llvm::Intrinsic::trap);
  3382. auto callInst = irBuilder->CreateCall(trapDecl);
  3383. callInst->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoReturn);
  3384. irBuilder->CreateBr(passBB);
  3385. curLLVMFunc->getBasicBlockList().push_back(passBB);
  3386. irBuilder->SetInsertPoint(passBB);
  3387. SetResult(curId, passBB);
  3388. }
  3389. else
  3390. {
  3391. llvm::Type* voidPtrType = llvm::Type::getInt8PtrTy(*mLLVMContext);
  3392. if (mAsmObjectCheckAsm == NULL)
  3393. {
  3394. std::vector<llvm::Type*> paramTypes;
  3395. paramTypes.push_back(voidPtrType);
  3396. auto funcType = llvm::FunctionType::get(llvm::Type::getVoidTy(*mLLVMContext), paramTypes, false);
  3397. String asmStr =
  3398. "cmpb $$128, ($0)\n"
  3399. "jb 1f\n"
  3400. "int $$3\n"
  3401. "1:";
  3402. mAsmObjectCheckAsm = llvm::InlineAsm::get(funcType,
  3403. asmStr.c_str(), "r,~{dirflag},~{fpsr},~{flags}", true,
  3404. false, llvm::InlineAsm::AD_ATT);
  3405. }
  3406. llvm::SmallVector<llvm::Value*, 1> llvmArgs;
  3407. llvmArgs.push_back(mIRBuilder->CreateBitCast(val, voidPtrType));
  3408. llvm::CallInst* callInst = irBuilder->CreateCall(mAsmObjectCheckAsm, llvmArgs);
  3409. callInst->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoUnwind);
  3410. SetResult(curId, mIRBuilder->GetInsertBlock());
  3411. }
  3412. }
  3413. break;
  3414. case BfIRCmd_DbgInit:
  3415. {
  3416. mDIBuilder = new llvm::DIBuilder(*mLLVMModule);
  3417. }
  3418. break;
  3419. case BfIRCmd_DbgFinalize:
  3420. {
  3421. for (auto& typeEntryPair : mTypes)
  3422. {
  3423. auto& typeEntry = typeEntryPair.mValue;
  3424. if (typeEntry.mInstDIType != NULL)
  3425. typeEntry.mInstDIType->resolveCycles();
  3426. }
  3427. mDIBuilder->finalize();
  3428. }
  3429. break;
  3430. case BfIRCmd_DbgCreateCompileUnit:
  3431. {
  3432. CMD_PARAM(int, lang);
  3433. CMD_PARAM(String, fileName);
  3434. CMD_PARAM(String, directory);
  3435. CMD_PARAM(String, producer);
  3436. CMD_PARAM(bool, isOptimized);
  3437. CMD_PARAM(String, flags);
  3438. CMD_PARAM(int, runtimeVer);
  3439. CMD_PARAM(bool, linesOnly);
  3440. auto diFile = mDIBuilder->createFile(fileName.c_str(), directory.c_str());
  3441. mDICompileUnit = mDIBuilder->createCompileUnit(lang, diFile, producer.c_str(), isOptimized, flags.c_str(), runtimeVer, "", linesOnly ? llvm::DICompileUnit::LineTablesOnly : llvm::DICompileUnit::FullDebug);
  3442. SetResult(curId, mDICompileUnit);
  3443. }
  3444. break;
  3445. case BfIRCmd_DbgCreateFile:
  3446. {
  3447. CMD_PARAM(String, fileName);
  3448. CMD_PARAM(String, directory);
  3449. CMD_PARAM(Val128, md5Hash);
  3450. char hashStr[64];
  3451. for (int i = 0; i < 16; i++)
  3452. sprintf(&hashStr[i * 2], "%.2x", ((uint8*)&md5Hash)[i]);
  3453. SetResult(curId, mDIBuilder->createFile(fileName.c_str(), directory.c_str(),
  3454. llvm::DIFile::ChecksumInfo<llvm::StringRef>(llvm::DIFile::CSK_MD5, hashStr)));
  3455. }
  3456. break;
  3457. case BfIRCmd_ConstValueI64:
  3458. {
  3459. CMD_PARAM(int64, val);
  3460. SetResult(curId, mDIBuilder->createConstantValueExpression((uint64)val));
  3461. }
  3462. break;
  3463. case BfIRCmd_DbgGetCurrentLocation:
  3464. {
  3465. SetResult(curId, mIRBuilder->getCurrentDebugLocation());
  3466. }
  3467. break;
  3468. case BfIRCmd_DbgSetType:
  3469. {
  3470. CMD_PARAM(int, typeId);
  3471. CMD_PARAM(llvm::MDNode*, type);
  3472. auto& typeEntry = GetTypeEntry(typeId);
  3473. typeEntry.mDIType = (llvm::DIType*)type;
  3474. if (typeEntry.mInstDIType == NULL)
  3475. typeEntry.mInstDIType = (llvm::DIType*)type;
  3476. }
  3477. break;
  3478. case BfIRCmd_DbgSetInstType:
  3479. {
  3480. CMD_PARAM(int, typeId);
  3481. CMD_PARAM(llvm::MDNode*, type);
  3482. GetTypeEntry(typeId).mInstDIType = (llvm::DIType*)type;
  3483. }
  3484. break;
  3485. case BfIRCmd_DbgGetType:
  3486. {
  3487. CMD_PARAM(int, typeId);
  3488. SetResult(curId, GetTypeEntry(typeId).mDIType);
  3489. }
  3490. break;
  3491. case BfIRCmd_DbgGetTypeInst:
  3492. {
  3493. CMD_PARAM(int, typeId);
  3494. SetResult(curId, GetTypeEntry(typeId).mInstDIType);
  3495. }
  3496. break;
  3497. case BfIRCmd_DbgTrackDITypes:
  3498. {
  3499. CMD_PARAM(int, typeId);
  3500. auto& typeEntry = GetTypeEntry(typeId);
  3501. if (typeEntry.mDIType != NULL)
  3502. llvm::MetadataTracking::track(*(llvm::Metadata**)&typeEntry.mDIType);
  3503. if (typeEntry.mInstDIType != NULL)
  3504. llvm::MetadataTracking::track(*(llvm::Metadata**)&typeEntry.mInstDIType);
  3505. }
  3506. break;
  3507. case BfIRCmd_DbgCreateNamespace:
  3508. {
  3509. CMD_PARAM(llvm::MDNode*, scope);
  3510. CMD_PARAM(String, name);
  3511. CMD_PARAM(llvm::MDNode*, file);
  3512. CMD_PARAM(int, lineNum);
  3513. BF_ASSERT(file != NULL);
  3514. SetResult(curId, mDIBuilder->createNameSpace((llvm::DIScope*)scope, name.c_str(), true));
  3515. }
  3516. break;
  3517. case BfIRCmd_DbgCreateImportedModule:
  3518. {
  3519. CMD_PARAM(llvm::MDNode*, context);
  3520. CMD_PARAM(llvm::MDNode*, namespaceNode);
  3521. CMD_PARAM(int, lineNum);
  3522. //SetResult(curId, mDIBuilder->createImportedModule((llvm::DIScope*)context, (llvm::DINamespace*)namespaceNode, lineNum));
  3523. }
  3524. break;
  3525. case BfIRCmd_DbgCreateBasicType:
  3526. {
  3527. CMD_PARAM(String, name);
  3528. CMD_PARAM(int64, sizeInBits);
  3529. CMD_PARAM(int64, alignInBits);
  3530. CMD_PARAM(int, encoding);
  3531. SetResult(curId, mDIBuilder->createBasicType(name.c_str(), sizeInBits, encoding));
  3532. }
  3533. break;
  3534. case BfIRCmd_DbgCreateStructType:
  3535. {
  3536. CMD_PARAM(llvm::MDNode*, context);
  3537. CMD_PARAM(String, name);
  3538. CMD_PARAM(llvm::MDNode*, file);
  3539. CMD_PARAM(int, lineNum);
  3540. CMD_PARAM(int64, sizeInBits);
  3541. CMD_PARAM(int64, alignInBits);
  3542. CMD_PARAM(int, flags);
  3543. CMD_PARAM(llvm::MDNode*, derivedFrom);
  3544. CMD_PARAM(CmdParamVec<llvm::Metadata*>, members);
  3545. auto diMembersArray = mDIBuilder->getOrCreateArray(members);
  3546. BF_ASSERT(file != NULL);
  3547. llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
  3548. auto mdStruct = mDIBuilder->createStructType((llvm::DIScope*)context, name.c_str(), (llvm::DIFile*)file, lineNum, sizeInBits, (uint32)alignInBits, diFlags, (llvm::DIType*)derivedFrom, diMembersArray);
  3549. SetResult(curId, mdStruct);
  3550. //OutputDebugStrF("BfIRCmd_DbgCreateStructType %p\n", mdStruct);
  3551. }
  3552. break;
  3553. case BfIRCmd_DbgCreateEnumerationType:
  3554. {
  3555. CMD_PARAM(llvm::MDNode*, context);
  3556. CMD_PARAM(String, name);
  3557. CMD_PARAM(llvm::MDNode*, file);
  3558. CMD_PARAM(int, lineNum);
  3559. CMD_PARAM(int64, sizeInBits);
  3560. CMD_PARAM(int64, alignInBits);
  3561. CMD_PARAM(CmdParamVec<llvm::Metadata*>, members);
  3562. CMD_PARAM(llvm::MDNode*, underlyingType);
  3563. auto diMembersArray = mDIBuilder->getOrCreateArray(members);
  3564. /*static int typeIdx = 0;
  3565. if (name == "TypeCode")
  3566. name += StrFormat("_%d", typeIdx);
  3567. typeIdx++;*/
  3568. BF_ASSERT(file != NULL);
  3569. auto enumType = mDIBuilder->createEnumerationType((llvm::DIScope*)context, name.c_str(), (llvm::DIFile*)file, lineNum, sizeInBits, (uint32)alignInBits, diMembersArray, (llvm::DIType*)underlyingType);
  3570. SetResult(curId, enumType);
  3571. //OutputDebugStrF("BfIRCmd_DbgCreateEnumerationType %p\n", enumType);
  3572. }
  3573. break;
  3574. case BfIRCmd_DbgCreatePointerType:
  3575. {
  3576. CMD_PARAM(llvm::MDNode*, diType);
  3577. SetResult(curId, mDIBuilder->createPointerType((llvm::DIType*)diType, mPtrSize*8, (uint32)mPtrSize * 8));
  3578. }
  3579. break;
  3580. case BfIRCmd_DbgCreateReferenceType:
  3581. {
  3582. CMD_PARAM(llvm::MDNode*, diType);
  3583. SetResult(curId, mDIBuilder->createReferenceType(llvm::dwarf::DW_TAG_reference_type, (llvm::DIType*)diType));
  3584. }
  3585. break;
  3586. case BfIRCmd_DbgCreateConstType:
  3587. {
  3588. CMD_PARAM(llvm::MDNode*, diType);
  3589. SetResult(curId, mDIBuilder->createQualifiedType(llvm::dwarf::DW_TAG_const_type, (llvm::DIType*)diType));
  3590. }
  3591. break;
  3592. case BfIRCmd_DbgCreateArtificialType:
  3593. {
  3594. CMD_PARAM(llvm::MDNode*, diType);
  3595. SetResult(curId, mDIBuilder->createArtificialType((llvm::DIType*)diType));
  3596. }
  3597. break;
  3598. case BfIRCmd_DbgCreateArrayType:
  3599. {
  3600. CMD_PARAM(int64, sizeInBits);
  3601. CMD_PARAM(int64, alignInBits);
  3602. CMD_PARAM(llvm::MDNode*, elementType);
  3603. CMD_PARAM(int64, numElements);
  3604. llvm::SmallVector<llvm::Metadata*, 1> diSizeVec;
  3605. diSizeVec.push_back(mDIBuilder->getOrCreateSubrange(0, numElements));
  3606. auto diSizeArray = mDIBuilder->getOrCreateArray(diSizeVec);
  3607. SetResult(curId, mDIBuilder->createArrayType(sizeInBits, (uint32)alignInBits, (llvm::DIType*)elementType, diSizeArray));
  3608. }
  3609. break;
  3610. case BfIRCmd_DbgCreateReplaceableCompositeType:
  3611. {
  3612. CMD_PARAM(int, tag);
  3613. CMD_PARAM(String, name);
  3614. CMD_PARAM(llvm::MDNode*, scope);
  3615. CMD_PARAM(llvm::MDNode*, file);
  3616. CMD_PARAM(int, line);
  3617. CMD_PARAM(int64, sizeInBits);
  3618. CMD_PARAM(int64, alignInBits);
  3619. CMD_PARAM(int, flags);
  3620. BF_ASSERT(file != NULL);
  3621. llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
  3622. SetResult(curId, mDIBuilder->createReplaceableCompositeType(tag, name.c_str(), (llvm::DIScope*)scope, (llvm::DIFile*)file, line, 0, sizeInBits, (uint32)alignInBits, diFlags));
  3623. }
  3624. break;
  3625. case BfIRCmd_DbgCreateForwardDecl:
  3626. {
  3627. CMD_PARAM(int, tag);
  3628. CMD_PARAM(String, name);
  3629. CMD_PARAM(llvm::MDNode*, scope);
  3630. CMD_PARAM(llvm::MDNode*, file);
  3631. CMD_PARAM(int, line);
  3632. BF_ASSERT(file != NULL);
  3633. auto diType = mDIBuilder->createForwardDecl(tag, name.c_str(), (llvm::DIScope*)scope, (llvm::DIFile*)file, line);
  3634. SetResult(curId, diType);
  3635. }
  3636. break;
  3637. case BfIRCmd_DbgCreateSizedForwardDecl:
  3638. {
  3639. CMD_PARAM(int, tag);
  3640. CMD_PARAM(String, name);
  3641. CMD_PARAM(llvm::MDNode*, scope);
  3642. CMD_PARAM(llvm::MDNode*, file);
  3643. CMD_PARAM(int, line);
  3644. CMD_PARAM(int64, sizeInBits);
  3645. CMD_PARAM(int64, alignInBits);
  3646. BF_ASSERT(file != NULL);
  3647. SetResult(curId, mDIBuilder->createForwardDecl(tag, name.c_str(), (llvm::DIScope*)scope, (llvm::DIFile*)file, line, 0, sizeInBits, (uint32)alignInBits));
  3648. }
  3649. break;
  3650. case BeIRCmd_DbgSetTypeSize:
  3651. {
  3652. CMD_PARAM(llvm::MDNode*, mdType);
  3653. CMD_PARAM(int64, sizeInBits);
  3654. CMD_PARAM(int64, alignInBits);
  3655. class DIMutType : public llvm::DIType
  3656. {
  3657. public:
  3658. void Resize(int64 newSize, int32 newAlign)
  3659. {
  3660. init(getLine(), newSize, newAlign, getOffsetInBits(), getFlags());
  3661. }
  3662. };
  3663. auto diType = (DIMutType*)mdType;
  3664. diType->Resize(sizeInBits, (int32)alignInBits);
  3665. }
  3666. break;
  3667. case BfIRCmd_DbgReplaceAllUses:
  3668. {
  3669. CMD_PARAM(llvm::MDNode*, diPrevNode);
  3670. CMD_PARAM(llvm::MDNode*, diNewNode);
  3671. diPrevNode->replaceAllUsesWith(diNewNode);
  3672. }
  3673. break;
  3674. case BfIRCmd_DbgDeleteTemporary:
  3675. {
  3676. CMD_PARAM(llvm::MDNode*, diNode);
  3677. llvm::MDNode::deleteTemporary(diNode);
  3678. }
  3679. break;
  3680. case BfIRCmd_DbgMakePermanent:
  3681. {
  3682. CMD_PARAM(llvm::MDNode*, diNode);
  3683. CMD_PARAM(llvm::MDNode*, diBaseType);
  3684. CMD_PARAM(CmdParamVec<llvm::Metadata*>, members);
  3685. llvm::MDNode* newNode = diNode;
  3686. if (auto diComposite = llvm::dyn_cast<llvm::DICompositeType>(diNode))
  3687. {
  3688. //diComposite->getBaseType()
  3689. if (diBaseType != NULL)
  3690. {
  3691. // It's unfortunate we have to hard-code the '3' here
  3692. diComposite->replaceOperandWith(3, diBaseType);
  3693. BF_ASSERT(diComposite->getBaseType() == diBaseType);
  3694. }
  3695. if (members.size() != 0)
  3696. {
  3697. llvm::DINodeArray elements = mDIBuilder->getOrCreateArray(members);
  3698. mDIBuilder->replaceArrays(diComposite, elements);
  3699. }
  3700. newNode = llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(diComposite));
  3701. }
  3702. /*else if (auto diEnumerator = llvm::dyn_cast<llvm::DIEnumerator>(diNode))
  3703. {
  3704. if (members.size() != 0)
  3705. {
  3706. llvm::DINodeArray elements = mDIBuilder->getOrCreateArray(diNode);
  3707. mDIBuilder->set(diComposite, elements);
  3708. }
  3709. newNode = llvm::MDNode::replaceWithPermanent(llvm::TempDIEnumerator(diEnumerator));
  3710. }*/
  3711. SetResult(curId, newNode);
  3712. break;
  3713. }
  3714. case BfIRCmd_CreateEnumerator:
  3715. {
  3716. CMD_PARAM(String, name);
  3717. CMD_PARAM(int64, val);
  3718. SetResult(curId, mDIBuilder->createEnumerator(name.c_str(), val));
  3719. }
  3720. break;
  3721. case BfIRCmd_DbgCreateMemberType:
  3722. {
  3723. CMD_PARAM(llvm::MDNode*, scope);
  3724. CMD_PARAM(String, name);
  3725. CMD_PARAM(llvm::MDNode*, file);
  3726. CMD_PARAM(int, lineNumber);
  3727. CMD_PARAM(int64, sizeInBits);
  3728. CMD_PARAM(int64, alignInBits);
  3729. CMD_PARAM(int64, offsetInBits);
  3730. CMD_PARAM(int, flags);
  3731. CMD_PARAM(llvm::MDNode*, type);
  3732. BF_ASSERT(file != NULL);
  3733. llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
  3734. /*Beefy::debug_ostream os;
  3735. os << "BfIRCmd_DbgCreateMemberType " << name.c_str() << "\n";
  3736. scope->print(os);
  3737. os << "\n";
  3738. type->print(os);
  3739. os << "\n";
  3740. os.flush();*/
  3741. auto member = mDIBuilder->createMemberType((llvm::DIScope*)scope, name.c_str(), (llvm::DIFile*)file, lineNumber, sizeInBits, (uint32)alignInBits, offsetInBits, diFlags, (llvm::DIType*)type);
  3742. SetResult(curId, member);
  3743. //OutputDebugStrF("BfIRCmd_DbgCreateMemberType = %p\n", member);
  3744. }
  3745. break;
  3746. case BfIRCmd_DbgStaticCreateMemberType:
  3747. {
  3748. CMD_PARAM(llvm::MDNode*, scope);
  3749. CMD_PARAM(String, name);
  3750. CMD_PARAM(llvm::MDNode*, file);
  3751. CMD_PARAM(int, lineNumber);
  3752. CMD_PARAM(llvm::MDNode*, type);
  3753. CMD_PARAM(int, flags);
  3754. CMD_PARAM(llvm::Constant*, val);
  3755. BF_ASSERT(file != NULL);
  3756. llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
  3757. /*Beefy::debug_ostream os;
  3758. os << "BfIRCmd_DbgStaticCreateMemberType " << name.c_str() << "\n";
  3759. scope->print(os);
  3760. os << "\n";
  3761. type->print(os);
  3762. os << "\n";
  3763. os.flush();*/
  3764. auto member = mDIBuilder->createStaticMemberType((llvm::DIScope*)scope, name.c_str(), (llvm::DIFile*)file, lineNumber, (llvm::DIType*)type, diFlags, val);
  3765. SetResult(curId, member);
  3766. //OutputDebugStrF("BfIRCmd_DbgStaticCreateMemberType = %p\n", member);
  3767. }
  3768. break;
  3769. case BfIRCmd_DbgCreateInheritance:
  3770. {
  3771. CMD_PARAM(llvm::MDNode*, type);
  3772. CMD_PARAM(llvm::MDNode*, baseType);
  3773. CMD_PARAM(int64, baseOffset);
  3774. CMD_PARAM(int, flags);
  3775. llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
  3776. auto member = mDIBuilder->createInheritance((llvm::DIType*)type, (llvm::DIType*)baseType, baseOffset, 0, diFlags);
  3777. SetResult(curId, member);
  3778. //OutputDebugStrF("BfIRCmd_DbgCreateInheritance = %p\n", member);
  3779. }
  3780. break;
  3781. case BfIRCmd_DbgCreateMethod:
  3782. {
  3783. CMD_PARAM(llvm::MDNode*, context);
  3784. CMD_PARAM(String, name);
  3785. CMD_PARAM(String, linkageName);
  3786. CMD_PARAM(llvm::MDNode*, file);
  3787. CMD_PARAM(int, lineNum);
  3788. CMD_PARAM(llvm::MDNode*, type);
  3789. CMD_PARAM(bool, isLocalToUnit);
  3790. CMD_PARAM(bool, isDefinition);
  3791. CMD_PARAM(int, vk);
  3792. CMD_PARAM(int, vIndex);
  3793. CMD_PARAM(llvm::MDNode*, vTableHolder);
  3794. CMD_PARAM(int, flags);
  3795. CMD_PARAM(bool, isOptimized);
  3796. CMD_PARAM(llvm::Value*, fn);
  3797. CMD_PARAM(CmdParamVec<llvm::MDNode*>, genericArgs);
  3798. CMD_PARAM(CmdParamVec<llvm::Constant*>, genericConstValueArgs);
  3799. BF_ASSERT(file != NULL);
  3800. llvm::DITemplateParameterArray templateParamArr = NULL;
  3801. llvm::DINodeArray templateParamNodes;
  3802. if (genericArgs.size() != 0)
  3803. {
  3804. llvm::SmallVector<llvm::Metadata*, 16> templateParams;
  3805. for (int i = 0; i < (int)genericArgs.size(); i++)
  3806. {
  3807. auto genericArg = (llvm::DIType*)genericArgs[i];
  3808. String name = StrFormat("T%d", i);
  3809. llvm::Constant* constant = NULL;
  3810. if (i < genericConstValueArgs.size())
  3811. constant = genericConstValueArgs[i];
  3812. if (constant != NULL)
  3813. templateParams.push_back(mDIBuilder->createTemplateValueParameter(mDICompileUnit, name.c_str(), genericArg, false, constant));
  3814. else
  3815. templateParams.push_back(mDIBuilder->createTemplateTypeParameter(mDICompileUnit, name.c_str(), false, genericArg));
  3816. }
  3817. templateParamNodes = mDIBuilder->getOrCreateArray(templateParams);
  3818. templateParamArr = templateParamNodes.get();
  3819. }
  3820. llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
  3821. llvm::DISubprogram::DISPFlags dispFlags = llvm::DISubprogram::DISPFlags::SPFlagZero;
  3822. if (isLocalToUnit)
  3823. dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagLocalToUnit);
  3824. if (isDefinition)
  3825. dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagDefinition);
  3826. if (isOptimized)
  3827. dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagOptimized);
  3828. if (vk != 0)
  3829. dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagVirtual);
  3830. auto diSubProgram = mDIBuilder->createMethod((llvm::DIScope*)context, name.c_str(), linkageName.c_str(), (llvm::DIFile*)file, lineNum,
  3831. (llvm::DISubroutineType*)type, vIndex, 0, (llvm::DIType*)vTableHolder, diFlags, dispFlags, templateParamArr);
  3832. if (fn != NULL)
  3833. ((llvm::Function*)fn)->setSubprogram(diSubProgram);
  3834. SetResult(curId, diSubProgram);
  3835. //OutputDebugStrF("BfIRCmd_DbgCreateMethod = %p\n", diSubProgram);
  3836. }
  3837. break;
  3838. case BfIRCmd_DbgCreateFunction:
  3839. {
  3840. CMD_PARAM(llvm::MDNode*, context);
  3841. CMD_PARAM(String, name);
  3842. CMD_PARAM(String, linkageName);
  3843. CMD_PARAM(llvm::MDNode*, file);
  3844. CMD_PARAM(int, lineNum);
  3845. CMD_PARAM(llvm::MDNode*, type);
  3846. CMD_PARAM(bool, isLocalToUnit);
  3847. CMD_PARAM(bool, isDefinition);
  3848. CMD_PARAM(int, scopeLine);
  3849. CMD_PARAM(int, flags);
  3850. CMD_PARAM(bool, isOptimized);
  3851. CMD_PARAM(llvm::Value*, fn);
  3852. BF_ASSERT(file != NULL);
  3853. llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
  3854. llvm::DISubprogram::DISPFlags dispFlags = llvm::DISubprogram::DISPFlags::SPFlagZero;
  3855. if (isLocalToUnit)
  3856. dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagLocalToUnit);
  3857. if (isDefinition)
  3858. dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagDefinition);
  3859. if (isOptimized)
  3860. dispFlags = (llvm::DISubprogram::DISPFlags)(dispFlags | llvm::DISubprogram::DISPFlags::SPFlagOptimized);
  3861. auto diSubProgram = mDIBuilder->createFunction((llvm::DIScope*)context, name.c_str(), linkageName.c_str(), (llvm::DIFile*)file, lineNum,
  3862. (llvm::DISubroutineType*)type, scopeLine, diFlags, dispFlags);
  3863. if (fn != NULL)
  3864. ((llvm::Function*)fn)->setSubprogram(diSubProgram);
  3865. SetResult(curId, diSubProgram);
  3866. //OutputDebugStrF("BfIRCmd_DbgCreateFunction = %p\n", diSubProgram);
  3867. }
  3868. break;
  3869. case BfIRCmd_DbgCreateParameterVariable:
  3870. {
  3871. CMD_PARAM(llvm::MDNode*, scope);
  3872. CMD_PARAM(String, name);
  3873. CMD_PARAM(int, argNo);
  3874. CMD_PARAM(llvm::MDNode*, file);
  3875. CMD_PARAM(int, lineNum);
  3876. CMD_PARAM(llvm::MDNode*, type);
  3877. CMD_PARAM(bool, alwaysPreserve);
  3878. CMD_PARAM(int, flags);
  3879. BF_ASSERT(file != NULL);
  3880. llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)flags;
  3881. SetResult(curId, mDIBuilder->createParameterVariable((llvm::DIScope*)scope, name.c_str(), argNo, (llvm::DIFile*)file, lineNum, (llvm::DIType*)type,
  3882. alwaysPreserve, diFlags));
  3883. }
  3884. break;
  3885. case BfIRCmd_DbgCreateSubroutineType:
  3886. {
  3887. CMD_PARAM(CmdParamVec<llvm::Metadata*>, elements);
  3888. auto diArray = mDIBuilder->getOrCreateTypeArray(elements);
  3889. SetResult(curId, mDIBuilder->createSubroutineType(diArray));
  3890. }
  3891. break;
  3892. case BfIRCmd_DbgCreateAutoVariable:
  3893. {
  3894. CMD_PARAM(llvm::MDNode*, scope);
  3895. CMD_PARAM(String, name);
  3896. CMD_PARAM(llvm::MDNode*, file);
  3897. CMD_PARAM(int, lineNo);
  3898. CMD_PARAM(llvm::MDNode*, type);
  3899. CMD_PARAM(int, initType);
  3900. BF_ASSERT(file != NULL);
  3901. llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)0;
  3902. auto loc = mIRBuilder->getCurrentDebugLocation();
  3903. auto dbgLoc = loc.getAsMDNode();
  3904. SetResult(curId, mDIBuilder->createAutoVariable((llvm::DIScope*)scope, name.c_str(), (llvm::DIFile*)file, lineNo, (llvm::DIType*)type, false, diFlags));
  3905. }
  3906. break;
  3907. case BfIRCmd_DbgInsertValueIntrinsic:
  3908. {
  3909. CMD_PARAM(llvm::Value*, val);
  3910. CMD_PARAM(llvm::MDNode*, varInfo);
  3911. auto diVariable = (llvm::DILocalVariable*)varInfo;
  3912. if (val == NULL)
  3913. {
  3914. val = llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), 0);
  3915. }
  3916. else if (mIsCodeView)
  3917. {
  3918. if (auto constant = llvm::dyn_cast<llvm::Constant>(val))
  3919. {
  3920. int64 writeVal = 0;
  3921. if (auto constantInt = llvm::dyn_cast<llvm::ConstantInt>(val))
  3922. {
  3923. writeVal = constantInt->getSExtValue();
  3924. }
  3925. auto nameRef = diVariable->getName();
  3926. if (writeVal < 0)
  3927. diVariable->replaceOperandWith(1, llvm::MDString::get(*mLLVMContext, (String(nameRef.data()) + StrFormat("$_%llu", -writeVal)).c_str()));
  3928. else
  3929. diVariable->replaceOperandWith(1, llvm::MDString::get(*mLLVMContext, (String(nameRef.data()) + StrFormat("$%llu", writeVal)).c_str()));
  3930. }
  3931. }
  3932. mDIBuilder->insertDbgValueIntrinsic(val, diVariable, mDIBuilder->createExpression(),
  3933. mIRBuilder->getCurrentDebugLocation(), (llvm::BasicBlock*)mIRBuilder->GetInsertBlock());
  3934. }
  3935. break;
  3936. case BfIRCmd_DbgInsertDeclare:
  3937. {
  3938. CMD_PARAM(llvm::Value*, val);
  3939. CMD_PARAM(llvm::MDNode*, varInfo);
  3940. CMD_PARAM(llvm::Value*, insertBefore);
  3941. llvm::Instruction* insertBeforeInst = NULL;
  3942. if (insertBefore != NULL)
  3943. insertBeforeInst = llvm::dyn_cast<llvm::Instruction>(insertBefore);
  3944. if (insertBeforeInst != NULL)
  3945. {
  3946. SetResult(curId, mDIBuilder->insertDeclare(val, (llvm::DILocalVariable*)varInfo, mDIBuilder->createExpression(),
  3947. mIRBuilder->getCurrentDebugLocation(), insertBeforeInst));
  3948. }
  3949. else
  3950. {
  3951. SetResult(curId, mDIBuilder->insertDeclare(val, (llvm::DILocalVariable*)varInfo, mDIBuilder->createExpression(),
  3952. mIRBuilder->getCurrentDebugLocation(), mIRBuilder->GetInsertBlock()));
  3953. }
  3954. }
  3955. break;
  3956. case BfIRCmd_DbgLifetimeEnd:
  3957. {
  3958. CMD_PARAM(llvm::MDNode*, varInfo);
  3959. }
  3960. break;
  3961. case BfIRCmd_DbgCreateGlobalVariable:
  3962. {
  3963. CMD_PARAM(llvm::MDNode*, context);
  3964. CMD_PARAM(String, name);
  3965. CMD_PARAM(String, linkageName);
  3966. CMD_PARAM(llvm::MDNode*, file);
  3967. CMD_PARAM(int, lineNum);
  3968. CMD_PARAM(llvm::MDNode*, type);
  3969. CMD_PARAM(bool, isLocalToUnit);
  3970. CMD_PARAM(llvm::Constant*, val);
  3971. CMD_PARAM(llvm::MDNode*, decl);
  3972. //BF_ASSERT(file != NULL);
  3973. llvm::DIExpression* diExpr = NULL;
  3974. auto gve = mDIBuilder->createGlobalVariableExpression((llvm::DIScope*)context, name.c_str(), linkageName.c_str(), (llvm::DIFile*)file, lineNum, (llvm::DIType*)type,
  3975. isLocalToUnit, true, diExpr, decl);
  3976. if (val != NULL)
  3977. {
  3978. if (auto globalVar = llvm::dyn_cast<llvm::GlobalVariable>(val))
  3979. {
  3980. globalVar->addDebugInfo(gve);
  3981. }
  3982. }
  3983. SetResult(curId, diExpr);
  3984. }
  3985. break;
  3986. case BfIRCmd_DbgCreateLexicalBlock:
  3987. {
  3988. CMD_PARAM(llvm::MDNode*, scope);
  3989. CMD_PARAM(llvm::MDNode*, file);
  3990. CMD_PARAM(int, lineNum);
  3991. CMD_PARAM(int, col);
  3992. BF_ASSERT(file != NULL);
  3993. SetResult(curId, mDIBuilder->createLexicalBlock((llvm::DIScope*)scope, (llvm::DIFile*)file, (unsigned)lineNum, (unsigned)col));
  3994. }
  3995. break;
  3996. case BfIRCmd_DbgCreateAnnotation:
  3997. {
  3998. CMD_PARAM(llvm::MDNode*, scope);
  3999. CMD_PARAM(String, name);
  4000. CMD_PARAM(llvm::Value*, value);
  4001. if (auto dbgFunc = llvm::dyn_cast<llvm::DISubprogram>(scope))
  4002. {
  4003. auto beType = value->getType();
  4004. auto diType = mDIBuilder->createBasicType("int32", 4 * 8, llvm::dwarf::DW_ATE_signed);
  4005. llvm::DINode::DIFlags diFlags = (llvm::DINode::DIFlags)0;
  4006. auto loc = mIRBuilder->getCurrentDebugLocation();
  4007. auto dbgLoc = loc.getAsMDNode();
  4008. auto diScope = (llvm::DIScope*)scope;
  4009. String dbgName = "#" + name;
  4010. int64 writeVal = 0;
  4011. if (auto constant = llvm::dyn_cast<llvm::ConstantInt>(value))
  4012. {
  4013. writeVal = constant->getSExtValue();
  4014. }
  4015. if (writeVal < 0)
  4016. dbgName += StrFormat("$_%llu", -writeVal);
  4017. else
  4018. dbgName += StrFormat("$%llu", writeVal);
  4019. auto dbgVar = mDIBuilder->createAutoVariable((llvm::DIScope*)scope, dbgName.c_str(), (llvm::DIFile*)diScope->getFile(), 0, diType, false, diFlags);
  4020. mDIBuilder->insertDbgValueIntrinsic(value, dbgVar, mDIBuilder->createExpression(),
  4021. mIRBuilder->getCurrentDebugLocation(), (llvm::BasicBlock*)mIRBuilder->GetInsertBlock());
  4022. }
  4023. }
  4024. break;
  4025. default:
  4026. BF_FATAL("Unhandled");
  4027. break;
  4028. }
  4029. }
  4030. void BfIRCodeGen::SetCodeGenOptions(BfCodeGenOptions codeGenOptions)
  4031. {
  4032. mCodeGenOptions = codeGenOptions;
  4033. }
  4034. void BfIRCodeGen::SetConfigConst(int idx, int value)
  4035. {
  4036. auto constVal = llvm::ConstantInt::get(llvm::Type::getInt32Ty(*mLLVMContext), value);
  4037. BF_ASSERT(idx == (int)mConfigConsts32.size());
  4038. mConfigConsts32.Add(constVal);
  4039. constVal = llvm::ConstantInt::get(llvm::Type::getInt64Ty(*mLLVMContext), value);
  4040. BF_ASSERT(idx == (int)mConfigConsts64.size());
  4041. mConfigConsts64.Add(constVal);
  4042. }
  4043. llvm::Value* BfIRCodeGen::GetLLVMValue(int id)
  4044. {
  4045. auto& result = mResults[id];
  4046. BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMValue);
  4047. return result.mLLVMValue;
  4048. }
  4049. llvm::Type* BfIRCodeGen::GetLLVMType(int id)
  4050. {
  4051. auto& result = mResults[id];
  4052. BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMType);
  4053. return result.mLLVMType;
  4054. }
  4055. llvm::BasicBlock * BfIRCodeGen::GetLLVMBlock(int id)
  4056. {
  4057. auto& result = mResults[id];
  4058. BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMBasicBlock);
  4059. return result.mLLVMBlock;
  4060. }
  4061. llvm::MDNode* BfIRCodeGen::GetLLVMMetadata(int id)
  4062. {
  4063. auto& result = mResults[id];
  4064. BF_ASSERT(result.mKind == BfIRCodeGenEntryKind_LLVMMetadata);
  4065. return result.mLLVMMetadata;
  4066. }
  4067. llvm::Type* BfIRCodeGen::GetLLVMTypeById(int id)
  4068. {
  4069. return GetTypeEntry(id).mLLVMType;
  4070. }
  4071. static int GetOptLevel(BfOptLevel optLevel)
  4072. {
  4073. switch (optLevel)
  4074. {
  4075. case BfOptLevel_O1: return 1;
  4076. case BfOptLevel_O2: return 2;
  4077. case BfOptLevel_O3: return 3;
  4078. default: return 0;
  4079. }
  4080. }
  4081. //enum CFLAAType { None, Steensgaard, Andersen, Both };
  4082. static void AddInitialAliasAnalysisPasses(llvm::legacy::PassManagerBase &PM, const BfCodeGenOptions& options)
  4083. {
  4084. switch (options.mUseCFLAA) {
  4085. case BfCFLAAType_Steensgaard:
  4086. PM.add(llvm::createCFLSteensAAWrapperPass());
  4087. break;
  4088. case BfCFLAAType_Andersen:
  4089. PM.add(llvm::createCFLAndersAAWrapperPass());
  4090. break;
  4091. case BfCFLAAType_Both:
  4092. PM.add(llvm::createCFLSteensAAWrapperPass());
  4093. PM.add(llvm::createCFLAndersAAWrapperPass());
  4094. break;
  4095. default:
  4096. break;
  4097. }
  4098. // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
  4099. // BasicAliasAnalysis wins if they disagree. This is intended to help
  4100. // support "obvious" type-punning idioms.
  4101. PM.add(llvm::createTypeBasedAAWrapperPass());
  4102. PM.add(llvm::createScopedNoAliasAAWrapperPass());
  4103. }
  4104. static void AddInstructionCombiningPass(llvm::legacy::PassManagerBase &PM, const BfCodeGenOptions& options)
  4105. {
  4106. bool ExpensiveCombines = GetOptLevel(options.mOptLevel) > 2;
  4107. PM.add(llvm::createInstructionCombiningPass(options.mExpensiveCombines));
  4108. }
  4109. static void AddFunctionSimplificationPasses(llvm::legacy::PassManagerBase &MPM, const BfCodeGenOptions& options)
  4110. {
  4111. // Start of function pass.
  4112. // Break up aggregate allocas, using SSAUpdater.
  4113. MPM.add(llvm::createSROAPass());
  4114. MPM.add(llvm::createEarlyCSEPass(options.mEnableEarlyCSEMemSSA)); // Catch trivial redundancies
  4115. //if (EnableGVNHoist)
  4116. if (options.mEnableGVNHoist)
  4117. MPM.add(llvm::createGVNHoistPass());
  4118. if (options.mEnableGVNSink)
  4119. {
  4120. MPM.add(llvm::createGVNSinkPass());
  4121. MPM.add(llvm::createCFGSimplificationPass());
  4122. }
  4123. // Speculative execution if the target has divergent branches; otherwise nop.
  4124. MPM.add(llvm::createSpeculativeExecutionIfHasBranchDivergencePass());
  4125. MPM.add(llvm::createJumpThreadingPass()); // Thread jumps.
  4126. MPM.add(llvm::createCorrelatedValuePropagationPass()); // Propagate conditionals
  4127. MPM.add(llvm::createCFGSimplificationPass()); // Merge & remove BBs
  4128. // Combine silly seq's
  4129. if (GetOptLevel(options.mOptLevel) > 2)
  4130. MPM.add(llvm::createAggressiveInstCombinerPass());
  4131. AddInstructionCombiningPass(MPM, options);
  4132. if (options.mSizeLevel == 0 && !options.mDisableLibCallsShrinkWrap)
  4133. MPM.add(llvm::createLibCallsShrinkWrapPass());
  4134. //AddExtensionsToPM(llvm::EP_Peephole, MPM);
  4135. // Optimize memory intrinsic calls based on the profiled size information.
  4136. if (options.mSizeLevel == 0)
  4137. MPM.add(llvm::createPGOMemOPSizeOptLegacyPass());
  4138. MPM.add(llvm::createTailCallEliminationPass()); // Eliminate tail calls
  4139. MPM.add(llvm::createCFGSimplificationPass()); // Merge & remove BBs
  4140. MPM.add(llvm::createReassociatePass()); // Reassociate expressions
  4141. // Begin the loop pass pipeline.
  4142. if (options.mEnableSimpleLoopUnswitch) {
  4143. // The simple loop unswitch pass relies on separate cleanup passes. Schedule
  4144. // them first so when we re-process a loop they run before other loop
  4145. // passes.
  4146. MPM.add(llvm::createLoopInstSimplifyPass());
  4147. MPM.add(llvm::createLoopSimplifyCFGPass());
  4148. }
  4149. // Rotate Loop - disable header duplication at -Oz
  4150. MPM.add(llvm::createLoopRotatePass(options.mSizeLevel == 2 ? 0 : -1));
  4151. MPM.add(llvm::createLICMPass()); // Hoist loop invariants
  4152. if (options.mEnableSimpleLoopUnswitch)
  4153. MPM.add(llvm::createSimpleLoopUnswitchLegacyPass());
  4154. else
  4155. MPM.add(llvm::createLoopUnswitchPass(options.mSizeLevel || GetOptLevel(options.mOptLevel) < 3, options.mDivergentTarget));
  4156. // FIXME: We break the loop pass pipeline here in order to do full
  4157. // simplify-cfg. Eventually loop-simplifycfg should be enhanced to replace the
  4158. // need for this.
  4159. MPM.add(llvm::createCFGSimplificationPass());
  4160. AddInstructionCombiningPass(MPM, options);
  4161. // We resume loop passes creating a second loop pipeline here.
  4162. MPM.add(llvm::createIndVarSimplifyPass()); // Canonicalize indvars
  4163. MPM.add(llvm::createLoopIdiomPass()); // Recognize idioms like memset.
  4164. //addExtensionsToPM(EP_LateLoopOptimizations, MPM);
  4165. MPM.add(llvm::createLoopDeletionPass()); // Delete dead loops
  4166. if (options.mEnableLoopInterchange)
  4167. MPM.add(llvm::createLoopInterchangePass()); // Interchange loops
  4168. MPM.add(llvm::createSimpleLoopUnrollPass(GetOptLevel(options.mOptLevel),
  4169. options.mDisableUnrollLoops)); // Unroll small loops
  4170. //addExtensionsToPM(EP_LoopOptimizerEnd, MPM);
  4171. // This ends the loop pass pipelines.
  4172. if (GetOptLevel(options.mOptLevel) > 1) {
  4173. MPM.add(llvm::createMergedLoadStoreMotionPass()); // Merge ld/st in diamonds
  4174. MPM.add(options.mNewGVN ? llvm::createNewGVNPass()
  4175. : llvm::createGVNPass(options.mDisableGVNLoadPRE)); // Remove redundancies
  4176. }
  4177. MPM.add(llvm::createMemCpyOptPass()); // Remove memcpy / form memset
  4178. MPM.add(llvm::createSCCPPass()); // Constant prop with SCCP
  4179. // Delete dead bit computations (instcombine runs after to fold away the dead
  4180. // computations, and then ADCE will run later to exploit any new DCE
  4181. // opportunities that creates).
  4182. MPM.add(llvm::createBitTrackingDCEPass()); // Delete dead bit computations
  4183. // Run instcombine after redundancy elimination to exploit opportunities
  4184. // opened up by them.
  4185. AddInstructionCombiningPass(MPM, options);
  4186. //addExtensionsToPM(EP_Peephole, MPM);
  4187. MPM.add(llvm::createJumpThreadingPass()); // Thread jumps
  4188. MPM.add(llvm::createCorrelatedValuePropagationPass());
  4189. MPM.add(llvm::createDeadStoreEliminationPass()); // Delete dead stores
  4190. MPM.add(llvm::createLICMPass());
  4191. //addExtensionsToPM(EP_ScalarOptimizerLate, MPM);
  4192. if (options.mRerollLoops)
  4193. MPM.add(llvm::createLoopRerollPass());
  4194. if (!options.mRunSLPAfterLoopVectorization && options.mSLPVectorize)
  4195. MPM.add(llvm::createSLPVectorizerPass()); // Vectorize parallel scalar chains.
  4196. MPM.add(llvm::createAggressiveDCEPass()); // Delete dead instructions
  4197. MPM.add(llvm::createCFGSimplificationPass()); // Merge & remove BBs
  4198. // Clean up after everything.
  4199. AddInstructionCombiningPass(MPM, options);
  4200. //addExtensionsToPM(EP_Peephole, MPM);
  4201. // if (options.mEnableCHR && options.mOptLevel >= 3 &&
  4202. // (!PGOInstrUse.empty() || !PGOSampleUse.empty()))
  4203. // MPM.add(createControlHeightReductionLegacyPass());
  4204. }
  4205. static void PopulateModulePassManager(llvm::legacy::PassManagerBase &MPM, const BfCodeGenOptions& options)
  4206. {
  4207. // if (!PGOSampleUse.empty()) {
  4208. // MPM.add(createPruneEHPass());
  4209. // MPM.add(createSampleProfileLoaderPass(PGOSampleUse));
  4210. // }
  4211. llvm::Pass* Inliner;
  4212. bool prepareForLTO = false;
  4213. bool prepareForThinLTO = options.mLTOType == BfLTOType_Thin;
  4214. bool performThinLTO = false;
  4215. bool enableNonLTOGlobalsModRef = false;
  4216. if (GetOptLevel(options.mOptLevel) > 0)
  4217. Inliner = llvm::createFunctionInliningPass(GetOptLevel(options.mOptLevel), options.mSizeLevel, false);
  4218. else
  4219. Inliner = llvm::createAlwaysInlinerLegacyPass();
  4220. // Allow forcing function attributes as a debugging and tuning aid.
  4221. MPM.add(llvm::createForceFunctionAttrsLegacyPass());
  4222. // If all optimizations are disabled, just run the always-inline pass and,
  4223. // if enabled, the function merging pass.
  4224. if (GetOptLevel(options.mOptLevel) == 0) {
  4225. //addPGOInstrPasses(MPM);
  4226. if (Inliner) {
  4227. MPM.add(Inliner);
  4228. Inliner = nullptr;
  4229. }
  4230. // FIXME: The BarrierNoopPass is a HACK! The inliner pass above implicitly
  4231. // creates a CGSCC pass manager, but we don't want to add extensions into
  4232. // that pass manager. To prevent this we insert a no-op module pass to reset
  4233. // the pass manager to get the same behavior as EP_OptimizerLast in non-O0
  4234. // builds. The function merging pass is
  4235. if (options.mMergeFunctions)
  4236. MPM.add(llvm::createMergeFunctionsPass());
  4237. // else if (GlobalExtensionsNotEmpty() || !Extensions.empty())
  4238. // MPM.add(createBarrierNoopPass());
  4239. if (performThinLTO)
  4240. {
  4241. // Drop available_externally and unreferenced globals. This is necessary
  4242. // with ThinLTO in order to avoid leaving undefined references to dead
  4243. // globals in the object file.
  4244. MPM.add(llvm::createEliminateAvailableExternallyPass());
  4245. MPM.add(llvm::createGlobalDCEPass());
  4246. }
  4247. //addExtensionsToPM(EP_EnabledOnOptLevel0, MPM);
  4248. if (prepareForLTO || prepareForThinLTO) {
  4249. MPM.add(llvm::createCanonicalizeAliasesPass());
  4250. // Rename anon globals to be able to export them in the summary.
  4251. // This has to be done after we add the extensions to the pass manager
  4252. // as there could be passes (e.g. Adddress sanitizer) which introduce
  4253. // new unnamed globals.
  4254. MPM.add(llvm::createNameAnonGlobalPass());
  4255. }
  4256. return;
  4257. }
  4258. // Add LibraryInfo if we have some.
  4259. // if (LibraryInfo)
  4260. // MPM.add(new TargetLibraryInfoWrapperPass(*LibraryInfo));
  4261. AddInitialAliasAnalysisPasses(MPM, options);
  4262. // For ThinLTO there are two passes of indirect call promotion. The
  4263. // first is during the compile phase when PerformThinLTO=false and
  4264. // intra-module indirect call targets are promoted. The second is during
  4265. // the ThinLTO backend when PerformThinLTO=true, when we promote imported
  4266. // inter-module indirect calls. For that we perform indirect call promotion
  4267. // earlier in the pass pipeline, here before globalopt. Otherwise imported
  4268. // available_externally functions look unreferenced and are removed.
  4269. // if (performThinLTO)
  4270. // MPM.add(llvm::createPGOIndirectCallPromotionLegacyPass(/*InLTO = */ true,
  4271. // !PGOSampleUse.empty()));
  4272. // For SamplePGO in ThinLTO compile phase, we do not want to unroll loops
  4273. // as it will change the CFG too much to make the 2nd profile annotation
  4274. // in backend more difficult.
  4275. // bool PrepareForThinLTOUsingPGOSampleProfile =
  4276. // PrepareForThinLTO && !PGOSampleUse.empty();
  4277. bool disableUnrollLoops = false;
  4278. bool prepareForThinLTOUsingPGOSampleProfile = false;
  4279. if (prepareForThinLTOUsingPGOSampleProfile)
  4280. disableUnrollLoops = true;
  4281. // Infer attributes about declarations if possible.
  4282. MPM.add(llvm::createInferFunctionAttrsLegacyPass());
  4283. //addExtensionsToPM(EP_ModuleOptimizerEarly, MPM);
  4284. if (GetOptLevel(options.mOptLevel) > 2)
  4285. MPM.add(llvm::createCallSiteSplittingPass());
  4286. MPM.add(llvm::createIPSCCPPass()); // IP SCCP
  4287. MPM.add(llvm::createCalledValuePropagationPass());
  4288. MPM.add(llvm::createGlobalOptimizerPass()); // Optimize out global vars
  4289. // Promote any localized global vars.
  4290. MPM.add(llvm::createPromoteMemoryToRegisterPass());
  4291. MPM.add(llvm::createDeadArgEliminationPass()); // Dead argument elimination
  4292. AddInstructionCombiningPass(MPM, options); // Clean up after IPCP & DAE
  4293. //addExtensionsToPM(EP_Peephole, MPM);
  4294. MPM.add(llvm::createCFGSimplificationPass()); // Clean up after IPCP & DAE
  4295. // For SamplePGO in ThinLTO compile phase, we do not want to do indirect
  4296. // call promotion as it will change the CFG too much to make the 2nd
  4297. // profile annotation in backend more difficult.
  4298. // PGO instrumentation is added during the compile phase for ThinLTO, do
  4299. // not run it a second time
  4300. // if (!performThinLTO && !prepareForThinLTOUsingPGOSampleProfile)
  4301. // llvm::addPGOInstrPasses(MPM);
  4302. // We add a module alias analysis pass here. In part due to bugs in the
  4303. // analysis infrastructure this "works" in that the analysis stays alive
  4304. // for the entire SCC pass run below.
  4305. MPM.add(llvm::createGlobalsAAWrapperPass());
  4306. // Start of CallGraph SCC passes.
  4307. MPM.add(llvm::createPruneEHPass()); // Remove dead EH info
  4308. bool RunInliner = false;
  4309. if (Inliner) {
  4310. MPM.add(Inliner);
  4311. Inliner = nullptr;
  4312. RunInliner = true;
  4313. }
  4314. MPM.add(llvm::createPostOrderFunctionAttrsLegacyPass());
  4315. if (GetOptLevel(options.mOptLevel) > 2)
  4316. MPM.add(llvm::createArgumentPromotionPass()); // Scalarize uninlined fn args
  4317. //addExtensionsToPM(EP_CGSCCOptimizerLate, MPM);
  4318. AddFunctionSimplificationPasses(MPM, options);
  4319. // FIXME: This is a HACK! The inliner pass above implicitly creates a CGSCC
  4320. // pass manager that we are specifically trying to avoid. To prevent this
  4321. // we must insert a no-op module pass to reset the pass manager.
  4322. MPM.add(llvm::createBarrierNoopPass());
  4323. if (options.mRunPartialInlining)
  4324. MPM.add(llvm::createPartialInliningPass());
  4325. if (GetOptLevel(options.mOptLevel) > 1 && !prepareForLTO && !prepareForThinLTO)
  4326. // Remove avail extern fns and globals definitions if we aren't
  4327. // compiling an object file for later LTO. For LTO we want to preserve
  4328. // these so they are eligible for inlining at link-time. Note if they
  4329. // are unreferenced they will be removed by GlobalDCE later, so
  4330. // this only impacts referenced available externally globals.
  4331. // Eventually they will be suppressed during codegen, but eliminating
  4332. // here enables more opportunity for GlobalDCE as it may make
  4333. // globals referenced by available external functions dead
  4334. // and saves running remaining passes on the eliminated functions.
  4335. MPM.add(llvm::createEliminateAvailableExternallyPass());
  4336. MPM.add(llvm::createReversePostOrderFunctionAttrsPass());
  4337. // The inliner performs some kind of dead code elimination as it goes,
  4338. // but there are cases that are not really caught by it. We might
  4339. // at some point consider teaching the inliner about them, but it
  4340. // is OK for now to run GlobalOpt + GlobalDCE in tandem as their
  4341. // benefits generally outweight the cost, making the whole pipeline
  4342. // faster.
  4343. if (RunInliner) {
  4344. MPM.add(llvm::createGlobalOptimizerPass());
  4345. MPM.add(llvm::createGlobalDCEPass());
  4346. }
  4347. // If we are planning to perform ThinLTO later, let's not bloat the code with
  4348. // unrolling/vectorization/... now. We'll first run the inliner + CGSCC passes
  4349. // during ThinLTO and perform the rest of the optimizations afterward.
  4350. if (prepareForThinLTO) {
  4351. // Ensure we perform any last passes, but do so before renaming anonymous
  4352. // globals in case the passes add any.
  4353. //addExtensionsToPM(EP_OptimizerLast, MPM);
  4354. MPM.add(llvm::createCanonicalizeAliasesPass());
  4355. // Rename anon globals to be able to export them in the summary.
  4356. MPM.add(llvm::createNameAnonGlobalPass());
  4357. return;
  4358. }
  4359. if (performThinLTO)
  4360. // Optimize globals now when performing ThinLTO, this enables more
  4361. // optimizations later.
  4362. MPM.add(llvm::createGlobalOptimizerPass());
  4363. // Scheduling LoopVersioningLICM when inlining is over, because after that
  4364. // we may see more accurate aliasing. Reason to run this late is that too
  4365. // early versioning may prevent further inlining due to increase of code
  4366. // size. By placing it just after inlining other optimizations which runs
  4367. // later might get benefit of no-alias assumption in clone loop.
  4368. if (options.mUseLoopVersioningLICM) {
  4369. MPM.add(llvm::createLoopVersioningLICMPass()); // Do LoopVersioningLICM
  4370. MPM.add(llvm::createLICMPass()); // Hoist loop invariants
  4371. }
  4372. // We add a fresh GlobalsModRef run at this point. This is particularly
  4373. // useful as the above will have inlined, DCE'ed, and function-attr
  4374. // propagated everything. We should at this point have a reasonably minimal
  4375. // and richly annotated call graph. By computing aliasing and mod/ref
  4376. // information for all local globals here, the late loop passes and notably
  4377. // the vectorizer will be able to use them to help recognize vectorizable
  4378. // memory operations.
  4379. //
  4380. // Note that this relies on a bug in the pass manager which preserves
  4381. // a module analysis into a function pass pipeline (and throughout it) so
  4382. // long as the first function pass doesn't invalidate the module analysis.
  4383. // Thus both Float2Int and LoopRotate have to preserve AliasAnalysis for
  4384. // this to work. Fortunately, it is trivial to preserve AliasAnalysis
  4385. // (doing nothing preserves it as it is required to be conservatively
  4386. // correct in the face of IR changes).
  4387. MPM.add(llvm::createGlobalsAAWrapperPass());
  4388. MPM.add(llvm::createFloat2IntPass());
  4389. //addExtensionsToPM(EP_VectorizerStart, MPM);
  4390. // Re-rotate loops in all our loop nests. These may have fallout out of
  4391. // rotated form due to GVN or other transformations, and the vectorizer relies
  4392. // on the rotated form. Disable header duplication at -Oz.
  4393. MPM.add(llvm::createLoopRotatePass(options.mSizeLevel == 2 ? 0 : -1));
  4394. // Distribute loops to allow partial vectorization. I.e. isolate dependences
  4395. // into separate loop that would otherwise inhibit vectorization. This is
  4396. // currently only performed for loops marked with the metadata
  4397. // llvm.loop.distribute=true or when -enable-loop-distribute is specified.
  4398. MPM.add(llvm::createLoopDistributePass());
  4399. MPM.add(llvm::createLoopVectorizePass(options.mDisableUnrollLoops, !options.mLoopVectorize));
  4400. // Eliminate loads by forwarding stores from the previous iteration to loads
  4401. // of the current iteration.
  4402. MPM.add(llvm::createLoopLoadEliminationPass());
  4403. // FIXME: Because of #pragma vectorize enable, the passes below are always
  4404. // inserted in the pipeline, even when the vectorizer doesn't run (ex. when
  4405. // on -O1 and no #pragma is found). Would be good to have these two passes
  4406. // as function calls, so that we can only pass them when the vectorizer
  4407. // changed the code.
  4408. AddInstructionCombiningPass(MPM, options);
  4409. if (GetOptLevel(options.mOptLevel) > 1 && options.mExtraVectorizerPasses) {
  4410. // At higher optimization levels, try to clean up any runtime overlap and
  4411. // alignment checks inserted by the vectorizer. We want to track correllated
  4412. // runtime checks for two inner loops in the same outer loop, fold any
  4413. // common computations, hoist loop-invariant aspects out of any outer loop,
  4414. // and unswitch the runtime checks if possible. Once hoisted, we may have
  4415. // dead (or speculatable) control flows or more combining opportunities.
  4416. MPM.add(llvm::createEarlyCSEPass());
  4417. MPM.add(llvm::createCorrelatedValuePropagationPass());
  4418. AddInstructionCombiningPass(MPM, options);
  4419. MPM.add(llvm::createLICMPass());
  4420. MPM.add(llvm::createLoopUnswitchPass(options.mSizeLevel || GetOptLevel(options.mOptLevel) < 3, options.mDivergentTarget));
  4421. MPM.add(llvm::createCFGSimplificationPass());
  4422. AddInstructionCombiningPass(MPM, options);
  4423. }
  4424. // Cleanup after loop vectorization, etc. Simplification passes like CVP and
  4425. // GVN, loop transforms, and others have already run, so it's now better to
  4426. // convert to more optimized IR using more aggressive simplify CFG options.
  4427. // The extra sinking transform can create larger basic blocks, so do this
  4428. // before SLP vectorization.
  4429. MPM.add(llvm::createCFGSimplificationPass(1, true, true, false, true));
  4430. if (options.mRunSLPAfterLoopVectorization && options.mSLPVectorize) {
  4431. MPM.add(llvm::createSLPVectorizerPass()); // Vectorize parallel scalar chains.
  4432. if (GetOptLevel(options.mOptLevel) > 1 && options.mExtraVectorizerPasses) {
  4433. MPM.add(llvm::createEarlyCSEPass());
  4434. }
  4435. }
  4436. //addExtensionsToPM(EP_Peephole, MPM);
  4437. AddInstructionCombiningPass(MPM, options);
  4438. if (options.mEnableUnrollAndJam && !disableUnrollLoops) {
  4439. // Unroll and Jam. We do this before unroll but need to be in a separate
  4440. // loop pass manager in order for the outer loop to be processed by
  4441. // unroll and jam before the inner loop is unrolled.
  4442. MPM.add(llvm::createLoopUnrollAndJamPass(GetOptLevel(options.mOptLevel)));
  4443. }
  4444. MPM.add(llvm::createLoopUnrollPass(GetOptLevel(options.mOptLevel),
  4445. disableUnrollLoops)); // Unroll small loops
  4446. if (!disableUnrollLoops) {
  4447. // LoopUnroll may generate some redundency to cleanup.
  4448. AddInstructionCombiningPass(MPM, options);
  4449. // Runtime unrolling will introduce runtime check in loop prologue. If the
  4450. // unrolled loop is a inner loop, then the prologue will be inside the
  4451. // outer loop. LICM pass can help to promote the runtime check out if the
  4452. // checked value is loop invariant.
  4453. MPM.add(llvm::createLICMPass());
  4454. }
  4455. MPM.add(llvm::createWarnMissedTransformationsPass());
  4456. // After vectorization and unrolling, assume intrinsics may tell us more
  4457. // about pointer alignments.
  4458. MPM.add(llvm::createAlignmentFromAssumptionsPass());
  4459. // FIXME: We shouldn't bother with this anymore.
  4460. MPM.add(llvm::createStripDeadPrototypesPass()); // Get rid of dead prototypes
  4461. // GlobalOpt already deletes dead functions and globals, at -O2 try a
  4462. // late pass of GlobalDCE. It is capable of deleting dead cycles.
  4463. if (GetOptLevel(options.mOptLevel) > 1) {
  4464. MPM.add(llvm::createGlobalDCEPass()); // Remove dead fns and globals.
  4465. MPM.add(llvm::createConstantMergePass()); // Merge dup global constants
  4466. }
  4467. if (options.mMergeFunctions)
  4468. MPM.add(llvm::createMergeFunctionsPass());
  4469. // LoopSink pass sinks instructions hoisted by LICM, which serves as a
  4470. // canonicalization pass that enables other optimizations. As a result,
  4471. // LoopSink pass needs to be a very late IR pass to avoid undoing LICM
  4472. // result too early.
  4473. MPM.add(llvm::createLoopSinkPass());
  4474. // Get rid of LCSSA nodes.
  4475. MPM.add(llvm::createInstSimplifyLegacyPass());
  4476. // This hoists/decomposes div/rem ops. It should run after other sink/hoist
  4477. // passes to avoid re-sinking, but before SimplifyCFG because it can allow
  4478. // flattening of blocks.
  4479. MPM.add(llvm::createDivRemPairsPass());
  4480. if (options.mEnableHotColdSplit)
  4481. MPM.add(llvm::createHotColdSplittingPass());
  4482. // LoopSink (and other loop passes since the last simplifyCFG) might have
  4483. // resulted in single-entry-single-exit or empty blocks. Clean up the CFG.
  4484. MPM.add(llvm::createCFGSimplificationPass());
  4485. //addExtensionsToPM(EP_OptimizerLast, MPM);
  4486. if (prepareForLTO) {
  4487. MPM.add(llvm::createCanonicalizeAliasesPass());
  4488. // Rename anon globals to be able to handle them in the summary
  4489. MPM.add(llvm::createNameAnonGlobalPass());
  4490. }
  4491. }
  4492. namespace
  4493. {
  4494. struct BfPass : public llvm::MachineFunctionPass
  4495. {
  4496. static char ID;
  4497. BfPass() : llvm::MachineFunctionPass(ID) {}
  4498. bool runOnMachineFunction(llvm::MachineFunction &F) override
  4499. {
  4500. //errs() << "Hello: ";
  4501. //errs().write_escaped(F.getName()) << '\n';
  4502. return false;
  4503. }
  4504. };
  4505. }
  4506. char BfPass::ID = 0;
  4507. static llvm::RegisterPass<BfPass> sBfPass("BfPass", "Beef Pass", false, false);
  4508. // We need this wrapper to access LangOpts and CGOpts from extension functions
  4509. // that we add to the PassManagerBuilder.
  4510. class PassManagerBuilderWrapper : public llvm::PassManagerBuilder
  4511. {
  4512. public:
  4513. /*PassManagerBuilderWrapper(const Triple &TargetTriple,
  4514. const CodeGenOptions &CGOpts,
  4515. const LangOptions &LangOpts)
  4516. : PassManagerBuilder(), TargetTriple(TargetTriple), CGOpts(CGOpts),
  4517. LangOpts(LangOpts) {}
  4518. const Triple &getTargetTriple() const { return TargetTriple; }
  4519. const CodeGenOptions &getCGOpts() const { return CGOpts; }
  4520. const LangOptions &getLangOpts() const { return LangOpts; }
  4521. private:
  4522. const Triple &TargetTriple;
  4523. const CodeGenOptions &CGOpts;
  4524. const LangOptions &LangOpts;*/
  4525. };
  4526. llvm::Expected<llvm::BitcodeModule> FindThinLTOModule(llvm::MemoryBufferRef MBRef)
  4527. {
  4528. llvm::Expected<std::vector<llvm::BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef);
  4529. if (!BMsOrErr)
  4530. return BMsOrErr.takeError();
  4531. // The bitcode file may contain multiple modules, we want the one that is
  4532. // marked as being the ThinLTO module.
  4533. for (llvm::BitcodeModule &BM : *BMsOrErr) {
  4534. llvm::Expected<llvm::BitcodeLTOInfo> LTOInfo = BM.getLTOInfo();
  4535. if (LTOInfo && LTOInfo->IsThinLTO)
  4536. return BM;
  4537. }
  4538. return llvm::make_error<llvm::StringError>("Could not find module summary",
  4539. llvm::inconvertibleErrorCode());
  4540. }
  4541. bool BfIRCodeGen::WriteObjectFile(const StringImpl& outFileName)
  4542. {
  4543. // {
  4544. // PassManagerBuilderWrapper pmBuilder;
  4545. //
  4546. //
  4547. // }
  4548. mHasDebugLoc = false; // So fails don't show a line number
  4549. bool enableLTO = mCodeGenOptions.mLTOType != BfLTOType_None;
  4550. if (enableLTO)
  4551. {
  4552. // We have some constructs which trip up ThinLTO, and it's not useful to LTO here anyway
  4553. if (GetFileName(outFileName) == "vdata.obj")
  4554. {
  4555. enableLTO = false;
  4556. }
  4557. }
  4558. std::error_code EC;
  4559. llvm::sys::fs::OpenFlags OpenFlags = llvm::sys::fs::F_None;
  4560. llvm::raw_fd_ostream out(outFileName.c_str(), EC, OpenFlags);
  4561. if (EC)
  4562. return false;
  4563. // Build up all of the passes that we want to do to the module.
  4564. llvm::legacy::PassManager PM;
  4565. llvm::Triple theTriple = llvm::Triple(mLLVMModule->getTargetTriple());
  4566. // Add an appropriate TargetLibraryInfo pass for the module's triple.
  4567. llvm::TargetLibraryInfoImpl TLII(theTriple);
  4568. PM.add(new llvm::TargetLibraryInfoWrapperPass(TLII));
  4569. // Add the target data from the target machine, if it exists, or the module.
  4570. //PM.add(new DataLayoutPass());
  4571. PopulateModulePassManager(PM, mCodeGenOptions);
  4572. llvm::raw_fd_ostream* outStream = NULL;
  4573. defer ( delete outStream; );
  4574. if ((enableLTO) || (mCodeGenOptions.mWriteBitcode))
  4575. {
  4576. std::error_code ec;
  4577. outStream = new llvm::raw_fd_ostream(outFileName.c_str(), ec, llvm::sys::fs::F_None);
  4578. if (outStream->has_error())
  4579. {
  4580. return false;
  4581. }
  4582. if (enableLTO)
  4583. PM.add(createWriteThinLTOBitcodePass(*outStream, NULL));
  4584. else
  4585. PM.add(createBitcodeWriterPass(*outStream, false, false, false));
  4586. }
  4587. //TargetPassConfig *PassConfig = target->createPassConfig(PM);
  4588. //PM.add(new BfPass());
  4589. //PM.add(sBfPass);
  4590. /*if ((RelaxAll.getNumOccurrences() > 0) && (FileType != TargetMachine::CGFT_ObjectFile))
  4591. {
  4592. //errs() << argv[0] << ": warning: ignoring -mc-relax-all because filetype != obj";
  4593. }*/
  4594. // Do
  4595. {
  4596. //formatted_raw_ostream FOS(out);
  4597. //raw_pwrite_stream *OS = &out->os();
  4598. llvm::AnalysisID StartAfterID = nullptr;
  4599. llvm::AnalysisID StopAfterID = nullptr;
  4600. const llvm::PassRegistry *PR = llvm::PassRegistry::getPassRegistry();
  4601. //WriteBitcode
  4602. bool noVerify = false; // Option
  4603. if ((!enableLTO) && (!mCodeGenOptions.mWriteBitcode))
  4604. {
  4605. // Ask the target to add backend passes as necessary.
  4606. if (mLLVMTargetMachine->addPassesToEmitFile(PM, out, NULL,
  4607. (mCodeGenOptions.mAsmKind != BfAsmKind_None) ? llvm::CGFT_AssemblyFile : llvm::CGFT_ObjectFile,
  4608. //TargetMachine::CGFT_AssemblyFile,
  4609. noVerify /*, StartAfterID, StopAfterID*/))
  4610. {
  4611. Fail("Target does not support generation of this file type");
  4612. /*errs() << argv[0] << ": target does not support generation of this"
  4613. << " file type!\n";*/
  4614. return false;
  4615. }
  4616. }
  4617. bool success = PM.run(*mLLVMModule);
  4618. if ((mCodeGenOptions.mOptLevel > BfOptLevel_O0) && (mCodeGenOptions.mWriteLLVMIR))
  4619. {
  4620. BP_ZONE("BfCodeGen::RunLoop.LLVM.IR");
  4621. String fileName = outFileName;
  4622. int dotPos = (int)fileName.LastIndexOf('.');
  4623. if (dotPos != -1)
  4624. fileName.RemoveToEnd(dotPos);
  4625. fileName += "_OPT.ll";
  4626. String irError;
  4627. WriteIR(fileName, irError);
  4628. }
  4629. }
  4630. return true;
  4631. }
  4632. bool BfIRCodeGen::WriteIR(const StringImpl& outFileName, StringImpl& error)
  4633. {
  4634. std::error_code ec;
  4635. llvm::raw_fd_ostream outStream(outFileName.c_str(), ec, llvm::sys::fs::OpenFlags::F_Text);
  4636. if (ec)
  4637. {
  4638. error = ec.message();
  4639. return false;
  4640. }
  4641. mLLVMModule->print(outStream, NULL);
  4642. return true;
  4643. }
  4644. int BfIRCodeGen::GetIntrinsicId(const StringImpl& name)
  4645. {
  4646. auto itr = std::lower_bound(std::begin(gIntrinEntries), std::end(gIntrinEntries), name);
  4647. if (itr != std::end(gIntrinEntries) && strcmp(itr->mName, name.c_str()) == 0)
  4648. {
  4649. int id = (int)(itr - gIntrinEntries);
  4650. return id;
  4651. }
  4652. if (name.StartsWith("shuffle"))
  4653. return BfIRIntrinsic_Shuffle;
  4654. if (name.Contains(':'))
  4655. return BfIRIntrinsic__PLATFORM;
  4656. return -1;
  4657. }
  4658. const char* BfIRCodeGen::GetIntrinsicName(int intrinId)
  4659. {
  4660. return gIntrinEntries[intrinId].mName;
  4661. }
  4662. void BfIRCodeGen::SetAsmKind(BfAsmKind asmKind)
  4663. {
  4664. const char* args[] = {"", (asmKind == BfAsmKind_ATT) ? "-x86-asm-syntax=att" : "-x86-asm-syntax=intel" };
  4665. llvm::cl::ParseCommandLineOptions(2, args);
  4666. }
  4667. #ifdef BF_PLATFORM_LINUX
  4668. //HACK: I don't know why this is needed, but we get link errors if we don't have it.
  4669. int BF_LinuxFixLinkage()
  4670. {
  4671. llvm::MCContext* ctx = NULL;
  4672. llvm::raw_pwrite_stream* stream = NULL;
  4673. createWasmStreamer(*ctx, NULL, NULL, NULL, false);
  4674. createMachOStreamer(*ctx, NULL, NULL, NULL, false, false, false);
  4675. createAsmStreamer(*ctx, NULL, false, false, NULL, NULL, NULL, false);
  4676. createELFStreamer(*ctx, NULL, NULL, NULL, false);
  4677. return 0;
  4678. }
  4679. #endif
  4680. //#include "aarch64/Disassembler/X86DisassemblerDecoder.h"
  4681. //#include "X86/MCTargetDesc/X86MCTargetDesc.h"
  4682. //#include "X86/MCTargetDesc/X86BaseInfo.h"
  4683. //#include "X86InstrInfo.h"
  4684. #ifdef BF_PLATFORM_MACOS
  4685. #include "AArch64/MCTargetDesc/AArch64MCTargetDesc.h"
  4686. //#include "AArch64/MCTargetDesc/AArch64BaseInfo.h"
  4687. //#include "../X86InstrInfo.h"
  4688. int BF_AARC64_Linkage()
  4689. {
  4690. LLVMInitializeAArch64TargetInfo();
  4691. LLVMInitializeAArch64Target();
  4692. LLVMInitializeAArch64TargetMC();
  4693. return 0;
  4694. }
  4695. #endif
  4696. void BfIRCodeGen::StaticInit()
  4697. {
  4698. LLVMInitializeX86TargetInfo();
  4699. LLVMInitializeX86Target();
  4700. LLVMInitializeX86TargetMC();
  4701. LLVMInitializeX86AsmPrinter();
  4702. LLVMInitializeX86AsmParser();
  4703. LLVMInitializeX86Disassembler();
  4704. LLVMInitializeARMTargetInfo();
  4705. LLVMInitializeARMTarget();
  4706. LLVMInitializeARMTargetMC();
  4707. LLVMInitializeARMAsmPrinter();
  4708. LLVMInitializeAArch64TargetInfo();
  4709. LLVMInitializeAArch64Target();
  4710. LLVMInitializeAArch64TargetMC();
  4711. LLVMInitializeAArch64AsmPrinter();
  4712. //LLVMInitializeAArch64Parser();
  4713. //LLVMInitializeX86Disassembler();
  4714. LLVMInitializeWebAssemblyTargetInfo();
  4715. LLVMInitializeWebAssemblyTarget();
  4716. LLVMInitializeWebAssemblyTargetMC();
  4717. LLVMInitializeWebAssemblyAsmPrinter();
  4718. LLVMInitializeWebAssemblyAsmParser();
  4719. LLVMInitializeWebAssemblyDisassembler();
  4720. }