BfIRCodeGen.cpp 132 KB

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