CGStmtOpenMP.cpp 315 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519
  1. //===--- CGStmtOpenMP.cpp - Emit LLVM Code from Statements ----------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This contains code to emit OpenMP nodes as LLVM code.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "CGCleanup.h"
  13. #include "CGOpenMPRuntime.h"
  14. #include "CodeGenFunction.h"
  15. #include "CodeGenModule.h"
  16. #include "TargetInfo.h"
  17. #include "clang/AST/ASTContext.h"
  18. #include "clang/AST/Attr.h"
  19. #include "clang/AST/DeclOpenMP.h"
  20. #include "clang/AST/OpenMPClause.h"
  21. #include "clang/AST/Stmt.h"
  22. #include "clang/AST/StmtOpenMP.h"
  23. #include "clang/AST/StmtVisitor.h"
  24. #include "clang/Basic/OpenMPKinds.h"
  25. #include "clang/Basic/PrettyStackTrace.h"
  26. #include "llvm/BinaryFormat/Dwarf.h"
  27. #include "llvm/Frontend/OpenMP/OMPConstants.h"
  28. #include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
  29. #include "llvm/IR/Constants.h"
  30. #include "llvm/IR/DebugInfoMetadata.h"
  31. #include "llvm/IR/Instructions.h"
  32. #include "llvm/IR/IntrinsicInst.h"
  33. #include "llvm/IR/Metadata.h"
  34. #include "llvm/Support/AtomicOrdering.h"
  35. using namespace clang;
  36. using namespace CodeGen;
  37. using namespace llvm::omp;
  38. static const VarDecl *getBaseDecl(const Expr *Ref);
  39. namespace {
  40. /// Lexical scope for OpenMP executable constructs, that handles correct codegen
  41. /// for captured expressions.
  42. class OMPLexicalScope : public CodeGenFunction::LexicalScope {
  43. void emitPreInitStmt(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
  44. for (const auto *C : S.clauses()) {
  45. if (const auto *CPI = OMPClauseWithPreInit::get(C)) {
  46. if (const auto *PreInit =
  47. cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
  48. for (const auto *I : PreInit->decls()) {
  49. if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
  50. CGF.EmitVarDecl(cast<VarDecl>(*I));
  51. } else {
  52. CodeGenFunction::AutoVarEmission Emission =
  53. CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
  54. CGF.EmitAutoVarCleanups(Emission);
  55. }
  56. }
  57. }
  58. }
  59. }
  60. }
  61. CodeGenFunction::OMPPrivateScope InlinedShareds;
  62. static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) {
  63. return CGF.LambdaCaptureFields.lookup(VD) ||
  64. (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) ||
  65. (CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl) &&
  66. cast<BlockDecl>(CGF.CurCodeDecl)->capturesVariable(VD));
  67. }
  68. public:
  69. OMPLexicalScope(
  70. CodeGenFunction &CGF, const OMPExecutableDirective &S,
  71. const llvm::Optional<OpenMPDirectiveKind> CapturedRegion = llvm::None,
  72. const bool EmitPreInitStmt = true)
  73. : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()),
  74. InlinedShareds(CGF) {
  75. if (EmitPreInitStmt)
  76. emitPreInitStmt(CGF, S);
  77. if (!CapturedRegion.hasValue())
  78. return;
  79. assert(S.hasAssociatedStmt() &&
  80. "Expected associated statement for inlined directive.");
  81. const CapturedStmt *CS = S.getCapturedStmt(*CapturedRegion);
  82. for (const auto &C : CS->captures()) {
  83. if (C.capturesVariable() || C.capturesVariableByCopy()) {
  84. auto *VD = C.getCapturedVar();
  85. assert(VD == VD->getCanonicalDecl() &&
  86. "Canonical decl must be captured.");
  87. DeclRefExpr DRE(
  88. CGF.getContext(), const_cast<VarDecl *>(VD),
  89. isCapturedVar(CGF, VD) || (CGF.CapturedStmtInfo &&
  90. InlinedShareds.isGlobalVarCaptured(VD)),
  91. VD->getType().getNonReferenceType(), VK_LValue, C.getLocation());
  92. InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address {
  93. return CGF.EmitLValue(&DRE).getAddress(CGF);
  94. });
  95. }
  96. }
  97. (void)InlinedShareds.Privatize();
  98. }
  99. };
  100. /// Lexical scope for OpenMP parallel construct, that handles correct codegen
  101. /// for captured expressions.
  102. class OMPParallelScope final : public OMPLexicalScope {
  103. bool EmitPreInitStmt(const OMPExecutableDirective &S) {
  104. OpenMPDirectiveKind Kind = S.getDirectiveKind();
  105. return !(isOpenMPTargetExecutionDirective(Kind) ||
  106. isOpenMPLoopBoundSharingDirective(Kind)) &&
  107. isOpenMPParallelDirective(Kind);
  108. }
  109. public:
  110. OMPParallelScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
  111. : OMPLexicalScope(CGF, S, /*CapturedRegion=*/llvm::None,
  112. EmitPreInitStmt(S)) {}
  113. };
  114. /// Lexical scope for OpenMP teams construct, that handles correct codegen
  115. /// for captured expressions.
  116. class OMPTeamsScope final : public OMPLexicalScope {
  117. bool EmitPreInitStmt(const OMPExecutableDirective &S) {
  118. OpenMPDirectiveKind Kind = S.getDirectiveKind();
  119. return !isOpenMPTargetExecutionDirective(Kind) &&
  120. isOpenMPTeamsDirective(Kind);
  121. }
  122. public:
  123. OMPTeamsScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
  124. : OMPLexicalScope(CGF, S, /*CapturedRegion=*/llvm::None,
  125. EmitPreInitStmt(S)) {}
  126. };
  127. /// Private scope for OpenMP loop-based directives, that supports capturing
  128. /// of used expression from loop statement.
  129. class OMPLoopScope : public CodeGenFunction::RunCleanupsScope {
  130. void emitPreInitStmt(CodeGenFunction &CGF, const OMPLoopBasedDirective &S) {
  131. const DeclStmt *PreInits;
  132. CodeGenFunction::OMPMapVars PreCondVars;
  133. if (auto *LD = dyn_cast<OMPLoopDirective>(&S)) {
  134. llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
  135. for (const auto *E : LD->counters()) {
  136. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
  137. EmittedAsPrivate.insert(VD->getCanonicalDecl());
  138. (void)PreCondVars.setVarAddr(
  139. CGF, VD, CGF.CreateMemTemp(VD->getType().getNonReferenceType()));
  140. }
  141. // Mark private vars as undefs.
  142. for (const auto *C : LD->getClausesOfKind<OMPPrivateClause>()) {
  143. for (const Expr *IRef : C->varlists()) {
  144. const auto *OrigVD =
  145. cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());
  146. if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
  147. (void)PreCondVars.setVarAddr(
  148. CGF, OrigVD,
  149. Address(llvm::UndefValue::get(CGF.ConvertTypeForMem(
  150. CGF.getContext().getPointerType(
  151. OrigVD->getType().getNonReferenceType()))),
  152. CGF.getContext().getDeclAlign(OrigVD)));
  153. }
  154. }
  155. }
  156. (void)PreCondVars.apply(CGF);
  157. // Emit init, __range and __end variables for C++ range loops.
  158. (void)OMPLoopBasedDirective::doForAllLoops(
  159. LD->getInnermostCapturedStmt()->getCapturedStmt(),
  160. /*TryImperfectlyNestedLoops=*/true, LD->getLoopsNumber(),
  161. [&CGF](unsigned Cnt, const Stmt *CurStmt) {
  162. if (const auto *CXXFor = dyn_cast<CXXForRangeStmt>(CurStmt)) {
  163. if (const Stmt *Init = CXXFor->getInit())
  164. CGF.EmitStmt(Init);
  165. CGF.EmitStmt(CXXFor->getRangeStmt());
  166. CGF.EmitStmt(CXXFor->getEndStmt());
  167. }
  168. return false;
  169. });
  170. PreInits = cast_or_null<DeclStmt>(LD->getPreInits());
  171. } else if (const auto *Tile = dyn_cast<OMPTileDirective>(&S)) {
  172. PreInits = cast_or_null<DeclStmt>(Tile->getPreInits());
  173. } else if (const auto *Unroll = dyn_cast<OMPUnrollDirective>(&S)) {
  174. PreInits = cast_or_null<DeclStmt>(Unroll->getPreInits());
  175. } else {
  176. llvm_unreachable("Unknown loop-based directive kind.");
  177. }
  178. if (PreInits) {
  179. for (const auto *I : PreInits->decls())
  180. CGF.EmitVarDecl(cast<VarDecl>(*I));
  181. }
  182. PreCondVars.restore(CGF);
  183. }
  184. public:
  185. OMPLoopScope(CodeGenFunction &CGF, const OMPLoopBasedDirective &S)
  186. : CodeGenFunction::RunCleanupsScope(CGF) {
  187. emitPreInitStmt(CGF, S);
  188. }
  189. };
  190. class OMPSimdLexicalScope : public CodeGenFunction::LexicalScope {
  191. CodeGenFunction::OMPPrivateScope InlinedShareds;
  192. static bool isCapturedVar(CodeGenFunction &CGF, const VarDecl *VD) {
  193. return CGF.LambdaCaptureFields.lookup(VD) ||
  194. (CGF.CapturedStmtInfo && CGF.CapturedStmtInfo->lookup(VD)) ||
  195. (CGF.CurCodeDecl && isa<BlockDecl>(CGF.CurCodeDecl) &&
  196. cast<BlockDecl>(CGF.CurCodeDecl)->capturesVariable(VD));
  197. }
  198. public:
  199. OMPSimdLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S)
  200. : CodeGenFunction::LexicalScope(CGF, S.getSourceRange()),
  201. InlinedShareds(CGF) {
  202. for (const auto *C : S.clauses()) {
  203. if (const auto *CPI = OMPClauseWithPreInit::get(C)) {
  204. if (const auto *PreInit =
  205. cast_or_null<DeclStmt>(CPI->getPreInitStmt())) {
  206. for (const auto *I : PreInit->decls()) {
  207. if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
  208. CGF.EmitVarDecl(cast<VarDecl>(*I));
  209. } else {
  210. CodeGenFunction::AutoVarEmission Emission =
  211. CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
  212. CGF.EmitAutoVarCleanups(Emission);
  213. }
  214. }
  215. }
  216. } else if (const auto *UDP = dyn_cast<OMPUseDevicePtrClause>(C)) {
  217. for (const Expr *E : UDP->varlists()) {
  218. const Decl *D = cast<DeclRefExpr>(E)->getDecl();
  219. if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(D))
  220. CGF.EmitVarDecl(*OED);
  221. }
  222. } else if (const auto *UDP = dyn_cast<OMPUseDeviceAddrClause>(C)) {
  223. for (const Expr *E : UDP->varlists()) {
  224. const Decl *D = getBaseDecl(E);
  225. if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(D))
  226. CGF.EmitVarDecl(*OED);
  227. }
  228. }
  229. }
  230. if (!isOpenMPSimdDirective(S.getDirectiveKind()))
  231. CGF.EmitOMPPrivateClause(S, InlinedShareds);
  232. if (const auto *TG = dyn_cast<OMPTaskgroupDirective>(&S)) {
  233. if (const Expr *E = TG->getReductionRef())
  234. CGF.EmitVarDecl(*cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()));
  235. }
  236. // Temp copy arrays for inscan reductions should not be emitted as they are
  237. // not used in simd only mode.
  238. llvm::DenseSet<CanonicalDeclPtr<const Decl>> CopyArrayTemps;
  239. for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
  240. if (C->getModifier() != OMPC_REDUCTION_inscan)
  241. continue;
  242. for (const Expr *E : C->copy_array_temps())
  243. CopyArrayTemps.insert(cast<DeclRefExpr>(E)->getDecl());
  244. }
  245. const auto *CS = cast_or_null<CapturedStmt>(S.getAssociatedStmt());
  246. while (CS) {
  247. for (auto &C : CS->captures()) {
  248. if (C.capturesVariable() || C.capturesVariableByCopy()) {
  249. auto *VD = C.getCapturedVar();
  250. if (CopyArrayTemps.contains(VD))
  251. continue;
  252. assert(VD == VD->getCanonicalDecl() &&
  253. "Canonical decl must be captured.");
  254. DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(VD),
  255. isCapturedVar(CGF, VD) ||
  256. (CGF.CapturedStmtInfo &&
  257. InlinedShareds.isGlobalVarCaptured(VD)),
  258. VD->getType().getNonReferenceType(), VK_LValue,
  259. C.getLocation());
  260. InlinedShareds.addPrivate(VD, [&CGF, &DRE]() -> Address {
  261. return CGF.EmitLValue(&DRE).getAddress(CGF);
  262. });
  263. }
  264. }
  265. CS = dyn_cast<CapturedStmt>(CS->getCapturedStmt());
  266. }
  267. (void)InlinedShareds.Privatize();
  268. }
  269. };
  270. } // namespace
  271. static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
  272. const OMPExecutableDirective &S,
  273. const RegionCodeGenTy &CodeGen);
  274. LValue CodeGenFunction::EmitOMPSharedLValue(const Expr *E) {
  275. if (const auto *OrigDRE = dyn_cast<DeclRefExpr>(E)) {
  276. if (const auto *OrigVD = dyn_cast<VarDecl>(OrigDRE->getDecl())) {
  277. OrigVD = OrigVD->getCanonicalDecl();
  278. bool IsCaptured =
  279. LambdaCaptureFields.lookup(OrigVD) ||
  280. (CapturedStmtInfo && CapturedStmtInfo->lookup(OrigVD)) ||
  281. (CurCodeDecl && isa<BlockDecl>(CurCodeDecl));
  282. DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD), IsCaptured,
  283. OrigDRE->getType(), VK_LValue, OrigDRE->getExprLoc());
  284. return EmitLValue(&DRE);
  285. }
  286. }
  287. return EmitLValue(E);
  288. }
  289. llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) {
  290. ASTContext &C = getContext();
  291. llvm::Value *Size = nullptr;
  292. auto SizeInChars = C.getTypeSizeInChars(Ty);
  293. if (SizeInChars.isZero()) {
  294. // getTypeSizeInChars() returns 0 for a VLA.
  295. while (const VariableArrayType *VAT = C.getAsVariableArrayType(Ty)) {
  296. VlaSizePair VlaSize = getVLASize(VAT);
  297. Ty = VlaSize.Type;
  298. Size =
  299. Size ? Builder.CreateNUWMul(Size, VlaSize.NumElts) : VlaSize.NumElts;
  300. }
  301. SizeInChars = C.getTypeSizeInChars(Ty);
  302. if (SizeInChars.isZero())
  303. return llvm::ConstantInt::get(SizeTy, /*V=*/0);
  304. return Builder.CreateNUWMul(Size, CGM.getSize(SizeInChars));
  305. }
  306. return CGM.getSize(SizeInChars);
  307. }
  308. void CodeGenFunction::GenerateOpenMPCapturedVars(
  309. const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars) {
  310. const RecordDecl *RD = S.getCapturedRecordDecl();
  311. auto CurField = RD->field_begin();
  312. auto CurCap = S.captures().begin();
  313. for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(),
  314. E = S.capture_init_end();
  315. I != E; ++I, ++CurField, ++CurCap) {
  316. if (CurField->hasCapturedVLAType()) {
  317. const VariableArrayType *VAT = CurField->getCapturedVLAType();
  318. llvm::Value *Val = VLASizeMap[VAT->getSizeExpr()];
  319. CapturedVars.push_back(Val);
  320. } else if (CurCap->capturesThis()) {
  321. CapturedVars.push_back(CXXThisValue);
  322. } else if (CurCap->capturesVariableByCopy()) {
  323. llvm::Value *CV = EmitLoadOfScalar(EmitLValue(*I), CurCap->getLocation());
  324. // If the field is not a pointer, we need to save the actual value
  325. // and load it as a void pointer.
  326. if (!CurField->getType()->isAnyPointerType()) {
  327. ASTContext &Ctx = getContext();
  328. Address DstAddr = CreateMemTemp(
  329. Ctx.getUIntPtrType(),
  330. Twine(CurCap->getCapturedVar()->getName(), ".casted"));
  331. LValue DstLV = MakeAddrLValue(DstAddr, Ctx.getUIntPtrType());
  332. llvm::Value *SrcAddrVal = EmitScalarConversion(
  333. DstAddr.getPointer(), Ctx.getPointerType(Ctx.getUIntPtrType()),
  334. Ctx.getPointerType(CurField->getType()), CurCap->getLocation());
  335. LValue SrcLV =
  336. MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType());
  337. // Store the value using the source type pointer.
  338. EmitStoreThroughLValue(RValue::get(CV), SrcLV);
  339. // Load the value using the destination type pointer.
  340. CV = EmitLoadOfScalar(DstLV, CurCap->getLocation());
  341. }
  342. CapturedVars.push_back(CV);
  343. } else {
  344. assert(CurCap->capturesVariable() && "Expected capture by reference.");
  345. CapturedVars.push_back(EmitLValue(*I).getAddress(*this).getPointer());
  346. }
  347. }
  348. }
  349. static Address castValueFromUintptr(CodeGenFunction &CGF, SourceLocation Loc,
  350. QualType DstType, StringRef Name,
  351. LValue AddrLV) {
  352. ASTContext &Ctx = CGF.getContext();
  353. llvm::Value *CastedPtr = CGF.EmitScalarConversion(
  354. AddrLV.getAddress(CGF).getPointer(), Ctx.getUIntPtrType(),
  355. Ctx.getPointerType(DstType), Loc);
  356. Address TmpAddr =
  357. CGF.MakeNaturalAlignAddrLValue(CastedPtr, DstType).getAddress(CGF);
  358. return TmpAddr;
  359. }
  360. static QualType getCanonicalParamType(ASTContext &C, QualType T) {
  361. if (T->isLValueReferenceType())
  362. return C.getLValueReferenceType(
  363. getCanonicalParamType(C, T.getNonReferenceType()),
  364. /*SpelledAsLValue=*/false);
  365. if (T->isPointerType())
  366. return C.getPointerType(getCanonicalParamType(C, T->getPointeeType()));
  367. if (const ArrayType *A = T->getAsArrayTypeUnsafe()) {
  368. if (const auto *VLA = dyn_cast<VariableArrayType>(A))
  369. return getCanonicalParamType(C, VLA->getElementType());
  370. if (!A->isVariablyModifiedType())
  371. return C.getCanonicalType(T);
  372. }
  373. return C.getCanonicalParamType(T);
  374. }
  375. namespace {
  376. /// Contains required data for proper outlined function codegen.
  377. struct FunctionOptions {
  378. /// Captured statement for which the function is generated.
  379. const CapturedStmt *S = nullptr;
  380. /// true if cast to/from UIntPtr is required for variables captured by
  381. /// value.
  382. const bool UIntPtrCastRequired = true;
  383. /// true if only casted arguments must be registered as local args or VLA
  384. /// sizes.
  385. const bool RegisterCastedArgsOnly = false;
  386. /// Name of the generated function.
  387. const StringRef FunctionName;
  388. /// Location of the non-debug version of the outlined function.
  389. SourceLocation Loc;
  390. explicit FunctionOptions(const CapturedStmt *S, bool UIntPtrCastRequired,
  391. bool RegisterCastedArgsOnly, StringRef FunctionName,
  392. SourceLocation Loc)
  393. : S(S), UIntPtrCastRequired(UIntPtrCastRequired),
  394. RegisterCastedArgsOnly(UIntPtrCastRequired && RegisterCastedArgsOnly),
  395. FunctionName(FunctionName), Loc(Loc) {}
  396. };
  397. } // namespace
  398. static llvm::Function *emitOutlinedFunctionPrologue(
  399. CodeGenFunction &CGF, FunctionArgList &Args,
  400. llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>>
  401. &LocalAddrs,
  402. llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>>
  403. &VLASizes,
  404. llvm::Value *&CXXThisValue, const FunctionOptions &FO) {
  405. const CapturedDecl *CD = FO.S->getCapturedDecl();
  406. const RecordDecl *RD = FO.S->getCapturedRecordDecl();
  407. assert(CD->hasBody() && "missing CapturedDecl body");
  408. CXXThisValue = nullptr;
  409. // Build the argument list.
  410. CodeGenModule &CGM = CGF.CGM;
  411. ASTContext &Ctx = CGM.getContext();
  412. FunctionArgList TargetArgs;
  413. Args.append(CD->param_begin(),
  414. std::next(CD->param_begin(), CD->getContextParamPosition()));
  415. TargetArgs.append(
  416. CD->param_begin(),
  417. std::next(CD->param_begin(), CD->getContextParamPosition()));
  418. auto I = FO.S->captures().begin();
  419. FunctionDecl *DebugFunctionDecl = nullptr;
  420. if (!FO.UIntPtrCastRequired) {
  421. FunctionProtoType::ExtProtoInfo EPI;
  422. QualType FunctionTy = Ctx.getFunctionType(Ctx.VoidTy, llvm::None, EPI);
  423. DebugFunctionDecl = FunctionDecl::Create(
  424. Ctx, Ctx.getTranslationUnitDecl(), FO.S->getBeginLoc(),
  425. SourceLocation(), DeclarationName(), FunctionTy,
  426. Ctx.getTrivialTypeSourceInfo(FunctionTy), SC_Static,
  427. /*UsesFPIntrin=*/false, /*isInlineSpecified=*/false,
  428. /*hasWrittenPrototype=*/false);
  429. }
  430. for (const FieldDecl *FD : RD->fields()) {
  431. QualType ArgType = FD->getType();
  432. IdentifierInfo *II = nullptr;
  433. VarDecl *CapVar = nullptr;
  434. // If this is a capture by copy and the type is not a pointer, the outlined
  435. // function argument type should be uintptr and the value properly casted to
  436. // uintptr. This is necessary given that the runtime library is only able to
  437. // deal with pointers. We can pass in the same way the VLA type sizes to the
  438. // outlined function.
  439. if (FO.UIntPtrCastRequired &&
  440. ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) ||
  441. I->capturesVariableArrayType()))
  442. ArgType = Ctx.getUIntPtrType();
  443. if (I->capturesVariable() || I->capturesVariableByCopy()) {
  444. CapVar = I->getCapturedVar();
  445. II = CapVar->getIdentifier();
  446. } else if (I->capturesThis()) {
  447. II = &Ctx.Idents.get("this");
  448. } else {
  449. assert(I->capturesVariableArrayType());
  450. II = &Ctx.Idents.get("vla");
  451. }
  452. if (ArgType->isVariablyModifiedType())
  453. ArgType = getCanonicalParamType(Ctx, ArgType);
  454. VarDecl *Arg;
  455. if (DebugFunctionDecl && (CapVar || I->capturesThis())) {
  456. Arg = ParmVarDecl::Create(
  457. Ctx, DebugFunctionDecl,
  458. CapVar ? CapVar->getBeginLoc() : FD->getBeginLoc(),
  459. CapVar ? CapVar->getLocation() : FD->getLocation(), II, ArgType,
  460. /*TInfo=*/nullptr, SC_None, /*DefArg=*/nullptr);
  461. } else {
  462. Arg = ImplicitParamDecl::Create(Ctx, /*DC=*/nullptr, FD->getLocation(),
  463. II, ArgType, ImplicitParamDecl::Other);
  464. }
  465. Args.emplace_back(Arg);
  466. // Do not cast arguments if we emit function with non-original types.
  467. TargetArgs.emplace_back(
  468. FO.UIntPtrCastRequired
  469. ? Arg
  470. : CGM.getOpenMPRuntime().translateParameter(FD, Arg));
  471. ++I;
  472. }
  473. Args.append(std::next(CD->param_begin(), CD->getContextParamPosition() + 1),
  474. CD->param_end());
  475. TargetArgs.append(
  476. std::next(CD->param_begin(), CD->getContextParamPosition() + 1),
  477. CD->param_end());
  478. // Create the function declaration.
  479. const CGFunctionInfo &FuncInfo =
  480. CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, TargetArgs);
  481. llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo);
  482. auto *F =
  483. llvm::Function::Create(FuncLLVMTy, llvm::GlobalValue::InternalLinkage,
  484. FO.FunctionName, &CGM.getModule());
  485. CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
  486. if (CD->isNothrow())
  487. F->setDoesNotThrow();
  488. F->setDoesNotRecurse();
  489. // Always inline the outlined function if optimizations are enabled.
  490. if (CGM.getCodeGenOpts().OptimizationLevel != 0) {
  491. F->removeFnAttr(llvm::Attribute::NoInline);
  492. F->addFnAttr(llvm::Attribute::AlwaysInline);
  493. }
  494. // Generate the function.
  495. CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, TargetArgs,
  496. FO.UIntPtrCastRequired ? FO.Loc : FO.S->getBeginLoc(),
  497. FO.UIntPtrCastRequired ? FO.Loc
  498. : CD->getBody()->getBeginLoc());
  499. unsigned Cnt = CD->getContextParamPosition();
  500. I = FO.S->captures().begin();
  501. for (const FieldDecl *FD : RD->fields()) {
  502. // Do not map arguments if we emit function with non-original types.
  503. Address LocalAddr(Address::invalid());
  504. if (!FO.UIntPtrCastRequired && Args[Cnt] != TargetArgs[Cnt]) {
  505. LocalAddr = CGM.getOpenMPRuntime().getParameterAddress(CGF, Args[Cnt],
  506. TargetArgs[Cnt]);
  507. } else {
  508. LocalAddr = CGF.GetAddrOfLocalVar(Args[Cnt]);
  509. }
  510. // If we are capturing a pointer by copy we don't need to do anything, just
  511. // use the value that we get from the arguments.
  512. if (I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
  513. const VarDecl *CurVD = I->getCapturedVar();
  514. if (!FO.RegisterCastedArgsOnly)
  515. LocalAddrs.insert({Args[Cnt], {CurVD, LocalAddr}});
  516. ++Cnt;
  517. ++I;
  518. continue;
  519. }
  520. LValue ArgLVal = CGF.MakeAddrLValue(LocalAddr, Args[Cnt]->getType(),
  521. AlignmentSource::Decl);
  522. if (FD->hasCapturedVLAType()) {
  523. if (FO.UIntPtrCastRequired) {
  524. ArgLVal = CGF.MakeAddrLValue(
  525. castValueFromUintptr(CGF, I->getLocation(), FD->getType(),
  526. Args[Cnt]->getName(), ArgLVal),
  527. FD->getType(), AlignmentSource::Decl);
  528. }
  529. llvm::Value *ExprArg = CGF.EmitLoadOfScalar(ArgLVal, I->getLocation());
  530. const VariableArrayType *VAT = FD->getCapturedVLAType();
  531. VLASizes.try_emplace(Args[Cnt], VAT->getSizeExpr(), ExprArg);
  532. } else if (I->capturesVariable()) {
  533. const VarDecl *Var = I->getCapturedVar();
  534. QualType VarTy = Var->getType();
  535. Address ArgAddr = ArgLVal.getAddress(CGF);
  536. if (ArgLVal.getType()->isLValueReferenceType()) {
  537. ArgAddr = CGF.EmitLoadOfReference(ArgLVal);
  538. } else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) {
  539. assert(ArgLVal.getType()->isPointerType());
  540. ArgAddr = CGF.EmitLoadOfPointer(
  541. ArgAddr, ArgLVal.getType()->castAs<PointerType>());
  542. }
  543. if (!FO.RegisterCastedArgsOnly) {
  544. LocalAddrs.insert(
  545. {Args[Cnt],
  546. {Var, Address(ArgAddr.getPointer(), Ctx.getDeclAlign(Var))}});
  547. }
  548. } else if (I->capturesVariableByCopy()) {
  549. assert(!FD->getType()->isAnyPointerType() &&
  550. "Not expecting a captured pointer.");
  551. const VarDecl *Var = I->getCapturedVar();
  552. LocalAddrs.insert({Args[Cnt],
  553. {Var, FO.UIntPtrCastRequired
  554. ? castValueFromUintptr(
  555. CGF, I->getLocation(), FD->getType(),
  556. Args[Cnt]->getName(), ArgLVal)
  557. : ArgLVal.getAddress(CGF)}});
  558. } else {
  559. // If 'this' is captured, load it into CXXThisValue.
  560. assert(I->capturesThis());
  561. CXXThisValue = CGF.EmitLoadOfScalar(ArgLVal, I->getLocation());
  562. LocalAddrs.insert({Args[Cnt], {nullptr, ArgLVal.getAddress(CGF)}});
  563. }
  564. ++Cnt;
  565. ++I;
  566. }
  567. return F;
  568. }
  569. llvm::Function *
  570. CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S,
  571. SourceLocation Loc) {
  572. assert(
  573. CapturedStmtInfo &&
  574. "CapturedStmtInfo should be set when generating the captured function");
  575. const CapturedDecl *CD = S.getCapturedDecl();
  576. // Build the argument list.
  577. bool NeedWrapperFunction =
  578. getDebugInfo() && CGM.getCodeGenOpts().hasReducedDebugInfo();
  579. FunctionArgList Args;
  580. llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs;
  581. llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes;
  582. SmallString<256> Buffer;
  583. llvm::raw_svector_ostream Out(Buffer);
  584. Out << CapturedStmtInfo->getHelperName();
  585. if (NeedWrapperFunction)
  586. Out << "_debug__";
  587. FunctionOptions FO(&S, !NeedWrapperFunction, /*RegisterCastedArgsOnly=*/false,
  588. Out.str(), Loc);
  589. llvm::Function *F = emitOutlinedFunctionPrologue(*this, Args, LocalAddrs,
  590. VLASizes, CXXThisValue, FO);
  591. CodeGenFunction::OMPPrivateScope LocalScope(*this);
  592. for (const auto &LocalAddrPair : LocalAddrs) {
  593. if (LocalAddrPair.second.first) {
  594. LocalScope.addPrivate(LocalAddrPair.second.first, [&LocalAddrPair]() {
  595. return LocalAddrPair.second.second;
  596. });
  597. }
  598. }
  599. (void)LocalScope.Privatize();
  600. for (const auto &VLASizePair : VLASizes)
  601. VLASizeMap[VLASizePair.second.first] = VLASizePair.second.second;
  602. PGO.assignRegionCounters(GlobalDecl(CD), F);
  603. CapturedStmtInfo->EmitBody(*this, CD->getBody());
  604. (void)LocalScope.ForceCleanup();
  605. FinishFunction(CD->getBodyRBrace());
  606. if (!NeedWrapperFunction)
  607. return F;
  608. FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true,
  609. /*RegisterCastedArgsOnly=*/true,
  610. CapturedStmtInfo->getHelperName(), Loc);
  611. CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true);
  612. WrapperCGF.CapturedStmtInfo = CapturedStmtInfo;
  613. Args.clear();
  614. LocalAddrs.clear();
  615. VLASizes.clear();
  616. llvm::Function *WrapperF =
  617. emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes,
  618. WrapperCGF.CXXThisValue, WrapperFO);
  619. llvm::SmallVector<llvm::Value *, 4> CallArgs;
  620. auto *PI = F->arg_begin();
  621. for (const auto *Arg : Args) {
  622. llvm::Value *CallArg;
  623. auto I = LocalAddrs.find(Arg);
  624. if (I != LocalAddrs.end()) {
  625. LValue LV = WrapperCGF.MakeAddrLValue(
  626. I->second.second,
  627. I->second.first ? I->second.first->getType() : Arg->getType(),
  628. AlignmentSource::Decl);
  629. if (LV.getType()->isAnyComplexType())
  630. LV.setAddress(WrapperCGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
  631. LV.getAddress(WrapperCGF),
  632. PI->getType()->getPointerTo(
  633. LV.getAddress(WrapperCGF).getAddressSpace())));
  634. CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc());
  635. } else {
  636. auto EI = VLASizes.find(Arg);
  637. if (EI != VLASizes.end()) {
  638. CallArg = EI->second.second;
  639. } else {
  640. LValue LV =
  641. WrapperCGF.MakeAddrLValue(WrapperCGF.GetAddrOfLocalVar(Arg),
  642. Arg->getType(), AlignmentSource::Decl);
  643. CallArg = WrapperCGF.EmitLoadOfScalar(LV, S.getBeginLoc());
  644. }
  645. }
  646. CallArgs.emplace_back(WrapperCGF.EmitFromMemory(CallArg, Arg->getType()));
  647. ++PI;
  648. }
  649. CGM.getOpenMPRuntime().emitOutlinedFunctionCall(WrapperCGF, Loc, F, CallArgs);
  650. WrapperCGF.FinishFunction();
  651. return WrapperF;
  652. }
  653. //===----------------------------------------------------------------------===//
  654. // OpenMP Directive Emission
  655. //===----------------------------------------------------------------------===//
  656. void CodeGenFunction::EmitOMPAggregateAssign(
  657. Address DestAddr, Address SrcAddr, QualType OriginalType,
  658. const llvm::function_ref<void(Address, Address)> CopyGen) {
  659. // Perform element-by-element initialization.
  660. QualType ElementTy;
  661. // Drill down to the base element type on both arrays.
  662. const ArrayType *ArrayTy = OriginalType->getAsArrayTypeUnsafe();
  663. llvm::Value *NumElements = emitArrayLength(ArrayTy, ElementTy, DestAddr);
  664. SrcAddr = Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
  665. llvm::Value *SrcBegin = SrcAddr.getPointer();
  666. llvm::Value *DestBegin = DestAddr.getPointer();
  667. // Cast from pointer to array type to pointer to single element.
  668. llvm::Value *DestEnd =
  669. Builder.CreateGEP(DestAddr.getElementType(), DestBegin, NumElements);
  670. // The basic structure here is a while-do loop.
  671. llvm::BasicBlock *BodyBB = createBasicBlock("omp.arraycpy.body");
  672. llvm::BasicBlock *DoneBB = createBasicBlock("omp.arraycpy.done");
  673. llvm::Value *IsEmpty =
  674. Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arraycpy.isempty");
  675. Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
  676. // Enter the loop body, making that address the current address.
  677. llvm::BasicBlock *EntryBB = Builder.GetInsertBlock();
  678. EmitBlock(BodyBB);
  679. CharUnits ElementSize = getContext().getTypeSizeInChars(ElementTy);
  680. llvm::PHINode *SrcElementPHI =
  681. Builder.CreatePHI(SrcBegin->getType(), 2, "omp.arraycpy.srcElementPast");
  682. SrcElementPHI->addIncoming(SrcBegin, EntryBB);
  683. Address SrcElementCurrent =
  684. Address(SrcElementPHI,
  685. SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
  686. llvm::PHINode *DestElementPHI = Builder.CreatePHI(
  687. DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
  688. DestElementPHI->addIncoming(DestBegin, EntryBB);
  689. Address DestElementCurrent =
  690. Address(DestElementPHI,
  691. DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
  692. // Emit copy.
  693. CopyGen(DestElementCurrent, SrcElementCurrent);
  694. // Shift the address forward by one element.
  695. llvm::Value *DestElementNext =
  696. Builder.CreateConstGEP1_32(DestAddr.getElementType(), DestElementPHI,
  697. /*Idx0=*/1, "omp.arraycpy.dest.element");
  698. llvm::Value *SrcElementNext =
  699. Builder.CreateConstGEP1_32(SrcAddr.getElementType(), SrcElementPHI,
  700. /*Idx0=*/1, "omp.arraycpy.src.element");
  701. // Check whether we've reached the end.
  702. llvm::Value *Done =
  703. Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
  704. Builder.CreateCondBr(Done, DoneBB, BodyBB);
  705. DestElementPHI->addIncoming(DestElementNext, Builder.GetInsertBlock());
  706. SrcElementPHI->addIncoming(SrcElementNext, Builder.GetInsertBlock());
  707. // Done.
  708. EmitBlock(DoneBB, /*IsFinished=*/true);
  709. }
  710. void CodeGenFunction::EmitOMPCopy(QualType OriginalType, Address DestAddr,
  711. Address SrcAddr, const VarDecl *DestVD,
  712. const VarDecl *SrcVD, const Expr *Copy) {
  713. if (OriginalType->isArrayType()) {
  714. const auto *BO = dyn_cast<BinaryOperator>(Copy);
  715. if (BO && BO->getOpcode() == BO_Assign) {
  716. // Perform simple memcpy for simple copying.
  717. LValue Dest = MakeAddrLValue(DestAddr, OriginalType);
  718. LValue Src = MakeAddrLValue(SrcAddr, OriginalType);
  719. EmitAggregateAssign(Dest, Src, OriginalType);
  720. } else {
  721. // For arrays with complex element types perform element by element
  722. // copying.
  723. EmitOMPAggregateAssign(
  724. DestAddr, SrcAddr, OriginalType,
  725. [this, Copy, SrcVD, DestVD](Address DestElement, Address SrcElement) {
  726. // Working with the single array element, so have to remap
  727. // destination and source variables to corresponding array
  728. // elements.
  729. CodeGenFunction::OMPPrivateScope Remap(*this);
  730. Remap.addPrivate(DestVD, [DestElement]() { return DestElement; });
  731. Remap.addPrivate(SrcVD, [SrcElement]() { return SrcElement; });
  732. (void)Remap.Privatize();
  733. EmitIgnoredExpr(Copy);
  734. });
  735. }
  736. } else {
  737. // Remap pseudo source variable to private copy.
  738. CodeGenFunction::OMPPrivateScope Remap(*this);
  739. Remap.addPrivate(SrcVD, [SrcAddr]() { return SrcAddr; });
  740. Remap.addPrivate(DestVD, [DestAddr]() { return DestAddr; });
  741. (void)Remap.Privatize();
  742. // Emit copying of the whole variable.
  743. EmitIgnoredExpr(Copy);
  744. }
  745. }
  746. bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
  747. OMPPrivateScope &PrivateScope) {
  748. if (!HaveInsertPoint())
  749. return false;
  750. bool DeviceConstTarget =
  751. getLangOpts().OpenMPIsDevice &&
  752. isOpenMPTargetExecutionDirective(D.getDirectiveKind());
  753. bool FirstprivateIsLastprivate = false;
  754. llvm::DenseMap<const VarDecl *, OpenMPLastprivateModifier> Lastprivates;
  755. for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
  756. for (const auto *D : C->varlists())
  757. Lastprivates.try_emplace(
  758. cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl())->getCanonicalDecl(),
  759. C->getKind());
  760. }
  761. llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate;
  762. llvm::SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
  763. getOpenMPCaptureRegions(CaptureRegions, D.getDirectiveKind());
  764. // Force emission of the firstprivate copy if the directive does not emit
  765. // outlined function, like omp for, omp simd, omp distribute etc.
  766. bool MustEmitFirstprivateCopy =
  767. CaptureRegions.size() == 1 && CaptureRegions.back() == OMPD_unknown;
  768. for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) {
  769. const auto *IRef = C->varlist_begin();
  770. const auto *InitsRef = C->inits().begin();
  771. for (const Expr *IInit : C->private_copies()) {
  772. const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
  773. bool ThisFirstprivateIsLastprivate =
  774. Lastprivates.count(OrigVD->getCanonicalDecl()) > 0;
  775. const FieldDecl *FD = CapturedStmtInfo->lookup(OrigVD);
  776. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
  777. if (!MustEmitFirstprivateCopy && !ThisFirstprivateIsLastprivate && FD &&
  778. !FD->getType()->isReferenceType() &&
  779. (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())) {
  780. EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());
  781. ++IRef;
  782. ++InitsRef;
  783. continue;
  784. }
  785. // Do not emit copy for firstprivate constant variables in target regions,
  786. // captured by reference.
  787. if (DeviceConstTarget && OrigVD->getType().isConstant(getContext()) &&
  788. FD && FD->getType()->isReferenceType() &&
  789. (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())) {
  790. EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl());
  791. ++IRef;
  792. ++InitsRef;
  793. continue;
  794. }
  795. FirstprivateIsLastprivate =
  796. FirstprivateIsLastprivate || ThisFirstprivateIsLastprivate;
  797. if (EmittedAsFirstprivate.insert(OrigVD->getCanonicalDecl()).second) {
  798. const auto *VDInit =
  799. cast<VarDecl>(cast<DeclRefExpr>(*InitsRef)->getDecl());
  800. bool IsRegistered;
  801. DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
  802. /*RefersToEnclosingVariableOrCapture=*/FD != nullptr,
  803. (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
  804. LValue OriginalLVal;
  805. if (!FD) {
  806. // Check if the firstprivate variable is just a constant value.
  807. ConstantEmission CE = tryEmitAsConstant(&DRE);
  808. if (CE && !CE.isReference()) {
  809. // Constant value, no need to create a copy.
  810. ++IRef;
  811. ++InitsRef;
  812. continue;
  813. }
  814. if (CE && CE.isReference()) {
  815. OriginalLVal = CE.getReferenceLValue(*this, &DRE);
  816. } else {
  817. assert(!CE && "Expected non-constant firstprivate.");
  818. OriginalLVal = EmitLValue(&DRE);
  819. }
  820. } else {
  821. OriginalLVal = EmitLValue(&DRE);
  822. }
  823. QualType Type = VD->getType();
  824. if (Type->isArrayType()) {
  825. // Emit VarDecl with copy init for arrays.
  826. // Get the address of the original variable captured in current
  827. // captured region.
  828. IsRegistered = PrivateScope.addPrivate(
  829. OrigVD, [this, VD, Type, OriginalLVal, VDInit]() {
  830. AutoVarEmission Emission = EmitAutoVarAlloca(*VD);
  831. const Expr *Init = VD->getInit();
  832. if (!isa<CXXConstructExpr>(Init) ||
  833. isTrivialInitializer(Init)) {
  834. // Perform simple memcpy.
  835. LValue Dest =
  836. MakeAddrLValue(Emission.getAllocatedAddress(), Type);
  837. EmitAggregateAssign(Dest, OriginalLVal, Type);
  838. } else {
  839. EmitOMPAggregateAssign(
  840. Emission.getAllocatedAddress(),
  841. OriginalLVal.getAddress(*this), Type,
  842. [this, VDInit, Init](Address DestElement,
  843. Address SrcElement) {
  844. // Clean up any temporaries needed by the
  845. // initialization.
  846. RunCleanupsScope InitScope(*this);
  847. // Emit initialization for single element.
  848. setAddrOfLocalVar(VDInit, SrcElement);
  849. EmitAnyExprToMem(Init, DestElement,
  850. Init->getType().getQualifiers(),
  851. /*IsInitializer*/ false);
  852. LocalDeclMap.erase(VDInit);
  853. });
  854. }
  855. EmitAutoVarCleanups(Emission);
  856. return Emission.getAllocatedAddress();
  857. });
  858. } else {
  859. Address OriginalAddr = OriginalLVal.getAddress(*this);
  860. IsRegistered =
  861. PrivateScope.addPrivate(OrigVD, [this, VDInit, OriginalAddr, VD,
  862. ThisFirstprivateIsLastprivate,
  863. OrigVD, &Lastprivates, IRef]() {
  864. // Emit private VarDecl with copy init.
  865. // Remap temp VDInit variable to the address of the original
  866. // variable (for proper handling of captured global variables).
  867. setAddrOfLocalVar(VDInit, OriginalAddr);
  868. EmitDecl(*VD);
  869. LocalDeclMap.erase(VDInit);
  870. if (ThisFirstprivateIsLastprivate &&
  871. Lastprivates[OrigVD->getCanonicalDecl()] ==
  872. OMPC_LASTPRIVATE_conditional) {
  873. // Create/init special variable for lastprivate conditionals.
  874. Address VDAddr =
  875. CGM.getOpenMPRuntime().emitLastprivateConditionalInit(
  876. *this, OrigVD);
  877. llvm::Value *V = EmitLoadOfScalar(
  878. MakeAddrLValue(GetAddrOfLocalVar(VD), (*IRef)->getType(),
  879. AlignmentSource::Decl),
  880. (*IRef)->getExprLoc());
  881. EmitStoreOfScalar(V,
  882. MakeAddrLValue(VDAddr, (*IRef)->getType(),
  883. AlignmentSource::Decl));
  884. LocalDeclMap.erase(VD);
  885. setAddrOfLocalVar(VD, VDAddr);
  886. return VDAddr;
  887. }
  888. return GetAddrOfLocalVar(VD);
  889. });
  890. }
  891. assert(IsRegistered &&
  892. "firstprivate var already registered as private");
  893. // Silence the warning about unused variable.
  894. (void)IsRegistered;
  895. }
  896. ++IRef;
  897. ++InitsRef;
  898. }
  899. }
  900. return FirstprivateIsLastprivate && !EmittedAsFirstprivate.empty();
  901. }
  902. void CodeGenFunction::EmitOMPPrivateClause(
  903. const OMPExecutableDirective &D,
  904. CodeGenFunction::OMPPrivateScope &PrivateScope) {
  905. if (!HaveInsertPoint())
  906. return;
  907. llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
  908. for (const auto *C : D.getClausesOfKind<OMPPrivateClause>()) {
  909. auto IRef = C->varlist_begin();
  910. for (const Expr *IInit : C->private_copies()) {
  911. const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
  912. if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
  913. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
  914. bool IsRegistered = PrivateScope.addPrivate(OrigVD, [this, VD]() {
  915. // Emit private VarDecl with copy init.
  916. EmitDecl(*VD);
  917. return GetAddrOfLocalVar(VD);
  918. });
  919. assert(IsRegistered && "private var already registered as private");
  920. // Silence the warning about unused variable.
  921. (void)IsRegistered;
  922. }
  923. ++IRef;
  924. }
  925. }
  926. }
  927. bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) {
  928. if (!HaveInsertPoint())
  929. return false;
  930. // threadprivate_var1 = master_threadprivate_var1;
  931. // operator=(threadprivate_var2, master_threadprivate_var2);
  932. // ...
  933. // __kmpc_barrier(&loc, global_tid);
  934. llvm::DenseSet<const VarDecl *> CopiedVars;
  935. llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr;
  936. for (const auto *C : D.getClausesOfKind<OMPCopyinClause>()) {
  937. auto IRef = C->varlist_begin();
  938. auto ISrcRef = C->source_exprs().begin();
  939. auto IDestRef = C->destination_exprs().begin();
  940. for (const Expr *AssignOp : C->assignment_ops()) {
  941. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
  942. QualType Type = VD->getType();
  943. if (CopiedVars.insert(VD->getCanonicalDecl()).second) {
  944. // Get the address of the master variable. If we are emitting code with
  945. // TLS support, the address is passed from the master as field in the
  946. // captured declaration.
  947. Address MasterAddr = Address::invalid();
  948. if (getLangOpts().OpenMPUseTLS &&
  949. getContext().getTargetInfo().isTLSSupported()) {
  950. assert(CapturedStmtInfo->lookup(VD) &&
  951. "Copyin threadprivates should have been captured!");
  952. DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(VD), true,
  953. (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
  954. MasterAddr = EmitLValue(&DRE).getAddress(*this);
  955. LocalDeclMap.erase(VD);
  956. } else {
  957. MasterAddr =
  958. Address(VD->isStaticLocal() ? CGM.getStaticLocalDeclAddress(VD)
  959. : CGM.GetAddrOfGlobal(VD),
  960. getContext().getDeclAlign(VD));
  961. }
  962. // Get the address of the threadprivate variable.
  963. Address PrivateAddr = EmitLValue(*IRef).getAddress(*this);
  964. if (CopiedVars.size() == 1) {
  965. // At first check if current thread is a master thread. If it is, no
  966. // need to copy data.
  967. CopyBegin = createBasicBlock("copyin.not.master");
  968. CopyEnd = createBasicBlock("copyin.not.master.end");
  969. // TODO: Avoid ptrtoint conversion.
  970. auto *MasterAddrInt =
  971. Builder.CreatePtrToInt(MasterAddr.getPointer(), CGM.IntPtrTy);
  972. auto *PrivateAddrInt =
  973. Builder.CreatePtrToInt(PrivateAddr.getPointer(), CGM.IntPtrTy);
  974. Builder.CreateCondBr(
  975. Builder.CreateICmpNE(MasterAddrInt, PrivateAddrInt), CopyBegin,
  976. CopyEnd);
  977. EmitBlock(CopyBegin);
  978. }
  979. const auto *SrcVD =
  980. cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
  981. const auto *DestVD =
  982. cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
  983. EmitOMPCopy(Type, PrivateAddr, MasterAddr, DestVD, SrcVD, AssignOp);
  984. }
  985. ++IRef;
  986. ++ISrcRef;
  987. ++IDestRef;
  988. }
  989. }
  990. if (CopyEnd) {
  991. // Exit out of copying procedure for non-master thread.
  992. EmitBlock(CopyEnd, /*IsFinished=*/true);
  993. return true;
  994. }
  995. return false;
  996. }
  997. bool CodeGenFunction::EmitOMPLastprivateClauseInit(
  998. const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) {
  999. if (!HaveInsertPoint())
  1000. return false;
  1001. bool HasAtLeastOneLastprivate = false;
  1002. llvm::DenseSet<const VarDecl *> SIMDLCVs;
  1003. if (isOpenMPSimdDirective(D.getDirectiveKind())) {
  1004. const auto *LoopDirective = cast<OMPLoopDirective>(&D);
  1005. for (const Expr *C : LoopDirective->counters()) {
  1006. SIMDLCVs.insert(
  1007. cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl());
  1008. }
  1009. }
  1010. llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
  1011. for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
  1012. HasAtLeastOneLastprivate = true;
  1013. if (isOpenMPTaskLoopDirective(D.getDirectiveKind()) &&
  1014. !getLangOpts().OpenMPSimd)
  1015. break;
  1016. const auto *IRef = C->varlist_begin();
  1017. const auto *IDestRef = C->destination_exprs().begin();
  1018. for (const Expr *IInit : C->private_copies()) {
  1019. // Keep the address of the original variable for future update at the end
  1020. // of the loop.
  1021. const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
  1022. // Taskloops do not require additional initialization, it is done in
  1023. // runtime support library.
  1024. if (AlreadyEmittedVars.insert(OrigVD->getCanonicalDecl()).second) {
  1025. const auto *DestVD =
  1026. cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
  1027. PrivateScope.addPrivate(DestVD, [this, OrigVD, IRef]() {
  1028. DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
  1029. /*RefersToEnclosingVariableOrCapture=*/
  1030. CapturedStmtInfo->lookup(OrigVD) != nullptr,
  1031. (*IRef)->getType(), VK_LValue, (*IRef)->getExprLoc());
  1032. return EmitLValue(&DRE).getAddress(*this);
  1033. });
  1034. // Check if the variable is also a firstprivate: in this case IInit is
  1035. // not generated. Initialization of this variable will happen in codegen
  1036. // for 'firstprivate' clause.
  1037. if (IInit && !SIMDLCVs.count(OrigVD->getCanonicalDecl())) {
  1038. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IInit)->getDecl());
  1039. bool IsRegistered =
  1040. PrivateScope.addPrivate(OrigVD, [this, VD, C, OrigVD]() {
  1041. if (C->getKind() == OMPC_LASTPRIVATE_conditional) {
  1042. Address VDAddr =
  1043. CGM.getOpenMPRuntime().emitLastprivateConditionalInit(
  1044. *this, OrigVD);
  1045. setAddrOfLocalVar(VD, VDAddr);
  1046. return VDAddr;
  1047. }
  1048. // Emit private VarDecl with copy init.
  1049. EmitDecl(*VD);
  1050. return GetAddrOfLocalVar(VD);
  1051. });
  1052. assert(IsRegistered &&
  1053. "lastprivate var already registered as private");
  1054. (void)IsRegistered;
  1055. }
  1056. }
  1057. ++IRef;
  1058. ++IDestRef;
  1059. }
  1060. }
  1061. return HasAtLeastOneLastprivate;
  1062. }
  1063. void CodeGenFunction::EmitOMPLastprivateClauseFinal(
  1064. const OMPExecutableDirective &D, bool NoFinals,
  1065. llvm::Value *IsLastIterCond) {
  1066. if (!HaveInsertPoint())
  1067. return;
  1068. // Emit following code:
  1069. // if (<IsLastIterCond>) {
  1070. // orig_var1 = private_orig_var1;
  1071. // ...
  1072. // orig_varn = private_orig_varn;
  1073. // }
  1074. llvm::BasicBlock *ThenBB = nullptr;
  1075. llvm::BasicBlock *DoneBB = nullptr;
  1076. if (IsLastIterCond) {
  1077. // Emit implicit barrier if at least one lastprivate conditional is found
  1078. // and this is not a simd mode.
  1079. if (!getLangOpts().OpenMPSimd &&
  1080. llvm::any_of(D.getClausesOfKind<OMPLastprivateClause>(),
  1081. [](const OMPLastprivateClause *C) {
  1082. return C->getKind() == OMPC_LASTPRIVATE_conditional;
  1083. })) {
  1084. CGM.getOpenMPRuntime().emitBarrierCall(*this, D.getBeginLoc(),
  1085. OMPD_unknown,
  1086. /*EmitChecks=*/false,
  1087. /*ForceSimpleCall=*/true);
  1088. }
  1089. ThenBB = createBasicBlock(".omp.lastprivate.then");
  1090. DoneBB = createBasicBlock(".omp.lastprivate.done");
  1091. Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
  1092. EmitBlock(ThenBB);
  1093. }
  1094. llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
  1095. llvm::DenseMap<const VarDecl *, const Expr *> LoopCountersAndUpdates;
  1096. if (const auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
  1097. auto IC = LoopDirective->counters().begin();
  1098. for (const Expr *F : LoopDirective->finals()) {
  1099. const auto *D =
  1100. cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl())->getCanonicalDecl();
  1101. if (NoFinals)
  1102. AlreadyEmittedVars.insert(D);
  1103. else
  1104. LoopCountersAndUpdates[D] = F;
  1105. ++IC;
  1106. }
  1107. }
  1108. for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
  1109. auto IRef = C->varlist_begin();
  1110. auto ISrcRef = C->source_exprs().begin();
  1111. auto IDestRef = C->destination_exprs().begin();
  1112. for (const Expr *AssignOp : C->assignment_ops()) {
  1113. const auto *PrivateVD =
  1114. cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
  1115. QualType Type = PrivateVD->getType();
  1116. const auto *CanonicalVD = PrivateVD->getCanonicalDecl();
  1117. if (AlreadyEmittedVars.insert(CanonicalVD).second) {
  1118. // If lastprivate variable is a loop control variable for loop-based
  1119. // directive, update its value before copyin back to original
  1120. // variable.
  1121. if (const Expr *FinalExpr = LoopCountersAndUpdates.lookup(CanonicalVD))
  1122. EmitIgnoredExpr(FinalExpr);
  1123. const auto *SrcVD =
  1124. cast<VarDecl>(cast<DeclRefExpr>(*ISrcRef)->getDecl());
  1125. const auto *DestVD =
  1126. cast<VarDecl>(cast<DeclRefExpr>(*IDestRef)->getDecl());
  1127. // Get the address of the private variable.
  1128. Address PrivateAddr = GetAddrOfLocalVar(PrivateVD);
  1129. if (const auto *RefTy = PrivateVD->getType()->getAs<ReferenceType>())
  1130. PrivateAddr =
  1131. Address(Builder.CreateLoad(PrivateAddr),
  1132. CGM.getNaturalTypeAlignment(RefTy->getPointeeType()));
  1133. // Store the last value to the private copy in the last iteration.
  1134. if (C->getKind() == OMPC_LASTPRIVATE_conditional)
  1135. CGM.getOpenMPRuntime().emitLastprivateConditionalFinalUpdate(
  1136. *this, MakeAddrLValue(PrivateAddr, (*IRef)->getType()), PrivateVD,
  1137. (*IRef)->getExprLoc());
  1138. // Get the address of the original variable.
  1139. Address OriginalAddr = GetAddrOfLocalVar(DestVD);
  1140. EmitOMPCopy(Type, OriginalAddr, PrivateAddr, DestVD, SrcVD, AssignOp);
  1141. }
  1142. ++IRef;
  1143. ++ISrcRef;
  1144. ++IDestRef;
  1145. }
  1146. if (const Expr *PostUpdate = C->getPostUpdateExpr())
  1147. EmitIgnoredExpr(PostUpdate);
  1148. }
  1149. if (IsLastIterCond)
  1150. EmitBlock(DoneBB, /*IsFinished=*/true);
  1151. }
  1152. void CodeGenFunction::EmitOMPReductionClauseInit(
  1153. const OMPExecutableDirective &D,
  1154. CodeGenFunction::OMPPrivateScope &PrivateScope, bool ForInscan) {
  1155. if (!HaveInsertPoint())
  1156. return;
  1157. SmallVector<const Expr *, 4> Shareds;
  1158. SmallVector<const Expr *, 4> Privates;
  1159. SmallVector<const Expr *, 4> ReductionOps;
  1160. SmallVector<const Expr *, 4> LHSs;
  1161. SmallVector<const Expr *, 4> RHSs;
  1162. OMPTaskDataTy Data;
  1163. SmallVector<const Expr *, 4> TaskLHSs;
  1164. SmallVector<const Expr *, 4> TaskRHSs;
  1165. for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
  1166. if (ForInscan != (C->getModifier() == OMPC_REDUCTION_inscan))
  1167. continue;
  1168. Shareds.append(C->varlist_begin(), C->varlist_end());
  1169. Privates.append(C->privates().begin(), C->privates().end());
  1170. ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
  1171. LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
  1172. RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
  1173. if (C->getModifier() == OMPC_REDUCTION_task) {
  1174. Data.ReductionVars.append(C->privates().begin(), C->privates().end());
  1175. Data.ReductionOrigs.append(C->varlist_begin(), C->varlist_end());
  1176. Data.ReductionCopies.append(C->privates().begin(), C->privates().end());
  1177. Data.ReductionOps.append(C->reduction_ops().begin(),
  1178. C->reduction_ops().end());
  1179. TaskLHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
  1180. TaskRHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
  1181. }
  1182. }
  1183. ReductionCodeGen RedCG(Shareds, Shareds, Privates, ReductionOps);
  1184. unsigned Count = 0;
  1185. auto *ILHS = LHSs.begin();
  1186. auto *IRHS = RHSs.begin();
  1187. auto *IPriv = Privates.begin();
  1188. for (const Expr *IRef : Shareds) {
  1189. const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());
  1190. // Emit private VarDecl with reduction init.
  1191. RedCG.emitSharedOrigLValue(*this, Count);
  1192. RedCG.emitAggregateType(*this, Count);
  1193. AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD);
  1194. RedCG.emitInitialization(*this, Count, Emission.getAllocatedAddress(),
  1195. RedCG.getSharedLValue(Count).getAddress(*this),
  1196. [&Emission](CodeGenFunction &CGF) {
  1197. CGF.EmitAutoVarInit(Emission);
  1198. return true;
  1199. });
  1200. EmitAutoVarCleanups(Emission);
  1201. Address BaseAddr = RedCG.adjustPrivateAddress(
  1202. *this, Count, Emission.getAllocatedAddress());
  1203. bool IsRegistered = PrivateScope.addPrivate(
  1204. RedCG.getBaseDecl(Count), [BaseAddr]() { return BaseAddr; });
  1205. assert(IsRegistered && "private var already registered as private");
  1206. // Silence the warning about unused variable.
  1207. (void)IsRegistered;
  1208. const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
  1209. const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
  1210. QualType Type = PrivateVD->getType();
  1211. bool isaOMPArraySectionExpr = isa<OMPArraySectionExpr>(IRef);
  1212. if (isaOMPArraySectionExpr && Type->isVariablyModifiedType()) {
  1213. // Store the address of the original variable associated with the LHS
  1214. // implicit variable.
  1215. PrivateScope.addPrivate(LHSVD, [&RedCG, Count, this]() {
  1216. return RedCG.getSharedLValue(Count).getAddress(*this);
  1217. });
  1218. PrivateScope.addPrivate(
  1219. RHSVD, [this, PrivateVD]() { return GetAddrOfLocalVar(PrivateVD); });
  1220. } else if ((isaOMPArraySectionExpr && Type->isScalarType()) ||
  1221. isa<ArraySubscriptExpr>(IRef)) {
  1222. // Store the address of the original variable associated with the LHS
  1223. // implicit variable.
  1224. PrivateScope.addPrivate(LHSVD, [&RedCG, Count, this]() {
  1225. return RedCG.getSharedLValue(Count).getAddress(*this);
  1226. });
  1227. PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() {
  1228. return Builder.CreateElementBitCast(GetAddrOfLocalVar(PrivateVD),
  1229. ConvertTypeForMem(RHSVD->getType()),
  1230. "rhs.begin");
  1231. });
  1232. } else {
  1233. QualType Type = PrivateVD->getType();
  1234. bool IsArray = getContext().getAsArrayType(Type) != nullptr;
  1235. Address OriginalAddr = RedCG.getSharedLValue(Count).getAddress(*this);
  1236. // Store the address of the original variable associated with the LHS
  1237. // implicit variable.
  1238. if (IsArray) {
  1239. OriginalAddr = Builder.CreateElementBitCast(
  1240. OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin");
  1241. }
  1242. PrivateScope.addPrivate(LHSVD, [OriginalAddr]() { return OriginalAddr; });
  1243. PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD, IsArray]() {
  1244. return IsArray ? Builder.CreateElementBitCast(
  1245. GetAddrOfLocalVar(PrivateVD),
  1246. ConvertTypeForMem(RHSVD->getType()), "rhs.begin")
  1247. : GetAddrOfLocalVar(PrivateVD);
  1248. });
  1249. }
  1250. ++ILHS;
  1251. ++IRHS;
  1252. ++IPriv;
  1253. ++Count;
  1254. }
  1255. if (!Data.ReductionVars.empty()) {
  1256. Data.IsReductionWithTaskMod = true;
  1257. Data.IsWorksharingReduction =
  1258. isOpenMPWorksharingDirective(D.getDirectiveKind());
  1259. llvm::Value *ReductionDesc = CGM.getOpenMPRuntime().emitTaskReductionInit(
  1260. *this, D.getBeginLoc(), TaskLHSs, TaskRHSs, Data);
  1261. const Expr *TaskRedRef = nullptr;
  1262. switch (D.getDirectiveKind()) {
  1263. case OMPD_parallel:
  1264. TaskRedRef = cast<OMPParallelDirective>(D).getTaskReductionRefExpr();
  1265. break;
  1266. case OMPD_for:
  1267. TaskRedRef = cast<OMPForDirective>(D).getTaskReductionRefExpr();
  1268. break;
  1269. case OMPD_sections:
  1270. TaskRedRef = cast<OMPSectionsDirective>(D).getTaskReductionRefExpr();
  1271. break;
  1272. case OMPD_parallel_for:
  1273. TaskRedRef = cast<OMPParallelForDirective>(D).getTaskReductionRefExpr();
  1274. break;
  1275. case OMPD_parallel_master:
  1276. TaskRedRef =
  1277. cast<OMPParallelMasterDirective>(D).getTaskReductionRefExpr();
  1278. break;
  1279. case OMPD_parallel_sections:
  1280. TaskRedRef =
  1281. cast<OMPParallelSectionsDirective>(D).getTaskReductionRefExpr();
  1282. break;
  1283. case OMPD_target_parallel:
  1284. TaskRedRef =
  1285. cast<OMPTargetParallelDirective>(D).getTaskReductionRefExpr();
  1286. break;
  1287. case OMPD_target_parallel_for:
  1288. TaskRedRef =
  1289. cast<OMPTargetParallelForDirective>(D).getTaskReductionRefExpr();
  1290. break;
  1291. case OMPD_distribute_parallel_for:
  1292. TaskRedRef =
  1293. cast<OMPDistributeParallelForDirective>(D).getTaskReductionRefExpr();
  1294. break;
  1295. case OMPD_teams_distribute_parallel_for:
  1296. TaskRedRef = cast<OMPTeamsDistributeParallelForDirective>(D)
  1297. .getTaskReductionRefExpr();
  1298. break;
  1299. case OMPD_target_teams_distribute_parallel_for:
  1300. TaskRedRef = cast<OMPTargetTeamsDistributeParallelForDirective>(D)
  1301. .getTaskReductionRefExpr();
  1302. break;
  1303. case OMPD_simd:
  1304. case OMPD_for_simd:
  1305. case OMPD_section:
  1306. case OMPD_single:
  1307. case OMPD_master:
  1308. case OMPD_critical:
  1309. case OMPD_parallel_for_simd:
  1310. case OMPD_task:
  1311. case OMPD_taskyield:
  1312. case OMPD_barrier:
  1313. case OMPD_taskwait:
  1314. case OMPD_taskgroup:
  1315. case OMPD_flush:
  1316. case OMPD_depobj:
  1317. case OMPD_scan:
  1318. case OMPD_ordered:
  1319. case OMPD_atomic:
  1320. case OMPD_teams:
  1321. case OMPD_target:
  1322. case OMPD_cancellation_point:
  1323. case OMPD_cancel:
  1324. case OMPD_target_data:
  1325. case OMPD_target_enter_data:
  1326. case OMPD_target_exit_data:
  1327. case OMPD_taskloop:
  1328. case OMPD_taskloop_simd:
  1329. case OMPD_master_taskloop:
  1330. case OMPD_master_taskloop_simd:
  1331. case OMPD_parallel_master_taskloop:
  1332. case OMPD_parallel_master_taskloop_simd:
  1333. case OMPD_distribute:
  1334. case OMPD_target_update:
  1335. case OMPD_distribute_parallel_for_simd:
  1336. case OMPD_distribute_simd:
  1337. case OMPD_target_parallel_for_simd:
  1338. case OMPD_target_simd:
  1339. case OMPD_teams_distribute:
  1340. case OMPD_teams_distribute_simd:
  1341. case OMPD_teams_distribute_parallel_for_simd:
  1342. case OMPD_target_teams:
  1343. case OMPD_target_teams_distribute:
  1344. case OMPD_target_teams_distribute_parallel_for_simd:
  1345. case OMPD_target_teams_distribute_simd:
  1346. case OMPD_declare_target:
  1347. case OMPD_end_declare_target:
  1348. case OMPD_threadprivate:
  1349. case OMPD_allocate:
  1350. case OMPD_declare_reduction:
  1351. case OMPD_declare_mapper:
  1352. case OMPD_declare_simd:
  1353. case OMPD_requires:
  1354. case OMPD_declare_variant:
  1355. case OMPD_begin_declare_variant:
  1356. case OMPD_end_declare_variant:
  1357. case OMPD_unknown:
  1358. default:
  1359. llvm_unreachable("Enexpected directive with task reductions.");
  1360. }
  1361. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(TaskRedRef)->getDecl());
  1362. EmitVarDecl(*VD);
  1363. EmitStoreOfScalar(ReductionDesc, GetAddrOfLocalVar(VD),
  1364. /*Volatile=*/false, TaskRedRef->getType());
  1365. }
  1366. }
  1367. void CodeGenFunction::EmitOMPReductionClauseFinal(
  1368. const OMPExecutableDirective &D, const OpenMPDirectiveKind ReductionKind) {
  1369. if (!HaveInsertPoint())
  1370. return;
  1371. llvm::SmallVector<const Expr *, 8> Privates;
  1372. llvm::SmallVector<const Expr *, 8> LHSExprs;
  1373. llvm::SmallVector<const Expr *, 8> RHSExprs;
  1374. llvm::SmallVector<const Expr *, 8> ReductionOps;
  1375. bool HasAtLeastOneReduction = false;
  1376. bool IsReductionWithTaskMod = false;
  1377. for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
  1378. // Do not emit for inscan reductions.
  1379. if (C->getModifier() == OMPC_REDUCTION_inscan)
  1380. continue;
  1381. HasAtLeastOneReduction = true;
  1382. Privates.append(C->privates().begin(), C->privates().end());
  1383. LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
  1384. RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
  1385. ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
  1386. IsReductionWithTaskMod =
  1387. IsReductionWithTaskMod || C->getModifier() == OMPC_REDUCTION_task;
  1388. }
  1389. if (HasAtLeastOneReduction) {
  1390. if (IsReductionWithTaskMod) {
  1391. CGM.getOpenMPRuntime().emitTaskReductionFini(
  1392. *this, D.getBeginLoc(),
  1393. isOpenMPWorksharingDirective(D.getDirectiveKind()));
  1394. }
  1395. bool WithNowait = D.getSingleClause<OMPNowaitClause>() ||
  1396. isOpenMPParallelDirective(D.getDirectiveKind()) ||
  1397. ReductionKind == OMPD_simd;
  1398. bool SimpleReduction = ReductionKind == OMPD_simd;
  1399. // Emit nowait reduction if nowait clause is present or directive is a
  1400. // parallel directive (it always has implicit barrier).
  1401. CGM.getOpenMPRuntime().emitReduction(
  1402. *this, D.getEndLoc(), Privates, LHSExprs, RHSExprs, ReductionOps,
  1403. {WithNowait, SimpleReduction, ReductionKind});
  1404. }
  1405. }
  1406. static void emitPostUpdateForReductionClause(
  1407. CodeGenFunction &CGF, const OMPExecutableDirective &D,
  1408. const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {
  1409. if (!CGF.HaveInsertPoint())
  1410. return;
  1411. llvm::BasicBlock *DoneBB = nullptr;
  1412. for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
  1413. if (const Expr *PostUpdate = C->getPostUpdateExpr()) {
  1414. if (!DoneBB) {
  1415. if (llvm::Value *Cond = CondGen(CGF)) {
  1416. // If the first post-update expression is found, emit conditional
  1417. // block if it was requested.
  1418. llvm::BasicBlock *ThenBB = CGF.createBasicBlock(".omp.reduction.pu");
  1419. DoneBB = CGF.createBasicBlock(".omp.reduction.pu.done");
  1420. CGF.Builder.CreateCondBr(Cond, ThenBB, DoneBB);
  1421. CGF.EmitBlock(ThenBB);
  1422. }
  1423. }
  1424. CGF.EmitIgnoredExpr(PostUpdate);
  1425. }
  1426. }
  1427. if (DoneBB)
  1428. CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
  1429. }
  1430. namespace {
  1431. /// Codegen lambda for appending distribute lower and upper bounds to outlined
  1432. /// parallel function. This is necessary for combined constructs such as
  1433. /// 'distribute parallel for'
  1434. typedef llvm::function_ref<void(CodeGenFunction &,
  1435. const OMPExecutableDirective &,
  1436. llvm::SmallVectorImpl<llvm::Value *> &)>
  1437. CodeGenBoundParametersTy;
  1438. } // anonymous namespace
  1439. static void
  1440. checkForLastprivateConditionalUpdate(CodeGenFunction &CGF,
  1441. const OMPExecutableDirective &S) {
  1442. if (CGF.getLangOpts().OpenMP < 50)
  1443. return;
  1444. llvm::DenseSet<CanonicalDeclPtr<const VarDecl>> PrivateDecls;
  1445. for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
  1446. for (const Expr *Ref : C->varlists()) {
  1447. if (!Ref->getType()->isScalarType())
  1448. continue;
  1449. const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
  1450. if (!DRE)
  1451. continue;
  1452. PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));
  1453. CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, Ref);
  1454. }
  1455. }
  1456. for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) {
  1457. for (const Expr *Ref : C->varlists()) {
  1458. if (!Ref->getType()->isScalarType())
  1459. continue;
  1460. const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
  1461. if (!DRE)
  1462. continue;
  1463. PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));
  1464. CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, Ref);
  1465. }
  1466. }
  1467. for (const auto *C : S.getClausesOfKind<OMPLinearClause>()) {
  1468. for (const Expr *Ref : C->varlists()) {
  1469. if (!Ref->getType()->isScalarType())
  1470. continue;
  1471. const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
  1472. if (!DRE)
  1473. continue;
  1474. PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));
  1475. CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, Ref);
  1476. }
  1477. }
  1478. // Privates should ne analyzed since they are not captured at all.
  1479. // Task reductions may be skipped - tasks are ignored.
  1480. // Firstprivates do not return value but may be passed by reference - no need
  1481. // to check for updated lastprivate conditional.
  1482. for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
  1483. for (const Expr *Ref : C->varlists()) {
  1484. if (!Ref->getType()->isScalarType())
  1485. continue;
  1486. const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
  1487. if (!DRE)
  1488. continue;
  1489. PrivateDecls.insert(cast<VarDecl>(DRE->getDecl()));
  1490. }
  1491. }
  1492. CGF.CGM.getOpenMPRuntime().checkAndEmitSharedLastprivateConditional(
  1493. CGF, S, PrivateDecls);
  1494. }
  1495. static void emitCommonOMPParallelDirective(
  1496. CodeGenFunction &CGF, const OMPExecutableDirective &S,
  1497. OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
  1498. const CodeGenBoundParametersTy &CodeGenBoundParameters) {
  1499. const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
  1500. llvm::Value *NumThreads = nullptr;
  1501. llvm::Function *OutlinedFn =
  1502. CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction(
  1503. S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
  1504. if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) {
  1505. CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
  1506. NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
  1507. /*IgnoreResultAssign=*/true);
  1508. CGF.CGM.getOpenMPRuntime().emitNumThreadsClause(
  1509. CGF, NumThreads, NumThreadsClause->getBeginLoc());
  1510. }
  1511. if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) {
  1512. CodeGenFunction::RunCleanupsScope ProcBindScope(CGF);
  1513. CGF.CGM.getOpenMPRuntime().emitProcBindClause(
  1514. CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getBeginLoc());
  1515. }
  1516. const Expr *IfCond = nullptr;
  1517. for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
  1518. if (C->getNameModifier() == OMPD_unknown ||
  1519. C->getNameModifier() == OMPD_parallel) {
  1520. IfCond = C->getCondition();
  1521. break;
  1522. }
  1523. }
  1524. OMPParallelScope Scope(CGF, S);
  1525. llvm::SmallVector<llvm::Value *, 16> CapturedVars;
  1526. // Combining 'distribute' with 'for' requires sharing each 'distribute' chunk
  1527. // lower and upper bounds with the pragma 'for' chunking mechanism.
  1528. // The following lambda takes care of appending the lower and upper bound
  1529. // parameters when necessary
  1530. CodeGenBoundParameters(CGF, S, CapturedVars);
  1531. CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
  1532. CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getBeginLoc(), OutlinedFn,
  1533. CapturedVars, IfCond, NumThreads);
  1534. }
  1535. static bool isAllocatableDecl(const VarDecl *VD) {
  1536. const VarDecl *CVD = VD->getCanonicalDecl();
  1537. if (!CVD->hasAttr<OMPAllocateDeclAttr>())
  1538. return false;
  1539. const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>();
  1540. // Use the default allocation.
  1541. return !((AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc ||
  1542. AA->getAllocatorType() == OMPAllocateDeclAttr::OMPNullMemAlloc) &&
  1543. !AA->getAllocator());
  1544. }
  1545. static void emitEmptyBoundParameters(CodeGenFunction &,
  1546. const OMPExecutableDirective &,
  1547. llvm::SmallVectorImpl<llvm::Value *> &) {}
  1548. Address CodeGenFunction::OMPBuilderCBHelpers::getAddressOfLocalVariable(
  1549. CodeGenFunction &CGF, const VarDecl *VD) {
  1550. CodeGenModule &CGM = CGF.CGM;
  1551. auto &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  1552. if (!VD)
  1553. return Address::invalid();
  1554. const VarDecl *CVD = VD->getCanonicalDecl();
  1555. if (!isAllocatableDecl(CVD))
  1556. return Address::invalid();
  1557. llvm::Value *Size;
  1558. CharUnits Align = CGM.getContext().getDeclAlign(CVD);
  1559. if (CVD->getType()->isVariablyModifiedType()) {
  1560. Size = CGF.getTypeSize(CVD->getType());
  1561. // Align the size: ((size + align - 1) / align) * align
  1562. Size = CGF.Builder.CreateNUWAdd(
  1563. Size, CGM.getSize(Align - CharUnits::fromQuantity(1)));
  1564. Size = CGF.Builder.CreateUDiv(Size, CGM.getSize(Align));
  1565. Size = CGF.Builder.CreateNUWMul(Size, CGM.getSize(Align));
  1566. } else {
  1567. CharUnits Sz = CGM.getContext().getTypeSizeInChars(CVD->getType());
  1568. Size = CGM.getSize(Sz.alignTo(Align));
  1569. }
  1570. const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>();
  1571. assert(AA->getAllocator() &&
  1572. "Expected allocator expression for non-default allocator.");
  1573. llvm::Value *Allocator = CGF.EmitScalarExpr(AA->getAllocator());
  1574. // According to the standard, the original allocator type is a enum (integer).
  1575. // Convert to pointer type, if required.
  1576. if (Allocator->getType()->isIntegerTy())
  1577. Allocator = CGF.Builder.CreateIntToPtr(Allocator, CGM.VoidPtrTy);
  1578. else if (Allocator->getType()->isPointerTy())
  1579. Allocator = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Allocator,
  1580. CGM.VoidPtrTy);
  1581. llvm::Value *Addr = OMPBuilder.createOMPAlloc(
  1582. CGF.Builder, Size, Allocator,
  1583. getNameWithSeparators({CVD->getName(), ".void.addr"}, ".", "."));
  1584. llvm::CallInst *FreeCI =
  1585. OMPBuilder.createOMPFree(CGF.Builder, Addr, Allocator);
  1586. CGF.EHStack.pushCleanup<OMPAllocateCleanupTy>(NormalAndEHCleanup, FreeCI);
  1587. Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
  1588. Addr,
  1589. CGF.ConvertTypeForMem(CGM.getContext().getPointerType(CVD->getType())),
  1590. getNameWithSeparators({CVD->getName(), ".addr"}, ".", "."));
  1591. return Address(Addr, Align);
  1592. }
  1593. Address CodeGenFunction::OMPBuilderCBHelpers::getAddrOfThreadPrivate(
  1594. CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr,
  1595. SourceLocation Loc) {
  1596. CodeGenModule &CGM = CGF.CGM;
  1597. if (CGM.getLangOpts().OpenMPUseTLS &&
  1598. CGM.getContext().getTargetInfo().isTLSSupported())
  1599. return VDAddr;
  1600. llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  1601. llvm::Type *VarTy = VDAddr.getElementType();
  1602. llvm::Value *Data =
  1603. CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.Int8PtrTy);
  1604. llvm::ConstantInt *Size = CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy));
  1605. std::string Suffix = getNameWithSeparators({"cache", ""});
  1606. llvm::Twine CacheName = Twine(CGM.getMangledName(VD)).concat(Suffix);
  1607. llvm::CallInst *ThreadPrivateCacheCall =
  1608. OMPBuilder.createCachedThreadPrivate(CGF.Builder, Data, Size, CacheName);
  1609. return Address(ThreadPrivateCacheCall, VDAddr.getAlignment());
  1610. }
  1611. std::string CodeGenFunction::OMPBuilderCBHelpers::getNameWithSeparators(
  1612. ArrayRef<StringRef> Parts, StringRef FirstSeparator, StringRef Separator) {
  1613. SmallString<128> Buffer;
  1614. llvm::raw_svector_ostream OS(Buffer);
  1615. StringRef Sep = FirstSeparator;
  1616. for (StringRef Part : Parts) {
  1617. OS << Sep << Part;
  1618. Sep = Separator;
  1619. }
  1620. return OS.str().str();
  1621. }
  1622. void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
  1623. if (CGM.getLangOpts().OpenMPIRBuilder) {
  1624. llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  1625. // Check if we have any if clause associated with the directive.
  1626. llvm::Value *IfCond = nullptr;
  1627. if (const auto *C = S.getSingleClause<OMPIfClause>())
  1628. IfCond = EmitScalarExpr(C->getCondition(),
  1629. /*IgnoreResultAssign=*/true);
  1630. llvm::Value *NumThreads = nullptr;
  1631. if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>())
  1632. NumThreads = EmitScalarExpr(NumThreadsClause->getNumThreads(),
  1633. /*IgnoreResultAssign=*/true);
  1634. ProcBindKind ProcBind = OMP_PROC_BIND_default;
  1635. if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>())
  1636. ProcBind = ProcBindClause->getProcBindKind();
  1637. using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
  1638. // The cleanup callback that finalizes all variabels at the given location,
  1639. // thus calls destructors etc.
  1640. auto FiniCB = [this](InsertPointTy IP) {
  1641. OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
  1642. };
  1643. // Privatization callback that performs appropriate action for
  1644. // shared/private/firstprivate/lastprivate/copyin/... variables.
  1645. //
  1646. // TODO: This defaults to shared right now.
  1647. auto PrivCB = [](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
  1648. llvm::Value &, llvm::Value &Val, llvm::Value *&ReplVal) {
  1649. // The next line is appropriate only for variables (Val) with the
  1650. // data-sharing attribute "shared".
  1651. ReplVal = &Val;
  1652. return CodeGenIP;
  1653. };
  1654. const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
  1655. const Stmt *ParallelRegionBodyStmt = CS->getCapturedStmt();
  1656. auto BodyGenCB = [ParallelRegionBodyStmt,
  1657. this](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
  1658. llvm::BasicBlock &ContinuationBB) {
  1659. OMPBuilderCBHelpers::OutlinedRegionBodyRAII ORB(*this, AllocaIP,
  1660. ContinuationBB);
  1661. OMPBuilderCBHelpers::EmitOMPRegionBody(*this, ParallelRegionBodyStmt,
  1662. CodeGenIP, ContinuationBB);
  1663. };
  1664. CGCapturedStmtInfo CGSI(*CS, CR_OpenMP);
  1665. CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI);
  1666. llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(
  1667. AllocaInsertPt->getParent(), AllocaInsertPt->getIterator());
  1668. Builder.restoreIP(
  1669. OMPBuilder.createParallel(Builder, AllocaIP, BodyGenCB, PrivCB, FiniCB,
  1670. IfCond, NumThreads, ProcBind, S.hasCancel()));
  1671. return;
  1672. }
  1673. // Emit parallel region as a standalone region.
  1674. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  1675. Action.Enter(CGF);
  1676. OMPPrivateScope PrivateScope(CGF);
  1677. bool Copyins = CGF.EmitOMPCopyinClause(S);
  1678. (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
  1679. if (Copyins) {
  1680. // Emit implicit barrier to synchronize threads and avoid data races on
  1681. // propagation master's thread values of threadprivate variables to local
  1682. // instances of that variables of all other implicit threads.
  1683. CGF.CGM.getOpenMPRuntime().emitBarrierCall(
  1684. CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
  1685. /*ForceSimpleCall=*/true);
  1686. }
  1687. CGF.EmitOMPPrivateClause(S, PrivateScope);
  1688. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  1689. (void)PrivateScope.Privatize();
  1690. CGF.EmitStmt(S.getCapturedStmt(OMPD_parallel)->getCapturedStmt());
  1691. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
  1692. };
  1693. {
  1694. auto LPCRegion =
  1695. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  1696. emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen,
  1697. emitEmptyBoundParameters);
  1698. emitPostUpdateForReductionClause(*this, S,
  1699. [](CodeGenFunction &) { return nullptr; });
  1700. }
  1701. // Check for outer lastprivate conditional update.
  1702. checkForLastprivateConditionalUpdate(*this, S);
  1703. }
  1704. void CodeGenFunction::EmitOMPMetaDirective(const OMPMetaDirective &S) {
  1705. EmitStmt(S.getIfStmt());
  1706. }
  1707. namespace {
  1708. /// RAII to handle scopes for loop transformation directives.
  1709. class OMPTransformDirectiveScopeRAII {
  1710. OMPLoopScope *Scope = nullptr;
  1711. CodeGenFunction::CGCapturedStmtInfo *CGSI = nullptr;
  1712. CodeGenFunction::CGCapturedStmtRAII *CapInfoRAII = nullptr;
  1713. public:
  1714. OMPTransformDirectiveScopeRAII(CodeGenFunction &CGF, const Stmt *S) {
  1715. if (const auto *Dir = dyn_cast<OMPLoopBasedDirective>(S)) {
  1716. Scope = new OMPLoopScope(CGF, *Dir);
  1717. CGSI = new CodeGenFunction::CGCapturedStmtInfo(CR_OpenMP);
  1718. CapInfoRAII = new CodeGenFunction::CGCapturedStmtRAII(CGF, CGSI);
  1719. }
  1720. }
  1721. ~OMPTransformDirectiveScopeRAII() {
  1722. if (!Scope)
  1723. return;
  1724. delete CapInfoRAII;
  1725. delete CGSI;
  1726. delete Scope;
  1727. }
  1728. };
  1729. } // namespace
  1730. static void emitBody(CodeGenFunction &CGF, const Stmt *S, const Stmt *NextLoop,
  1731. int MaxLevel, int Level = 0) {
  1732. assert(Level < MaxLevel && "Too deep lookup during loop body codegen.");
  1733. const Stmt *SimplifiedS = S->IgnoreContainers();
  1734. if (const auto *CS = dyn_cast<CompoundStmt>(SimplifiedS)) {
  1735. PrettyStackTraceLoc CrashInfo(
  1736. CGF.getContext().getSourceManager(), CS->getLBracLoc(),
  1737. "LLVM IR generation of compound statement ('{}')");
  1738. // Keep track of the current cleanup stack depth, including debug scopes.
  1739. CodeGenFunction::LexicalScope Scope(CGF, S->getSourceRange());
  1740. for (const Stmt *CurStmt : CS->body())
  1741. emitBody(CGF, CurStmt, NextLoop, MaxLevel, Level);
  1742. return;
  1743. }
  1744. if (SimplifiedS == NextLoop) {
  1745. if (auto *Dir = dyn_cast<OMPLoopTransformationDirective>(SimplifiedS))
  1746. SimplifiedS = Dir->getTransformedStmt();
  1747. if (const auto *CanonLoop = dyn_cast<OMPCanonicalLoop>(SimplifiedS))
  1748. SimplifiedS = CanonLoop->getLoopStmt();
  1749. if (const auto *For = dyn_cast<ForStmt>(SimplifiedS)) {
  1750. S = For->getBody();
  1751. } else {
  1752. assert(isa<CXXForRangeStmt>(SimplifiedS) &&
  1753. "Expected canonical for loop or range-based for loop.");
  1754. const auto *CXXFor = cast<CXXForRangeStmt>(SimplifiedS);
  1755. CGF.EmitStmt(CXXFor->getLoopVarStmt());
  1756. S = CXXFor->getBody();
  1757. }
  1758. if (Level + 1 < MaxLevel) {
  1759. NextLoop = OMPLoopDirective::tryToFindNextInnerLoop(
  1760. S, /*TryImperfectlyNestedLoops=*/true);
  1761. emitBody(CGF, S, NextLoop, MaxLevel, Level + 1);
  1762. return;
  1763. }
  1764. }
  1765. CGF.EmitStmt(S);
  1766. }
  1767. void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
  1768. JumpDest LoopExit) {
  1769. RunCleanupsScope BodyScope(*this);
  1770. // Update counters values on current iteration.
  1771. for (const Expr *UE : D.updates())
  1772. EmitIgnoredExpr(UE);
  1773. // Update the linear variables.
  1774. // In distribute directives only loop counters may be marked as linear, no
  1775. // need to generate the code for them.
  1776. if (!isOpenMPDistributeDirective(D.getDirectiveKind())) {
  1777. for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
  1778. for (const Expr *UE : C->updates())
  1779. EmitIgnoredExpr(UE);
  1780. }
  1781. }
  1782. // On a continue in the body, jump to the end.
  1783. JumpDest Continue = getJumpDestInCurrentScope("omp.body.continue");
  1784. BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
  1785. for (const Expr *E : D.finals_conditions()) {
  1786. if (!E)
  1787. continue;
  1788. // Check that loop counter in non-rectangular nest fits into the iteration
  1789. // space.
  1790. llvm::BasicBlock *NextBB = createBasicBlock("omp.body.next");
  1791. EmitBranchOnBoolExpr(E, NextBB, Continue.getBlock(),
  1792. getProfileCount(D.getBody()));
  1793. EmitBlock(NextBB);
  1794. }
  1795. OMPPrivateScope InscanScope(*this);
  1796. EmitOMPReductionClauseInit(D, InscanScope, /*ForInscan=*/true);
  1797. bool IsInscanRegion = InscanScope.Privatize();
  1798. if (IsInscanRegion) {
  1799. // Need to remember the block before and after scan directive
  1800. // to dispatch them correctly depending on the clause used in
  1801. // this directive, inclusive or exclusive. For inclusive scan the natural
  1802. // order of the blocks is used, for exclusive clause the blocks must be
  1803. // executed in reverse order.
  1804. OMPBeforeScanBlock = createBasicBlock("omp.before.scan.bb");
  1805. OMPAfterScanBlock = createBasicBlock("omp.after.scan.bb");
  1806. // No need to allocate inscan exit block, in simd mode it is selected in the
  1807. // codegen for the scan directive.
  1808. if (D.getDirectiveKind() != OMPD_simd && !getLangOpts().OpenMPSimd)
  1809. OMPScanExitBlock = createBasicBlock("omp.exit.inscan.bb");
  1810. OMPScanDispatch = createBasicBlock("omp.inscan.dispatch");
  1811. EmitBranch(OMPScanDispatch);
  1812. EmitBlock(OMPBeforeScanBlock);
  1813. }
  1814. // Emit loop variables for C++ range loops.
  1815. const Stmt *Body =
  1816. D.getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers();
  1817. // Emit loop body.
  1818. emitBody(*this, Body,
  1819. OMPLoopBasedDirective::tryToFindNextInnerLoop(
  1820. Body, /*TryImperfectlyNestedLoops=*/true),
  1821. D.getLoopsNumber());
  1822. // Jump to the dispatcher at the end of the loop body.
  1823. if (IsInscanRegion)
  1824. EmitBranch(OMPScanExitBlock);
  1825. // The end (updates/cleanups).
  1826. EmitBlock(Continue.getBlock());
  1827. BreakContinueStack.pop_back();
  1828. }
  1829. using EmittedClosureTy = std::pair<llvm::Function *, llvm::Value *>;
  1830. /// Emit a captured statement and return the function as well as its captured
  1831. /// closure context.
  1832. static EmittedClosureTy emitCapturedStmtFunc(CodeGenFunction &ParentCGF,
  1833. const CapturedStmt *S) {
  1834. LValue CapStruct = ParentCGF.InitCapturedStruct(*S);
  1835. CodeGenFunction CGF(ParentCGF.CGM, /*suppressNewContext=*/true);
  1836. std::unique_ptr<CodeGenFunction::CGCapturedStmtInfo> CSI =
  1837. std::make_unique<CodeGenFunction::CGCapturedStmtInfo>(*S);
  1838. CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, CSI.get());
  1839. llvm::Function *F = CGF.GenerateCapturedStmtFunction(*S);
  1840. return {F, CapStruct.getPointer(ParentCGF)};
  1841. }
  1842. /// Emit a call to a previously captured closure.
  1843. static llvm::CallInst *
  1844. emitCapturedStmtCall(CodeGenFunction &ParentCGF, EmittedClosureTy Cap,
  1845. llvm::ArrayRef<llvm::Value *> Args) {
  1846. // Append the closure context to the argument.
  1847. SmallVector<llvm::Value *> EffectiveArgs;
  1848. EffectiveArgs.reserve(Args.size() + 1);
  1849. llvm::append_range(EffectiveArgs, Args);
  1850. EffectiveArgs.push_back(Cap.second);
  1851. return ParentCGF.Builder.CreateCall(Cap.first, EffectiveArgs);
  1852. }
  1853. llvm::CanonicalLoopInfo *
  1854. CodeGenFunction::EmitOMPCollapsedCanonicalLoopNest(const Stmt *S, int Depth) {
  1855. assert(Depth == 1 && "Nested loops with OpenMPIRBuilder not yet implemented");
  1856. // The caller is processing the loop-associated directive processing the \p
  1857. // Depth loops nested in \p S. Put the previous pending loop-associated
  1858. // directive to the stack. If the current loop-associated directive is a loop
  1859. // transformation directive, it will push its generated loops onto the stack
  1860. // such that together with the loops left here they form the combined loop
  1861. // nest for the parent loop-associated directive.
  1862. int ParentExpectedOMPLoopDepth = ExpectedOMPLoopDepth;
  1863. ExpectedOMPLoopDepth = Depth;
  1864. EmitStmt(S);
  1865. assert(OMPLoopNestStack.size() >= (size_t)Depth && "Found too few loops");
  1866. // The last added loop is the outermost one.
  1867. llvm::CanonicalLoopInfo *Result = OMPLoopNestStack.back();
  1868. // Pop the \p Depth loops requested by the call from that stack and restore
  1869. // the previous context.
  1870. OMPLoopNestStack.pop_back_n(Depth);
  1871. ExpectedOMPLoopDepth = ParentExpectedOMPLoopDepth;
  1872. return Result;
  1873. }
  1874. void CodeGenFunction::EmitOMPCanonicalLoop(const OMPCanonicalLoop *S) {
  1875. const Stmt *SyntacticalLoop = S->getLoopStmt();
  1876. if (!getLangOpts().OpenMPIRBuilder) {
  1877. // Ignore if OpenMPIRBuilder is not enabled.
  1878. EmitStmt(SyntacticalLoop);
  1879. return;
  1880. }
  1881. LexicalScope ForScope(*this, S->getSourceRange());
  1882. // Emit init statements. The Distance/LoopVar funcs may reference variable
  1883. // declarations they contain.
  1884. const Stmt *BodyStmt;
  1885. if (const auto *For = dyn_cast<ForStmt>(SyntacticalLoop)) {
  1886. if (const Stmt *InitStmt = For->getInit())
  1887. EmitStmt(InitStmt);
  1888. BodyStmt = For->getBody();
  1889. } else if (const auto *RangeFor =
  1890. dyn_cast<CXXForRangeStmt>(SyntacticalLoop)) {
  1891. if (const DeclStmt *RangeStmt = RangeFor->getRangeStmt())
  1892. EmitStmt(RangeStmt);
  1893. if (const DeclStmt *BeginStmt = RangeFor->getBeginStmt())
  1894. EmitStmt(BeginStmt);
  1895. if (const DeclStmt *EndStmt = RangeFor->getEndStmt())
  1896. EmitStmt(EndStmt);
  1897. if (const DeclStmt *LoopVarStmt = RangeFor->getLoopVarStmt())
  1898. EmitStmt(LoopVarStmt);
  1899. BodyStmt = RangeFor->getBody();
  1900. } else
  1901. llvm_unreachable("Expected for-stmt or range-based for-stmt");
  1902. // Emit closure for later use. By-value captures will be captured here.
  1903. const CapturedStmt *DistanceFunc = S->getDistanceFunc();
  1904. EmittedClosureTy DistanceClosure = emitCapturedStmtFunc(*this, DistanceFunc);
  1905. const CapturedStmt *LoopVarFunc = S->getLoopVarFunc();
  1906. EmittedClosureTy LoopVarClosure = emitCapturedStmtFunc(*this, LoopVarFunc);
  1907. // Call the distance function to get the number of iterations of the loop to
  1908. // come.
  1909. QualType LogicalTy = DistanceFunc->getCapturedDecl()
  1910. ->getParam(0)
  1911. ->getType()
  1912. .getNonReferenceType();
  1913. Address CountAddr = CreateMemTemp(LogicalTy, ".count.addr");
  1914. emitCapturedStmtCall(*this, DistanceClosure, {CountAddr.getPointer()});
  1915. llvm::Value *DistVal = Builder.CreateLoad(CountAddr, ".count");
  1916. // Emit the loop structure.
  1917. llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  1918. auto BodyGen = [&, this](llvm::OpenMPIRBuilder::InsertPointTy CodeGenIP,
  1919. llvm::Value *IndVar) {
  1920. Builder.restoreIP(CodeGenIP);
  1921. // Emit the loop body: Convert the logical iteration number to the loop
  1922. // variable and emit the body.
  1923. const DeclRefExpr *LoopVarRef = S->getLoopVarRef();
  1924. LValue LCVal = EmitLValue(LoopVarRef);
  1925. Address LoopVarAddress = LCVal.getAddress(*this);
  1926. emitCapturedStmtCall(*this, LoopVarClosure,
  1927. {LoopVarAddress.getPointer(), IndVar});
  1928. RunCleanupsScope BodyScope(*this);
  1929. EmitStmt(BodyStmt);
  1930. };
  1931. llvm::CanonicalLoopInfo *CL =
  1932. OMPBuilder.createCanonicalLoop(Builder, BodyGen, DistVal);
  1933. // Finish up the loop.
  1934. Builder.restoreIP(CL->getAfterIP());
  1935. ForScope.ForceCleanup();
  1936. // Remember the CanonicalLoopInfo for parent AST nodes consuming it.
  1937. OMPLoopNestStack.push_back(CL);
  1938. }
  1939. void CodeGenFunction::EmitOMPInnerLoop(
  1940. const OMPExecutableDirective &S, bool RequiresCleanup, const Expr *LoopCond,
  1941. const Expr *IncExpr,
  1942. const llvm::function_ref<void(CodeGenFunction &)> BodyGen,
  1943. const llvm::function_ref<void(CodeGenFunction &)> PostIncGen) {
  1944. auto LoopExit = getJumpDestInCurrentScope("omp.inner.for.end");
  1945. // Start the loop with a block that tests the condition.
  1946. auto CondBlock = createBasicBlock("omp.inner.for.cond");
  1947. EmitBlock(CondBlock);
  1948. const SourceRange R = S.getSourceRange();
  1949. // If attributes are attached, push to the basic block with them.
  1950. const auto &OMPED = cast<OMPExecutableDirective>(S);
  1951. const CapturedStmt *ICS = OMPED.getInnermostCapturedStmt();
  1952. const Stmt *SS = ICS->getCapturedStmt();
  1953. const AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(SS);
  1954. OMPLoopNestStack.clear();
  1955. if (AS)
  1956. LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(),
  1957. AS->getAttrs(), SourceLocToDebugLoc(R.getBegin()),
  1958. SourceLocToDebugLoc(R.getEnd()));
  1959. else
  1960. LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
  1961. SourceLocToDebugLoc(R.getEnd()));
  1962. // If there are any cleanups between here and the loop-exit scope,
  1963. // create a block to stage a loop exit along.
  1964. llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
  1965. if (RequiresCleanup)
  1966. ExitBlock = createBasicBlock("omp.inner.for.cond.cleanup");
  1967. llvm::BasicBlock *LoopBody = createBasicBlock("omp.inner.for.body");
  1968. // Emit condition.
  1969. EmitBranchOnBoolExpr(LoopCond, LoopBody, ExitBlock, getProfileCount(&S));
  1970. if (ExitBlock != LoopExit.getBlock()) {
  1971. EmitBlock(ExitBlock);
  1972. EmitBranchThroughCleanup(LoopExit);
  1973. }
  1974. EmitBlock(LoopBody);
  1975. incrementProfileCounter(&S);
  1976. // Create a block for the increment.
  1977. JumpDest Continue = getJumpDestInCurrentScope("omp.inner.for.inc");
  1978. BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
  1979. BodyGen(*this);
  1980. // Emit "IV = IV + 1" and a back-edge to the condition block.
  1981. EmitBlock(Continue.getBlock());
  1982. EmitIgnoredExpr(IncExpr);
  1983. PostIncGen(*this);
  1984. BreakContinueStack.pop_back();
  1985. EmitBranch(CondBlock);
  1986. LoopStack.pop();
  1987. // Emit the fall-through block.
  1988. EmitBlock(LoopExit.getBlock());
  1989. }
  1990. bool CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
  1991. if (!HaveInsertPoint())
  1992. return false;
  1993. // Emit inits for the linear variables.
  1994. bool HasLinears = false;
  1995. for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
  1996. for (const Expr *Init : C->inits()) {
  1997. HasLinears = true;
  1998. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
  1999. if (const auto *Ref =
  2000. dyn_cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())) {
  2001. AutoVarEmission Emission = EmitAutoVarAlloca(*VD);
  2002. const auto *OrigVD = cast<VarDecl>(Ref->getDecl());
  2003. DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
  2004. CapturedStmtInfo->lookup(OrigVD) != nullptr,
  2005. VD->getInit()->getType(), VK_LValue,
  2006. VD->getInit()->getExprLoc());
  2007. EmitExprAsInit(
  2008. &DRE, VD,
  2009. MakeAddrLValue(Emission.getAllocatedAddress(), VD->getType()),
  2010. /*capturedByInit=*/false);
  2011. EmitAutoVarCleanups(Emission);
  2012. } else {
  2013. EmitVarDecl(*VD);
  2014. }
  2015. }
  2016. // Emit the linear steps for the linear clauses.
  2017. // If a step is not constant, it is pre-calculated before the loop.
  2018. if (const auto *CS = cast_or_null<BinaryOperator>(C->getCalcStep()))
  2019. if (const auto *SaveRef = cast<DeclRefExpr>(CS->getLHS())) {
  2020. EmitVarDecl(*cast<VarDecl>(SaveRef->getDecl()));
  2021. // Emit calculation of the linear step.
  2022. EmitIgnoredExpr(CS);
  2023. }
  2024. }
  2025. return HasLinears;
  2026. }
  2027. void CodeGenFunction::EmitOMPLinearClauseFinal(
  2028. const OMPLoopDirective &D,
  2029. const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {
  2030. if (!HaveInsertPoint())
  2031. return;
  2032. llvm::BasicBlock *DoneBB = nullptr;
  2033. // Emit the final values of the linear variables.
  2034. for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
  2035. auto IC = C->varlist_begin();
  2036. for (const Expr *F : C->finals()) {
  2037. if (!DoneBB) {
  2038. if (llvm::Value *Cond = CondGen(*this)) {
  2039. // If the first post-update expression is found, emit conditional
  2040. // block if it was requested.
  2041. llvm::BasicBlock *ThenBB = createBasicBlock(".omp.linear.pu");
  2042. DoneBB = createBasicBlock(".omp.linear.pu.done");
  2043. Builder.CreateCondBr(Cond, ThenBB, DoneBB);
  2044. EmitBlock(ThenBB);
  2045. }
  2046. }
  2047. const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
  2048. DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(OrigVD),
  2049. CapturedStmtInfo->lookup(OrigVD) != nullptr,
  2050. (*IC)->getType(), VK_LValue, (*IC)->getExprLoc());
  2051. Address OrigAddr = EmitLValue(&DRE).getAddress(*this);
  2052. CodeGenFunction::OMPPrivateScope VarScope(*this);
  2053. VarScope.addPrivate(OrigVD, [OrigAddr]() { return OrigAddr; });
  2054. (void)VarScope.Privatize();
  2055. EmitIgnoredExpr(F);
  2056. ++IC;
  2057. }
  2058. if (const Expr *PostUpdate = C->getPostUpdateExpr())
  2059. EmitIgnoredExpr(PostUpdate);
  2060. }
  2061. if (DoneBB)
  2062. EmitBlock(DoneBB, /*IsFinished=*/true);
  2063. }
  2064. static void emitAlignedClause(CodeGenFunction &CGF,
  2065. const OMPExecutableDirective &D) {
  2066. if (!CGF.HaveInsertPoint())
  2067. return;
  2068. for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) {
  2069. llvm::APInt ClauseAlignment(64, 0);
  2070. if (const Expr *AlignmentExpr = Clause->getAlignment()) {
  2071. auto *AlignmentCI =
  2072. cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AlignmentExpr));
  2073. ClauseAlignment = AlignmentCI->getValue();
  2074. }
  2075. for (const Expr *E : Clause->varlists()) {
  2076. llvm::APInt Alignment(ClauseAlignment);
  2077. if (Alignment == 0) {
  2078. // OpenMP [2.8.1, Description]
  2079. // If no optional parameter is specified, implementation-defined default
  2080. // alignments for SIMD instructions on the target platforms are assumed.
  2081. Alignment =
  2082. CGF.getContext()
  2083. .toCharUnitsFromBits(CGF.getContext().getOpenMPDefaultSimdAlign(
  2084. E->getType()->getPointeeType()))
  2085. .getQuantity();
  2086. }
  2087. assert((Alignment == 0 || Alignment.isPowerOf2()) &&
  2088. "alignment is not power of 2");
  2089. if (Alignment != 0) {
  2090. llvm::Value *PtrValue = CGF.EmitScalarExpr(E);
  2091. CGF.emitAlignmentAssumption(
  2092. PtrValue, E, /*No second loc needed*/ SourceLocation(),
  2093. llvm::ConstantInt::get(CGF.getLLVMContext(), Alignment));
  2094. }
  2095. }
  2096. }
  2097. }
  2098. void CodeGenFunction::EmitOMPPrivateLoopCounters(
  2099. const OMPLoopDirective &S, CodeGenFunction::OMPPrivateScope &LoopScope) {
  2100. if (!HaveInsertPoint())
  2101. return;
  2102. auto I = S.private_counters().begin();
  2103. for (const Expr *E : S.counters()) {
  2104. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
  2105. const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl());
  2106. // Emit var without initialization.
  2107. AutoVarEmission VarEmission = EmitAutoVarAlloca(*PrivateVD);
  2108. EmitAutoVarCleanups(VarEmission);
  2109. LocalDeclMap.erase(PrivateVD);
  2110. (void)LoopScope.addPrivate(
  2111. VD, [&VarEmission]() { return VarEmission.getAllocatedAddress(); });
  2112. if (LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD) ||
  2113. VD->hasGlobalStorage()) {
  2114. (void)LoopScope.addPrivate(PrivateVD, [this, VD, E]() {
  2115. DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(VD),
  2116. LocalDeclMap.count(VD) || CapturedStmtInfo->lookup(VD),
  2117. E->getType(), VK_LValue, E->getExprLoc());
  2118. return EmitLValue(&DRE).getAddress(*this);
  2119. });
  2120. } else {
  2121. (void)LoopScope.addPrivate(PrivateVD, [&VarEmission]() {
  2122. return VarEmission.getAllocatedAddress();
  2123. });
  2124. }
  2125. ++I;
  2126. }
  2127. // Privatize extra loop counters used in loops for ordered(n) clauses.
  2128. for (const auto *C : S.getClausesOfKind<OMPOrderedClause>()) {
  2129. if (!C->getNumForLoops())
  2130. continue;
  2131. for (unsigned I = S.getLoopsNumber(), E = C->getLoopNumIterations().size();
  2132. I < E; ++I) {
  2133. const auto *DRE = cast<DeclRefExpr>(C->getLoopCounter(I));
  2134. const auto *VD = cast<VarDecl>(DRE->getDecl());
  2135. // Override only those variables that can be captured to avoid re-emission
  2136. // of the variables declared within the loops.
  2137. if (DRE->refersToEnclosingVariableOrCapture()) {
  2138. (void)LoopScope.addPrivate(VD, [this, DRE, VD]() {
  2139. return CreateMemTemp(DRE->getType(), VD->getName());
  2140. });
  2141. }
  2142. }
  2143. }
  2144. }
  2145. static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S,
  2146. const Expr *Cond, llvm::BasicBlock *TrueBlock,
  2147. llvm::BasicBlock *FalseBlock, uint64_t TrueCount) {
  2148. if (!CGF.HaveInsertPoint())
  2149. return;
  2150. {
  2151. CodeGenFunction::OMPPrivateScope PreCondScope(CGF);
  2152. CGF.EmitOMPPrivateLoopCounters(S, PreCondScope);
  2153. (void)PreCondScope.Privatize();
  2154. // Get initial values of real counters.
  2155. for (const Expr *I : S.inits()) {
  2156. CGF.EmitIgnoredExpr(I);
  2157. }
  2158. }
  2159. // Create temp loop control variables with their init values to support
  2160. // non-rectangular loops.
  2161. CodeGenFunction::OMPMapVars PreCondVars;
  2162. for (const Expr *E : S.dependent_counters()) {
  2163. if (!E)
  2164. continue;
  2165. assert(!E->getType().getNonReferenceType()->isRecordType() &&
  2166. "dependent counter must not be an iterator.");
  2167. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
  2168. Address CounterAddr =
  2169. CGF.CreateMemTemp(VD->getType().getNonReferenceType());
  2170. (void)PreCondVars.setVarAddr(CGF, VD, CounterAddr);
  2171. }
  2172. (void)PreCondVars.apply(CGF);
  2173. for (const Expr *E : S.dependent_inits()) {
  2174. if (!E)
  2175. continue;
  2176. CGF.EmitIgnoredExpr(E);
  2177. }
  2178. // Check that loop is executed at least one time.
  2179. CGF.EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount);
  2180. PreCondVars.restore(CGF);
  2181. }
  2182. void CodeGenFunction::EmitOMPLinearClause(
  2183. const OMPLoopDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) {
  2184. if (!HaveInsertPoint())
  2185. return;
  2186. llvm::DenseSet<const VarDecl *> SIMDLCVs;
  2187. if (isOpenMPSimdDirective(D.getDirectiveKind())) {
  2188. const auto *LoopDirective = cast<OMPLoopDirective>(&D);
  2189. for (const Expr *C : LoopDirective->counters()) {
  2190. SIMDLCVs.insert(
  2191. cast<VarDecl>(cast<DeclRefExpr>(C)->getDecl())->getCanonicalDecl());
  2192. }
  2193. }
  2194. for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
  2195. auto CurPrivate = C->privates().begin();
  2196. for (const Expr *E : C->varlists()) {
  2197. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
  2198. const auto *PrivateVD =
  2199. cast<VarDecl>(cast<DeclRefExpr>(*CurPrivate)->getDecl());
  2200. if (!SIMDLCVs.count(VD->getCanonicalDecl())) {
  2201. bool IsRegistered = PrivateScope.addPrivate(VD, [this, PrivateVD]() {
  2202. // Emit private VarDecl with copy init.
  2203. EmitVarDecl(*PrivateVD);
  2204. return GetAddrOfLocalVar(PrivateVD);
  2205. });
  2206. assert(IsRegistered && "linear var already registered as private");
  2207. // Silence the warning about unused variable.
  2208. (void)IsRegistered;
  2209. } else {
  2210. EmitVarDecl(*PrivateVD);
  2211. }
  2212. ++CurPrivate;
  2213. }
  2214. }
  2215. }
  2216. static void emitSimdlenSafelenClause(CodeGenFunction &CGF,
  2217. const OMPExecutableDirective &D) {
  2218. if (!CGF.HaveInsertPoint())
  2219. return;
  2220. if (const auto *C = D.getSingleClause<OMPSimdlenClause>()) {
  2221. RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(),
  2222. /*ignoreResult=*/true);
  2223. auto *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
  2224. CGF.LoopStack.setVectorizeWidth(Val->getZExtValue());
  2225. // In presence of finite 'safelen', it may be unsafe to mark all
  2226. // the memory instructions parallel, because loop-carried
  2227. // dependences of 'safelen' iterations are possible.
  2228. CGF.LoopStack.setParallel(!D.getSingleClause<OMPSafelenClause>());
  2229. } else if (const auto *C = D.getSingleClause<OMPSafelenClause>()) {
  2230. RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(),
  2231. /*ignoreResult=*/true);
  2232. auto *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
  2233. CGF.LoopStack.setVectorizeWidth(Val->getZExtValue());
  2234. // In presence of finite 'safelen', it may be unsafe to mark all
  2235. // the memory instructions parallel, because loop-carried
  2236. // dependences of 'safelen' iterations are possible.
  2237. CGF.LoopStack.setParallel(/*Enable=*/false);
  2238. }
  2239. }
  2240. void CodeGenFunction::EmitOMPSimdInit(const OMPLoopDirective &D) {
  2241. // Walk clauses and process safelen/lastprivate.
  2242. LoopStack.setParallel(/*Enable=*/true);
  2243. LoopStack.setVectorizeEnable();
  2244. emitSimdlenSafelenClause(*this, D);
  2245. if (const auto *C = D.getSingleClause<OMPOrderClause>())
  2246. if (C->getKind() == OMPC_ORDER_concurrent)
  2247. LoopStack.setParallel(/*Enable=*/true);
  2248. if ((D.getDirectiveKind() == OMPD_simd ||
  2249. (getLangOpts().OpenMPSimd &&
  2250. isOpenMPSimdDirective(D.getDirectiveKind()))) &&
  2251. llvm::any_of(D.getClausesOfKind<OMPReductionClause>(),
  2252. [](const OMPReductionClause *C) {
  2253. return C->getModifier() == OMPC_REDUCTION_inscan;
  2254. }))
  2255. // Disable parallel access in case of prefix sum.
  2256. LoopStack.setParallel(/*Enable=*/false);
  2257. }
  2258. void CodeGenFunction::EmitOMPSimdFinal(
  2259. const OMPLoopDirective &D,
  2260. const llvm::function_ref<llvm::Value *(CodeGenFunction &)> CondGen) {
  2261. if (!HaveInsertPoint())
  2262. return;
  2263. llvm::BasicBlock *DoneBB = nullptr;
  2264. auto IC = D.counters().begin();
  2265. auto IPC = D.private_counters().begin();
  2266. for (const Expr *F : D.finals()) {
  2267. const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl());
  2268. const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>((*IPC))->getDecl());
  2269. const auto *CED = dyn_cast<OMPCapturedExprDecl>(OrigVD);
  2270. if (LocalDeclMap.count(OrigVD) || CapturedStmtInfo->lookup(OrigVD) ||
  2271. OrigVD->hasGlobalStorage() || CED) {
  2272. if (!DoneBB) {
  2273. if (llvm::Value *Cond = CondGen(*this)) {
  2274. // If the first post-update expression is found, emit conditional
  2275. // block if it was requested.
  2276. llvm::BasicBlock *ThenBB = createBasicBlock(".omp.final.then");
  2277. DoneBB = createBasicBlock(".omp.final.done");
  2278. Builder.CreateCondBr(Cond, ThenBB, DoneBB);
  2279. EmitBlock(ThenBB);
  2280. }
  2281. }
  2282. Address OrigAddr = Address::invalid();
  2283. if (CED) {
  2284. OrigAddr =
  2285. EmitLValue(CED->getInit()->IgnoreImpCasts()).getAddress(*this);
  2286. } else {
  2287. DeclRefExpr DRE(getContext(), const_cast<VarDecl *>(PrivateVD),
  2288. /*RefersToEnclosingVariableOrCapture=*/false,
  2289. (*IPC)->getType(), VK_LValue, (*IPC)->getExprLoc());
  2290. OrigAddr = EmitLValue(&DRE).getAddress(*this);
  2291. }
  2292. OMPPrivateScope VarScope(*this);
  2293. VarScope.addPrivate(OrigVD, [OrigAddr]() { return OrigAddr; });
  2294. (void)VarScope.Privatize();
  2295. EmitIgnoredExpr(F);
  2296. }
  2297. ++IC;
  2298. ++IPC;
  2299. }
  2300. if (DoneBB)
  2301. EmitBlock(DoneBB, /*IsFinished=*/true);
  2302. }
  2303. static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF,
  2304. const OMPLoopDirective &S,
  2305. CodeGenFunction::JumpDest LoopExit) {
  2306. CGF.EmitOMPLoopBody(S, LoopExit);
  2307. CGF.EmitStopPoint(&S);
  2308. }
  2309. /// Emit a helper variable and return corresponding lvalue.
  2310. static LValue EmitOMPHelperVar(CodeGenFunction &CGF,
  2311. const DeclRefExpr *Helper) {
  2312. auto VDecl = cast<VarDecl>(Helper->getDecl());
  2313. CGF.EmitVarDecl(*VDecl);
  2314. return CGF.EmitLValue(Helper);
  2315. }
  2316. static void emitCommonSimdLoop(CodeGenFunction &CGF, const OMPLoopDirective &S,
  2317. const RegionCodeGenTy &SimdInitGen,
  2318. const RegionCodeGenTy &BodyCodeGen) {
  2319. auto &&ThenGen = [&S, &SimdInitGen, &BodyCodeGen](CodeGenFunction &CGF,
  2320. PrePostActionTy &) {
  2321. CGOpenMPRuntime::NontemporalDeclsRAII NontemporalsRegion(CGF.CGM, S);
  2322. CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
  2323. SimdInitGen(CGF);
  2324. BodyCodeGen(CGF);
  2325. };
  2326. auto &&ElseGen = [&BodyCodeGen](CodeGenFunction &CGF, PrePostActionTy &) {
  2327. CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
  2328. CGF.LoopStack.setVectorizeEnable(/*Enable=*/false);
  2329. BodyCodeGen(CGF);
  2330. };
  2331. const Expr *IfCond = nullptr;
  2332. if (isOpenMPSimdDirective(S.getDirectiveKind())) {
  2333. for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
  2334. if (CGF.getLangOpts().OpenMP >= 50 &&
  2335. (C->getNameModifier() == OMPD_unknown ||
  2336. C->getNameModifier() == OMPD_simd)) {
  2337. IfCond = C->getCondition();
  2338. break;
  2339. }
  2340. }
  2341. }
  2342. if (IfCond) {
  2343. CGF.CGM.getOpenMPRuntime().emitIfClause(CGF, IfCond, ThenGen, ElseGen);
  2344. } else {
  2345. RegionCodeGenTy ThenRCG(ThenGen);
  2346. ThenRCG(CGF);
  2347. }
  2348. }
  2349. static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
  2350. PrePostActionTy &Action) {
  2351. Action.Enter(CGF);
  2352. assert(isOpenMPSimdDirective(S.getDirectiveKind()) &&
  2353. "Expected simd directive");
  2354. OMPLoopScope PreInitScope(CGF, S);
  2355. // if (PreCond) {
  2356. // for (IV in 0..LastIteration) BODY;
  2357. // <Final counter/linear vars updates>;
  2358. // }
  2359. //
  2360. if (isOpenMPDistributeDirective(S.getDirectiveKind()) ||
  2361. isOpenMPWorksharingDirective(S.getDirectiveKind()) ||
  2362. isOpenMPTaskLoopDirective(S.getDirectiveKind())) {
  2363. (void)EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()));
  2364. (void)EmitOMPHelperVar(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()));
  2365. }
  2366. // Emit: if (PreCond) - begin.
  2367. // If the condition constant folds and can be elided, avoid emitting the
  2368. // whole loop.
  2369. bool CondConstant;
  2370. llvm::BasicBlock *ContBlock = nullptr;
  2371. if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
  2372. if (!CondConstant)
  2373. return;
  2374. } else {
  2375. llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("simd.if.then");
  2376. ContBlock = CGF.createBasicBlock("simd.if.end");
  2377. emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
  2378. CGF.getProfileCount(&S));
  2379. CGF.EmitBlock(ThenBlock);
  2380. CGF.incrementProfileCounter(&S);
  2381. }
  2382. // Emit the loop iteration variable.
  2383. const Expr *IVExpr = S.getIterationVariable();
  2384. const auto *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
  2385. CGF.EmitVarDecl(*IVDecl);
  2386. CGF.EmitIgnoredExpr(S.getInit());
  2387. // Emit the iterations count variable.
  2388. // If it is not a variable, Sema decided to calculate iterations count on
  2389. // each iteration (e.g., it is foldable into a constant).
  2390. if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
  2391. CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
  2392. // Emit calculation of the iterations count.
  2393. CGF.EmitIgnoredExpr(S.getCalcLastIteration());
  2394. }
  2395. emitAlignedClause(CGF, S);
  2396. (void)CGF.EmitOMPLinearClauseInit(S);
  2397. {
  2398. CodeGenFunction::OMPPrivateScope LoopScope(CGF);
  2399. CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
  2400. CGF.EmitOMPLinearClause(S, LoopScope);
  2401. CGF.EmitOMPPrivateClause(S, LoopScope);
  2402. CGF.EmitOMPReductionClauseInit(S, LoopScope);
  2403. CGOpenMPRuntime::LastprivateConditionalRAII LPCRegion(
  2404. CGF, S, CGF.EmitLValue(S.getIterationVariable()));
  2405. bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
  2406. (void)LoopScope.Privatize();
  2407. if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
  2408. CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
  2409. emitCommonSimdLoop(
  2410. CGF, S,
  2411. [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  2412. CGF.EmitOMPSimdInit(S);
  2413. },
  2414. [&S, &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) {
  2415. CGF.EmitOMPInnerLoop(
  2416. S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),
  2417. [&S](CodeGenFunction &CGF) {
  2418. emitOMPLoopBodyWithStopPoint(CGF, S,
  2419. CodeGenFunction::JumpDest());
  2420. },
  2421. [](CodeGenFunction &) {});
  2422. });
  2423. CGF.EmitOMPSimdFinal(S, [](CodeGenFunction &) { return nullptr; });
  2424. // Emit final copy of the lastprivate variables at the end of loops.
  2425. if (HasLastprivateClause)
  2426. CGF.EmitOMPLastprivateClauseFinal(S, /*NoFinals=*/true);
  2427. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_simd);
  2428. emitPostUpdateForReductionClause(CGF, S,
  2429. [](CodeGenFunction &) { return nullptr; });
  2430. }
  2431. CGF.EmitOMPLinearClauseFinal(S, [](CodeGenFunction &) { return nullptr; });
  2432. // Emit: if (PreCond) - end.
  2433. if (ContBlock) {
  2434. CGF.EmitBranch(ContBlock);
  2435. CGF.EmitBlock(ContBlock, true);
  2436. }
  2437. }
  2438. static bool isSupportedByOpenMPIRBuilder(const OMPExecutableDirective &S) {
  2439. // Check for unsupported clauses
  2440. if (!S.clauses().empty()) {
  2441. // Currently no clause is supported
  2442. return false;
  2443. }
  2444. // Check if we have a statement with the ordered directive.
  2445. // Visit the statement hierarchy to find a compound statement
  2446. // with a ordered directive in it.
  2447. if (const auto *CanonLoop = dyn_cast<OMPCanonicalLoop>(S.getRawStmt())) {
  2448. if (const Stmt *SyntacticalLoop = CanonLoop->getLoopStmt()) {
  2449. for (const Stmt *SubStmt : SyntacticalLoop->children()) {
  2450. if (!SubStmt)
  2451. continue;
  2452. if (const CompoundStmt *CS = dyn_cast<CompoundStmt>(SubStmt)) {
  2453. for (const Stmt *CSSubStmt : CS->children()) {
  2454. if (!CSSubStmt)
  2455. continue;
  2456. if (isa<OMPOrderedDirective>(CSSubStmt)) {
  2457. return false;
  2458. }
  2459. }
  2460. }
  2461. }
  2462. }
  2463. }
  2464. return true;
  2465. }
  2466. void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
  2467. bool UseOMPIRBuilder =
  2468. CGM.getLangOpts().OpenMPIRBuilder && isSupportedByOpenMPIRBuilder(S);
  2469. if (UseOMPIRBuilder) {
  2470. auto &&CodeGenIRBuilder = [this, &S, UseOMPIRBuilder](CodeGenFunction &CGF,
  2471. PrePostActionTy &) {
  2472. // Use the OpenMPIRBuilder if enabled.
  2473. if (UseOMPIRBuilder) {
  2474. // Emit the associated statement and get its loop representation.
  2475. llvm::DebugLoc DL = SourceLocToDebugLoc(S.getBeginLoc());
  2476. const Stmt *Inner = S.getRawStmt();
  2477. llvm::CanonicalLoopInfo *CLI =
  2478. EmitOMPCollapsedCanonicalLoopNest(Inner, 1);
  2479. llvm::OpenMPIRBuilder &OMPBuilder =
  2480. CGM.getOpenMPRuntime().getOMPBuilder();
  2481. // Add SIMD specific metadata
  2482. OMPBuilder.applySimd(DL, CLI);
  2483. return;
  2484. }
  2485. };
  2486. {
  2487. auto LPCRegion =
  2488. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  2489. OMPLexicalScope Scope(*this, S, OMPD_unknown);
  2490. CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd,
  2491. CodeGenIRBuilder);
  2492. }
  2493. return;
  2494. }
  2495. ParentLoopDirectiveForScanRegion ScanRegion(*this, S);
  2496. OMPFirstScanLoop = true;
  2497. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  2498. emitOMPSimdRegion(CGF, S, Action);
  2499. };
  2500. {
  2501. auto LPCRegion =
  2502. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  2503. OMPLexicalScope Scope(*this, S, OMPD_unknown);
  2504. CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
  2505. }
  2506. // Check for outer lastprivate conditional update.
  2507. checkForLastprivateConditionalUpdate(*this, S);
  2508. }
  2509. void CodeGenFunction::EmitOMPTileDirective(const OMPTileDirective &S) {
  2510. // Emit the de-sugared statement.
  2511. OMPTransformDirectiveScopeRAII TileScope(*this, &S);
  2512. EmitStmt(S.getTransformedStmt());
  2513. }
  2514. void CodeGenFunction::EmitOMPUnrollDirective(const OMPUnrollDirective &S) {
  2515. bool UseOMPIRBuilder = CGM.getLangOpts().OpenMPIRBuilder;
  2516. if (UseOMPIRBuilder) {
  2517. auto DL = SourceLocToDebugLoc(S.getBeginLoc());
  2518. const Stmt *Inner = S.getRawStmt();
  2519. // Consume nested loop. Clear the entire remaining loop stack because a
  2520. // fully unrolled loop is non-transformable. For partial unrolling the
  2521. // generated outer loop is pushed back to the stack.
  2522. llvm::CanonicalLoopInfo *CLI = EmitOMPCollapsedCanonicalLoopNest(Inner, 1);
  2523. OMPLoopNestStack.clear();
  2524. llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  2525. bool NeedsUnrolledCLI = ExpectedOMPLoopDepth >= 1;
  2526. llvm::CanonicalLoopInfo *UnrolledCLI = nullptr;
  2527. if (S.hasClausesOfKind<OMPFullClause>()) {
  2528. assert(ExpectedOMPLoopDepth == 0);
  2529. OMPBuilder.unrollLoopFull(DL, CLI);
  2530. } else if (auto *PartialClause = S.getSingleClause<OMPPartialClause>()) {
  2531. uint64_t Factor = 0;
  2532. if (Expr *FactorExpr = PartialClause->getFactor()) {
  2533. Factor = FactorExpr->EvaluateKnownConstInt(getContext()).getZExtValue();
  2534. assert(Factor >= 1 && "Only positive factors are valid");
  2535. }
  2536. OMPBuilder.unrollLoopPartial(DL, CLI, Factor,
  2537. NeedsUnrolledCLI ? &UnrolledCLI : nullptr);
  2538. } else {
  2539. OMPBuilder.unrollLoopHeuristic(DL, CLI);
  2540. }
  2541. assert((!NeedsUnrolledCLI || UnrolledCLI) &&
  2542. "NeedsUnrolledCLI implies UnrolledCLI to be set");
  2543. if (UnrolledCLI)
  2544. OMPLoopNestStack.push_back(UnrolledCLI);
  2545. return;
  2546. }
  2547. // This function is only called if the unrolled loop is not consumed by any
  2548. // other loop-associated construct. Such a loop-associated construct will have
  2549. // used the transformed AST.
  2550. // Set the unroll metadata for the next emitted loop.
  2551. LoopStack.setUnrollState(LoopAttributes::Enable);
  2552. if (S.hasClausesOfKind<OMPFullClause>()) {
  2553. LoopStack.setUnrollState(LoopAttributes::Full);
  2554. } else if (auto *PartialClause = S.getSingleClause<OMPPartialClause>()) {
  2555. if (Expr *FactorExpr = PartialClause->getFactor()) {
  2556. uint64_t Factor =
  2557. FactorExpr->EvaluateKnownConstInt(getContext()).getZExtValue();
  2558. assert(Factor >= 1 && "Only positive factors are valid");
  2559. LoopStack.setUnrollCount(Factor);
  2560. }
  2561. }
  2562. EmitStmt(S.getAssociatedStmt());
  2563. }
  2564. void CodeGenFunction::EmitOMPOuterLoop(
  2565. bool DynamicOrOrdered, bool IsMonotonic, const OMPLoopDirective &S,
  2566. CodeGenFunction::OMPPrivateScope &LoopScope,
  2567. const CodeGenFunction::OMPLoopArguments &LoopArgs,
  2568. const CodeGenFunction::CodeGenLoopTy &CodeGenLoop,
  2569. const CodeGenFunction::CodeGenOrderedTy &CodeGenOrdered) {
  2570. CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
  2571. const Expr *IVExpr = S.getIterationVariable();
  2572. const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
  2573. const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
  2574. JumpDest LoopExit = getJumpDestInCurrentScope("omp.dispatch.end");
  2575. // Start the loop with a block that tests the condition.
  2576. llvm::BasicBlock *CondBlock = createBasicBlock("omp.dispatch.cond");
  2577. EmitBlock(CondBlock);
  2578. const SourceRange R = S.getSourceRange();
  2579. OMPLoopNestStack.clear();
  2580. LoopStack.push(CondBlock, SourceLocToDebugLoc(R.getBegin()),
  2581. SourceLocToDebugLoc(R.getEnd()));
  2582. llvm::Value *BoolCondVal = nullptr;
  2583. if (!DynamicOrOrdered) {
  2584. // UB = min(UB, GlobalUB) or
  2585. // UB = min(UB, PrevUB) for combined loop sharing constructs (e.g.
  2586. // 'distribute parallel for')
  2587. EmitIgnoredExpr(LoopArgs.EUB);
  2588. // IV = LB
  2589. EmitIgnoredExpr(LoopArgs.Init);
  2590. // IV < UB
  2591. BoolCondVal = EvaluateExprAsBool(LoopArgs.Cond);
  2592. } else {
  2593. BoolCondVal =
  2594. RT.emitForNext(*this, S.getBeginLoc(), IVSize, IVSigned, LoopArgs.IL,
  2595. LoopArgs.LB, LoopArgs.UB, LoopArgs.ST);
  2596. }
  2597. // If there are any cleanups between here and the loop-exit scope,
  2598. // create a block to stage a loop exit along.
  2599. llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
  2600. if (LoopScope.requiresCleanups())
  2601. ExitBlock = createBasicBlock("omp.dispatch.cleanup");
  2602. llvm::BasicBlock *LoopBody = createBasicBlock("omp.dispatch.body");
  2603. Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
  2604. if (ExitBlock != LoopExit.getBlock()) {
  2605. EmitBlock(ExitBlock);
  2606. EmitBranchThroughCleanup(LoopExit);
  2607. }
  2608. EmitBlock(LoopBody);
  2609. // Emit "IV = LB" (in case of static schedule, we have already calculated new
  2610. // LB for loop condition and emitted it above).
  2611. if (DynamicOrOrdered)
  2612. EmitIgnoredExpr(LoopArgs.Init);
  2613. // Create a block for the increment.
  2614. JumpDest Continue = getJumpDestInCurrentScope("omp.dispatch.inc");
  2615. BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
  2616. emitCommonSimdLoop(
  2617. *this, S,
  2618. [&S, IsMonotonic](CodeGenFunction &CGF, PrePostActionTy &) {
  2619. // Generate !llvm.loop.parallel metadata for loads and stores for loops
  2620. // with dynamic/guided scheduling and without ordered clause.
  2621. if (!isOpenMPSimdDirective(S.getDirectiveKind())) {
  2622. CGF.LoopStack.setParallel(!IsMonotonic);
  2623. if (const auto *C = S.getSingleClause<OMPOrderClause>())
  2624. if (C->getKind() == OMPC_ORDER_concurrent)
  2625. CGF.LoopStack.setParallel(/*Enable=*/true);
  2626. } else {
  2627. CGF.EmitOMPSimdInit(S);
  2628. }
  2629. },
  2630. [&S, &LoopArgs, LoopExit, &CodeGenLoop, IVSize, IVSigned, &CodeGenOrdered,
  2631. &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) {
  2632. SourceLocation Loc = S.getBeginLoc();
  2633. // when 'distribute' is not combined with a 'for':
  2634. // while (idx <= UB) { BODY; ++idx; }
  2635. // when 'distribute' is combined with a 'for'
  2636. // (e.g. 'distribute parallel for')
  2637. // while (idx <= UB) { <CodeGen rest of pragma>; idx += ST; }
  2638. CGF.EmitOMPInnerLoop(
  2639. S, LoopScope.requiresCleanups(), LoopArgs.Cond, LoopArgs.IncExpr,
  2640. [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) {
  2641. CodeGenLoop(CGF, S, LoopExit);
  2642. },
  2643. [IVSize, IVSigned, Loc, &CodeGenOrdered](CodeGenFunction &CGF) {
  2644. CodeGenOrdered(CGF, Loc, IVSize, IVSigned);
  2645. });
  2646. });
  2647. EmitBlock(Continue.getBlock());
  2648. BreakContinueStack.pop_back();
  2649. if (!DynamicOrOrdered) {
  2650. // Emit "LB = LB + Stride", "UB = UB + Stride".
  2651. EmitIgnoredExpr(LoopArgs.NextLB);
  2652. EmitIgnoredExpr(LoopArgs.NextUB);
  2653. }
  2654. EmitBranch(CondBlock);
  2655. OMPLoopNestStack.clear();
  2656. LoopStack.pop();
  2657. // Emit the fall-through block.
  2658. EmitBlock(LoopExit.getBlock());
  2659. // Tell the runtime we are done.
  2660. auto &&CodeGen = [DynamicOrOrdered, &S](CodeGenFunction &CGF) {
  2661. if (!DynamicOrOrdered)
  2662. CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
  2663. S.getDirectiveKind());
  2664. };
  2665. OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
  2666. }
  2667. void CodeGenFunction::EmitOMPForOuterLoop(
  2668. const OpenMPScheduleTy &ScheduleKind, bool IsMonotonic,
  2669. const OMPLoopDirective &S, OMPPrivateScope &LoopScope, bool Ordered,
  2670. const OMPLoopArguments &LoopArgs,
  2671. const CodeGenDispatchBoundsTy &CGDispatchBounds) {
  2672. CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
  2673. // Dynamic scheduling of the outer loop (dynamic, guided, auto, runtime).
  2674. const bool DynamicOrOrdered = Ordered || RT.isDynamic(ScheduleKind.Schedule);
  2675. assert((Ordered || !RT.isStaticNonchunked(ScheduleKind.Schedule,
  2676. LoopArgs.Chunk != nullptr)) &&
  2677. "static non-chunked schedule does not need outer loop");
  2678. // Emit outer loop.
  2679. //
  2680. // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
  2681. // When schedule(dynamic,chunk_size) is specified, the iterations are
  2682. // distributed to threads in the team in chunks as the threads request them.
  2683. // Each thread executes a chunk of iterations, then requests another chunk,
  2684. // until no chunks remain to be distributed. Each chunk contains chunk_size
  2685. // iterations, except for the last chunk to be distributed, which may have
  2686. // fewer iterations. When no chunk_size is specified, it defaults to 1.
  2687. //
  2688. // When schedule(guided,chunk_size) is specified, the iterations are assigned
  2689. // to threads in the team in chunks as the executing threads request them.
  2690. // Each thread executes a chunk of iterations, then requests another chunk,
  2691. // until no chunks remain to be assigned. For a chunk_size of 1, the size of
  2692. // each chunk is proportional to the number of unassigned iterations divided
  2693. // by the number of threads in the team, decreasing to 1. For a chunk_size
  2694. // with value k (greater than 1), the size of each chunk is determined in the
  2695. // same way, with the restriction that the chunks do not contain fewer than k
  2696. // iterations (except for the last chunk to be assigned, which may have fewer
  2697. // than k iterations).
  2698. //
  2699. // When schedule(auto) is specified, the decision regarding scheduling is
  2700. // delegated to the compiler and/or runtime system. The programmer gives the
  2701. // implementation the freedom to choose any possible mapping of iterations to
  2702. // threads in the team.
  2703. //
  2704. // When schedule(runtime) is specified, the decision regarding scheduling is
  2705. // deferred until run time, and the schedule and chunk size are taken from the
  2706. // run-sched-var ICV. If the ICV is set to auto, the schedule is
  2707. // implementation defined
  2708. //
  2709. // while(__kmpc_dispatch_next(&LB, &UB)) {
  2710. // idx = LB;
  2711. // while (idx <= UB) { BODY; ++idx;
  2712. // __kmpc_dispatch_fini_(4|8)[u](); // For ordered loops only.
  2713. // } // inner loop
  2714. // }
  2715. //
  2716. // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
  2717. // When schedule(static, chunk_size) is specified, iterations are divided into
  2718. // chunks of size chunk_size, and the chunks are assigned to the threads in
  2719. // the team in a round-robin fashion in the order of the thread number.
  2720. //
  2721. // while(UB = min(UB, GlobalUB), idx = LB, idx < UB) {
  2722. // while (idx <= UB) { BODY; ++idx; } // inner loop
  2723. // LB = LB + ST;
  2724. // UB = UB + ST;
  2725. // }
  2726. //
  2727. const Expr *IVExpr = S.getIterationVariable();
  2728. const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
  2729. const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
  2730. if (DynamicOrOrdered) {
  2731. const std::pair<llvm::Value *, llvm::Value *> DispatchBounds =
  2732. CGDispatchBounds(*this, S, LoopArgs.LB, LoopArgs.UB);
  2733. llvm::Value *LBVal = DispatchBounds.first;
  2734. llvm::Value *UBVal = DispatchBounds.second;
  2735. CGOpenMPRuntime::DispatchRTInput DipatchRTInputValues = {LBVal, UBVal,
  2736. LoopArgs.Chunk};
  2737. RT.emitForDispatchInit(*this, S.getBeginLoc(), ScheduleKind, IVSize,
  2738. IVSigned, Ordered, DipatchRTInputValues);
  2739. } else {
  2740. CGOpenMPRuntime::StaticRTInput StaticInit(
  2741. IVSize, IVSigned, Ordered, LoopArgs.IL, LoopArgs.LB, LoopArgs.UB,
  2742. LoopArgs.ST, LoopArgs.Chunk);
  2743. RT.emitForStaticInit(*this, S.getBeginLoc(), S.getDirectiveKind(),
  2744. ScheduleKind, StaticInit);
  2745. }
  2746. auto &&CodeGenOrdered = [Ordered](CodeGenFunction &CGF, SourceLocation Loc,
  2747. const unsigned IVSize,
  2748. const bool IVSigned) {
  2749. if (Ordered) {
  2750. CGF.CGM.getOpenMPRuntime().emitForOrderedIterationEnd(CGF, Loc, IVSize,
  2751. IVSigned);
  2752. }
  2753. };
  2754. OMPLoopArguments OuterLoopArgs(LoopArgs.LB, LoopArgs.UB, LoopArgs.ST,
  2755. LoopArgs.IL, LoopArgs.Chunk, LoopArgs.EUB);
  2756. OuterLoopArgs.IncExpr = S.getInc();
  2757. OuterLoopArgs.Init = S.getInit();
  2758. OuterLoopArgs.Cond = S.getCond();
  2759. OuterLoopArgs.NextLB = S.getNextLowerBound();
  2760. OuterLoopArgs.NextUB = S.getNextUpperBound();
  2761. EmitOMPOuterLoop(DynamicOrOrdered, IsMonotonic, S, LoopScope, OuterLoopArgs,
  2762. emitOMPLoopBodyWithStopPoint, CodeGenOrdered);
  2763. }
  2764. static void emitEmptyOrdered(CodeGenFunction &, SourceLocation Loc,
  2765. const unsigned IVSize, const bool IVSigned) {}
  2766. void CodeGenFunction::EmitOMPDistributeOuterLoop(
  2767. OpenMPDistScheduleClauseKind ScheduleKind, const OMPLoopDirective &S,
  2768. OMPPrivateScope &LoopScope, const OMPLoopArguments &LoopArgs,
  2769. const CodeGenLoopTy &CodeGenLoopContent) {
  2770. CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
  2771. // Emit outer loop.
  2772. // Same behavior as a OMPForOuterLoop, except that schedule cannot be
  2773. // dynamic
  2774. //
  2775. const Expr *IVExpr = S.getIterationVariable();
  2776. const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
  2777. const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
  2778. CGOpenMPRuntime::StaticRTInput StaticInit(
  2779. IVSize, IVSigned, /* Ordered = */ false, LoopArgs.IL, LoopArgs.LB,
  2780. LoopArgs.UB, LoopArgs.ST, LoopArgs.Chunk);
  2781. RT.emitDistributeStaticInit(*this, S.getBeginLoc(), ScheduleKind, StaticInit);
  2782. // for combined 'distribute' and 'for' the increment expression of distribute
  2783. // is stored in DistInc. For 'distribute' alone, it is in Inc.
  2784. Expr *IncExpr;
  2785. if (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind()))
  2786. IncExpr = S.getDistInc();
  2787. else
  2788. IncExpr = S.getInc();
  2789. // this routine is shared by 'omp distribute parallel for' and
  2790. // 'omp distribute': select the right EUB expression depending on the
  2791. // directive
  2792. OMPLoopArguments OuterLoopArgs;
  2793. OuterLoopArgs.LB = LoopArgs.LB;
  2794. OuterLoopArgs.UB = LoopArgs.UB;
  2795. OuterLoopArgs.ST = LoopArgs.ST;
  2796. OuterLoopArgs.IL = LoopArgs.IL;
  2797. OuterLoopArgs.Chunk = LoopArgs.Chunk;
  2798. OuterLoopArgs.EUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
  2799. ? S.getCombinedEnsureUpperBound()
  2800. : S.getEnsureUpperBound();
  2801. OuterLoopArgs.IncExpr = IncExpr;
  2802. OuterLoopArgs.Init = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
  2803. ? S.getCombinedInit()
  2804. : S.getInit();
  2805. OuterLoopArgs.Cond = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
  2806. ? S.getCombinedCond()
  2807. : S.getCond();
  2808. OuterLoopArgs.NextLB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
  2809. ? S.getCombinedNextLowerBound()
  2810. : S.getNextLowerBound();
  2811. OuterLoopArgs.NextUB = isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
  2812. ? S.getCombinedNextUpperBound()
  2813. : S.getNextUpperBound();
  2814. EmitOMPOuterLoop(/* DynamicOrOrdered = */ false, /* IsMonotonic = */ false, S,
  2815. LoopScope, OuterLoopArgs, CodeGenLoopContent,
  2816. emitEmptyOrdered);
  2817. }
  2818. static std::pair<LValue, LValue>
  2819. emitDistributeParallelForInnerBounds(CodeGenFunction &CGF,
  2820. const OMPExecutableDirective &S) {
  2821. const OMPLoopDirective &LS = cast<OMPLoopDirective>(S);
  2822. LValue LB =
  2823. EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable()));
  2824. LValue UB =
  2825. EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable()));
  2826. // When composing 'distribute' with 'for' (e.g. as in 'distribute
  2827. // parallel for') we need to use the 'distribute'
  2828. // chunk lower and upper bounds rather than the whole loop iteration
  2829. // space. These are parameters to the outlined function for 'parallel'
  2830. // and we copy the bounds of the previous schedule into the
  2831. // the current ones.
  2832. LValue PrevLB = CGF.EmitLValue(LS.getPrevLowerBoundVariable());
  2833. LValue PrevUB = CGF.EmitLValue(LS.getPrevUpperBoundVariable());
  2834. llvm::Value *PrevLBVal = CGF.EmitLoadOfScalar(
  2835. PrevLB, LS.getPrevLowerBoundVariable()->getExprLoc());
  2836. PrevLBVal = CGF.EmitScalarConversion(
  2837. PrevLBVal, LS.getPrevLowerBoundVariable()->getType(),
  2838. LS.getIterationVariable()->getType(),
  2839. LS.getPrevLowerBoundVariable()->getExprLoc());
  2840. llvm::Value *PrevUBVal = CGF.EmitLoadOfScalar(
  2841. PrevUB, LS.getPrevUpperBoundVariable()->getExprLoc());
  2842. PrevUBVal = CGF.EmitScalarConversion(
  2843. PrevUBVal, LS.getPrevUpperBoundVariable()->getType(),
  2844. LS.getIterationVariable()->getType(),
  2845. LS.getPrevUpperBoundVariable()->getExprLoc());
  2846. CGF.EmitStoreOfScalar(PrevLBVal, LB);
  2847. CGF.EmitStoreOfScalar(PrevUBVal, UB);
  2848. return {LB, UB};
  2849. }
  2850. /// if the 'for' loop has a dispatch schedule (e.g. dynamic, guided) then
  2851. /// we need to use the LB and UB expressions generated by the worksharing
  2852. /// code generation support, whereas in non combined situations we would
  2853. /// just emit 0 and the LastIteration expression
  2854. /// This function is necessary due to the difference of the LB and UB
  2855. /// types for the RT emission routines for 'for_static_init' and
  2856. /// 'for_dispatch_init'
  2857. static std::pair<llvm::Value *, llvm::Value *>
  2858. emitDistributeParallelForDispatchBounds(CodeGenFunction &CGF,
  2859. const OMPExecutableDirective &S,
  2860. Address LB, Address UB) {
  2861. const OMPLoopDirective &LS = cast<OMPLoopDirective>(S);
  2862. const Expr *IVExpr = LS.getIterationVariable();
  2863. // when implementing a dynamic schedule for a 'for' combined with a
  2864. // 'distribute' (e.g. 'distribute parallel for'), the 'for' loop
  2865. // is not normalized as each team only executes its own assigned
  2866. // distribute chunk
  2867. QualType IteratorTy = IVExpr->getType();
  2868. llvm::Value *LBVal =
  2869. CGF.EmitLoadOfScalar(LB, /*Volatile=*/false, IteratorTy, S.getBeginLoc());
  2870. llvm::Value *UBVal =
  2871. CGF.EmitLoadOfScalar(UB, /*Volatile=*/false, IteratorTy, S.getBeginLoc());
  2872. return {LBVal, UBVal};
  2873. }
  2874. static void emitDistributeParallelForDistributeInnerBoundParams(
  2875. CodeGenFunction &CGF, const OMPExecutableDirective &S,
  2876. llvm::SmallVectorImpl<llvm::Value *> &CapturedVars) {
  2877. const auto &Dir = cast<OMPLoopDirective>(S);
  2878. LValue LB =
  2879. CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedLowerBoundVariable()));
  2880. llvm::Value *LBCast =
  2881. CGF.Builder.CreateIntCast(CGF.Builder.CreateLoad(LB.getAddress(CGF)),
  2882. CGF.SizeTy, /*isSigned=*/false);
  2883. CapturedVars.push_back(LBCast);
  2884. LValue UB =
  2885. CGF.EmitLValue(cast<DeclRefExpr>(Dir.getCombinedUpperBoundVariable()));
  2886. llvm::Value *UBCast =
  2887. CGF.Builder.CreateIntCast(CGF.Builder.CreateLoad(UB.getAddress(CGF)),
  2888. CGF.SizeTy, /*isSigned=*/false);
  2889. CapturedVars.push_back(UBCast);
  2890. }
  2891. static void
  2892. emitInnerParallelForWhenCombined(CodeGenFunction &CGF,
  2893. const OMPLoopDirective &S,
  2894. CodeGenFunction::JumpDest LoopExit) {
  2895. auto &&CGInlinedWorksharingLoop = [&S](CodeGenFunction &CGF,
  2896. PrePostActionTy &Action) {
  2897. Action.Enter(CGF);
  2898. bool HasCancel = false;
  2899. if (!isOpenMPSimdDirective(S.getDirectiveKind())) {
  2900. if (const auto *D = dyn_cast<OMPTeamsDistributeParallelForDirective>(&S))
  2901. HasCancel = D->hasCancel();
  2902. else if (const auto *D = dyn_cast<OMPDistributeParallelForDirective>(&S))
  2903. HasCancel = D->hasCancel();
  2904. else if (const auto *D =
  2905. dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&S))
  2906. HasCancel = D->hasCancel();
  2907. }
  2908. CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, S.getDirectiveKind(),
  2909. HasCancel);
  2910. CGF.EmitOMPWorksharingLoop(S, S.getPrevEnsureUpperBound(),
  2911. emitDistributeParallelForInnerBounds,
  2912. emitDistributeParallelForDispatchBounds);
  2913. };
  2914. emitCommonOMPParallelDirective(
  2915. CGF, S,
  2916. isOpenMPSimdDirective(S.getDirectiveKind()) ? OMPD_for_simd : OMPD_for,
  2917. CGInlinedWorksharingLoop,
  2918. emitDistributeParallelForDistributeInnerBoundParams);
  2919. }
  2920. void CodeGenFunction::EmitOMPDistributeParallelForDirective(
  2921. const OMPDistributeParallelForDirective &S) {
  2922. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  2923. CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
  2924. S.getDistInc());
  2925. };
  2926. OMPLexicalScope Scope(*this, S, OMPD_parallel);
  2927. CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen);
  2928. }
  2929. void CodeGenFunction::EmitOMPDistributeParallelForSimdDirective(
  2930. const OMPDistributeParallelForSimdDirective &S) {
  2931. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  2932. CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
  2933. S.getDistInc());
  2934. };
  2935. OMPLexicalScope Scope(*this, S, OMPD_parallel);
  2936. CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen);
  2937. }
  2938. void CodeGenFunction::EmitOMPDistributeSimdDirective(
  2939. const OMPDistributeSimdDirective &S) {
  2940. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  2941. CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
  2942. };
  2943. OMPLexicalScope Scope(*this, S, OMPD_unknown);
  2944. CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
  2945. }
  2946. void CodeGenFunction::EmitOMPTargetSimdDeviceFunction(
  2947. CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S) {
  2948. // Emit SPMD target parallel for region as a standalone region.
  2949. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  2950. emitOMPSimdRegion(CGF, S, Action);
  2951. };
  2952. llvm::Function *Fn;
  2953. llvm::Constant *Addr;
  2954. // Emit target region as a standalone region.
  2955. CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
  2956. S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
  2957. assert(Fn && Addr && "Target device function emission failed.");
  2958. }
  2959. void CodeGenFunction::EmitOMPTargetSimdDirective(
  2960. const OMPTargetSimdDirective &S) {
  2961. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  2962. emitOMPSimdRegion(CGF, S, Action);
  2963. };
  2964. emitCommonOMPTargetDirective(*this, S, CodeGen);
  2965. }
  2966. namespace {
  2967. struct ScheduleKindModifiersTy {
  2968. OpenMPScheduleClauseKind Kind;
  2969. OpenMPScheduleClauseModifier M1;
  2970. OpenMPScheduleClauseModifier M2;
  2971. ScheduleKindModifiersTy(OpenMPScheduleClauseKind Kind,
  2972. OpenMPScheduleClauseModifier M1,
  2973. OpenMPScheduleClauseModifier M2)
  2974. : Kind(Kind), M1(M1), M2(M2) {}
  2975. };
  2976. } // namespace
  2977. bool CodeGenFunction::EmitOMPWorksharingLoop(
  2978. const OMPLoopDirective &S, Expr *EUB,
  2979. const CodeGenLoopBoundsTy &CodeGenLoopBounds,
  2980. const CodeGenDispatchBoundsTy &CGDispatchBounds) {
  2981. // Emit the loop iteration variable.
  2982. const auto *IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
  2983. const auto *IVDecl = cast<VarDecl>(IVExpr->getDecl());
  2984. EmitVarDecl(*IVDecl);
  2985. // Emit the iterations count variable.
  2986. // If it is not a variable, Sema decided to calculate iterations count on each
  2987. // iteration (e.g., it is foldable into a constant).
  2988. if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
  2989. EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
  2990. // Emit calculation of the iterations count.
  2991. EmitIgnoredExpr(S.getCalcLastIteration());
  2992. }
  2993. CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
  2994. bool HasLastprivateClause;
  2995. // Check pre-condition.
  2996. {
  2997. OMPLoopScope PreInitScope(*this, S);
  2998. // Skip the entire loop if we don't meet the precondition.
  2999. // If the condition constant folds and can be elided, avoid emitting the
  3000. // whole loop.
  3001. bool CondConstant;
  3002. llvm::BasicBlock *ContBlock = nullptr;
  3003. if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
  3004. if (!CondConstant)
  3005. return false;
  3006. } else {
  3007. llvm::BasicBlock *ThenBlock = createBasicBlock("omp.precond.then");
  3008. ContBlock = createBasicBlock("omp.precond.end");
  3009. emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock,
  3010. getProfileCount(&S));
  3011. EmitBlock(ThenBlock);
  3012. incrementProfileCounter(&S);
  3013. }
  3014. RunCleanupsScope DoacrossCleanupScope(*this);
  3015. bool Ordered = false;
  3016. if (const auto *OrderedClause = S.getSingleClause<OMPOrderedClause>()) {
  3017. if (OrderedClause->getNumForLoops())
  3018. RT.emitDoacrossInit(*this, S, OrderedClause->getLoopNumIterations());
  3019. else
  3020. Ordered = true;
  3021. }
  3022. llvm::DenseSet<const Expr *> EmittedFinals;
  3023. emitAlignedClause(*this, S);
  3024. bool HasLinears = EmitOMPLinearClauseInit(S);
  3025. // Emit helper vars inits.
  3026. std::pair<LValue, LValue> Bounds = CodeGenLoopBounds(*this, S);
  3027. LValue LB = Bounds.first;
  3028. LValue UB = Bounds.second;
  3029. LValue ST =
  3030. EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
  3031. LValue IL =
  3032. EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
  3033. // Emit 'then' code.
  3034. {
  3035. OMPPrivateScope LoopScope(*this);
  3036. if (EmitOMPFirstprivateClause(S, LoopScope) || HasLinears) {
  3037. // Emit implicit barrier to synchronize threads and avoid data races on
  3038. // initialization of firstprivate variables and post-update of
  3039. // lastprivate variables.
  3040. CGM.getOpenMPRuntime().emitBarrierCall(
  3041. *this, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
  3042. /*ForceSimpleCall=*/true);
  3043. }
  3044. EmitOMPPrivateClause(S, LoopScope);
  3045. CGOpenMPRuntime::LastprivateConditionalRAII LPCRegion(
  3046. *this, S, EmitLValue(S.getIterationVariable()));
  3047. HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
  3048. EmitOMPReductionClauseInit(S, LoopScope);
  3049. EmitOMPPrivateLoopCounters(S, LoopScope);
  3050. EmitOMPLinearClause(S, LoopScope);
  3051. (void)LoopScope.Privatize();
  3052. if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
  3053. CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*this, S);
  3054. // Detect the loop schedule kind and chunk.
  3055. const Expr *ChunkExpr = nullptr;
  3056. OpenMPScheduleTy ScheduleKind;
  3057. if (const auto *C = S.getSingleClause<OMPScheduleClause>()) {
  3058. ScheduleKind.Schedule = C->getScheduleKind();
  3059. ScheduleKind.M1 = C->getFirstScheduleModifier();
  3060. ScheduleKind.M2 = C->getSecondScheduleModifier();
  3061. ChunkExpr = C->getChunkSize();
  3062. } else {
  3063. // Default behaviour for schedule clause.
  3064. CGM.getOpenMPRuntime().getDefaultScheduleAndChunk(
  3065. *this, S, ScheduleKind.Schedule, ChunkExpr);
  3066. }
  3067. bool HasChunkSizeOne = false;
  3068. llvm::Value *Chunk = nullptr;
  3069. if (ChunkExpr) {
  3070. Chunk = EmitScalarExpr(ChunkExpr);
  3071. Chunk = EmitScalarConversion(Chunk, ChunkExpr->getType(),
  3072. S.getIterationVariable()->getType(),
  3073. S.getBeginLoc());
  3074. Expr::EvalResult Result;
  3075. if (ChunkExpr->EvaluateAsInt(Result, getContext())) {
  3076. llvm::APSInt EvaluatedChunk = Result.Val.getInt();
  3077. HasChunkSizeOne = (EvaluatedChunk.getLimitedValue() == 1);
  3078. }
  3079. }
  3080. const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
  3081. const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
  3082. // OpenMP 4.5, 2.7.1 Loop Construct, Description.
  3083. // If the static schedule kind is specified or if the ordered clause is
  3084. // specified, and if no monotonic modifier is specified, the effect will
  3085. // be as if the monotonic modifier was specified.
  3086. bool StaticChunkedOne =
  3087. RT.isStaticChunked(ScheduleKind.Schedule,
  3088. /* Chunked */ Chunk != nullptr) &&
  3089. HasChunkSizeOne &&
  3090. isOpenMPLoopBoundSharingDirective(S.getDirectiveKind());
  3091. bool IsMonotonic =
  3092. Ordered ||
  3093. (ScheduleKind.Schedule == OMPC_SCHEDULE_static &&
  3094. !(ScheduleKind.M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
  3095. ScheduleKind.M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)) ||
  3096. ScheduleKind.M1 == OMPC_SCHEDULE_MODIFIER_monotonic ||
  3097. ScheduleKind.M2 == OMPC_SCHEDULE_MODIFIER_monotonic;
  3098. if ((RT.isStaticNonchunked(ScheduleKind.Schedule,
  3099. /* Chunked */ Chunk != nullptr) ||
  3100. StaticChunkedOne) &&
  3101. !Ordered) {
  3102. JumpDest LoopExit =
  3103. getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
  3104. emitCommonSimdLoop(
  3105. *this, S,
  3106. [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  3107. if (isOpenMPSimdDirective(S.getDirectiveKind())) {
  3108. CGF.EmitOMPSimdInit(S);
  3109. } else if (const auto *C = S.getSingleClause<OMPOrderClause>()) {
  3110. if (C->getKind() == OMPC_ORDER_concurrent)
  3111. CGF.LoopStack.setParallel(/*Enable=*/true);
  3112. }
  3113. },
  3114. [IVSize, IVSigned, Ordered, IL, LB, UB, ST, StaticChunkedOne, Chunk,
  3115. &S, ScheduleKind, LoopExit,
  3116. &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) {
  3117. // OpenMP [2.7.1, Loop Construct, Description, table 2-1]
  3118. // When no chunk_size is specified, the iteration space is divided
  3119. // into chunks that are approximately equal in size, and at most
  3120. // one chunk is distributed to each thread. Note that the size of
  3121. // the chunks is unspecified in this case.
  3122. CGOpenMPRuntime::StaticRTInput StaticInit(
  3123. IVSize, IVSigned, Ordered, IL.getAddress(CGF),
  3124. LB.getAddress(CGF), UB.getAddress(CGF), ST.getAddress(CGF),
  3125. StaticChunkedOne ? Chunk : nullptr);
  3126. CGF.CGM.getOpenMPRuntime().emitForStaticInit(
  3127. CGF, S.getBeginLoc(), S.getDirectiveKind(), ScheduleKind,
  3128. StaticInit);
  3129. // UB = min(UB, GlobalUB);
  3130. if (!StaticChunkedOne)
  3131. CGF.EmitIgnoredExpr(S.getEnsureUpperBound());
  3132. // IV = LB;
  3133. CGF.EmitIgnoredExpr(S.getInit());
  3134. // For unchunked static schedule generate:
  3135. //
  3136. // while (idx <= UB) {
  3137. // BODY;
  3138. // ++idx;
  3139. // }
  3140. //
  3141. // For static schedule with chunk one:
  3142. //
  3143. // while (IV <= PrevUB) {
  3144. // BODY;
  3145. // IV += ST;
  3146. // }
  3147. CGF.EmitOMPInnerLoop(
  3148. S, LoopScope.requiresCleanups(),
  3149. StaticChunkedOne ? S.getCombinedParForInDistCond()
  3150. : S.getCond(),
  3151. StaticChunkedOne ? S.getDistInc() : S.getInc(),
  3152. [&S, LoopExit](CodeGenFunction &CGF) {
  3153. emitOMPLoopBodyWithStopPoint(CGF, S, LoopExit);
  3154. },
  3155. [](CodeGenFunction &) {});
  3156. });
  3157. EmitBlock(LoopExit.getBlock());
  3158. // Tell the runtime we are done.
  3159. auto &&CodeGen = [&S](CodeGenFunction &CGF) {
  3160. CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
  3161. S.getDirectiveKind());
  3162. };
  3163. OMPCancelStack.emitExit(*this, S.getDirectiveKind(), CodeGen);
  3164. } else {
  3165. // Emit the outer loop, which requests its work chunk [LB..UB] from
  3166. // runtime and runs the inner loop to process it.
  3167. const OMPLoopArguments LoopArguments(
  3168. LB.getAddress(*this), UB.getAddress(*this), ST.getAddress(*this),
  3169. IL.getAddress(*this), Chunk, EUB);
  3170. EmitOMPForOuterLoop(ScheduleKind, IsMonotonic, S, LoopScope, Ordered,
  3171. LoopArguments, CGDispatchBounds);
  3172. }
  3173. if (isOpenMPSimdDirective(S.getDirectiveKind())) {
  3174. EmitOMPSimdFinal(S, [IL, &S](CodeGenFunction &CGF) {
  3175. return CGF.Builder.CreateIsNotNull(
  3176. CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
  3177. });
  3178. }
  3179. EmitOMPReductionClauseFinal(
  3180. S, /*ReductionKind=*/isOpenMPSimdDirective(S.getDirectiveKind())
  3181. ? /*Parallel and Simd*/ OMPD_parallel_for_simd
  3182. : /*Parallel only*/ OMPD_parallel);
  3183. // Emit post-update of the reduction variables if IsLastIter != 0.
  3184. emitPostUpdateForReductionClause(
  3185. *this, S, [IL, &S](CodeGenFunction &CGF) {
  3186. return CGF.Builder.CreateIsNotNull(
  3187. CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
  3188. });
  3189. // Emit final copy of the lastprivate variables if IsLastIter != 0.
  3190. if (HasLastprivateClause)
  3191. EmitOMPLastprivateClauseFinal(
  3192. S, isOpenMPSimdDirective(S.getDirectiveKind()),
  3193. Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getBeginLoc())));
  3194. }
  3195. EmitOMPLinearClauseFinal(S, [IL, &S](CodeGenFunction &CGF) {
  3196. return CGF.Builder.CreateIsNotNull(
  3197. CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
  3198. });
  3199. DoacrossCleanupScope.ForceCleanup();
  3200. // We're now done with the loop, so jump to the continuation block.
  3201. if (ContBlock) {
  3202. EmitBranch(ContBlock);
  3203. EmitBlock(ContBlock, /*IsFinished=*/true);
  3204. }
  3205. }
  3206. return HasLastprivateClause;
  3207. }
  3208. /// The following two functions generate expressions for the loop lower
  3209. /// and upper bounds in case of static and dynamic (dispatch) schedule
  3210. /// of the associated 'for' or 'distribute' loop.
  3211. static std::pair<LValue, LValue>
  3212. emitForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
  3213. const auto &LS = cast<OMPLoopDirective>(S);
  3214. LValue LB =
  3215. EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getLowerBoundVariable()));
  3216. LValue UB =
  3217. EmitOMPHelperVar(CGF, cast<DeclRefExpr>(LS.getUpperBoundVariable()));
  3218. return {LB, UB};
  3219. }
  3220. /// When dealing with dispatch schedules (e.g. dynamic, guided) we do not
  3221. /// consider the lower and upper bound expressions generated by the
  3222. /// worksharing loop support, but we use 0 and the iteration space size as
  3223. /// constants
  3224. static std::pair<llvm::Value *, llvm::Value *>
  3225. emitDispatchForLoopBounds(CodeGenFunction &CGF, const OMPExecutableDirective &S,
  3226. Address LB, Address UB) {
  3227. const auto &LS = cast<OMPLoopDirective>(S);
  3228. const Expr *IVExpr = LS.getIterationVariable();
  3229. const unsigned IVSize = CGF.getContext().getTypeSize(IVExpr->getType());
  3230. llvm::Value *LBVal = CGF.Builder.getIntN(IVSize, 0);
  3231. llvm::Value *UBVal = CGF.EmitScalarExpr(LS.getLastIteration());
  3232. return {LBVal, UBVal};
  3233. }
  3234. /// Emits internal temp array declarations for the directive with inscan
  3235. /// reductions.
  3236. /// The code is the following:
  3237. /// \code
  3238. /// size num_iters = <num_iters>;
  3239. /// <type> buffer[num_iters];
  3240. /// \endcode
  3241. static void emitScanBasedDirectiveDecls(
  3242. CodeGenFunction &CGF, const OMPLoopDirective &S,
  3243. llvm::function_ref<llvm::Value *(CodeGenFunction &)> NumIteratorsGen) {
  3244. llvm::Value *OMPScanNumIterations = CGF.Builder.CreateIntCast(
  3245. NumIteratorsGen(CGF), CGF.SizeTy, /*isSigned=*/false);
  3246. SmallVector<const Expr *, 4> Shareds;
  3247. SmallVector<const Expr *, 4> Privates;
  3248. SmallVector<const Expr *, 4> ReductionOps;
  3249. SmallVector<const Expr *, 4> CopyArrayTemps;
  3250. for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
  3251. assert(C->getModifier() == OMPC_REDUCTION_inscan &&
  3252. "Only inscan reductions are expected.");
  3253. Shareds.append(C->varlist_begin(), C->varlist_end());
  3254. Privates.append(C->privates().begin(), C->privates().end());
  3255. ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
  3256. CopyArrayTemps.append(C->copy_array_temps().begin(),
  3257. C->copy_array_temps().end());
  3258. }
  3259. {
  3260. // Emit buffers for each reduction variables.
  3261. // ReductionCodeGen is required to emit correctly the code for array
  3262. // reductions.
  3263. ReductionCodeGen RedCG(Shareds, Shareds, Privates, ReductionOps);
  3264. unsigned Count = 0;
  3265. auto *ITA = CopyArrayTemps.begin();
  3266. for (const Expr *IRef : Privates) {
  3267. const auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());
  3268. // Emit variably modified arrays, used for arrays/array sections
  3269. // reductions.
  3270. if (PrivateVD->getType()->isVariablyModifiedType()) {
  3271. RedCG.emitSharedOrigLValue(CGF, Count);
  3272. RedCG.emitAggregateType(CGF, Count);
  3273. }
  3274. CodeGenFunction::OpaqueValueMapping DimMapping(
  3275. CGF,
  3276. cast<OpaqueValueExpr>(
  3277. cast<VariableArrayType>((*ITA)->getType()->getAsArrayTypeUnsafe())
  3278. ->getSizeExpr()),
  3279. RValue::get(OMPScanNumIterations));
  3280. // Emit temp buffer.
  3281. CGF.EmitVarDecl(*cast<VarDecl>(cast<DeclRefExpr>(*ITA)->getDecl()));
  3282. ++ITA;
  3283. ++Count;
  3284. }
  3285. }
  3286. }
  3287. /// Emits the code for the directive with inscan reductions.
  3288. /// The code is the following:
  3289. /// \code
  3290. /// #pragma omp ...
  3291. /// for (i: 0..<num_iters>) {
  3292. /// <input phase>;
  3293. /// buffer[i] = red;
  3294. /// }
  3295. /// #pragma omp master // in parallel region
  3296. /// for (int k = 0; k != ceil(log2(num_iters)); ++k)
  3297. /// for (size cnt = last_iter; cnt >= pow(2, k); --k)
  3298. /// buffer[i] op= buffer[i-pow(2,k)];
  3299. /// #pragma omp barrier // in parallel region
  3300. /// #pragma omp ...
  3301. /// for (0..<num_iters>) {
  3302. /// red = InclusiveScan ? buffer[i] : buffer[i-1];
  3303. /// <scan phase>;
  3304. /// }
  3305. /// \endcode
  3306. static void emitScanBasedDirective(
  3307. CodeGenFunction &CGF, const OMPLoopDirective &S,
  3308. llvm::function_ref<llvm::Value *(CodeGenFunction &)> NumIteratorsGen,
  3309. llvm::function_ref<void(CodeGenFunction &)> FirstGen,
  3310. llvm::function_ref<void(CodeGenFunction &)> SecondGen) {
  3311. llvm::Value *OMPScanNumIterations = CGF.Builder.CreateIntCast(
  3312. NumIteratorsGen(CGF), CGF.SizeTy, /*isSigned=*/false);
  3313. SmallVector<const Expr *, 4> Privates;
  3314. SmallVector<const Expr *, 4> ReductionOps;
  3315. SmallVector<const Expr *, 4> LHSs;
  3316. SmallVector<const Expr *, 4> RHSs;
  3317. SmallVector<const Expr *, 4> CopyArrayElems;
  3318. for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
  3319. assert(C->getModifier() == OMPC_REDUCTION_inscan &&
  3320. "Only inscan reductions are expected.");
  3321. Privates.append(C->privates().begin(), C->privates().end());
  3322. ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
  3323. LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
  3324. RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
  3325. CopyArrayElems.append(C->copy_array_elems().begin(),
  3326. C->copy_array_elems().end());
  3327. }
  3328. CodeGenFunction::ParentLoopDirectiveForScanRegion ScanRegion(CGF, S);
  3329. {
  3330. // Emit loop with input phase:
  3331. // #pragma omp ...
  3332. // for (i: 0..<num_iters>) {
  3333. // <input phase>;
  3334. // buffer[i] = red;
  3335. // }
  3336. CGF.OMPFirstScanLoop = true;
  3337. CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
  3338. FirstGen(CGF);
  3339. }
  3340. // #pragma omp barrier // in parallel region
  3341. auto &&CodeGen = [&S, OMPScanNumIterations, &LHSs, &RHSs, &CopyArrayElems,
  3342. &ReductionOps,
  3343. &Privates](CodeGenFunction &CGF, PrePostActionTy &Action) {
  3344. Action.Enter(CGF);
  3345. // Emit prefix reduction:
  3346. // #pragma omp master // in parallel region
  3347. // for (int k = 0; k <= ceil(log2(n)); ++k)
  3348. llvm::BasicBlock *InputBB = CGF.Builder.GetInsertBlock();
  3349. llvm::BasicBlock *LoopBB = CGF.createBasicBlock("omp.outer.log.scan.body");
  3350. llvm::BasicBlock *ExitBB = CGF.createBasicBlock("omp.outer.log.scan.exit");
  3351. llvm::Function *F =
  3352. CGF.CGM.getIntrinsic(llvm::Intrinsic::log2, CGF.DoubleTy);
  3353. llvm::Value *Arg =
  3354. CGF.Builder.CreateUIToFP(OMPScanNumIterations, CGF.DoubleTy);
  3355. llvm::Value *LogVal = CGF.EmitNounwindRuntimeCall(F, Arg);
  3356. F = CGF.CGM.getIntrinsic(llvm::Intrinsic::ceil, CGF.DoubleTy);
  3357. LogVal = CGF.EmitNounwindRuntimeCall(F, LogVal);
  3358. LogVal = CGF.Builder.CreateFPToUI(LogVal, CGF.IntTy);
  3359. llvm::Value *NMin1 = CGF.Builder.CreateNUWSub(
  3360. OMPScanNumIterations, llvm::ConstantInt::get(CGF.SizeTy, 1));
  3361. auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, S.getBeginLoc());
  3362. CGF.EmitBlock(LoopBB);
  3363. auto *Counter = CGF.Builder.CreatePHI(CGF.IntTy, 2);
  3364. // size pow2k = 1;
  3365. auto *Pow2K = CGF.Builder.CreatePHI(CGF.SizeTy, 2);
  3366. Counter->addIncoming(llvm::ConstantInt::get(CGF.IntTy, 0), InputBB);
  3367. Pow2K->addIncoming(llvm::ConstantInt::get(CGF.SizeTy, 1), InputBB);
  3368. // for (size i = n - 1; i >= 2 ^ k; --i)
  3369. // tmp[i] op= tmp[i-pow2k];
  3370. llvm::BasicBlock *InnerLoopBB =
  3371. CGF.createBasicBlock("omp.inner.log.scan.body");
  3372. llvm::BasicBlock *InnerExitBB =
  3373. CGF.createBasicBlock("omp.inner.log.scan.exit");
  3374. llvm::Value *CmpI = CGF.Builder.CreateICmpUGE(NMin1, Pow2K);
  3375. CGF.Builder.CreateCondBr(CmpI, InnerLoopBB, InnerExitBB);
  3376. CGF.EmitBlock(InnerLoopBB);
  3377. auto *IVal = CGF.Builder.CreatePHI(CGF.SizeTy, 2);
  3378. IVal->addIncoming(NMin1, LoopBB);
  3379. {
  3380. CodeGenFunction::OMPPrivateScope PrivScope(CGF);
  3381. auto *ILHS = LHSs.begin();
  3382. auto *IRHS = RHSs.begin();
  3383. for (const Expr *CopyArrayElem : CopyArrayElems) {
  3384. const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
  3385. const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
  3386. Address LHSAddr = Address::invalid();
  3387. {
  3388. CodeGenFunction::OpaqueValueMapping IdxMapping(
  3389. CGF,
  3390. cast<OpaqueValueExpr>(
  3391. cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
  3392. RValue::get(IVal));
  3393. LHSAddr = CGF.EmitLValue(CopyArrayElem).getAddress(CGF);
  3394. }
  3395. PrivScope.addPrivate(LHSVD, [LHSAddr]() { return LHSAddr; });
  3396. Address RHSAddr = Address::invalid();
  3397. {
  3398. llvm::Value *OffsetIVal = CGF.Builder.CreateNUWSub(IVal, Pow2K);
  3399. CodeGenFunction::OpaqueValueMapping IdxMapping(
  3400. CGF,
  3401. cast<OpaqueValueExpr>(
  3402. cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
  3403. RValue::get(OffsetIVal));
  3404. RHSAddr = CGF.EmitLValue(CopyArrayElem).getAddress(CGF);
  3405. }
  3406. PrivScope.addPrivate(RHSVD, [RHSAddr]() { return RHSAddr; });
  3407. ++ILHS;
  3408. ++IRHS;
  3409. }
  3410. PrivScope.Privatize();
  3411. CGF.CGM.getOpenMPRuntime().emitReduction(
  3412. CGF, S.getEndLoc(), Privates, LHSs, RHSs, ReductionOps,
  3413. {/*WithNowait=*/true, /*SimpleReduction=*/true, OMPD_unknown});
  3414. }
  3415. llvm::Value *NextIVal =
  3416. CGF.Builder.CreateNUWSub(IVal, llvm::ConstantInt::get(CGF.SizeTy, 1));
  3417. IVal->addIncoming(NextIVal, CGF.Builder.GetInsertBlock());
  3418. CmpI = CGF.Builder.CreateICmpUGE(NextIVal, Pow2K);
  3419. CGF.Builder.CreateCondBr(CmpI, InnerLoopBB, InnerExitBB);
  3420. CGF.EmitBlock(InnerExitBB);
  3421. llvm::Value *Next =
  3422. CGF.Builder.CreateNUWAdd(Counter, llvm::ConstantInt::get(CGF.IntTy, 1));
  3423. Counter->addIncoming(Next, CGF.Builder.GetInsertBlock());
  3424. // pow2k <<= 1;
  3425. llvm::Value *NextPow2K =
  3426. CGF.Builder.CreateShl(Pow2K, 1, "", /*HasNUW=*/true);
  3427. Pow2K->addIncoming(NextPow2K, CGF.Builder.GetInsertBlock());
  3428. llvm::Value *Cmp = CGF.Builder.CreateICmpNE(Next, LogVal);
  3429. CGF.Builder.CreateCondBr(Cmp, LoopBB, ExitBB);
  3430. auto DL1 = ApplyDebugLocation::CreateDefaultArtificial(CGF, S.getEndLoc());
  3431. CGF.EmitBlock(ExitBB);
  3432. };
  3433. if (isOpenMPParallelDirective(S.getDirectiveKind())) {
  3434. CGF.CGM.getOpenMPRuntime().emitMasterRegion(CGF, CodeGen, S.getBeginLoc());
  3435. CGF.CGM.getOpenMPRuntime().emitBarrierCall(
  3436. CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
  3437. /*ForceSimpleCall=*/true);
  3438. } else {
  3439. RegionCodeGenTy RCG(CodeGen);
  3440. RCG(CGF);
  3441. }
  3442. CGF.OMPFirstScanLoop = false;
  3443. SecondGen(CGF);
  3444. }
  3445. static bool emitWorksharingDirective(CodeGenFunction &CGF,
  3446. const OMPLoopDirective &S,
  3447. bool HasCancel) {
  3448. bool HasLastprivates;
  3449. if (llvm::any_of(S.getClausesOfKind<OMPReductionClause>(),
  3450. [](const OMPReductionClause *C) {
  3451. return C->getModifier() == OMPC_REDUCTION_inscan;
  3452. })) {
  3453. const auto &&NumIteratorsGen = [&S](CodeGenFunction &CGF) {
  3454. CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
  3455. OMPLoopScope LoopScope(CGF, S);
  3456. return CGF.EmitScalarExpr(S.getNumIterations());
  3457. };
  3458. const auto &&FirstGen = [&S, HasCancel](CodeGenFunction &CGF) {
  3459. CodeGenFunction::OMPCancelStackRAII CancelRegion(
  3460. CGF, S.getDirectiveKind(), HasCancel);
  3461. (void)CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(),
  3462. emitForLoopBounds,
  3463. emitDispatchForLoopBounds);
  3464. // Emit an implicit barrier at the end.
  3465. CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getBeginLoc(),
  3466. OMPD_for);
  3467. };
  3468. const auto &&SecondGen = [&S, HasCancel,
  3469. &HasLastprivates](CodeGenFunction &CGF) {
  3470. CodeGenFunction::OMPCancelStackRAII CancelRegion(
  3471. CGF, S.getDirectiveKind(), HasCancel);
  3472. HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(),
  3473. emitForLoopBounds,
  3474. emitDispatchForLoopBounds);
  3475. };
  3476. if (!isOpenMPParallelDirective(S.getDirectiveKind()))
  3477. emitScanBasedDirectiveDecls(CGF, S, NumIteratorsGen);
  3478. emitScanBasedDirective(CGF, S, NumIteratorsGen, FirstGen, SecondGen);
  3479. } else {
  3480. CodeGenFunction::OMPCancelStackRAII CancelRegion(CGF, S.getDirectiveKind(),
  3481. HasCancel);
  3482. HasLastprivates = CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(),
  3483. emitForLoopBounds,
  3484. emitDispatchForLoopBounds);
  3485. }
  3486. return HasLastprivates;
  3487. }
  3488. static bool isSupportedByOpenMPIRBuilder(const OMPForDirective &S) {
  3489. if (S.hasCancel())
  3490. return false;
  3491. for (OMPClause *C : S.clauses())
  3492. if (!isa<OMPNowaitClause>(C))
  3493. return false;
  3494. return true;
  3495. }
  3496. void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
  3497. bool HasLastprivates = false;
  3498. bool UseOMPIRBuilder =
  3499. CGM.getLangOpts().OpenMPIRBuilder && isSupportedByOpenMPIRBuilder(S);
  3500. auto &&CodeGen = [this, &S, &HasLastprivates,
  3501. UseOMPIRBuilder](CodeGenFunction &CGF, PrePostActionTy &) {
  3502. // Use the OpenMPIRBuilder if enabled.
  3503. if (UseOMPIRBuilder) {
  3504. // Emit the associated statement and get its loop representation.
  3505. const Stmt *Inner = S.getRawStmt();
  3506. llvm::CanonicalLoopInfo *CLI =
  3507. EmitOMPCollapsedCanonicalLoopNest(Inner, 1);
  3508. bool NeedsBarrier = !S.getSingleClause<OMPNowaitClause>();
  3509. llvm::OpenMPIRBuilder &OMPBuilder =
  3510. CGM.getOpenMPRuntime().getOMPBuilder();
  3511. llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(
  3512. AllocaInsertPt->getParent(), AllocaInsertPt->getIterator());
  3513. OMPBuilder.applyWorkshareLoop(Builder.getCurrentDebugLocation(), CLI,
  3514. AllocaIP, NeedsBarrier);
  3515. return;
  3516. }
  3517. HasLastprivates = emitWorksharingDirective(CGF, S, S.hasCancel());
  3518. };
  3519. {
  3520. auto LPCRegion =
  3521. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  3522. OMPLexicalScope Scope(*this, S, OMPD_unknown);
  3523. CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen,
  3524. S.hasCancel());
  3525. }
  3526. if (!UseOMPIRBuilder) {
  3527. // Emit an implicit barrier at the end.
  3528. if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates)
  3529. CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_for);
  3530. }
  3531. // Check for outer lastprivate conditional update.
  3532. checkForLastprivateConditionalUpdate(*this, S);
  3533. }
  3534. void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) {
  3535. bool HasLastprivates = false;
  3536. auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF,
  3537. PrePostActionTy &) {
  3538. HasLastprivates = emitWorksharingDirective(CGF, S, /*HasCancel=*/false);
  3539. };
  3540. {
  3541. auto LPCRegion =
  3542. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  3543. OMPLexicalScope Scope(*this, S, OMPD_unknown);
  3544. CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
  3545. }
  3546. // Emit an implicit barrier at the end.
  3547. if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates)
  3548. CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_for);
  3549. // Check for outer lastprivate conditional update.
  3550. checkForLastprivateConditionalUpdate(*this, S);
  3551. }
  3552. static LValue createSectionLVal(CodeGenFunction &CGF, QualType Ty,
  3553. const Twine &Name,
  3554. llvm::Value *Init = nullptr) {
  3555. LValue LVal = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty, Name), Ty);
  3556. if (Init)
  3557. CGF.EmitStoreThroughLValue(RValue::get(Init), LVal, /*isInit*/ true);
  3558. return LVal;
  3559. }
  3560. void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
  3561. const Stmt *CapturedStmt = S.getInnermostCapturedStmt()->getCapturedStmt();
  3562. const auto *CS = dyn_cast<CompoundStmt>(CapturedStmt);
  3563. bool HasLastprivates = false;
  3564. auto &&CodeGen = [&S, CapturedStmt, CS,
  3565. &HasLastprivates](CodeGenFunction &CGF, PrePostActionTy &) {
  3566. const ASTContext &C = CGF.getContext();
  3567. QualType KmpInt32Ty =
  3568. C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
  3569. // Emit helper vars inits.
  3570. LValue LB = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.lb.",
  3571. CGF.Builder.getInt32(0));
  3572. llvm::ConstantInt *GlobalUBVal = CS != nullptr
  3573. ? CGF.Builder.getInt32(CS->size() - 1)
  3574. : CGF.Builder.getInt32(0);
  3575. LValue UB =
  3576. createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.ub.", GlobalUBVal);
  3577. LValue ST = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.st.",
  3578. CGF.Builder.getInt32(1));
  3579. LValue IL = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.il.",
  3580. CGF.Builder.getInt32(0));
  3581. // Loop counter.
  3582. LValue IV = createSectionLVal(CGF, KmpInt32Ty, ".omp.sections.iv.");
  3583. OpaqueValueExpr IVRefExpr(S.getBeginLoc(), KmpInt32Ty, VK_LValue);
  3584. CodeGenFunction::OpaqueValueMapping OpaqueIV(CGF, &IVRefExpr, IV);
  3585. OpaqueValueExpr UBRefExpr(S.getBeginLoc(), KmpInt32Ty, VK_LValue);
  3586. CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
  3587. // Generate condition for loop.
  3588. BinaryOperator *Cond = BinaryOperator::Create(
  3589. C, &IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_PRValue, OK_Ordinary,
  3590. S.getBeginLoc(), FPOptionsOverride());
  3591. // Increment for loop counter.
  3592. UnaryOperator *Inc = UnaryOperator::Create(
  3593. C, &IVRefExpr, UO_PreInc, KmpInt32Ty, VK_PRValue, OK_Ordinary,
  3594. S.getBeginLoc(), true, FPOptionsOverride());
  3595. auto &&BodyGen = [CapturedStmt, CS, &S, &IV](CodeGenFunction &CGF) {
  3596. // Iterate through all sections and emit a switch construct:
  3597. // switch (IV) {
  3598. // case 0:
  3599. // <SectionStmt[0]>;
  3600. // break;
  3601. // ...
  3602. // case <NumSection> - 1:
  3603. // <SectionStmt[<NumSection> - 1]>;
  3604. // break;
  3605. // }
  3606. // .omp.sections.exit:
  3607. llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".omp.sections.exit");
  3608. llvm::SwitchInst *SwitchStmt =
  3609. CGF.Builder.CreateSwitch(CGF.EmitLoadOfScalar(IV, S.getBeginLoc()),
  3610. ExitBB, CS == nullptr ? 1 : CS->size());
  3611. if (CS) {
  3612. unsigned CaseNumber = 0;
  3613. for (const Stmt *SubStmt : CS->children()) {
  3614. auto CaseBB = CGF.createBasicBlock(".omp.sections.case");
  3615. CGF.EmitBlock(CaseBB);
  3616. SwitchStmt->addCase(CGF.Builder.getInt32(CaseNumber), CaseBB);
  3617. CGF.EmitStmt(SubStmt);
  3618. CGF.EmitBranch(ExitBB);
  3619. ++CaseNumber;
  3620. }
  3621. } else {
  3622. llvm::BasicBlock *CaseBB = CGF.createBasicBlock(".omp.sections.case");
  3623. CGF.EmitBlock(CaseBB);
  3624. SwitchStmt->addCase(CGF.Builder.getInt32(0), CaseBB);
  3625. CGF.EmitStmt(CapturedStmt);
  3626. CGF.EmitBranch(ExitBB);
  3627. }
  3628. CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
  3629. };
  3630. CodeGenFunction::OMPPrivateScope LoopScope(CGF);
  3631. if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) {
  3632. // Emit implicit barrier to synchronize threads and avoid data races on
  3633. // initialization of firstprivate variables and post-update of lastprivate
  3634. // variables.
  3635. CGF.CGM.getOpenMPRuntime().emitBarrierCall(
  3636. CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
  3637. /*ForceSimpleCall=*/true);
  3638. }
  3639. CGF.EmitOMPPrivateClause(S, LoopScope);
  3640. CGOpenMPRuntime::LastprivateConditionalRAII LPCRegion(CGF, S, IV);
  3641. HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
  3642. CGF.EmitOMPReductionClauseInit(S, LoopScope);
  3643. (void)LoopScope.Privatize();
  3644. if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
  3645. CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
  3646. // Emit static non-chunked loop.
  3647. OpenMPScheduleTy ScheduleKind;
  3648. ScheduleKind.Schedule = OMPC_SCHEDULE_static;
  3649. CGOpenMPRuntime::StaticRTInput StaticInit(
  3650. /*IVSize=*/32, /*IVSigned=*/true, /*Ordered=*/false, IL.getAddress(CGF),
  3651. LB.getAddress(CGF), UB.getAddress(CGF), ST.getAddress(CGF));
  3652. CGF.CGM.getOpenMPRuntime().emitForStaticInit(
  3653. CGF, S.getBeginLoc(), S.getDirectiveKind(), ScheduleKind, StaticInit);
  3654. // UB = min(UB, GlobalUB);
  3655. llvm::Value *UBVal = CGF.EmitLoadOfScalar(UB, S.getBeginLoc());
  3656. llvm::Value *MinUBGlobalUB = CGF.Builder.CreateSelect(
  3657. CGF.Builder.CreateICmpSLT(UBVal, GlobalUBVal), UBVal, GlobalUBVal);
  3658. CGF.EmitStoreOfScalar(MinUBGlobalUB, UB);
  3659. // IV = LB;
  3660. CGF.EmitStoreOfScalar(CGF.EmitLoadOfScalar(LB, S.getBeginLoc()), IV);
  3661. // while (idx <= UB) { BODY; ++idx; }
  3662. CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, Cond, Inc, BodyGen,
  3663. [](CodeGenFunction &) {});
  3664. // Tell the runtime we are done.
  3665. auto &&CodeGen = [&S](CodeGenFunction &CGF) {
  3666. CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getEndLoc(),
  3667. S.getDirectiveKind());
  3668. };
  3669. CGF.OMPCancelStack.emitExit(CGF, S.getDirectiveKind(), CodeGen);
  3670. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
  3671. // Emit post-update of the reduction variables if IsLastIter != 0.
  3672. emitPostUpdateForReductionClause(CGF, S, [IL, &S](CodeGenFunction &CGF) {
  3673. return CGF.Builder.CreateIsNotNull(
  3674. CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
  3675. });
  3676. // Emit final copy of the lastprivate variables if IsLastIter != 0.
  3677. if (HasLastprivates)
  3678. CGF.EmitOMPLastprivateClauseFinal(
  3679. S, /*NoFinals=*/false,
  3680. CGF.Builder.CreateIsNotNull(
  3681. CGF.EmitLoadOfScalar(IL, S.getBeginLoc())));
  3682. };
  3683. bool HasCancel = false;
  3684. if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S))
  3685. HasCancel = OSD->hasCancel();
  3686. else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S))
  3687. HasCancel = OPSD->hasCancel();
  3688. OMPCancelStackRAII CancelRegion(*this, S.getDirectiveKind(), HasCancel);
  3689. CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen,
  3690. HasCancel);
  3691. // Emit barrier for lastprivates only if 'sections' directive has 'nowait'
  3692. // clause. Otherwise the barrier will be generated by the codegen for the
  3693. // directive.
  3694. if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
  3695. // Emit implicit barrier to synchronize threads and avoid data races on
  3696. // initialization of firstprivate variables.
  3697. CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(),
  3698. OMPD_unknown);
  3699. }
  3700. }
  3701. void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
  3702. if (CGM.getLangOpts().OpenMPIRBuilder) {
  3703. llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  3704. using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
  3705. using BodyGenCallbackTy = llvm::OpenMPIRBuilder::StorableBodyGenCallbackTy;
  3706. auto FiniCB = [this](InsertPointTy IP) {
  3707. OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
  3708. };
  3709. const CapturedStmt *ICS = S.getInnermostCapturedStmt();
  3710. const Stmt *CapturedStmt = S.getInnermostCapturedStmt()->getCapturedStmt();
  3711. const auto *CS = dyn_cast<CompoundStmt>(CapturedStmt);
  3712. llvm::SmallVector<BodyGenCallbackTy, 4> SectionCBVector;
  3713. if (CS) {
  3714. for (const Stmt *SubStmt : CS->children()) {
  3715. auto SectionCB = [this, SubStmt](InsertPointTy AllocaIP,
  3716. InsertPointTy CodeGenIP,
  3717. llvm::BasicBlock &FiniBB) {
  3718. OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP,
  3719. FiniBB);
  3720. OMPBuilderCBHelpers::EmitOMPRegionBody(*this, SubStmt, CodeGenIP,
  3721. FiniBB);
  3722. };
  3723. SectionCBVector.push_back(SectionCB);
  3724. }
  3725. } else {
  3726. auto SectionCB = [this, CapturedStmt](InsertPointTy AllocaIP,
  3727. InsertPointTy CodeGenIP,
  3728. llvm::BasicBlock &FiniBB) {
  3729. OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP, FiniBB);
  3730. OMPBuilderCBHelpers::EmitOMPRegionBody(*this, CapturedStmt, CodeGenIP,
  3731. FiniBB);
  3732. };
  3733. SectionCBVector.push_back(SectionCB);
  3734. }
  3735. // Privatization callback that performs appropriate action for
  3736. // shared/private/firstprivate/lastprivate/copyin/... variables.
  3737. //
  3738. // TODO: This defaults to shared right now.
  3739. auto PrivCB = [](InsertPointTy AllocaIP, InsertPointTy CodeGenIP,
  3740. llvm::Value &, llvm::Value &Val, llvm::Value *&ReplVal) {
  3741. // The next line is appropriate only for variables (Val) with the
  3742. // data-sharing attribute "shared".
  3743. ReplVal = &Val;
  3744. return CodeGenIP;
  3745. };
  3746. CGCapturedStmtInfo CGSI(*ICS, CR_OpenMP);
  3747. CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(*this, &CGSI);
  3748. llvm::OpenMPIRBuilder::InsertPointTy AllocaIP(
  3749. AllocaInsertPt->getParent(), AllocaInsertPt->getIterator());
  3750. Builder.restoreIP(OMPBuilder.createSections(
  3751. Builder, AllocaIP, SectionCBVector, PrivCB, FiniCB, S.hasCancel(),
  3752. S.getSingleClause<OMPNowaitClause>()));
  3753. return;
  3754. }
  3755. {
  3756. auto LPCRegion =
  3757. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  3758. OMPLexicalScope Scope(*this, S, OMPD_unknown);
  3759. EmitSections(S);
  3760. }
  3761. // Emit an implicit barrier at the end.
  3762. if (!S.getSingleClause<OMPNowaitClause>()) {
  3763. CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(),
  3764. OMPD_sections);
  3765. }
  3766. // Check for outer lastprivate conditional update.
  3767. checkForLastprivateConditionalUpdate(*this, S);
  3768. }
  3769. void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) {
  3770. if (CGM.getLangOpts().OpenMPIRBuilder) {
  3771. llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  3772. using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
  3773. const Stmt *SectionRegionBodyStmt = S.getAssociatedStmt();
  3774. auto FiniCB = [this](InsertPointTy IP) {
  3775. OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
  3776. };
  3777. auto BodyGenCB = [SectionRegionBodyStmt, this](InsertPointTy AllocaIP,
  3778. InsertPointTy CodeGenIP,
  3779. llvm::BasicBlock &FiniBB) {
  3780. OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP, FiniBB);
  3781. OMPBuilderCBHelpers::EmitOMPRegionBody(*this, SectionRegionBodyStmt,
  3782. CodeGenIP, FiniBB);
  3783. };
  3784. LexicalScope Scope(*this, S.getSourceRange());
  3785. EmitStopPoint(&S);
  3786. Builder.restoreIP(OMPBuilder.createSection(Builder, BodyGenCB, FiniCB));
  3787. return;
  3788. }
  3789. LexicalScope Scope(*this, S.getSourceRange());
  3790. EmitStopPoint(&S);
  3791. EmitStmt(S.getAssociatedStmt());
  3792. }
  3793. void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
  3794. llvm::SmallVector<const Expr *, 8> CopyprivateVars;
  3795. llvm::SmallVector<const Expr *, 8> DestExprs;
  3796. llvm::SmallVector<const Expr *, 8> SrcExprs;
  3797. llvm::SmallVector<const Expr *, 8> AssignmentOps;
  3798. // Check if there are any 'copyprivate' clauses associated with this
  3799. // 'single' construct.
  3800. // Build a list of copyprivate variables along with helper expressions
  3801. // (<source>, <destination>, <destination>=<source> expressions)
  3802. for (const auto *C : S.getClausesOfKind<OMPCopyprivateClause>()) {
  3803. CopyprivateVars.append(C->varlists().begin(), C->varlists().end());
  3804. DestExprs.append(C->destination_exprs().begin(),
  3805. C->destination_exprs().end());
  3806. SrcExprs.append(C->source_exprs().begin(), C->source_exprs().end());
  3807. AssignmentOps.append(C->assignment_ops().begin(),
  3808. C->assignment_ops().end());
  3809. }
  3810. // Emit code for 'single' region along with 'copyprivate' clauses
  3811. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  3812. Action.Enter(CGF);
  3813. OMPPrivateScope SingleScope(CGF);
  3814. (void)CGF.EmitOMPFirstprivateClause(S, SingleScope);
  3815. CGF.EmitOMPPrivateClause(S, SingleScope);
  3816. (void)SingleScope.Privatize();
  3817. CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
  3818. };
  3819. {
  3820. auto LPCRegion =
  3821. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  3822. OMPLexicalScope Scope(*this, S, OMPD_unknown);
  3823. CGM.getOpenMPRuntime().emitSingleRegion(*this, CodeGen, S.getBeginLoc(),
  3824. CopyprivateVars, DestExprs,
  3825. SrcExprs, AssignmentOps);
  3826. }
  3827. // Emit an implicit barrier at the end (to avoid data race on firstprivate
  3828. // init or if no 'nowait' clause was specified and no 'copyprivate' clause).
  3829. if (!S.getSingleClause<OMPNowaitClause>() && CopyprivateVars.empty()) {
  3830. CGM.getOpenMPRuntime().emitBarrierCall(
  3831. *this, S.getBeginLoc(),
  3832. S.getSingleClause<OMPNowaitClause>() ? OMPD_unknown : OMPD_single);
  3833. }
  3834. // Check for outer lastprivate conditional update.
  3835. checkForLastprivateConditionalUpdate(*this, S);
  3836. }
  3837. static void emitMaster(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
  3838. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  3839. Action.Enter(CGF);
  3840. CGF.EmitStmt(S.getRawStmt());
  3841. };
  3842. CGF.CGM.getOpenMPRuntime().emitMasterRegion(CGF, CodeGen, S.getBeginLoc());
  3843. }
  3844. void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &S) {
  3845. if (CGM.getLangOpts().OpenMPIRBuilder) {
  3846. llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  3847. using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
  3848. const Stmt *MasterRegionBodyStmt = S.getAssociatedStmt();
  3849. auto FiniCB = [this](InsertPointTy IP) {
  3850. OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
  3851. };
  3852. auto BodyGenCB = [MasterRegionBodyStmt, this](InsertPointTy AllocaIP,
  3853. InsertPointTy CodeGenIP,
  3854. llvm::BasicBlock &FiniBB) {
  3855. OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP, FiniBB);
  3856. OMPBuilderCBHelpers::EmitOMPRegionBody(*this, MasterRegionBodyStmt,
  3857. CodeGenIP, FiniBB);
  3858. };
  3859. LexicalScope Scope(*this, S.getSourceRange());
  3860. EmitStopPoint(&S);
  3861. Builder.restoreIP(OMPBuilder.createMaster(Builder, BodyGenCB, FiniCB));
  3862. return;
  3863. }
  3864. LexicalScope Scope(*this, S.getSourceRange());
  3865. EmitStopPoint(&S);
  3866. emitMaster(*this, S);
  3867. }
  3868. static void emitMasked(CodeGenFunction &CGF, const OMPExecutableDirective &S) {
  3869. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  3870. Action.Enter(CGF);
  3871. CGF.EmitStmt(S.getRawStmt());
  3872. };
  3873. Expr *Filter = nullptr;
  3874. if (const auto *FilterClause = S.getSingleClause<OMPFilterClause>())
  3875. Filter = FilterClause->getThreadID();
  3876. CGF.CGM.getOpenMPRuntime().emitMaskedRegion(CGF, CodeGen, S.getBeginLoc(),
  3877. Filter);
  3878. }
  3879. void CodeGenFunction::EmitOMPMaskedDirective(const OMPMaskedDirective &S) {
  3880. if (CGM.getLangOpts().OpenMPIRBuilder) {
  3881. llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  3882. using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
  3883. const Stmt *MaskedRegionBodyStmt = S.getAssociatedStmt();
  3884. const Expr *Filter = nullptr;
  3885. if (const auto *FilterClause = S.getSingleClause<OMPFilterClause>())
  3886. Filter = FilterClause->getThreadID();
  3887. llvm::Value *FilterVal = Filter
  3888. ? EmitScalarExpr(Filter, CGM.Int32Ty)
  3889. : llvm::ConstantInt::get(CGM.Int32Ty, /*V=*/0);
  3890. auto FiniCB = [this](InsertPointTy IP) {
  3891. OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
  3892. };
  3893. auto BodyGenCB = [MaskedRegionBodyStmt, this](InsertPointTy AllocaIP,
  3894. InsertPointTy CodeGenIP,
  3895. llvm::BasicBlock &FiniBB) {
  3896. OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP, FiniBB);
  3897. OMPBuilderCBHelpers::EmitOMPRegionBody(*this, MaskedRegionBodyStmt,
  3898. CodeGenIP, FiniBB);
  3899. };
  3900. LexicalScope Scope(*this, S.getSourceRange());
  3901. EmitStopPoint(&S);
  3902. Builder.restoreIP(
  3903. OMPBuilder.createMasked(Builder, BodyGenCB, FiniCB, FilterVal));
  3904. return;
  3905. }
  3906. LexicalScope Scope(*this, S.getSourceRange());
  3907. EmitStopPoint(&S);
  3908. emitMasked(*this, S);
  3909. }
  3910. void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
  3911. if (CGM.getLangOpts().OpenMPIRBuilder) {
  3912. llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  3913. using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
  3914. const Stmt *CriticalRegionBodyStmt = S.getAssociatedStmt();
  3915. const Expr *Hint = nullptr;
  3916. if (const auto *HintClause = S.getSingleClause<OMPHintClause>())
  3917. Hint = HintClause->getHint();
  3918. // TODO: This is slightly different from what's currently being done in
  3919. // clang. Fix the Int32Ty to IntPtrTy (pointer width size) when everything
  3920. // about typing is final.
  3921. llvm::Value *HintInst = nullptr;
  3922. if (Hint)
  3923. HintInst =
  3924. Builder.CreateIntCast(EmitScalarExpr(Hint), CGM.Int32Ty, false);
  3925. auto FiniCB = [this](InsertPointTy IP) {
  3926. OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
  3927. };
  3928. auto BodyGenCB = [CriticalRegionBodyStmt, this](InsertPointTy AllocaIP,
  3929. InsertPointTy CodeGenIP,
  3930. llvm::BasicBlock &FiniBB) {
  3931. OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP, FiniBB);
  3932. OMPBuilderCBHelpers::EmitOMPRegionBody(*this, CriticalRegionBodyStmt,
  3933. CodeGenIP, FiniBB);
  3934. };
  3935. LexicalScope Scope(*this, S.getSourceRange());
  3936. EmitStopPoint(&S);
  3937. Builder.restoreIP(OMPBuilder.createCritical(
  3938. Builder, BodyGenCB, FiniCB, S.getDirectiveName().getAsString(),
  3939. HintInst));
  3940. return;
  3941. }
  3942. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  3943. Action.Enter(CGF);
  3944. CGF.EmitStmt(S.getAssociatedStmt());
  3945. };
  3946. const Expr *Hint = nullptr;
  3947. if (const auto *HintClause = S.getSingleClause<OMPHintClause>())
  3948. Hint = HintClause->getHint();
  3949. LexicalScope Scope(*this, S.getSourceRange());
  3950. EmitStopPoint(&S);
  3951. CGM.getOpenMPRuntime().emitCriticalRegion(*this,
  3952. S.getDirectiveName().getAsString(),
  3953. CodeGen, S.getBeginLoc(), Hint);
  3954. }
  3955. void CodeGenFunction::EmitOMPParallelForDirective(
  3956. const OMPParallelForDirective &S) {
  3957. // Emit directive as a combined directive that consists of two implicit
  3958. // directives: 'parallel' with 'for' directive.
  3959. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  3960. Action.Enter(CGF);
  3961. (void)emitWorksharingDirective(CGF, S, S.hasCancel());
  3962. };
  3963. {
  3964. if (llvm::any_of(S.getClausesOfKind<OMPReductionClause>(),
  3965. [](const OMPReductionClause *C) {
  3966. return C->getModifier() == OMPC_REDUCTION_inscan;
  3967. })) {
  3968. const auto &&NumIteratorsGen = [&S](CodeGenFunction &CGF) {
  3969. CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
  3970. CGCapturedStmtInfo CGSI(CR_OpenMP);
  3971. CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGSI);
  3972. OMPLoopScope LoopScope(CGF, S);
  3973. return CGF.EmitScalarExpr(S.getNumIterations());
  3974. };
  3975. emitScanBasedDirectiveDecls(*this, S, NumIteratorsGen);
  3976. }
  3977. auto LPCRegion =
  3978. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  3979. emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen,
  3980. emitEmptyBoundParameters);
  3981. }
  3982. // Check for outer lastprivate conditional update.
  3983. checkForLastprivateConditionalUpdate(*this, S);
  3984. }
  3985. void CodeGenFunction::EmitOMPParallelForSimdDirective(
  3986. const OMPParallelForSimdDirective &S) {
  3987. // Emit directive as a combined directive that consists of two implicit
  3988. // directives: 'parallel' with 'for' directive.
  3989. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  3990. Action.Enter(CGF);
  3991. (void)emitWorksharingDirective(CGF, S, /*HasCancel=*/false);
  3992. };
  3993. {
  3994. if (llvm::any_of(S.getClausesOfKind<OMPReductionClause>(),
  3995. [](const OMPReductionClause *C) {
  3996. return C->getModifier() == OMPC_REDUCTION_inscan;
  3997. })) {
  3998. const auto &&NumIteratorsGen = [&S](CodeGenFunction &CGF) {
  3999. CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
  4000. CGCapturedStmtInfo CGSI(CR_OpenMP);
  4001. CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGSI);
  4002. OMPLoopScope LoopScope(CGF, S);
  4003. return CGF.EmitScalarExpr(S.getNumIterations());
  4004. };
  4005. emitScanBasedDirectiveDecls(*this, S, NumIteratorsGen);
  4006. }
  4007. auto LPCRegion =
  4008. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  4009. emitCommonOMPParallelDirective(*this, S, OMPD_for_simd, CodeGen,
  4010. emitEmptyBoundParameters);
  4011. }
  4012. // Check for outer lastprivate conditional update.
  4013. checkForLastprivateConditionalUpdate(*this, S);
  4014. }
  4015. void CodeGenFunction::EmitOMPParallelMasterDirective(
  4016. const OMPParallelMasterDirective &S) {
  4017. // Emit directive as a combined directive that consists of two implicit
  4018. // directives: 'parallel' with 'master' directive.
  4019. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  4020. Action.Enter(CGF);
  4021. OMPPrivateScope PrivateScope(CGF);
  4022. bool Copyins = CGF.EmitOMPCopyinClause(S);
  4023. (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
  4024. if (Copyins) {
  4025. // Emit implicit barrier to synchronize threads and avoid data races on
  4026. // propagation master's thread values of threadprivate variables to local
  4027. // instances of that variables of all other implicit threads.
  4028. CGF.CGM.getOpenMPRuntime().emitBarrierCall(
  4029. CGF, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
  4030. /*ForceSimpleCall=*/true);
  4031. }
  4032. CGF.EmitOMPPrivateClause(S, PrivateScope);
  4033. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  4034. (void)PrivateScope.Privatize();
  4035. emitMaster(CGF, S);
  4036. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
  4037. };
  4038. {
  4039. auto LPCRegion =
  4040. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  4041. emitCommonOMPParallelDirective(*this, S, OMPD_master, CodeGen,
  4042. emitEmptyBoundParameters);
  4043. emitPostUpdateForReductionClause(*this, S,
  4044. [](CodeGenFunction &) { return nullptr; });
  4045. }
  4046. // Check for outer lastprivate conditional update.
  4047. checkForLastprivateConditionalUpdate(*this, S);
  4048. }
  4049. void CodeGenFunction::EmitOMPParallelSectionsDirective(
  4050. const OMPParallelSectionsDirective &S) {
  4051. // Emit directive as a combined directive that consists of two implicit
  4052. // directives: 'parallel' with 'sections' directive.
  4053. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  4054. Action.Enter(CGF);
  4055. CGF.EmitSections(S);
  4056. };
  4057. {
  4058. auto LPCRegion =
  4059. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  4060. emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen,
  4061. emitEmptyBoundParameters);
  4062. }
  4063. // Check for outer lastprivate conditional update.
  4064. checkForLastprivateConditionalUpdate(*this, S);
  4065. }
  4066. namespace {
  4067. /// Get the list of variables declared in the context of the untied tasks.
  4068. class CheckVarsEscapingUntiedTaskDeclContext final
  4069. : public ConstStmtVisitor<CheckVarsEscapingUntiedTaskDeclContext> {
  4070. llvm::SmallVector<const VarDecl *, 4> PrivateDecls;
  4071. public:
  4072. explicit CheckVarsEscapingUntiedTaskDeclContext() = default;
  4073. virtual ~CheckVarsEscapingUntiedTaskDeclContext() = default;
  4074. void VisitDeclStmt(const DeclStmt *S) {
  4075. if (!S)
  4076. return;
  4077. // Need to privatize only local vars, static locals can be processed as is.
  4078. for (const Decl *D : S->decls()) {
  4079. if (const auto *VD = dyn_cast_or_null<VarDecl>(D))
  4080. if (VD->hasLocalStorage())
  4081. PrivateDecls.push_back(VD);
  4082. }
  4083. }
  4084. void VisitOMPExecutableDirective(const OMPExecutableDirective *) {}
  4085. void VisitCapturedStmt(const CapturedStmt *) {}
  4086. void VisitLambdaExpr(const LambdaExpr *) {}
  4087. void VisitBlockExpr(const BlockExpr *) {}
  4088. void VisitStmt(const Stmt *S) {
  4089. if (!S)
  4090. return;
  4091. for (const Stmt *Child : S->children())
  4092. if (Child)
  4093. Visit(Child);
  4094. }
  4095. /// Swaps list of vars with the provided one.
  4096. ArrayRef<const VarDecl *> getPrivateDecls() const { return PrivateDecls; }
  4097. };
  4098. } // anonymous namespace
  4099. void CodeGenFunction::EmitOMPTaskBasedDirective(
  4100. const OMPExecutableDirective &S, const OpenMPDirectiveKind CapturedRegion,
  4101. const RegionCodeGenTy &BodyGen, const TaskGenTy &TaskGen,
  4102. OMPTaskDataTy &Data) {
  4103. // Emit outlined function for task construct.
  4104. const CapturedStmt *CS = S.getCapturedStmt(CapturedRegion);
  4105. auto I = CS->getCapturedDecl()->param_begin();
  4106. auto PartId = std::next(I);
  4107. auto TaskT = std::next(I, 4);
  4108. // Check if the task is final
  4109. if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) {
  4110. // If the condition constant folds and can be elided, try to avoid emitting
  4111. // the condition and the dead arm of the if/else.
  4112. const Expr *Cond = Clause->getCondition();
  4113. bool CondConstant;
  4114. if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
  4115. Data.Final.setInt(CondConstant);
  4116. else
  4117. Data.Final.setPointer(EvaluateExprAsBool(Cond));
  4118. } else {
  4119. // By default the task is not final.
  4120. Data.Final.setInt(/*IntVal=*/false);
  4121. }
  4122. // Check if the task has 'priority' clause.
  4123. if (const auto *Clause = S.getSingleClause<OMPPriorityClause>()) {
  4124. const Expr *Prio = Clause->getPriority();
  4125. Data.Priority.setInt(/*IntVal=*/true);
  4126. Data.Priority.setPointer(EmitScalarConversion(
  4127. EmitScalarExpr(Prio), Prio->getType(),
  4128. getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1),
  4129. Prio->getExprLoc()));
  4130. }
  4131. // The first function argument for tasks is a thread id, the second one is a
  4132. // part id (0 for tied tasks, >=0 for untied task).
  4133. llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
  4134. // Get list of private variables.
  4135. for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) {
  4136. auto IRef = C->varlist_begin();
  4137. for (const Expr *IInit : C->private_copies()) {
  4138. const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
  4139. if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
  4140. Data.PrivateVars.push_back(*IRef);
  4141. Data.PrivateCopies.push_back(IInit);
  4142. }
  4143. ++IRef;
  4144. }
  4145. }
  4146. EmittedAsPrivate.clear();
  4147. // Get list of firstprivate variables.
  4148. for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
  4149. auto IRef = C->varlist_begin();
  4150. auto IElemInitRef = C->inits().begin();
  4151. for (const Expr *IInit : C->private_copies()) {
  4152. const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
  4153. if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
  4154. Data.FirstprivateVars.push_back(*IRef);
  4155. Data.FirstprivateCopies.push_back(IInit);
  4156. Data.FirstprivateInits.push_back(*IElemInitRef);
  4157. }
  4158. ++IRef;
  4159. ++IElemInitRef;
  4160. }
  4161. }
  4162. // Get list of lastprivate variables (for taskloops).
  4163. llvm::MapVector<const VarDecl *, const DeclRefExpr *> LastprivateDstsOrigs;
  4164. for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) {
  4165. auto IRef = C->varlist_begin();
  4166. auto ID = C->destination_exprs().begin();
  4167. for (const Expr *IInit : C->private_copies()) {
  4168. const auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
  4169. if (EmittedAsPrivate.insert(OrigVD->getCanonicalDecl()).second) {
  4170. Data.LastprivateVars.push_back(*IRef);
  4171. Data.LastprivateCopies.push_back(IInit);
  4172. }
  4173. LastprivateDstsOrigs.insert(
  4174. std::make_pair(cast<VarDecl>(cast<DeclRefExpr>(*ID)->getDecl()),
  4175. cast<DeclRefExpr>(*IRef)));
  4176. ++IRef;
  4177. ++ID;
  4178. }
  4179. }
  4180. SmallVector<const Expr *, 4> LHSs;
  4181. SmallVector<const Expr *, 4> RHSs;
  4182. for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
  4183. Data.ReductionVars.append(C->varlist_begin(), C->varlist_end());
  4184. Data.ReductionOrigs.append(C->varlist_begin(), C->varlist_end());
  4185. Data.ReductionCopies.append(C->privates().begin(), C->privates().end());
  4186. Data.ReductionOps.append(C->reduction_ops().begin(),
  4187. C->reduction_ops().end());
  4188. LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
  4189. RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
  4190. }
  4191. Data.Reductions = CGM.getOpenMPRuntime().emitTaskReductionInit(
  4192. *this, S.getBeginLoc(), LHSs, RHSs, Data);
  4193. // Build list of dependences.
  4194. for (const auto *C : S.getClausesOfKind<OMPDependClause>()) {
  4195. OMPTaskDataTy::DependData &DD =
  4196. Data.Dependences.emplace_back(C->getDependencyKind(), C->getModifier());
  4197. DD.DepExprs.append(C->varlist_begin(), C->varlist_end());
  4198. }
  4199. // Get list of local vars for untied tasks.
  4200. if (!Data.Tied) {
  4201. CheckVarsEscapingUntiedTaskDeclContext Checker;
  4202. Checker.Visit(S.getInnermostCapturedStmt()->getCapturedStmt());
  4203. Data.PrivateLocals.append(Checker.getPrivateDecls().begin(),
  4204. Checker.getPrivateDecls().end());
  4205. }
  4206. auto &&CodeGen = [&Data, &S, CS, &BodyGen, &LastprivateDstsOrigs,
  4207. CapturedRegion](CodeGenFunction &CGF,
  4208. PrePostActionTy &Action) {
  4209. llvm::MapVector<CanonicalDeclPtr<const VarDecl>,
  4210. std::pair<Address, Address>>
  4211. UntiedLocalVars;
  4212. // Set proper addresses for generated private copies.
  4213. OMPPrivateScope Scope(CGF);
  4214. // Generate debug info for variables present in shared clause.
  4215. if (auto *DI = CGF.getDebugInfo()) {
  4216. llvm::SmallDenseMap<const VarDecl *, FieldDecl *> CaptureFields =
  4217. CGF.CapturedStmtInfo->getCaptureFields();
  4218. llvm::Value *ContextValue = CGF.CapturedStmtInfo->getContextValue();
  4219. if (CaptureFields.size() && ContextValue) {
  4220. unsigned CharWidth = CGF.getContext().getCharWidth();
  4221. // The shared variables are packed together as members of structure.
  4222. // So the address of each shared variable can be computed by adding
  4223. // offset of it (within record) to the base address of record. For each
  4224. // shared variable, debug intrinsic llvm.dbg.declare is generated with
  4225. // appropriate expressions (DIExpression).
  4226. // Ex:
  4227. // %12 = load %struct.anon*, %struct.anon** %__context.addr.i
  4228. // call void @llvm.dbg.declare(metadata %struct.anon* %12,
  4229. // metadata !svar1,
  4230. // metadata !DIExpression(DW_OP_deref))
  4231. // call void @llvm.dbg.declare(metadata %struct.anon* %12,
  4232. // metadata !svar2,
  4233. // metadata !DIExpression(DW_OP_plus_uconst, 8, DW_OP_deref))
  4234. for (auto It = CaptureFields.begin(); It != CaptureFields.end(); ++It) {
  4235. const VarDecl *SharedVar = It->first;
  4236. RecordDecl *CaptureRecord = It->second->getParent();
  4237. const ASTRecordLayout &Layout =
  4238. CGF.getContext().getASTRecordLayout(CaptureRecord);
  4239. unsigned Offset =
  4240. Layout.getFieldOffset(It->second->getFieldIndex()) / CharWidth;
  4241. if (CGF.CGM.getCodeGenOpts().hasReducedDebugInfo())
  4242. (void)DI->EmitDeclareOfAutoVariable(SharedVar, ContextValue,
  4243. CGF.Builder, false);
  4244. llvm::Instruction &Last = CGF.Builder.GetInsertBlock()->back();
  4245. // Get the call dbg.declare instruction we just created and update
  4246. // its DIExpression to add offset to base address.
  4247. if (auto DDI = dyn_cast<llvm::DbgVariableIntrinsic>(&Last)) {
  4248. SmallVector<uint64_t, 8> Ops;
  4249. // Add offset to the base address if non zero.
  4250. if (Offset) {
  4251. Ops.push_back(llvm::dwarf::DW_OP_plus_uconst);
  4252. Ops.push_back(Offset);
  4253. }
  4254. Ops.push_back(llvm::dwarf::DW_OP_deref);
  4255. auto &Ctx = DDI->getContext();
  4256. llvm::DIExpression *DIExpr = llvm::DIExpression::get(Ctx, Ops);
  4257. Last.setOperand(2, llvm::MetadataAsValue::get(Ctx, DIExpr));
  4258. }
  4259. }
  4260. }
  4261. }
  4262. llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> FirstprivatePtrs;
  4263. if (!Data.PrivateVars.empty() || !Data.FirstprivateVars.empty() ||
  4264. !Data.LastprivateVars.empty() || !Data.PrivateLocals.empty()) {
  4265. enum { PrivatesParam = 2, CopyFnParam = 3 };
  4266. llvm::Value *CopyFn = CGF.Builder.CreateLoad(
  4267. CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
  4268. llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(
  4269. CS->getCapturedDecl()->getParam(PrivatesParam)));
  4270. // Map privates.
  4271. llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs;
  4272. llvm::SmallVector<llvm::Value *, 16> CallArgs;
  4273. llvm::SmallVector<llvm::Type *, 4> ParamTypes;
  4274. CallArgs.push_back(PrivatesPtr);
  4275. ParamTypes.push_back(PrivatesPtr->getType());
  4276. for (const Expr *E : Data.PrivateVars) {
  4277. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
  4278. Address PrivatePtr = CGF.CreateMemTemp(
  4279. CGF.getContext().getPointerType(E->getType()), ".priv.ptr.addr");
  4280. PrivatePtrs.emplace_back(VD, PrivatePtr);
  4281. CallArgs.push_back(PrivatePtr.getPointer());
  4282. ParamTypes.push_back(PrivatePtr.getType());
  4283. }
  4284. for (const Expr *E : Data.FirstprivateVars) {
  4285. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
  4286. Address PrivatePtr =
  4287. CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
  4288. ".firstpriv.ptr.addr");
  4289. PrivatePtrs.emplace_back(VD, PrivatePtr);
  4290. FirstprivatePtrs.emplace_back(VD, PrivatePtr);
  4291. CallArgs.push_back(PrivatePtr.getPointer());
  4292. ParamTypes.push_back(PrivatePtr.getType());
  4293. }
  4294. for (const Expr *E : Data.LastprivateVars) {
  4295. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
  4296. Address PrivatePtr =
  4297. CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
  4298. ".lastpriv.ptr.addr");
  4299. PrivatePtrs.emplace_back(VD, PrivatePtr);
  4300. CallArgs.push_back(PrivatePtr.getPointer());
  4301. ParamTypes.push_back(PrivatePtr.getType());
  4302. }
  4303. for (const VarDecl *VD : Data.PrivateLocals) {
  4304. QualType Ty = VD->getType().getNonReferenceType();
  4305. if (VD->getType()->isLValueReferenceType())
  4306. Ty = CGF.getContext().getPointerType(Ty);
  4307. if (isAllocatableDecl(VD))
  4308. Ty = CGF.getContext().getPointerType(Ty);
  4309. Address PrivatePtr = CGF.CreateMemTemp(
  4310. CGF.getContext().getPointerType(Ty), ".local.ptr.addr");
  4311. auto Result = UntiedLocalVars.insert(
  4312. std::make_pair(VD, std::make_pair(PrivatePtr, Address::invalid())));
  4313. // If key exists update in place.
  4314. if (Result.second == false)
  4315. *Result.first = std::make_pair(
  4316. VD, std::make_pair(PrivatePtr, Address::invalid()));
  4317. CallArgs.push_back(PrivatePtr.getPointer());
  4318. ParamTypes.push_back(PrivatePtr.getType());
  4319. }
  4320. auto *CopyFnTy = llvm::FunctionType::get(CGF.Builder.getVoidTy(),
  4321. ParamTypes, /*isVarArg=*/false);
  4322. CopyFn = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
  4323. CopyFn, CopyFnTy->getPointerTo());
  4324. CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
  4325. CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
  4326. for (const auto &Pair : LastprivateDstsOrigs) {
  4327. const auto *OrigVD = cast<VarDecl>(Pair.second->getDecl());
  4328. DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(OrigVD),
  4329. /*RefersToEnclosingVariableOrCapture=*/
  4330. CGF.CapturedStmtInfo->lookup(OrigVD) != nullptr,
  4331. Pair.second->getType(), VK_LValue,
  4332. Pair.second->getExprLoc());
  4333. Scope.addPrivate(Pair.first, [&CGF, &DRE]() {
  4334. return CGF.EmitLValue(&DRE).getAddress(CGF);
  4335. });
  4336. }
  4337. for (const auto &Pair : PrivatePtrs) {
  4338. Address Replacement(CGF.Builder.CreateLoad(Pair.second),
  4339. CGF.getContext().getDeclAlign(Pair.first));
  4340. Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
  4341. if (auto *DI = CGF.getDebugInfo())
  4342. if (CGF.CGM.getCodeGenOpts().hasReducedDebugInfo())
  4343. (void)DI->EmitDeclareOfAutoVariable(
  4344. Pair.first, Pair.second.getPointer(), CGF.Builder,
  4345. /*UsePointerValue*/ true);
  4346. }
  4347. // Adjust mapping for internal locals by mapping actual memory instead of
  4348. // a pointer to this memory.
  4349. for (auto &Pair : UntiedLocalVars) {
  4350. if (isAllocatableDecl(Pair.first)) {
  4351. llvm::Value *Ptr = CGF.Builder.CreateLoad(Pair.second.first);
  4352. Address Replacement(Ptr, CGF.getPointerAlign());
  4353. Pair.second.first = Replacement;
  4354. Ptr = CGF.Builder.CreateLoad(Replacement);
  4355. Replacement = Address(Ptr, CGF.getContext().getDeclAlign(Pair.first));
  4356. Pair.second.second = Replacement;
  4357. } else {
  4358. llvm::Value *Ptr = CGF.Builder.CreateLoad(Pair.second.first);
  4359. Address Replacement(Ptr, CGF.getContext().getDeclAlign(Pair.first));
  4360. Pair.second.first = Replacement;
  4361. }
  4362. }
  4363. }
  4364. if (Data.Reductions) {
  4365. OMPPrivateScope FirstprivateScope(CGF);
  4366. for (const auto &Pair : FirstprivatePtrs) {
  4367. Address Replacement(CGF.Builder.CreateLoad(Pair.second),
  4368. CGF.getContext().getDeclAlign(Pair.first));
  4369. FirstprivateScope.addPrivate(Pair.first,
  4370. [Replacement]() { return Replacement; });
  4371. }
  4372. (void)FirstprivateScope.Privatize();
  4373. OMPLexicalScope LexScope(CGF, S, CapturedRegion);
  4374. ReductionCodeGen RedCG(Data.ReductionVars, Data.ReductionVars,
  4375. Data.ReductionCopies, Data.ReductionOps);
  4376. llvm::Value *ReductionsPtr = CGF.Builder.CreateLoad(
  4377. CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(9)));
  4378. for (unsigned Cnt = 0, E = Data.ReductionVars.size(); Cnt < E; ++Cnt) {
  4379. RedCG.emitSharedOrigLValue(CGF, Cnt);
  4380. RedCG.emitAggregateType(CGF, Cnt);
  4381. // FIXME: This must removed once the runtime library is fixed.
  4382. // Emit required threadprivate variables for
  4383. // initializer/combiner/finalizer.
  4384. CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),
  4385. RedCG, Cnt);
  4386. Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
  4387. CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
  4388. Replacement =
  4389. Address(CGF.EmitScalarConversion(
  4390. Replacement.getPointer(), CGF.getContext().VoidPtrTy,
  4391. CGF.getContext().getPointerType(
  4392. Data.ReductionCopies[Cnt]->getType()),
  4393. Data.ReductionCopies[Cnt]->getExprLoc()),
  4394. Replacement.getAlignment());
  4395. Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
  4396. Scope.addPrivate(RedCG.getBaseDecl(Cnt),
  4397. [Replacement]() { return Replacement; });
  4398. }
  4399. }
  4400. // Privatize all private variables except for in_reduction items.
  4401. (void)Scope.Privatize();
  4402. SmallVector<const Expr *, 4> InRedVars;
  4403. SmallVector<const Expr *, 4> InRedPrivs;
  4404. SmallVector<const Expr *, 4> InRedOps;
  4405. SmallVector<const Expr *, 4> TaskgroupDescriptors;
  4406. for (const auto *C : S.getClausesOfKind<OMPInReductionClause>()) {
  4407. auto IPriv = C->privates().begin();
  4408. auto IRed = C->reduction_ops().begin();
  4409. auto ITD = C->taskgroup_descriptors().begin();
  4410. for (const Expr *Ref : C->varlists()) {
  4411. InRedVars.emplace_back(Ref);
  4412. InRedPrivs.emplace_back(*IPriv);
  4413. InRedOps.emplace_back(*IRed);
  4414. TaskgroupDescriptors.emplace_back(*ITD);
  4415. std::advance(IPriv, 1);
  4416. std::advance(IRed, 1);
  4417. std::advance(ITD, 1);
  4418. }
  4419. }
  4420. // Privatize in_reduction items here, because taskgroup descriptors must be
  4421. // privatized earlier.
  4422. OMPPrivateScope InRedScope(CGF);
  4423. if (!InRedVars.empty()) {
  4424. ReductionCodeGen RedCG(InRedVars, InRedVars, InRedPrivs, InRedOps);
  4425. for (unsigned Cnt = 0, E = InRedVars.size(); Cnt < E; ++Cnt) {
  4426. RedCG.emitSharedOrigLValue(CGF, Cnt);
  4427. RedCG.emitAggregateType(CGF, Cnt);
  4428. // The taskgroup descriptor variable is always implicit firstprivate and
  4429. // privatized already during processing of the firstprivates.
  4430. // FIXME: This must removed once the runtime library is fixed.
  4431. // Emit required threadprivate variables for
  4432. // initializer/combiner/finalizer.
  4433. CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getBeginLoc(),
  4434. RedCG, Cnt);
  4435. llvm::Value *ReductionsPtr;
  4436. if (const Expr *TRExpr = TaskgroupDescriptors[Cnt]) {
  4437. ReductionsPtr = CGF.EmitLoadOfScalar(CGF.EmitLValue(TRExpr),
  4438. TRExpr->getExprLoc());
  4439. } else {
  4440. ReductionsPtr = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
  4441. }
  4442. Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
  4443. CGF, S.getBeginLoc(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
  4444. Replacement = Address(
  4445. CGF.EmitScalarConversion(
  4446. Replacement.getPointer(), CGF.getContext().VoidPtrTy,
  4447. CGF.getContext().getPointerType(InRedPrivs[Cnt]->getType()),
  4448. InRedPrivs[Cnt]->getExprLoc()),
  4449. Replacement.getAlignment());
  4450. Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
  4451. InRedScope.addPrivate(RedCG.getBaseDecl(Cnt),
  4452. [Replacement]() { return Replacement; });
  4453. }
  4454. }
  4455. (void)InRedScope.Privatize();
  4456. CGOpenMPRuntime::UntiedTaskLocalDeclsRAII LocalVarsScope(CGF,
  4457. UntiedLocalVars);
  4458. Action.Enter(CGF);
  4459. BodyGen(CGF);
  4460. };
  4461. llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
  4462. S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, Data.Tied,
  4463. Data.NumberOfParts);
  4464. OMPLexicalScope Scope(*this, S, llvm::None,
  4465. !isOpenMPParallelDirective(S.getDirectiveKind()) &&
  4466. !isOpenMPSimdDirective(S.getDirectiveKind()));
  4467. TaskGen(*this, OutlinedFn, Data);
  4468. }
  4469. static ImplicitParamDecl *
  4470. createImplicitFirstprivateForType(ASTContext &C, OMPTaskDataTy &Data,
  4471. QualType Ty, CapturedDecl *CD,
  4472. SourceLocation Loc) {
  4473. auto *OrigVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, Ty,
  4474. ImplicitParamDecl::Other);
  4475. auto *OrigRef = DeclRefExpr::Create(
  4476. C, NestedNameSpecifierLoc(), SourceLocation(), OrigVD,
  4477. /*RefersToEnclosingVariableOrCapture=*/false, Loc, Ty, VK_LValue);
  4478. auto *PrivateVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, Ty,
  4479. ImplicitParamDecl::Other);
  4480. auto *PrivateRef = DeclRefExpr::Create(
  4481. C, NestedNameSpecifierLoc(), SourceLocation(), PrivateVD,
  4482. /*RefersToEnclosingVariableOrCapture=*/false, Loc, Ty, VK_LValue);
  4483. QualType ElemType = C.getBaseElementType(Ty);
  4484. auto *InitVD = ImplicitParamDecl::Create(C, CD, Loc, /*Id=*/nullptr, ElemType,
  4485. ImplicitParamDecl::Other);
  4486. auto *InitRef = DeclRefExpr::Create(
  4487. C, NestedNameSpecifierLoc(), SourceLocation(), InitVD,
  4488. /*RefersToEnclosingVariableOrCapture=*/false, Loc, ElemType, VK_LValue);
  4489. PrivateVD->setInitStyle(VarDecl::CInit);
  4490. PrivateVD->setInit(ImplicitCastExpr::Create(C, ElemType, CK_LValueToRValue,
  4491. InitRef, /*BasePath=*/nullptr,
  4492. VK_PRValue, FPOptionsOverride()));
  4493. Data.FirstprivateVars.emplace_back(OrigRef);
  4494. Data.FirstprivateCopies.emplace_back(PrivateRef);
  4495. Data.FirstprivateInits.emplace_back(InitRef);
  4496. return OrigVD;
  4497. }
  4498. void CodeGenFunction::EmitOMPTargetTaskBasedDirective(
  4499. const OMPExecutableDirective &S, const RegionCodeGenTy &BodyGen,
  4500. OMPTargetDataInfo &InputInfo) {
  4501. // Emit outlined function for task construct.
  4502. const CapturedStmt *CS = S.getCapturedStmt(OMPD_task);
  4503. Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
  4504. QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
  4505. auto I = CS->getCapturedDecl()->param_begin();
  4506. auto PartId = std::next(I);
  4507. auto TaskT = std::next(I, 4);
  4508. OMPTaskDataTy Data;
  4509. // The task is not final.
  4510. Data.Final.setInt(/*IntVal=*/false);
  4511. // Get list of firstprivate variables.
  4512. for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
  4513. auto IRef = C->varlist_begin();
  4514. auto IElemInitRef = C->inits().begin();
  4515. for (auto *IInit : C->private_copies()) {
  4516. Data.FirstprivateVars.push_back(*IRef);
  4517. Data.FirstprivateCopies.push_back(IInit);
  4518. Data.FirstprivateInits.push_back(*IElemInitRef);
  4519. ++IRef;
  4520. ++IElemInitRef;
  4521. }
  4522. }
  4523. OMPPrivateScope TargetScope(*this);
  4524. VarDecl *BPVD = nullptr;
  4525. VarDecl *PVD = nullptr;
  4526. VarDecl *SVD = nullptr;
  4527. VarDecl *MVD = nullptr;
  4528. if (InputInfo.NumberOfTargetItems > 0) {
  4529. auto *CD = CapturedDecl::Create(
  4530. getContext(), getContext().getTranslationUnitDecl(), /*NumParams=*/0);
  4531. llvm::APInt ArrSize(/*numBits=*/32, InputInfo.NumberOfTargetItems);
  4532. QualType BaseAndPointerAndMapperType = getContext().getConstantArrayType(
  4533. getContext().VoidPtrTy, ArrSize, nullptr, ArrayType::Normal,
  4534. /*IndexTypeQuals=*/0);
  4535. BPVD = createImplicitFirstprivateForType(
  4536. getContext(), Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
  4537. PVD = createImplicitFirstprivateForType(
  4538. getContext(), Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
  4539. QualType SizesType = getContext().getConstantArrayType(
  4540. getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1),
  4541. ArrSize, nullptr, ArrayType::Normal,
  4542. /*IndexTypeQuals=*/0);
  4543. SVD = createImplicitFirstprivateForType(getContext(), Data, SizesType, CD,
  4544. S.getBeginLoc());
  4545. TargetScope.addPrivate(
  4546. BPVD, [&InputInfo]() { return InputInfo.BasePointersArray; });
  4547. TargetScope.addPrivate(PVD,
  4548. [&InputInfo]() { return InputInfo.PointersArray; });
  4549. TargetScope.addPrivate(SVD,
  4550. [&InputInfo]() { return InputInfo.SizesArray; });
  4551. // If there is no user-defined mapper, the mapper array will be nullptr. In
  4552. // this case, we don't need to privatize it.
  4553. if (!isa_and_nonnull<llvm::ConstantPointerNull>(
  4554. InputInfo.MappersArray.getPointer())) {
  4555. MVD = createImplicitFirstprivateForType(
  4556. getContext(), Data, BaseAndPointerAndMapperType, CD, S.getBeginLoc());
  4557. TargetScope.addPrivate(MVD,
  4558. [&InputInfo]() { return InputInfo.MappersArray; });
  4559. }
  4560. }
  4561. (void)TargetScope.Privatize();
  4562. // Build list of dependences.
  4563. for (const auto *C : S.getClausesOfKind<OMPDependClause>()) {
  4564. OMPTaskDataTy::DependData &DD =
  4565. Data.Dependences.emplace_back(C->getDependencyKind(), C->getModifier());
  4566. DD.DepExprs.append(C->varlist_begin(), C->varlist_end());
  4567. }
  4568. auto &&CodeGen = [&Data, &S, CS, &BodyGen, BPVD, PVD, SVD, MVD,
  4569. &InputInfo](CodeGenFunction &CGF, PrePostActionTy &Action) {
  4570. // Set proper addresses for generated private copies.
  4571. OMPPrivateScope Scope(CGF);
  4572. if (!Data.FirstprivateVars.empty()) {
  4573. enum { PrivatesParam = 2, CopyFnParam = 3 };
  4574. llvm::Value *CopyFn = CGF.Builder.CreateLoad(
  4575. CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(CopyFnParam)));
  4576. llvm::Value *PrivatesPtr = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(
  4577. CS->getCapturedDecl()->getParam(PrivatesParam)));
  4578. // Map privates.
  4579. llvm::SmallVector<std::pair<const VarDecl *, Address>, 16> PrivatePtrs;
  4580. llvm::SmallVector<llvm::Value *, 16> CallArgs;
  4581. llvm::SmallVector<llvm::Type *, 4> ParamTypes;
  4582. CallArgs.push_back(PrivatesPtr);
  4583. ParamTypes.push_back(PrivatesPtr->getType());
  4584. for (const Expr *E : Data.FirstprivateVars) {
  4585. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
  4586. Address PrivatePtr =
  4587. CGF.CreateMemTemp(CGF.getContext().getPointerType(E->getType()),
  4588. ".firstpriv.ptr.addr");
  4589. PrivatePtrs.emplace_back(VD, PrivatePtr);
  4590. CallArgs.push_back(PrivatePtr.getPointer());
  4591. ParamTypes.push_back(PrivatePtr.getType());
  4592. }
  4593. auto *CopyFnTy = llvm::FunctionType::get(CGF.Builder.getVoidTy(),
  4594. ParamTypes, /*isVarArg=*/false);
  4595. CopyFn = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
  4596. CopyFn, CopyFnTy->getPointerTo());
  4597. CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(
  4598. CGF, S.getBeginLoc(), {CopyFnTy, CopyFn}, CallArgs);
  4599. for (const auto &Pair : PrivatePtrs) {
  4600. Address Replacement(CGF.Builder.CreateLoad(Pair.second),
  4601. CGF.getContext().getDeclAlign(Pair.first));
  4602. Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
  4603. }
  4604. }
  4605. // Privatize all private variables except for in_reduction items.
  4606. (void)Scope.Privatize();
  4607. if (InputInfo.NumberOfTargetItems > 0) {
  4608. InputInfo.BasePointersArray = CGF.Builder.CreateConstArrayGEP(
  4609. CGF.GetAddrOfLocalVar(BPVD), /*Index=*/0);
  4610. InputInfo.PointersArray = CGF.Builder.CreateConstArrayGEP(
  4611. CGF.GetAddrOfLocalVar(PVD), /*Index=*/0);
  4612. InputInfo.SizesArray = CGF.Builder.CreateConstArrayGEP(
  4613. CGF.GetAddrOfLocalVar(SVD), /*Index=*/0);
  4614. // If MVD is nullptr, the mapper array is not privatized
  4615. if (MVD)
  4616. InputInfo.MappersArray = CGF.Builder.CreateConstArrayGEP(
  4617. CGF.GetAddrOfLocalVar(MVD), /*Index=*/0);
  4618. }
  4619. Action.Enter(CGF);
  4620. OMPLexicalScope LexScope(CGF, S, OMPD_task, /*EmitPreInitStmt=*/false);
  4621. BodyGen(CGF);
  4622. };
  4623. llvm::Function *OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
  4624. S, *I, *PartId, *TaskT, S.getDirectiveKind(), CodeGen, /*Tied=*/true,
  4625. Data.NumberOfParts);
  4626. llvm::APInt TrueOrFalse(32, S.hasClausesOfKind<OMPNowaitClause>() ? 1 : 0);
  4627. IntegerLiteral IfCond(getContext(), TrueOrFalse,
  4628. getContext().getIntTypeForBitwidth(32, /*Signed=*/0),
  4629. SourceLocation());
  4630. CGM.getOpenMPRuntime().emitTaskCall(*this, S.getBeginLoc(), S, OutlinedFn,
  4631. SharedsTy, CapturedStruct, &IfCond, Data);
  4632. }
  4633. void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
  4634. // Emit outlined function for task construct.
  4635. const CapturedStmt *CS = S.getCapturedStmt(OMPD_task);
  4636. Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
  4637. QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
  4638. const Expr *IfCond = nullptr;
  4639. for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
  4640. if (C->getNameModifier() == OMPD_unknown ||
  4641. C->getNameModifier() == OMPD_task) {
  4642. IfCond = C->getCondition();
  4643. break;
  4644. }
  4645. }
  4646. OMPTaskDataTy Data;
  4647. // Check if we should emit tied or untied task.
  4648. Data.Tied = !S.getSingleClause<OMPUntiedClause>();
  4649. auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) {
  4650. CGF.EmitStmt(CS->getCapturedStmt());
  4651. };
  4652. auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
  4653. IfCond](CodeGenFunction &CGF, llvm::Function *OutlinedFn,
  4654. const OMPTaskDataTy &Data) {
  4655. CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getBeginLoc(), S, OutlinedFn,
  4656. SharedsTy, CapturedStruct, IfCond,
  4657. Data);
  4658. };
  4659. auto LPCRegion =
  4660. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  4661. EmitOMPTaskBasedDirective(S, OMPD_task, BodyGen, TaskGen, Data);
  4662. }
  4663. void CodeGenFunction::EmitOMPTaskyieldDirective(
  4664. const OMPTaskyieldDirective &S) {
  4665. CGM.getOpenMPRuntime().emitTaskyieldCall(*this, S.getBeginLoc());
  4666. }
  4667. void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {
  4668. CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getBeginLoc(), OMPD_barrier);
  4669. }
  4670. void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) {
  4671. OMPTaskDataTy Data;
  4672. // Build list of dependences
  4673. for (const auto *C : S.getClausesOfKind<OMPDependClause>()) {
  4674. OMPTaskDataTy::DependData &DD =
  4675. Data.Dependences.emplace_back(C->getDependencyKind(), C->getModifier());
  4676. DD.DepExprs.append(C->varlist_begin(), C->varlist_end());
  4677. }
  4678. CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getBeginLoc(), Data);
  4679. }
  4680. void CodeGenFunction::EmitOMPTaskgroupDirective(
  4681. const OMPTaskgroupDirective &S) {
  4682. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  4683. Action.Enter(CGF);
  4684. if (const Expr *E = S.getReductionRef()) {
  4685. SmallVector<const Expr *, 4> LHSs;
  4686. SmallVector<const Expr *, 4> RHSs;
  4687. OMPTaskDataTy Data;
  4688. for (const auto *C : S.getClausesOfKind<OMPTaskReductionClause>()) {
  4689. Data.ReductionVars.append(C->varlist_begin(), C->varlist_end());
  4690. Data.ReductionOrigs.append(C->varlist_begin(), C->varlist_end());
  4691. Data.ReductionCopies.append(C->privates().begin(), C->privates().end());
  4692. Data.ReductionOps.append(C->reduction_ops().begin(),
  4693. C->reduction_ops().end());
  4694. LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
  4695. RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
  4696. }
  4697. llvm::Value *ReductionDesc =
  4698. CGF.CGM.getOpenMPRuntime().emitTaskReductionInit(CGF, S.getBeginLoc(),
  4699. LHSs, RHSs, Data);
  4700. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
  4701. CGF.EmitVarDecl(*VD);
  4702. CGF.EmitStoreOfScalar(ReductionDesc, CGF.GetAddrOfLocalVar(VD),
  4703. /*Volatile=*/false, E->getType());
  4704. }
  4705. CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
  4706. };
  4707. OMPLexicalScope Scope(*this, S, OMPD_unknown);
  4708. CGM.getOpenMPRuntime().emitTaskgroupRegion(*this, CodeGen, S.getBeginLoc());
  4709. }
  4710. void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {
  4711. llvm::AtomicOrdering AO = S.getSingleClause<OMPFlushClause>()
  4712. ? llvm::AtomicOrdering::NotAtomic
  4713. : llvm::AtomicOrdering::AcquireRelease;
  4714. CGM.getOpenMPRuntime().emitFlush(
  4715. *this,
  4716. [&S]() -> ArrayRef<const Expr *> {
  4717. if (const auto *FlushClause = S.getSingleClause<OMPFlushClause>())
  4718. return llvm::makeArrayRef(FlushClause->varlist_begin(),
  4719. FlushClause->varlist_end());
  4720. return llvm::None;
  4721. }(),
  4722. S.getBeginLoc(), AO);
  4723. }
  4724. void CodeGenFunction::EmitOMPDepobjDirective(const OMPDepobjDirective &S) {
  4725. const auto *DO = S.getSingleClause<OMPDepobjClause>();
  4726. LValue DOLVal = EmitLValue(DO->getDepobj());
  4727. if (const auto *DC = S.getSingleClause<OMPDependClause>()) {
  4728. OMPTaskDataTy::DependData Dependencies(DC->getDependencyKind(),
  4729. DC->getModifier());
  4730. Dependencies.DepExprs.append(DC->varlist_begin(), DC->varlist_end());
  4731. Address DepAddr = CGM.getOpenMPRuntime().emitDepobjDependClause(
  4732. *this, Dependencies, DC->getBeginLoc());
  4733. EmitStoreOfScalar(DepAddr.getPointer(), DOLVal);
  4734. return;
  4735. }
  4736. if (const auto *DC = S.getSingleClause<OMPDestroyClause>()) {
  4737. CGM.getOpenMPRuntime().emitDestroyClause(*this, DOLVal, DC->getBeginLoc());
  4738. return;
  4739. }
  4740. if (const auto *UC = S.getSingleClause<OMPUpdateClause>()) {
  4741. CGM.getOpenMPRuntime().emitUpdateClause(
  4742. *this, DOLVal, UC->getDependencyKind(), UC->getBeginLoc());
  4743. return;
  4744. }
  4745. }
  4746. void CodeGenFunction::EmitOMPScanDirective(const OMPScanDirective &S) {
  4747. if (!OMPParentLoopDirectiveForScan)
  4748. return;
  4749. const OMPExecutableDirective &ParentDir = *OMPParentLoopDirectiveForScan;
  4750. bool IsInclusive = S.hasClausesOfKind<OMPInclusiveClause>();
  4751. SmallVector<const Expr *, 4> Shareds;
  4752. SmallVector<const Expr *, 4> Privates;
  4753. SmallVector<const Expr *, 4> LHSs;
  4754. SmallVector<const Expr *, 4> RHSs;
  4755. SmallVector<const Expr *, 4> ReductionOps;
  4756. SmallVector<const Expr *, 4> CopyOps;
  4757. SmallVector<const Expr *, 4> CopyArrayTemps;
  4758. SmallVector<const Expr *, 4> CopyArrayElems;
  4759. for (const auto *C : ParentDir.getClausesOfKind<OMPReductionClause>()) {
  4760. if (C->getModifier() != OMPC_REDUCTION_inscan)
  4761. continue;
  4762. Shareds.append(C->varlist_begin(), C->varlist_end());
  4763. Privates.append(C->privates().begin(), C->privates().end());
  4764. LHSs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
  4765. RHSs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
  4766. ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
  4767. CopyOps.append(C->copy_ops().begin(), C->copy_ops().end());
  4768. CopyArrayTemps.append(C->copy_array_temps().begin(),
  4769. C->copy_array_temps().end());
  4770. CopyArrayElems.append(C->copy_array_elems().begin(),
  4771. C->copy_array_elems().end());
  4772. }
  4773. if (ParentDir.getDirectiveKind() == OMPD_simd ||
  4774. (getLangOpts().OpenMPSimd &&
  4775. isOpenMPSimdDirective(ParentDir.getDirectiveKind()))) {
  4776. // For simd directive and simd-based directives in simd only mode, use the
  4777. // following codegen:
  4778. // int x = 0;
  4779. // #pragma omp simd reduction(inscan, +: x)
  4780. // for (..) {
  4781. // <first part>
  4782. // #pragma omp scan inclusive(x)
  4783. // <second part>
  4784. // }
  4785. // is transformed to:
  4786. // int x = 0;
  4787. // for (..) {
  4788. // int x_priv = 0;
  4789. // <first part>
  4790. // x = x_priv + x;
  4791. // x_priv = x;
  4792. // <second part>
  4793. // }
  4794. // and
  4795. // int x = 0;
  4796. // #pragma omp simd reduction(inscan, +: x)
  4797. // for (..) {
  4798. // <first part>
  4799. // #pragma omp scan exclusive(x)
  4800. // <second part>
  4801. // }
  4802. // to
  4803. // int x = 0;
  4804. // for (..) {
  4805. // int x_priv = 0;
  4806. // <second part>
  4807. // int temp = x;
  4808. // x = x_priv + x;
  4809. // x_priv = temp;
  4810. // <first part>
  4811. // }
  4812. llvm::BasicBlock *OMPScanReduce = createBasicBlock("omp.inscan.reduce");
  4813. EmitBranch(IsInclusive
  4814. ? OMPScanReduce
  4815. : BreakContinueStack.back().ContinueBlock.getBlock());
  4816. EmitBlock(OMPScanDispatch);
  4817. {
  4818. // New scope for correct construction/destruction of temp variables for
  4819. // exclusive scan.
  4820. LexicalScope Scope(*this, S.getSourceRange());
  4821. EmitBranch(IsInclusive ? OMPBeforeScanBlock : OMPAfterScanBlock);
  4822. EmitBlock(OMPScanReduce);
  4823. if (!IsInclusive) {
  4824. // Create temp var and copy LHS value to this temp value.
  4825. // TMP = LHS;
  4826. for (unsigned I = 0, E = CopyArrayElems.size(); I < E; ++I) {
  4827. const Expr *PrivateExpr = Privates[I];
  4828. const Expr *TempExpr = CopyArrayTemps[I];
  4829. EmitAutoVarDecl(
  4830. *cast<VarDecl>(cast<DeclRefExpr>(TempExpr)->getDecl()));
  4831. LValue DestLVal = EmitLValue(TempExpr);
  4832. LValue SrcLVal = EmitLValue(LHSs[I]);
  4833. EmitOMPCopy(PrivateExpr->getType(), DestLVal.getAddress(*this),
  4834. SrcLVal.getAddress(*this),
  4835. cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
  4836. cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()),
  4837. CopyOps[I]);
  4838. }
  4839. }
  4840. CGM.getOpenMPRuntime().emitReduction(
  4841. *this, ParentDir.getEndLoc(), Privates, LHSs, RHSs, ReductionOps,
  4842. {/*WithNowait=*/true, /*SimpleReduction=*/true, OMPD_simd});
  4843. for (unsigned I = 0, E = CopyArrayElems.size(); I < E; ++I) {
  4844. const Expr *PrivateExpr = Privates[I];
  4845. LValue DestLVal;
  4846. LValue SrcLVal;
  4847. if (IsInclusive) {
  4848. DestLVal = EmitLValue(RHSs[I]);
  4849. SrcLVal = EmitLValue(LHSs[I]);
  4850. } else {
  4851. const Expr *TempExpr = CopyArrayTemps[I];
  4852. DestLVal = EmitLValue(RHSs[I]);
  4853. SrcLVal = EmitLValue(TempExpr);
  4854. }
  4855. EmitOMPCopy(PrivateExpr->getType(), DestLVal.getAddress(*this),
  4856. SrcLVal.getAddress(*this),
  4857. cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
  4858. cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()),
  4859. CopyOps[I]);
  4860. }
  4861. }
  4862. EmitBranch(IsInclusive ? OMPAfterScanBlock : OMPBeforeScanBlock);
  4863. OMPScanExitBlock = IsInclusive
  4864. ? BreakContinueStack.back().ContinueBlock.getBlock()
  4865. : OMPScanReduce;
  4866. EmitBlock(OMPAfterScanBlock);
  4867. return;
  4868. }
  4869. if (!IsInclusive) {
  4870. EmitBranch(BreakContinueStack.back().ContinueBlock.getBlock());
  4871. EmitBlock(OMPScanExitBlock);
  4872. }
  4873. if (OMPFirstScanLoop) {
  4874. // Emit buffer[i] = red; at the end of the input phase.
  4875. const auto *IVExpr = cast<OMPLoopDirective>(ParentDir)
  4876. .getIterationVariable()
  4877. ->IgnoreParenImpCasts();
  4878. LValue IdxLVal = EmitLValue(IVExpr);
  4879. llvm::Value *IdxVal = EmitLoadOfScalar(IdxLVal, IVExpr->getExprLoc());
  4880. IdxVal = Builder.CreateIntCast(IdxVal, SizeTy, /*isSigned=*/false);
  4881. for (unsigned I = 0, E = CopyArrayElems.size(); I < E; ++I) {
  4882. const Expr *PrivateExpr = Privates[I];
  4883. const Expr *OrigExpr = Shareds[I];
  4884. const Expr *CopyArrayElem = CopyArrayElems[I];
  4885. OpaqueValueMapping IdxMapping(
  4886. *this,
  4887. cast<OpaqueValueExpr>(
  4888. cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
  4889. RValue::get(IdxVal));
  4890. LValue DestLVal = EmitLValue(CopyArrayElem);
  4891. LValue SrcLVal = EmitLValue(OrigExpr);
  4892. EmitOMPCopy(PrivateExpr->getType(), DestLVal.getAddress(*this),
  4893. SrcLVal.getAddress(*this),
  4894. cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
  4895. cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()),
  4896. CopyOps[I]);
  4897. }
  4898. }
  4899. EmitBranch(BreakContinueStack.back().ContinueBlock.getBlock());
  4900. if (IsInclusive) {
  4901. EmitBlock(OMPScanExitBlock);
  4902. EmitBranch(BreakContinueStack.back().ContinueBlock.getBlock());
  4903. }
  4904. EmitBlock(OMPScanDispatch);
  4905. if (!OMPFirstScanLoop) {
  4906. // Emit red = buffer[i]; at the entrance to the scan phase.
  4907. const auto *IVExpr = cast<OMPLoopDirective>(ParentDir)
  4908. .getIterationVariable()
  4909. ->IgnoreParenImpCasts();
  4910. LValue IdxLVal = EmitLValue(IVExpr);
  4911. llvm::Value *IdxVal = EmitLoadOfScalar(IdxLVal, IVExpr->getExprLoc());
  4912. IdxVal = Builder.CreateIntCast(IdxVal, SizeTy, /*isSigned=*/false);
  4913. llvm::BasicBlock *ExclusiveExitBB = nullptr;
  4914. if (!IsInclusive) {
  4915. llvm::BasicBlock *ContBB = createBasicBlock("omp.exclusive.dec");
  4916. ExclusiveExitBB = createBasicBlock("omp.exclusive.copy.exit");
  4917. llvm::Value *Cmp = Builder.CreateIsNull(IdxVal);
  4918. Builder.CreateCondBr(Cmp, ExclusiveExitBB, ContBB);
  4919. EmitBlock(ContBB);
  4920. // Use idx - 1 iteration for exclusive scan.
  4921. IdxVal = Builder.CreateNUWSub(IdxVal, llvm::ConstantInt::get(SizeTy, 1));
  4922. }
  4923. for (unsigned I = 0, E = CopyArrayElems.size(); I < E; ++I) {
  4924. const Expr *PrivateExpr = Privates[I];
  4925. const Expr *OrigExpr = Shareds[I];
  4926. const Expr *CopyArrayElem = CopyArrayElems[I];
  4927. OpaqueValueMapping IdxMapping(
  4928. *this,
  4929. cast<OpaqueValueExpr>(
  4930. cast<ArraySubscriptExpr>(CopyArrayElem)->getIdx()),
  4931. RValue::get(IdxVal));
  4932. LValue SrcLVal = EmitLValue(CopyArrayElem);
  4933. LValue DestLVal = EmitLValue(OrigExpr);
  4934. EmitOMPCopy(PrivateExpr->getType(), DestLVal.getAddress(*this),
  4935. SrcLVal.getAddress(*this),
  4936. cast<VarDecl>(cast<DeclRefExpr>(LHSs[I])->getDecl()),
  4937. cast<VarDecl>(cast<DeclRefExpr>(RHSs[I])->getDecl()),
  4938. CopyOps[I]);
  4939. }
  4940. if (!IsInclusive) {
  4941. EmitBlock(ExclusiveExitBB);
  4942. }
  4943. }
  4944. EmitBranch((OMPFirstScanLoop == IsInclusive) ? OMPBeforeScanBlock
  4945. : OMPAfterScanBlock);
  4946. EmitBlock(OMPAfterScanBlock);
  4947. }
  4948. void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S,
  4949. const CodeGenLoopTy &CodeGenLoop,
  4950. Expr *IncExpr) {
  4951. // Emit the loop iteration variable.
  4952. const auto *IVExpr = cast<DeclRefExpr>(S.getIterationVariable());
  4953. const auto *IVDecl = cast<VarDecl>(IVExpr->getDecl());
  4954. EmitVarDecl(*IVDecl);
  4955. // Emit the iterations count variable.
  4956. // If it is not a variable, Sema decided to calculate iterations count on each
  4957. // iteration (e.g., it is foldable into a constant).
  4958. if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
  4959. EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
  4960. // Emit calculation of the iterations count.
  4961. EmitIgnoredExpr(S.getCalcLastIteration());
  4962. }
  4963. CGOpenMPRuntime &RT = CGM.getOpenMPRuntime();
  4964. bool HasLastprivateClause = false;
  4965. // Check pre-condition.
  4966. {
  4967. OMPLoopScope PreInitScope(*this, S);
  4968. // Skip the entire loop if we don't meet the precondition.
  4969. // If the condition constant folds and can be elided, avoid emitting the
  4970. // whole loop.
  4971. bool CondConstant;
  4972. llvm::BasicBlock *ContBlock = nullptr;
  4973. if (ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
  4974. if (!CondConstant)
  4975. return;
  4976. } else {
  4977. llvm::BasicBlock *ThenBlock = createBasicBlock("omp.precond.then");
  4978. ContBlock = createBasicBlock("omp.precond.end");
  4979. emitPreCond(*this, S, S.getPreCond(), ThenBlock, ContBlock,
  4980. getProfileCount(&S));
  4981. EmitBlock(ThenBlock);
  4982. incrementProfileCounter(&S);
  4983. }
  4984. emitAlignedClause(*this, S);
  4985. // Emit 'then' code.
  4986. {
  4987. // Emit helper vars inits.
  4988. LValue LB = EmitOMPHelperVar(
  4989. *this, cast<DeclRefExpr>(
  4990. (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
  4991. ? S.getCombinedLowerBoundVariable()
  4992. : S.getLowerBoundVariable())));
  4993. LValue UB = EmitOMPHelperVar(
  4994. *this, cast<DeclRefExpr>(
  4995. (isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
  4996. ? S.getCombinedUpperBoundVariable()
  4997. : S.getUpperBoundVariable())));
  4998. LValue ST =
  4999. EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable()));
  5000. LValue IL =
  5001. EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable()));
  5002. OMPPrivateScope LoopScope(*this);
  5003. if (EmitOMPFirstprivateClause(S, LoopScope)) {
  5004. // Emit implicit barrier to synchronize threads and avoid data races
  5005. // on initialization of firstprivate variables and post-update of
  5006. // lastprivate variables.
  5007. CGM.getOpenMPRuntime().emitBarrierCall(
  5008. *this, S.getBeginLoc(), OMPD_unknown, /*EmitChecks=*/false,
  5009. /*ForceSimpleCall=*/true);
  5010. }
  5011. EmitOMPPrivateClause(S, LoopScope);
  5012. if (isOpenMPSimdDirective(S.getDirectiveKind()) &&
  5013. !isOpenMPParallelDirective(S.getDirectiveKind()) &&
  5014. !isOpenMPTeamsDirective(S.getDirectiveKind()))
  5015. EmitOMPReductionClauseInit(S, LoopScope);
  5016. HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope);
  5017. EmitOMPPrivateLoopCounters(S, LoopScope);
  5018. (void)LoopScope.Privatize();
  5019. if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
  5020. CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(*this, S);
  5021. // Detect the distribute schedule kind and chunk.
  5022. llvm::Value *Chunk = nullptr;
  5023. OpenMPDistScheduleClauseKind ScheduleKind = OMPC_DIST_SCHEDULE_unknown;
  5024. if (const auto *C = S.getSingleClause<OMPDistScheduleClause>()) {
  5025. ScheduleKind = C->getDistScheduleKind();
  5026. if (const Expr *Ch = C->getChunkSize()) {
  5027. Chunk = EmitScalarExpr(Ch);
  5028. Chunk = EmitScalarConversion(Chunk, Ch->getType(),
  5029. S.getIterationVariable()->getType(),
  5030. S.getBeginLoc());
  5031. }
  5032. } else {
  5033. // Default behaviour for dist_schedule clause.
  5034. CGM.getOpenMPRuntime().getDefaultDistScheduleAndChunk(
  5035. *this, S, ScheduleKind, Chunk);
  5036. }
  5037. const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
  5038. const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
  5039. // OpenMP [2.10.8, distribute Construct, Description]
  5040. // If dist_schedule is specified, kind must be static. If specified,
  5041. // iterations are divided into chunks of size chunk_size, chunks are
  5042. // assigned to the teams of the league in a round-robin fashion in the
  5043. // order of the team number. When no chunk_size is specified, the
  5044. // iteration space is divided into chunks that are approximately equal
  5045. // in size, and at most one chunk is distributed to each team of the
  5046. // league. The size of the chunks is unspecified in this case.
  5047. bool StaticChunked =
  5048. RT.isStaticChunked(ScheduleKind, /* Chunked */ Chunk != nullptr) &&
  5049. isOpenMPLoopBoundSharingDirective(S.getDirectiveKind());
  5050. if (RT.isStaticNonchunked(ScheduleKind,
  5051. /* Chunked */ Chunk != nullptr) ||
  5052. StaticChunked) {
  5053. CGOpenMPRuntime::StaticRTInput StaticInit(
  5054. IVSize, IVSigned, /* Ordered = */ false, IL.getAddress(*this),
  5055. LB.getAddress(*this), UB.getAddress(*this), ST.getAddress(*this),
  5056. StaticChunked ? Chunk : nullptr);
  5057. RT.emitDistributeStaticInit(*this, S.getBeginLoc(), ScheduleKind,
  5058. StaticInit);
  5059. JumpDest LoopExit =
  5060. getJumpDestInCurrentScope(createBasicBlock("omp.loop.exit"));
  5061. // UB = min(UB, GlobalUB);
  5062. EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
  5063. ? S.getCombinedEnsureUpperBound()
  5064. : S.getEnsureUpperBound());
  5065. // IV = LB;
  5066. EmitIgnoredExpr(isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
  5067. ? S.getCombinedInit()
  5068. : S.getInit());
  5069. const Expr *Cond =
  5070. isOpenMPLoopBoundSharingDirective(S.getDirectiveKind())
  5071. ? S.getCombinedCond()
  5072. : S.getCond();
  5073. if (StaticChunked)
  5074. Cond = S.getCombinedDistCond();
  5075. // For static unchunked schedules generate:
  5076. //
  5077. // 1. For distribute alone, codegen
  5078. // while (idx <= UB) {
  5079. // BODY;
  5080. // ++idx;
  5081. // }
  5082. //
  5083. // 2. When combined with 'for' (e.g. as in 'distribute parallel for')
  5084. // while (idx <= UB) {
  5085. // <CodeGen rest of pragma>(LB, UB);
  5086. // idx += ST;
  5087. // }
  5088. //
  5089. // For static chunk one schedule generate:
  5090. //
  5091. // while (IV <= GlobalUB) {
  5092. // <CodeGen rest of pragma>(LB, UB);
  5093. // LB += ST;
  5094. // UB += ST;
  5095. // UB = min(UB, GlobalUB);
  5096. // IV = LB;
  5097. // }
  5098. //
  5099. emitCommonSimdLoop(
  5100. *this, S,
  5101. [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  5102. if (isOpenMPSimdDirective(S.getDirectiveKind()))
  5103. CGF.EmitOMPSimdInit(S);
  5104. },
  5105. [&S, &LoopScope, Cond, IncExpr, LoopExit, &CodeGenLoop,
  5106. StaticChunked](CodeGenFunction &CGF, PrePostActionTy &) {
  5107. CGF.EmitOMPInnerLoop(
  5108. S, LoopScope.requiresCleanups(), Cond, IncExpr,
  5109. [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) {
  5110. CodeGenLoop(CGF, S, LoopExit);
  5111. },
  5112. [&S, StaticChunked](CodeGenFunction &CGF) {
  5113. if (StaticChunked) {
  5114. CGF.EmitIgnoredExpr(S.getCombinedNextLowerBound());
  5115. CGF.EmitIgnoredExpr(S.getCombinedNextUpperBound());
  5116. CGF.EmitIgnoredExpr(S.getCombinedEnsureUpperBound());
  5117. CGF.EmitIgnoredExpr(S.getCombinedInit());
  5118. }
  5119. });
  5120. });
  5121. EmitBlock(LoopExit.getBlock());
  5122. // Tell the runtime we are done.
  5123. RT.emitForStaticFinish(*this, S.getEndLoc(), S.getDirectiveKind());
  5124. } else {
  5125. // Emit the outer loop, which requests its work chunk [LB..UB] from
  5126. // runtime and runs the inner loop to process it.
  5127. const OMPLoopArguments LoopArguments = {
  5128. LB.getAddress(*this), UB.getAddress(*this), ST.getAddress(*this),
  5129. IL.getAddress(*this), Chunk};
  5130. EmitOMPDistributeOuterLoop(ScheduleKind, S, LoopScope, LoopArguments,
  5131. CodeGenLoop);
  5132. }
  5133. if (isOpenMPSimdDirective(S.getDirectiveKind())) {
  5134. EmitOMPSimdFinal(S, [IL, &S](CodeGenFunction &CGF) {
  5135. return CGF.Builder.CreateIsNotNull(
  5136. CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
  5137. });
  5138. }
  5139. if (isOpenMPSimdDirective(S.getDirectiveKind()) &&
  5140. !isOpenMPParallelDirective(S.getDirectiveKind()) &&
  5141. !isOpenMPTeamsDirective(S.getDirectiveKind())) {
  5142. EmitOMPReductionClauseFinal(S, OMPD_simd);
  5143. // Emit post-update of the reduction variables if IsLastIter != 0.
  5144. emitPostUpdateForReductionClause(
  5145. *this, S, [IL, &S](CodeGenFunction &CGF) {
  5146. return CGF.Builder.CreateIsNotNull(
  5147. CGF.EmitLoadOfScalar(IL, S.getBeginLoc()));
  5148. });
  5149. }
  5150. // Emit final copy of the lastprivate variables if IsLastIter != 0.
  5151. if (HasLastprivateClause) {
  5152. EmitOMPLastprivateClauseFinal(
  5153. S, /*NoFinals=*/false,
  5154. Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getBeginLoc())));
  5155. }
  5156. }
  5157. // We're now done with the loop, so jump to the continuation block.
  5158. if (ContBlock) {
  5159. EmitBranch(ContBlock);
  5160. EmitBlock(ContBlock, true);
  5161. }
  5162. }
  5163. }
  5164. void CodeGenFunction::EmitOMPDistributeDirective(
  5165. const OMPDistributeDirective &S) {
  5166. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  5167. CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
  5168. };
  5169. OMPLexicalScope Scope(*this, S, OMPD_unknown);
  5170. CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_distribute, CodeGen);
  5171. }
  5172. static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM,
  5173. const CapturedStmt *S,
  5174. SourceLocation Loc) {
  5175. CodeGenFunction CGF(CGM, /*suppressNewContext=*/true);
  5176. CodeGenFunction::CGCapturedStmtInfo CapStmtInfo;
  5177. CGF.CapturedStmtInfo = &CapStmtInfo;
  5178. llvm::Function *Fn = CGF.GenerateOpenMPCapturedStmtFunction(*S, Loc);
  5179. Fn->setDoesNotRecurse();
  5180. return Fn;
  5181. }
  5182. void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) {
  5183. if (CGM.getLangOpts().OpenMPIRBuilder) {
  5184. llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  5185. using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
  5186. if (S.hasClausesOfKind<OMPDependClause>()) {
  5187. // The ordered directive with depend clause.
  5188. assert(!S.hasAssociatedStmt() &&
  5189. "No associated statement must be in ordered depend construct.");
  5190. InsertPointTy AllocaIP(AllocaInsertPt->getParent(),
  5191. AllocaInsertPt->getIterator());
  5192. for (const auto *DC : S.getClausesOfKind<OMPDependClause>()) {
  5193. unsigned NumLoops = DC->getNumLoops();
  5194. QualType Int64Ty = CGM.getContext().getIntTypeForBitwidth(
  5195. /*DestWidth=*/64, /*Signed=*/1);
  5196. llvm::SmallVector<llvm::Value *> StoreValues;
  5197. for (unsigned I = 0; I < NumLoops; I++) {
  5198. const Expr *CounterVal = DC->getLoopData(I);
  5199. assert(CounterVal);
  5200. llvm::Value *StoreValue = EmitScalarConversion(
  5201. EmitScalarExpr(CounterVal), CounterVal->getType(), Int64Ty,
  5202. CounterVal->getExprLoc());
  5203. StoreValues.emplace_back(StoreValue);
  5204. }
  5205. bool IsDependSource = false;
  5206. if (DC->getDependencyKind() == OMPC_DEPEND_source)
  5207. IsDependSource = true;
  5208. Builder.restoreIP(OMPBuilder.createOrderedDepend(
  5209. Builder, AllocaIP, NumLoops, StoreValues, ".cnt.addr",
  5210. IsDependSource));
  5211. }
  5212. } else {
  5213. // The ordered directive with threads or simd clause, or without clause.
  5214. // Without clause, it behaves as if the threads clause is specified.
  5215. const auto *C = S.getSingleClause<OMPSIMDClause>();
  5216. auto FiniCB = [this](InsertPointTy IP) {
  5217. OMPBuilderCBHelpers::FinalizeOMPRegion(*this, IP);
  5218. };
  5219. auto BodyGenCB = [&S, C, this](InsertPointTy AllocaIP,
  5220. InsertPointTy CodeGenIP,
  5221. llvm::BasicBlock &FiniBB) {
  5222. const CapturedStmt *CS = S.getInnermostCapturedStmt();
  5223. if (C) {
  5224. llvm::SmallVector<llvm::Value *, 16> CapturedVars;
  5225. GenerateOpenMPCapturedVars(*CS, CapturedVars);
  5226. llvm::Function *OutlinedFn =
  5227. emitOutlinedOrderedFunction(CGM, CS, S.getBeginLoc());
  5228. assert(S.getBeginLoc().isValid() &&
  5229. "Outlined function call location must be valid.");
  5230. ApplyDebugLocation::CreateDefaultArtificial(*this, S.getBeginLoc());
  5231. OMPBuilderCBHelpers::EmitCaptureStmt(*this, CodeGenIP, FiniBB,
  5232. OutlinedFn, CapturedVars);
  5233. } else {
  5234. OMPBuilderCBHelpers::InlinedRegionBodyRAII IRB(*this, AllocaIP,
  5235. FiniBB);
  5236. OMPBuilderCBHelpers::EmitOMPRegionBody(*this, CS->getCapturedStmt(),
  5237. CodeGenIP, FiniBB);
  5238. }
  5239. };
  5240. OMPLexicalScope Scope(*this, S, OMPD_unknown);
  5241. Builder.restoreIP(
  5242. OMPBuilder.createOrderedThreadsSimd(Builder, BodyGenCB, FiniCB, !C));
  5243. }
  5244. return;
  5245. }
  5246. if (S.hasClausesOfKind<OMPDependClause>()) {
  5247. assert(!S.hasAssociatedStmt() &&
  5248. "No associated statement must be in ordered depend construct.");
  5249. for (const auto *DC : S.getClausesOfKind<OMPDependClause>())
  5250. CGM.getOpenMPRuntime().emitDoacrossOrdered(*this, DC);
  5251. return;
  5252. }
  5253. const auto *C = S.getSingleClause<OMPSIMDClause>();
  5254. auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF,
  5255. PrePostActionTy &Action) {
  5256. const CapturedStmt *CS = S.getInnermostCapturedStmt();
  5257. if (C) {
  5258. llvm::SmallVector<llvm::Value *, 16> CapturedVars;
  5259. CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
  5260. llvm::Function *OutlinedFn =
  5261. emitOutlinedOrderedFunction(CGM, CS, S.getBeginLoc());
  5262. CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getBeginLoc(),
  5263. OutlinedFn, CapturedVars);
  5264. } else {
  5265. Action.Enter(CGF);
  5266. CGF.EmitStmt(CS->getCapturedStmt());
  5267. }
  5268. };
  5269. OMPLexicalScope Scope(*this, S, OMPD_unknown);
  5270. CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getBeginLoc(), !C);
  5271. }
  5272. static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val,
  5273. QualType SrcType, QualType DestType,
  5274. SourceLocation Loc) {
  5275. assert(CGF.hasScalarEvaluationKind(DestType) &&
  5276. "DestType must have scalar evaluation kind.");
  5277. assert(!Val.isAggregate() && "Must be a scalar or complex.");
  5278. return Val.isScalar() ? CGF.EmitScalarConversion(Val.getScalarVal(), SrcType,
  5279. DestType, Loc)
  5280. : CGF.EmitComplexToScalarConversion(
  5281. Val.getComplexVal(), SrcType, DestType, Loc);
  5282. }
  5283. static CodeGenFunction::ComplexPairTy
  5284. convertToComplexValue(CodeGenFunction &CGF, RValue Val, QualType SrcType,
  5285. QualType DestType, SourceLocation Loc) {
  5286. assert(CGF.getEvaluationKind(DestType) == TEK_Complex &&
  5287. "DestType must have complex evaluation kind.");
  5288. CodeGenFunction::ComplexPairTy ComplexVal;
  5289. if (Val.isScalar()) {
  5290. // Convert the input element to the element type of the complex.
  5291. QualType DestElementType =
  5292. DestType->castAs<ComplexType>()->getElementType();
  5293. llvm::Value *ScalarVal = CGF.EmitScalarConversion(
  5294. Val.getScalarVal(), SrcType, DestElementType, Loc);
  5295. ComplexVal = CodeGenFunction::ComplexPairTy(
  5296. ScalarVal, llvm::Constant::getNullValue(ScalarVal->getType()));
  5297. } else {
  5298. assert(Val.isComplex() && "Must be a scalar or complex.");
  5299. QualType SrcElementType = SrcType->castAs<ComplexType>()->getElementType();
  5300. QualType DestElementType =
  5301. DestType->castAs<ComplexType>()->getElementType();
  5302. ComplexVal.first = CGF.EmitScalarConversion(
  5303. Val.getComplexVal().first, SrcElementType, DestElementType, Loc);
  5304. ComplexVal.second = CGF.EmitScalarConversion(
  5305. Val.getComplexVal().second, SrcElementType, DestElementType, Loc);
  5306. }
  5307. return ComplexVal;
  5308. }
  5309. static void emitSimpleAtomicStore(CodeGenFunction &CGF, llvm::AtomicOrdering AO,
  5310. LValue LVal, RValue RVal) {
  5311. if (LVal.isGlobalReg())
  5312. CGF.EmitStoreThroughGlobalRegLValue(RVal, LVal);
  5313. else
  5314. CGF.EmitAtomicStore(RVal, LVal, AO, LVal.isVolatile(), /*isInit=*/false);
  5315. }
  5316. static RValue emitSimpleAtomicLoad(CodeGenFunction &CGF,
  5317. llvm::AtomicOrdering AO, LValue LVal,
  5318. SourceLocation Loc) {
  5319. if (LVal.isGlobalReg())
  5320. return CGF.EmitLoadOfLValue(LVal, Loc);
  5321. return CGF.EmitAtomicLoad(
  5322. LVal, Loc, llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO),
  5323. LVal.isVolatile());
  5324. }
  5325. void CodeGenFunction::emitOMPSimpleStore(LValue LVal, RValue RVal,
  5326. QualType RValTy, SourceLocation Loc) {
  5327. switch (getEvaluationKind(LVal.getType())) {
  5328. case TEK_Scalar:
  5329. EmitStoreThroughLValue(RValue::get(convertToScalarValue(
  5330. *this, RVal, RValTy, LVal.getType(), Loc)),
  5331. LVal);
  5332. break;
  5333. case TEK_Complex:
  5334. EmitStoreOfComplex(
  5335. convertToComplexValue(*this, RVal, RValTy, LVal.getType(), Loc), LVal,
  5336. /*isInit=*/false);
  5337. break;
  5338. case TEK_Aggregate:
  5339. llvm_unreachable("Must be a scalar or complex.");
  5340. }
  5341. }
  5342. static void emitOMPAtomicReadExpr(CodeGenFunction &CGF, llvm::AtomicOrdering AO,
  5343. const Expr *X, const Expr *V,
  5344. SourceLocation Loc) {
  5345. // v = x;
  5346. assert(V->isLValue() && "V of 'omp atomic read' is not lvalue");
  5347. assert(X->isLValue() && "X of 'omp atomic read' is not lvalue");
  5348. LValue XLValue = CGF.EmitLValue(X);
  5349. LValue VLValue = CGF.EmitLValue(V);
  5350. RValue Res = emitSimpleAtomicLoad(CGF, AO, XLValue, Loc);
  5351. // OpenMP, 2.17.7, atomic Construct
  5352. // If the read or capture clause is specified and the acquire, acq_rel, or
  5353. // seq_cst clause is specified then the strong flush on exit from the atomic
  5354. // operation is also an acquire flush.
  5355. switch (AO) {
  5356. case llvm::AtomicOrdering::Acquire:
  5357. case llvm::AtomicOrdering::AcquireRelease:
  5358. case llvm::AtomicOrdering::SequentiallyConsistent:
  5359. CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc,
  5360. llvm::AtomicOrdering::Acquire);
  5361. break;
  5362. case llvm::AtomicOrdering::Monotonic:
  5363. case llvm::AtomicOrdering::Release:
  5364. break;
  5365. case llvm::AtomicOrdering::NotAtomic:
  5366. case llvm::AtomicOrdering::Unordered:
  5367. llvm_unreachable("Unexpected ordering.");
  5368. }
  5369. CGF.emitOMPSimpleStore(VLValue, Res, X->getType().getNonReferenceType(), Loc);
  5370. CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, V);
  5371. }
  5372. static void emitOMPAtomicWriteExpr(CodeGenFunction &CGF,
  5373. llvm::AtomicOrdering AO, const Expr *X,
  5374. const Expr *E, SourceLocation Loc) {
  5375. // x = expr;
  5376. assert(X->isLValue() && "X of 'omp atomic write' is not lvalue");
  5377. emitSimpleAtomicStore(CGF, AO, CGF.EmitLValue(X), CGF.EmitAnyExpr(E));
  5378. CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X);
  5379. // OpenMP, 2.17.7, atomic Construct
  5380. // If the write, update, or capture clause is specified and the release,
  5381. // acq_rel, or seq_cst clause is specified then the strong flush on entry to
  5382. // the atomic operation is also a release flush.
  5383. switch (AO) {
  5384. case llvm::AtomicOrdering::Release:
  5385. case llvm::AtomicOrdering::AcquireRelease:
  5386. case llvm::AtomicOrdering::SequentiallyConsistent:
  5387. CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc,
  5388. llvm::AtomicOrdering::Release);
  5389. break;
  5390. case llvm::AtomicOrdering::Acquire:
  5391. case llvm::AtomicOrdering::Monotonic:
  5392. break;
  5393. case llvm::AtomicOrdering::NotAtomic:
  5394. case llvm::AtomicOrdering::Unordered:
  5395. llvm_unreachable("Unexpected ordering.");
  5396. }
  5397. }
  5398. static std::pair<bool, RValue> emitOMPAtomicRMW(CodeGenFunction &CGF, LValue X,
  5399. RValue Update,
  5400. BinaryOperatorKind BO,
  5401. llvm::AtomicOrdering AO,
  5402. bool IsXLHSInRHSPart) {
  5403. ASTContext &Context = CGF.getContext();
  5404. // Allow atomicrmw only if 'x' and 'update' are integer values, lvalue for 'x'
  5405. // expression is simple and atomic is allowed for the given type for the
  5406. // target platform.
  5407. if (BO == BO_Comma || !Update.isScalar() ||
  5408. !Update.getScalarVal()->getType()->isIntegerTy() || !X.isSimple() ||
  5409. (!isa<llvm::ConstantInt>(Update.getScalarVal()) &&
  5410. (Update.getScalarVal()->getType() !=
  5411. X.getAddress(CGF).getElementType())) ||
  5412. !X.getAddress(CGF).getElementType()->isIntegerTy() ||
  5413. !Context.getTargetInfo().hasBuiltinAtomic(
  5414. Context.getTypeSize(X.getType()), Context.toBits(X.getAlignment())))
  5415. return std::make_pair(false, RValue::get(nullptr));
  5416. llvm::AtomicRMWInst::BinOp RMWOp;
  5417. switch (BO) {
  5418. case BO_Add:
  5419. RMWOp = llvm::AtomicRMWInst::Add;
  5420. break;
  5421. case BO_Sub:
  5422. if (!IsXLHSInRHSPart)
  5423. return std::make_pair(false, RValue::get(nullptr));
  5424. RMWOp = llvm::AtomicRMWInst::Sub;
  5425. break;
  5426. case BO_And:
  5427. RMWOp = llvm::AtomicRMWInst::And;
  5428. break;
  5429. case BO_Or:
  5430. RMWOp = llvm::AtomicRMWInst::Or;
  5431. break;
  5432. case BO_Xor:
  5433. RMWOp = llvm::AtomicRMWInst::Xor;
  5434. break;
  5435. case BO_LT:
  5436. RMWOp = X.getType()->hasSignedIntegerRepresentation()
  5437. ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Min
  5438. : llvm::AtomicRMWInst::Max)
  5439. : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMin
  5440. : llvm::AtomicRMWInst::UMax);
  5441. break;
  5442. case BO_GT:
  5443. RMWOp = X.getType()->hasSignedIntegerRepresentation()
  5444. ? (IsXLHSInRHSPart ? llvm::AtomicRMWInst::Max
  5445. : llvm::AtomicRMWInst::Min)
  5446. : (IsXLHSInRHSPart ? llvm::AtomicRMWInst::UMax
  5447. : llvm::AtomicRMWInst::UMin);
  5448. break;
  5449. case BO_Assign:
  5450. RMWOp = llvm::AtomicRMWInst::Xchg;
  5451. break;
  5452. case BO_Mul:
  5453. case BO_Div:
  5454. case BO_Rem:
  5455. case BO_Shl:
  5456. case BO_Shr:
  5457. case BO_LAnd:
  5458. case BO_LOr:
  5459. return std::make_pair(false, RValue::get(nullptr));
  5460. case BO_PtrMemD:
  5461. case BO_PtrMemI:
  5462. case BO_LE:
  5463. case BO_GE:
  5464. case BO_EQ:
  5465. case BO_NE:
  5466. case BO_Cmp:
  5467. case BO_AddAssign:
  5468. case BO_SubAssign:
  5469. case BO_AndAssign:
  5470. case BO_OrAssign:
  5471. case BO_XorAssign:
  5472. case BO_MulAssign:
  5473. case BO_DivAssign:
  5474. case BO_RemAssign:
  5475. case BO_ShlAssign:
  5476. case BO_ShrAssign:
  5477. case BO_Comma:
  5478. llvm_unreachable("Unsupported atomic update operation");
  5479. }
  5480. llvm::Value *UpdateVal = Update.getScalarVal();
  5481. if (auto *IC = dyn_cast<llvm::ConstantInt>(UpdateVal)) {
  5482. UpdateVal = CGF.Builder.CreateIntCast(
  5483. IC, X.getAddress(CGF).getElementType(),
  5484. X.getType()->hasSignedIntegerRepresentation());
  5485. }
  5486. llvm::Value *Res =
  5487. CGF.Builder.CreateAtomicRMW(RMWOp, X.getPointer(CGF), UpdateVal, AO);
  5488. return std::make_pair(true, RValue::get(Res));
  5489. }
  5490. std::pair<bool, RValue> CodeGenFunction::EmitOMPAtomicSimpleUpdateExpr(
  5491. LValue X, RValue E, BinaryOperatorKind BO, bool IsXLHSInRHSPart,
  5492. llvm::AtomicOrdering AO, SourceLocation Loc,
  5493. const llvm::function_ref<RValue(RValue)> CommonGen) {
  5494. // Update expressions are allowed to have the following forms:
  5495. // x binop= expr; -> xrval + expr;
  5496. // x++, ++x -> xrval + 1;
  5497. // x--, --x -> xrval - 1;
  5498. // x = x binop expr; -> xrval binop expr
  5499. // x = expr Op x; - > expr binop xrval;
  5500. auto Res = emitOMPAtomicRMW(*this, X, E, BO, AO, IsXLHSInRHSPart);
  5501. if (!Res.first) {
  5502. if (X.isGlobalReg()) {
  5503. // Emit an update expression: 'xrval' binop 'expr' or 'expr' binop
  5504. // 'xrval'.
  5505. EmitStoreThroughLValue(CommonGen(EmitLoadOfLValue(X, Loc)), X);
  5506. } else {
  5507. // Perform compare-and-swap procedure.
  5508. EmitAtomicUpdate(X, AO, CommonGen, X.getType().isVolatileQualified());
  5509. }
  5510. }
  5511. return Res;
  5512. }
  5513. static void emitOMPAtomicUpdateExpr(CodeGenFunction &CGF,
  5514. llvm::AtomicOrdering AO, const Expr *X,
  5515. const Expr *E, const Expr *UE,
  5516. bool IsXLHSInRHSPart, SourceLocation Loc) {
  5517. assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
  5518. "Update expr in 'atomic update' must be a binary operator.");
  5519. const auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
  5520. // Update expressions are allowed to have the following forms:
  5521. // x binop= expr; -> xrval + expr;
  5522. // x++, ++x -> xrval + 1;
  5523. // x--, --x -> xrval - 1;
  5524. // x = x binop expr; -> xrval binop expr
  5525. // x = expr Op x; - > expr binop xrval;
  5526. assert(X->isLValue() && "X of 'omp atomic update' is not lvalue");
  5527. LValue XLValue = CGF.EmitLValue(X);
  5528. RValue ExprRValue = CGF.EmitAnyExpr(E);
  5529. const auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
  5530. const auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
  5531. const OpaqueValueExpr *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
  5532. const OpaqueValueExpr *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
  5533. auto &&Gen = [&CGF, UE, ExprRValue, XRValExpr, ERValExpr](RValue XRValue) {
  5534. CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
  5535. CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
  5536. return CGF.EmitAnyExpr(UE);
  5537. };
  5538. (void)CGF.EmitOMPAtomicSimpleUpdateExpr(
  5539. XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
  5540. CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X);
  5541. // OpenMP, 2.17.7, atomic Construct
  5542. // If the write, update, or capture clause is specified and the release,
  5543. // acq_rel, or seq_cst clause is specified then the strong flush on entry to
  5544. // the atomic operation is also a release flush.
  5545. switch (AO) {
  5546. case llvm::AtomicOrdering::Release:
  5547. case llvm::AtomicOrdering::AcquireRelease:
  5548. case llvm::AtomicOrdering::SequentiallyConsistent:
  5549. CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc,
  5550. llvm::AtomicOrdering::Release);
  5551. break;
  5552. case llvm::AtomicOrdering::Acquire:
  5553. case llvm::AtomicOrdering::Monotonic:
  5554. break;
  5555. case llvm::AtomicOrdering::NotAtomic:
  5556. case llvm::AtomicOrdering::Unordered:
  5557. llvm_unreachable("Unexpected ordering.");
  5558. }
  5559. }
  5560. static RValue convertToType(CodeGenFunction &CGF, RValue Value,
  5561. QualType SourceType, QualType ResType,
  5562. SourceLocation Loc) {
  5563. switch (CGF.getEvaluationKind(ResType)) {
  5564. case TEK_Scalar:
  5565. return RValue::get(
  5566. convertToScalarValue(CGF, Value, SourceType, ResType, Loc));
  5567. case TEK_Complex: {
  5568. auto Res = convertToComplexValue(CGF, Value, SourceType, ResType, Loc);
  5569. return RValue::getComplex(Res.first, Res.second);
  5570. }
  5571. case TEK_Aggregate:
  5572. break;
  5573. }
  5574. llvm_unreachable("Must be a scalar or complex.");
  5575. }
  5576. static void emitOMPAtomicCaptureExpr(CodeGenFunction &CGF,
  5577. llvm::AtomicOrdering AO,
  5578. bool IsPostfixUpdate, const Expr *V,
  5579. const Expr *X, const Expr *E,
  5580. const Expr *UE, bool IsXLHSInRHSPart,
  5581. SourceLocation Loc) {
  5582. assert(X->isLValue() && "X of 'omp atomic capture' is not lvalue");
  5583. assert(V->isLValue() && "V of 'omp atomic capture' is not lvalue");
  5584. RValue NewVVal;
  5585. LValue VLValue = CGF.EmitLValue(V);
  5586. LValue XLValue = CGF.EmitLValue(X);
  5587. RValue ExprRValue = CGF.EmitAnyExpr(E);
  5588. QualType NewVValType;
  5589. if (UE) {
  5590. // 'x' is updated with some additional value.
  5591. assert(isa<BinaryOperator>(UE->IgnoreImpCasts()) &&
  5592. "Update expr in 'atomic capture' must be a binary operator.");
  5593. const auto *BOUE = cast<BinaryOperator>(UE->IgnoreImpCasts());
  5594. // Update expressions are allowed to have the following forms:
  5595. // x binop= expr; -> xrval + expr;
  5596. // x++, ++x -> xrval + 1;
  5597. // x--, --x -> xrval - 1;
  5598. // x = x binop expr; -> xrval binop expr
  5599. // x = expr Op x; - > expr binop xrval;
  5600. const auto *LHS = cast<OpaqueValueExpr>(BOUE->getLHS()->IgnoreImpCasts());
  5601. const auto *RHS = cast<OpaqueValueExpr>(BOUE->getRHS()->IgnoreImpCasts());
  5602. const OpaqueValueExpr *XRValExpr = IsXLHSInRHSPart ? LHS : RHS;
  5603. NewVValType = XRValExpr->getType();
  5604. const OpaqueValueExpr *ERValExpr = IsXLHSInRHSPart ? RHS : LHS;
  5605. auto &&Gen = [&CGF, &NewVVal, UE, ExprRValue, XRValExpr, ERValExpr,
  5606. IsPostfixUpdate](RValue XRValue) {
  5607. CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
  5608. CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, XRValue);
  5609. RValue Res = CGF.EmitAnyExpr(UE);
  5610. NewVVal = IsPostfixUpdate ? XRValue : Res;
  5611. return Res;
  5612. };
  5613. auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
  5614. XLValue, ExprRValue, BOUE->getOpcode(), IsXLHSInRHSPart, AO, Loc, Gen);
  5615. CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X);
  5616. if (Res.first) {
  5617. // 'atomicrmw' instruction was generated.
  5618. if (IsPostfixUpdate) {
  5619. // Use old value from 'atomicrmw'.
  5620. NewVVal = Res.second;
  5621. } else {
  5622. // 'atomicrmw' does not provide new value, so evaluate it using old
  5623. // value of 'x'.
  5624. CodeGenFunction::OpaqueValueMapping MapExpr(CGF, ERValExpr, ExprRValue);
  5625. CodeGenFunction::OpaqueValueMapping MapX(CGF, XRValExpr, Res.second);
  5626. NewVVal = CGF.EmitAnyExpr(UE);
  5627. }
  5628. }
  5629. } else {
  5630. // 'x' is simply rewritten with some 'expr'.
  5631. NewVValType = X->getType().getNonReferenceType();
  5632. ExprRValue = convertToType(CGF, ExprRValue, E->getType(),
  5633. X->getType().getNonReferenceType(), Loc);
  5634. auto &&Gen = [&NewVVal, ExprRValue](RValue XRValue) {
  5635. NewVVal = XRValue;
  5636. return ExprRValue;
  5637. };
  5638. // Try to perform atomicrmw xchg, otherwise simple exchange.
  5639. auto Res = CGF.EmitOMPAtomicSimpleUpdateExpr(
  5640. XLValue, ExprRValue, /*BO=*/BO_Assign, /*IsXLHSInRHSPart=*/false, AO,
  5641. Loc, Gen);
  5642. CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, X);
  5643. if (Res.first) {
  5644. // 'atomicrmw' instruction was generated.
  5645. NewVVal = IsPostfixUpdate ? Res.second : ExprRValue;
  5646. }
  5647. }
  5648. // Emit post-update store to 'v' of old/new 'x' value.
  5649. CGF.emitOMPSimpleStore(VLValue, NewVVal, NewVValType, Loc);
  5650. CGF.CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(CGF, V);
  5651. // OpenMP 5.1 removes the required flush for capture clause.
  5652. if (CGF.CGM.getLangOpts().OpenMP < 51) {
  5653. // OpenMP, 2.17.7, atomic Construct
  5654. // If the write, update, or capture clause is specified and the release,
  5655. // acq_rel, or seq_cst clause is specified then the strong flush on entry to
  5656. // the atomic operation is also a release flush.
  5657. // If the read or capture clause is specified and the acquire, acq_rel, or
  5658. // seq_cst clause is specified then the strong flush on exit from the atomic
  5659. // operation is also an acquire flush.
  5660. switch (AO) {
  5661. case llvm::AtomicOrdering::Release:
  5662. CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc,
  5663. llvm::AtomicOrdering::Release);
  5664. break;
  5665. case llvm::AtomicOrdering::Acquire:
  5666. CGF.CGM.getOpenMPRuntime().emitFlush(CGF, llvm::None, Loc,
  5667. llvm::AtomicOrdering::Acquire);
  5668. break;
  5669. case llvm::AtomicOrdering::AcquireRelease:
  5670. case llvm::AtomicOrdering::SequentiallyConsistent:
  5671. CGF.CGM.getOpenMPRuntime().emitFlush(
  5672. CGF, llvm::None, Loc, llvm::AtomicOrdering::AcquireRelease);
  5673. break;
  5674. case llvm::AtomicOrdering::Monotonic:
  5675. break;
  5676. case llvm::AtomicOrdering::NotAtomic:
  5677. case llvm::AtomicOrdering::Unordered:
  5678. llvm_unreachable("Unexpected ordering.");
  5679. }
  5680. }
  5681. }
  5682. static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
  5683. llvm::AtomicOrdering AO, bool IsPostfixUpdate,
  5684. const Expr *X, const Expr *V, const Expr *E,
  5685. const Expr *UE, bool IsXLHSInRHSPart,
  5686. SourceLocation Loc) {
  5687. switch (Kind) {
  5688. case OMPC_read:
  5689. emitOMPAtomicReadExpr(CGF, AO, X, V, Loc);
  5690. break;
  5691. case OMPC_write:
  5692. emitOMPAtomicWriteExpr(CGF, AO, X, E, Loc);
  5693. break;
  5694. case OMPC_unknown:
  5695. case OMPC_update:
  5696. emitOMPAtomicUpdateExpr(CGF, AO, X, E, UE, IsXLHSInRHSPart, Loc);
  5697. break;
  5698. case OMPC_capture:
  5699. emitOMPAtomicCaptureExpr(CGF, AO, IsPostfixUpdate, V, X, E, UE,
  5700. IsXLHSInRHSPart, Loc);
  5701. break;
  5702. case OMPC_compare:
  5703. // Do nothing here as we already emit an error.
  5704. break;
  5705. case OMPC_if:
  5706. case OMPC_final:
  5707. case OMPC_num_threads:
  5708. case OMPC_private:
  5709. case OMPC_firstprivate:
  5710. case OMPC_lastprivate:
  5711. case OMPC_reduction:
  5712. case OMPC_task_reduction:
  5713. case OMPC_in_reduction:
  5714. case OMPC_safelen:
  5715. case OMPC_simdlen:
  5716. case OMPC_sizes:
  5717. case OMPC_full:
  5718. case OMPC_partial:
  5719. case OMPC_allocator:
  5720. case OMPC_allocate:
  5721. case OMPC_collapse:
  5722. case OMPC_default:
  5723. case OMPC_seq_cst:
  5724. case OMPC_acq_rel:
  5725. case OMPC_acquire:
  5726. case OMPC_release:
  5727. case OMPC_relaxed:
  5728. case OMPC_shared:
  5729. case OMPC_linear:
  5730. case OMPC_aligned:
  5731. case OMPC_copyin:
  5732. case OMPC_copyprivate:
  5733. case OMPC_flush:
  5734. case OMPC_depobj:
  5735. case OMPC_proc_bind:
  5736. case OMPC_schedule:
  5737. case OMPC_ordered:
  5738. case OMPC_nowait:
  5739. case OMPC_untied:
  5740. case OMPC_threadprivate:
  5741. case OMPC_depend:
  5742. case OMPC_mergeable:
  5743. case OMPC_device:
  5744. case OMPC_threads:
  5745. case OMPC_simd:
  5746. case OMPC_map:
  5747. case OMPC_num_teams:
  5748. case OMPC_thread_limit:
  5749. case OMPC_priority:
  5750. case OMPC_grainsize:
  5751. case OMPC_nogroup:
  5752. case OMPC_num_tasks:
  5753. case OMPC_hint:
  5754. case OMPC_dist_schedule:
  5755. case OMPC_defaultmap:
  5756. case OMPC_uniform:
  5757. case OMPC_to:
  5758. case OMPC_from:
  5759. case OMPC_use_device_ptr:
  5760. case OMPC_use_device_addr:
  5761. case OMPC_is_device_ptr:
  5762. case OMPC_unified_address:
  5763. case OMPC_unified_shared_memory:
  5764. case OMPC_reverse_offload:
  5765. case OMPC_dynamic_allocators:
  5766. case OMPC_atomic_default_mem_order:
  5767. case OMPC_device_type:
  5768. case OMPC_match:
  5769. case OMPC_nontemporal:
  5770. case OMPC_order:
  5771. case OMPC_destroy:
  5772. case OMPC_detach:
  5773. case OMPC_inclusive:
  5774. case OMPC_exclusive:
  5775. case OMPC_uses_allocators:
  5776. case OMPC_affinity:
  5777. case OMPC_init:
  5778. case OMPC_inbranch:
  5779. case OMPC_notinbranch:
  5780. case OMPC_link:
  5781. case OMPC_indirect:
  5782. case OMPC_use:
  5783. case OMPC_novariants:
  5784. case OMPC_nocontext:
  5785. case OMPC_filter:
  5786. case OMPC_when:
  5787. case OMPC_adjust_args:
  5788. case OMPC_append_args:
  5789. case OMPC_memory_order:
  5790. case OMPC_bind:
  5791. case OMPC_align:
  5792. llvm_unreachable("Clause is not allowed in 'omp atomic'.");
  5793. }
  5794. }
  5795. void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
  5796. llvm::AtomicOrdering AO = llvm::AtomicOrdering::Monotonic;
  5797. bool MemOrderingSpecified = false;
  5798. if (S.getSingleClause<OMPSeqCstClause>()) {
  5799. AO = llvm::AtomicOrdering::SequentiallyConsistent;
  5800. MemOrderingSpecified = true;
  5801. } else if (S.getSingleClause<OMPAcqRelClause>()) {
  5802. AO = llvm::AtomicOrdering::AcquireRelease;
  5803. MemOrderingSpecified = true;
  5804. } else if (S.getSingleClause<OMPAcquireClause>()) {
  5805. AO = llvm::AtomicOrdering::Acquire;
  5806. MemOrderingSpecified = true;
  5807. } else if (S.getSingleClause<OMPReleaseClause>()) {
  5808. AO = llvm::AtomicOrdering::Release;
  5809. MemOrderingSpecified = true;
  5810. } else if (S.getSingleClause<OMPRelaxedClause>()) {
  5811. AO = llvm::AtomicOrdering::Monotonic;
  5812. MemOrderingSpecified = true;
  5813. }
  5814. OpenMPClauseKind Kind = OMPC_unknown;
  5815. for (const OMPClause *C : S.clauses()) {
  5816. // Find first clause (skip seq_cst|acq_rel|aqcuire|release|relaxed clause,
  5817. // if it is first).
  5818. if (C->getClauseKind() != OMPC_seq_cst &&
  5819. C->getClauseKind() != OMPC_acq_rel &&
  5820. C->getClauseKind() != OMPC_acquire &&
  5821. C->getClauseKind() != OMPC_release &&
  5822. C->getClauseKind() != OMPC_relaxed && C->getClauseKind() != OMPC_hint) {
  5823. Kind = C->getClauseKind();
  5824. break;
  5825. }
  5826. }
  5827. if (!MemOrderingSpecified) {
  5828. llvm::AtomicOrdering DefaultOrder =
  5829. CGM.getOpenMPRuntime().getDefaultMemoryOrdering();
  5830. if (DefaultOrder == llvm::AtomicOrdering::Monotonic ||
  5831. DefaultOrder == llvm::AtomicOrdering::SequentiallyConsistent ||
  5832. (DefaultOrder == llvm::AtomicOrdering::AcquireRelease &&
  5833. Kind == OMPC_capture)) {
  5834. AO = DefaultOrder;
  5835. } else if (DefaultOrder == llvm::AtomicOrdering::AcquireRelease) {
  5836. if (Kind == OMPC_unknown || Kind == OMPC_update || Kind == OMPC_write) {
  5837. AO = llvm::AtomicOrdering::Release;
  5838. } else if (Kind == OMPC_read) {
  5839. assert(Kind == OMPC_read && "Unexpected atomic kind.");
  5840. AO = llvm::AtomicOrdering::Acquire;
  5841. }
  5842. }
  5843. }
  5844. LexicalScope Scope(*this, S.getSourceRange());
  5845. EmitStopPoint(S.getAssociatedStmt());
  5846. emitOMPAtomicExpr(*this, Kind, AO, S.isPostfixUpdate(), S.getX(), S.getV(),
  5847. S.getExpr(), S.getUpdateExpr(), S.isXLHSInRHSPart(),
  5848. S.getBeginLoc());
  5849. }
  5850. static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
  5851. const OMPExecutableDirective &S,
  5852. const RegionCodeGenTy &CodeGen) {
  5853. assert(isOpenMPTargetExecutionDirective(S.getDirectiveKind()));
  5854. CodeGenModule &CGM = CGF.CGM;
  5855. // On device emit this construct as inlined code.
  5856. if (CGM.getLangOpts().OpenMPIsDevice) {
  5857. OMPLexicalScope Scope(CGF, S, OMPD_target);
  5858. CGM.getOpenMPRuntime().emitInlinedDirective(
  5859. CGF, OMPD_target, [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  5860. CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
  5861. });
  5862. return;
  5863. }
  5864. auto LPCRegion = CGOpenMPRuntime::LastprivateConditionalRAII::disable(CGF, S);
  5865. llvm::Function *Fn = nullptr;
  5866. llvm::Constant *FnID = nullptr;
  5867. const Expr *IfCond = nullptr;
  5868. // Check for the at most one if clause associated with the target region.
  5869. for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
  5870. if (C->getNameModifier() == OMPD_unknown ||
  5871. C->getNameModifier() == OMPD_target) {
  5872. IfCond = C->getCondition();
  5873. break;
  5874. }
  5875. }
  5876. // Check if we have any device clause associated with the directive.
  5877. llvm::PointerIntPair<const Expr *, 2, OpenMPDeviceClauseModifier> Device(
  5878. nullptr, OMPC_DEVICE_unknown);
  5879. if (auto *C = S.getSingleClause<OMPDeviceClause>())
  5880. Device.setPointerAndInt(C->getDevice(), C->getModifier());
  5881. // Check if we have an if clause whose conditional always evaluates to false
  5882. // or if we do not have any targets specified. If so the target region is not
  5883. // an offload entry point.
  5884. bool IsOffloadEntry = true;
  5885. if (IfCond) {
  5886. bool Val;
  5887. if (CGF.ConstantFoldsToSimpleInteger(IfCond, Val) && !Val)
  5888. IsOffloadEntry = false;
  5889. }
  5890. if (CGM.getLangOpts().OMPTargetTriples.empty())
  5891. IsOffloadEntry = false;
  5892. assert(CGF.CurFuncDecl && "No parent declaration for target region!");
  5893. StringRef ParentName;
  5894. // In case we have Ctors/Dtors we use the complete type variant to produce
  5895. // the mangling of the device outlined kernel.
  5896. if (const auto *D = dyn_cast<CXXConstructorDecl>(CGF.CurFuncDecl))
  5897. ParentName = CGM.getMangledName(GlobalDecl(D, Ctor_Complete));
  5898. else if (const auto *D = dyn_cast<CXXDestructorDecl>(CGF.CurFuncDecl))
  5899. ParentName = CGM.getMangledName(GlobalDecl(D, Dtor_Complete));
  5900. else
  5901. ParentName =
  5902. CGM.getMangledName(GlobalDecl(cast<FunctionDecl>(CGF.CurFuncDecl)));
  5903. // Emit target region as a standalone region.
  5904. CGM.getOpenMPRuntime().emitTargetOutlinedFunction(S, ParentName, Fn, FnID,
  5905. IsOffloadEntry, CodeGen);
  5906. OMPLexicalScope Scope(CGF, S, OMPD_task);
  5907. auto &&SizeEmitter =
  5908. [IsOffloadEntry](CodeGenFunction &CGF,
  5909. const OMPLoopDirective &D) -> llvm::Value * {
  5910. if (IsOffloadEntry) {
  5911. OMPLoopScope(CGF, D);
  5912. // Emit calculation of the iterations count.
  5913. llvm::Value *NumIterations = CGF.EmitScalarExpr(D.getNumIterations());
  5914. NumIterations = CGF.Builder.CreateIntCast(NumIterations, CGF.Int64Ty,
  5915. /*isSigned=*/false);
  5916. return NumIterations;
  5917. }
  5918. return nullptr;
  5919. };
  5920. CGM.getOpenMPRuntime().emitTargetCall(CGF, S, Fn, FnID, IfCond, Device,
  5921. SizeEmitter);
  5922. }
  5923. static void emitTargetRegion(CodeGenFunction &CGF, const OMPTargetDirective &S,
  5924. PrePostActionTy &Action) {
  5925. Action.Enter(CGF);
  5926. CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
  5927. (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
  5928. CGF.EmitOMPPrivateClause(S, PrivateScope);
  5929. (void)PrivateScope.Privatize();
  5930. if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
  5931. CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
  5932. CGF.EmitStmt(S.getCapturedStmt(OMPD_target)->getCapturedStmt());
  5933. CGF.EnsureInsertPoint();
  5934. }
  5935. void CodeGenFunction::EmitOMPTargetDeviceFunction(CodeGenModule &CGM,
  5936. StringRef ParentName,
  5937. const OMPTargetDirective &S) {
  5938. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  5939. emitTargetRegion(CGF, S, Action);
  5940. };
  5941. llvm::Function *Fn;
  5942. llvm::Constant *Addr;
  5943. // Emit target region as a standalone region.
  5944. CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
  5945. S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
  5946. assert(Fn && Addr && "Target device function emission failed.");
  5947. }
  5948. void CodeGenFunction::EmitOMPTargetDirective(const OMPTargetDirective &S) {
  5949. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  5950. emitTargetRegion(CGF, S, Action);
  5951. };
  5952. emitCommonOMPTargetDirective(*this, S, CodeGen);
  5953. }
  5954. static void emitCommonOMPTeamsDirective(CodeGenFunction &CGF,
  5955. const OMPExecutableDirective &S,
  5956. OpenMPDirectiveKind InnermostKind,
  5957. const RegionCodeGenTy &CodeGen) {
  5958. const CapturedStmt *CS = S.getCapturedStmt(OMPD_teams);
  5959. llvm::Function *OutlinedFn =
  5960. CGF.CGM.getOpenMPRuntime().emitTeamsOutlinedFunction(
  5961. S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
  5962. const auto *NT = S.getSingleClause<OMPNumTeamsClause>();
  5963. const auto *TL = S.getSingleClause<OMPThreadLimitClause>();
  5964. if (NT || TL) {
  5965. const Expr *NumTeams = NT ? NT->getNumTeams() : nullptr;
  5966. const Expr *ThreadLimit = TL ? TL->getThreadLimit() : nullptr;
  5967. CGF.CGM.getOpenMPRuntime().emitNumTeamsClause(CGF, NumTeams, ThreadLimit,
  5968. S.getBeginLoc());
  5969. }
  5970. OMPTeamsScope Scope(CGF, S);
  5971. llvm::SmallVector<llvm::Value *, 16> CapturedVars;
  5972. CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
  5973. CGF.CGM.getOpenMPRuntime().emitTeamsCall(CGF, S, S.getBeginLoc(), OutlinedFn,
  5974. CapturedVars);
  5975. }
  5976. void CodeGenFunction::EmitOMPTeamsDirective(const OMPTeamsDirective &S) {
  5977. // Emit teams region as a standalone region.
  5978. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  5979. Action.Enter(CGF);
  5980. OMPPrivateScope PrivateScope(CGF);
  5981. (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
  5982. CGF.EmitOMPPrivateClause(S, PrivateScope);
  5983. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  5984. (void)PrivateScope.Privatize();
  5985. CGF.EmitStmt(S.getCapturedStmt(OMPD_teams)->getCapturedStmt());
  5986. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
  5987. };
  5988. emitCommonOMPTeamsDirective(*this, S, OMPD_distribute, CodeGen);
  5989. emitPostUpdateForReductionClause(*this, S,
  5990. [](CodeGenFunction &) { return nullptr; });
  5991. }
  5992. static void emitTargetTeamsRegion(CodeGenFunction &CGF, PrePostActionTy &Action,
  5993. const OMPTargetTeamsDirective &S) {
  5994. auto *CS = S.getCapturedStmt(OMPD_teams);
  5995. Action.Enter(CGF);
  5996. // Emit teams region as a standalone region.
  5997. auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &Action) {
  5998. Action.Enter(CGF);
  5999. CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
  6000. (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
  6001. CGF.EmitOMPPrivateClause(S, PrivateScope);
  6002. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  6003. (void)PrivateScope.Privatize();
  6004. if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
  6005. CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
  6006. CGF.EmitStmt(CS->getCapturedStmt());
  6007. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
  6008. };
  6009. emitCommonOMPTeamsDirective(CGF, S, OMPD_teams, CodeGen);
  6010. emitPostUpdateForReductionClause(CGF, S,
  6011. [](CodeGenFunction &) { return nullptr; });
  6012. }
  6013. void CodeGenFunction::EmitOMPTargetTeamsDeviceFunction(
  6014. CodeGenModule &CGM, StringRef ParentName,
  6015. const OMPTargetTeamsDirective &S) {
  6016. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6017. emitTargetTeamsRegion(CGF, Action, S);
  6018. };
  6019. llvm::Function *Fn;
  6020. llvm::Constant *Addr;
  6021. // Emit target region as a standalone region.
  6022. CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
  6023. S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
  6024. assert(Fn && Addr && "Target device function emission failed.");
  6025. }
  6026. void CodeGenFunction::EmitOMPTargetTeamsDirective(
  6027. const OMPTargetTeamsDirective &S) {
  6028. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6029. emitTargetTeamsRegion(CGF, Action, S);
  6030. };
  6031. emitCommonOMPTargetDirective(*this, S, CodeGen);
  6032. }
  6033. static void
  6034. emitTargetTeamsDistributeRegion(CodeGenFunction &CGF, PrePostActionTy &Action,
  6035. const OMPTargetTeamsDistributeDirective &S) {
  6036. Action.Enter(CGF);
  6037. auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  6038. CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
  6039. };
  6040. // Emit teams region as a standalone region.
  6041. auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
  6042. PrePostActionTy &Action) {
  6043. Action.Enter(CGF);
  6044. CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
  6045. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  6046. (void)PrivateScope.Privatize();
  6047. CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
  6048. CodeGenDistribute);
  6049. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
  6050. };
  6051. emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute, CodeGen);
  6052. emitPostUpdateForReductionClause(CGF, S,
  6053. [](CodeGenFunction &) { return nullptr; });
  6054. }
  6055. void CodeGenFunction::EmitOMPTargetTeamsDistributeDeviceFunction(
  6056. CodeGenModule &CGM, StringRef ParentName,
  6057. const OMPTargetTeamsDistributeDirective &S) {
  6058. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6059. emitTargetTeamsDistributeRegion(CGF, Action, S);
  6060. };
  6061. llvm::Function *Fn;
  6062. llvm::Constant *Addr;
  6063. // Emit target region as a standalone region.
  6064. CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
  6065. S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
  6066. assert(Fn && Addr && "Target device function emission failed.");
  6067. }
  6068. void CodeGenFunction::EmitOMPTargetTeamsDistributeDirective(
  6069. const OMPTargetTeamsDistributeDirective &S) {
  6070. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6071. emitTargetTeamsDistributeRegion(CGF, Action, S);
  6072. };
  6073. emitCommonOMPTargetDirective(*this, S, CodeGen);
  6074. }
  6075. static void emitTargetTeamsDistributeSimdRegion(
  6076. CodeGenFunction &CGF, PrePostActionTy &Action,
  6077. const OMPTargetTeamsDistributeSimdDirective &S) {
  6078. Action.Enter(CGF);
  6079. auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  6080. CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
  6081. };
  6082. // Emit teams region as a standalone region.
  6083. auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
  6084. PrePostActionTy &Action) {
  6085. Action.Enter(CGF);
  6086. CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
  6087. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  6088. (void)PrivateScope.Privatize();
  6089. CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
  6090. CodeGenDistribute);
  6091. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
  6092. };
  6093. emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_simd, CodeGen);
  6094. emitPostUpdateForReductionClause(CGF, S,
  6095. [](CodeGenFunction &) { return nullptr; });
  6096. }
  6097. void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDeviceFunction(
  6098. CodeGenModule &CGM, StringRef ParentName,
  6099. const OMPTargetTeamsDistributeSimdDirective &S) {
  6100. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6101. emitTargetTeamsDistributeSimdRegion(CGF, Action, S);
  6102. };
  6103. llvm::Function *Fn;
  6104. llvm::Constant *Addr;
  6105. // Emit target region as a standalone region.
  6106. CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
  6107. S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
  6108. assert(Fn && Addr && "Target device function emission failed.");
  6109. }
  6110. void CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDirective(
  6111. const OMPTargetTeamsDistributeSimdDirective &S) {
  6112. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6113. emitTargetTeamsDistributeSimdRegion(CGF, Action, S);
  6114. };
  6115. emitCommonOMPTargetDirective(*this, S, CodeGen);
  6116. }
  6117. void CodeGenFunction::EmitOMPTeamsDistributeDirective(
  6118. const OMPTeamsDistributeDirective &S) {
  6119. auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  6120. CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
  6121. };
  6122. // Emit teams region as a standalone region.
  6123. auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
  6124. PrePostActionTy &Action) {
  6125. Action.Enter(CGF);
  6126. OMPPrivateScope PrivateScope(CGF);
  6127. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  6128. (void)PrivateScope.Privatize();
  6129. CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
  6130. CodeGenDistribute);
  6131. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
  6132. };
  6133. emitCommonOMPTeamsDirective(*this, S, OMPD_distribute, CodeGen);
  6134. emitPostUpdateForReductionClause(*this, S,
  6135. [](CodeGenFunction &) { return nullptr; });
  6136. }
  6137. void CodeGenFunction::EmitOMPTeamsDistributeSimdDirective(
  6138. const OMPTeamsDistributeSimdDirective &S) {
  6139. auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  6140. CGF.EmitOMPDistributeLoop(S, emitOMPLoopBodyWithStopPoint, S.getInc());
  6141. };
  6142. // Emit teams region as a standalone region.
  6143. auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
  6144. PrePostActionTy &Action) {
  6145. Action.Enter(CGF);
  6146. OMPPrivateScope PrivateScope(CGF);
  6147. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  6148. (void)PrivateScope.Privatize();
  6149. CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_simd,
  6150. CodeGenDistribute);
  6151. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
  6152. };
  6153. emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_simd, CodeGen);
  6154. emitPostUpdateForReductionClause(*this, S,
  6155. [](CodeGenFunction &) { return nullptr; });
  6156. }
  6157. void CodeGenFunction::EmitOMPTeamsDistributeParallelForDirective(
  6158. const OMPTeamsDistributeParallelForDirective &S) {
  6159. auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  6160. CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
  6161. S.getDistInc());
  6162. };
  6163. // Emit teams region as a standalone region.
  6164. auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
  6165. PrePostActionTy &Action) {
  6166. Action.Enter(CGF);
  6167. OMPPrivateScope PrivateScope(CGF);
  6168. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  6169. (void)PrivateScope.Privatize();
  6170. CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_distribute,
  6171. CodeGenDistribute);
  6172. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
  6173. };
  6174. emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_parallel_for, CodeGen);
  6175. emitPostUpdateForReductionClause(*this, S,
  6176. [](CodeGenFunction &) { return nullptr; });
  6177. }
  6178. void CodeGenFunction::EmitOMPTeamsDistributeParallelForSimdDirective(
  6179. const OMPTeamsDistributeParallelForSimdDirective &S) {
  6180. auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  6181. CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
  6182. S.getDistInc());
  6183. };
  6184. // Emit teams region as a standalone region.
  6185. auto &&CodeGen = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
  6186. PrePostActionTy &Action) {
  6187. Action.Enter(CGF);
  6188. OMPPrivateScope PrivateScope(CGF);
  6189. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  6190. (void)PrivateScope.Privatize();
  6191. CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
  6192. CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false);
  6193. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
  6194. };
  6195. emitCommonOMPTeamsDirective(*this, S, OMPD_distribute_parallel_for_simd,
  6196. CodeGen);
  6197. emitPostUpdateForReductionClause(*this, S,
  6198. [](CodeGenFunction &) { return nullptr; });
  6199. }
  6200. void CodeGenFunction::EmitOMPInteropDirective(const OMPInteropDirective &S) {
  6201. llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  6202. llvm::Value *Device = nullptr;
  6203. if (const auto *C = S.getSingleClause<OMPDeviceClause>())
  6204. Device = EmitScalarExpr(C->getDevice());
  6205. llvm::Value *NumDependences = nullptr;
  6206. llvm::Value *DependenceAddress = nullptr;
  6207. if (const auto *DC = S.getSingleClause<OMPDependClause>()) {
  6208. OMPTaskDataTy::DependData Dependencies(DC->getDependencyKind(),
  6209. DC->getModifier());
  6210. Dependencies.DepExprs.append(DC->varlist_begin(), DC->varlist_end());
  6211. std::pair<llvm::Value *, Address> DependencePair =
  6212. CGM.getOpenMPRuntime().emitDependClause(*this, Dependencies,
  6213. DC->getBeginLoc());
  6214. NumDependences = DependencePair.first;
  6215. DependenceAddress = Builder.CreatePointerCast(
  6216. DependencePair.second.getPointer(), CGM.Int8PtrTy);
  6217. }
  6218. assert(!(S.hasClausesOfKind<OMPNowaitClause>() &&
  6219. !(S.getSingleClause<OMPInitClause>() ||
  6220. S.getSingleClause<OMPDestroyClause>() ||
  6221. S.getSingleClause<OMPUseClause>())) &&
  6222. "OMPNowaitClause clause is used separately in OMPInteropDirective.");
  6223. if (const auto *C = S.getSingleClause<OMPInitClause>()) {
  6224. llvm::Value *InteropvarPtr =
  6225. EmitLValue(C->getInteropVar()).getPointer(*this);
  6226. llvm::omp::OMPInteropType InteropType = llvm::omp::OMPInteropType::Unknown;
  6227. if (C->getIsTarget()) {
  6228. InteropType = llvm::omp::OMPInteropType::Target;
  6229. } else {
  6230. assert(C->getIsTargetSync() && "Expected interop-type target/targetsync");
  6231. InteropType = llvm::omp::OMPInteropType::TargetSync;
  6232. }
  6233. OMPBuilder.createOMPInteropInit(Builder, InteropvarPtr, InteropType, Device,
  6234. NumDependences, DependenceAddress,
  6235. S.hasClausesOfKind<OMPNowaitClause>());
  6236. } else if (const auto *C = S.getSingleClause<OMPDestroyClause>()) {
  6237. llvm::Value *InteropvarPtr =
  6238. EmitLValue(C->getInteropVar()).getPointer(*this);
  6239. OMPBuilder.createOMPInteropDestroy(Builder, InteropvarPtr, Device,
  6240. NumDependences, DependenceAddress,
  6241. S.hasClausesOfKind<OMPNowaitClause>());
  6242. } else if (const auto *C = S.getSingleClause<OMPUseClause>()) {
  6243. llvm::Value *InteropvarPtr =
  6244. EmitLValue(C->getInteropVar()).getPointer(*this);
  6245. OMPBuilder.createOMPInteropUse(Builder, InteropvarPtr, Device,
  6246. NumDependences, DependenceAddress,
  6247. S.hasClausesOfKind<OMPNowaitClause>());
  6248. }
  6249. }
  6250. static void emitTargetTeamsDistributeParallelForRegion(
  6251. CodeGenFunction &CGF, const OMPTargetTeamsDistributeParallelForDirective &S,
  6252. PrePostActionTy &Action) {
  6253. Action.Enter(CGF);
  6254. auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  6255. CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
  6256. S.getDistInc());
  6257. };
  6258. // Emit teams region as a standalone region.
  6259. auto &&CodeGenTeams = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
  6260. PrePostActionTy &Action) {
  6261. Action.Enter(CGF);
  6262. CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
  6263. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  6264. (void)PrivateScope.Privatize();
  6265. CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
  6266. CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false);
  6267. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
  6268. };
  6269. emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_parallel_for,
  6270. CodeGenTeams);
  6271. emitPostUpdateForReductionClause(CGF, S,
  6272. [](CodeGenFunction &) { return nullptr; });
  6273. }
  6274. void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDeviceFunction(
  6275. CodeGenModule &CGM, StringRef ParentName,
  6276. const OMPTargetTeamsDistributeParallelForDirective &S) {
  6277. // Emit SPMD target teams distribute parallel for region as a standalone
  6278. // region.
  6279. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6280. emitTargetTeamsDistributeParallelForRegion(CGF, S, Action);
  6281. };
  6282. llvm::Function *Fn;
  6283. llvm::Constant *Addr;
  6284. // Emit target region as a standalone region.
  6285. CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
  6286. S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
  6287. assert(Fn && Addr && "Target device function emission failed.");
  6288. }
  6289. void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDirective(
  6290. const OMPTargetTeamsDistributeParallelForDirective &S) {
  6291. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6292. emitTargetTeamsDistributeParallelForRegion(CGF, S, Action);
  6293. };
  6294. emitCommonOMPTargetDirective(*this, S, CodeGen);
  6295. }
  6296. static void emitTargetTeamsDistributeParallelForSimdRegion(
  6297. CodeGenFunction &CGF,
  6298. const OMPTargetTeamsDistributeParallelForSimdDirective &S,
  6299. PrePostActionTy &Action) {
  6300. Action.Enter(CGF);
  6301. auto &&CodeGenDistribute = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  6302. CGF.EmitOMPDistributeLoop(S, emitInnerParallelForWhenCombined,
  6303. S.getDistInc());
  6304. };
  6305. // Emit teams region as a standalone region.
  6306. auto &&CodeGenTeams = [&S, &CodeGenDistribute](CodeGenFunction &CGF,
  6307. PrePostActionTy &Action) {
  6308. Action.Enter(CGF);
  6309. CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
  6310. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  6311. (void)PrivateScope.Privatize();
  6312. CGF.CGM.getOpenMPRuntime().emitInlinedDirective(
  6313. CGF, OMPD_distribute, CodeGenDistribute, /*HasCancel=*/false);
  6314. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_teams);
  6315. };
  6316. emitCommonOMPTeamsDirective(CGF, S, OMPD_distribute_parallel_for_simd,
  6317. CodeGenTeams);
  6318. emitPostUpdateForReductionClause(CGF, S,
  6319. [](CodeGenFunction &) { return nullptr; });
  6320. }
  6321. void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(
  6322. CodeGenModule &CGM, StringRef ParentName,
  6323. const OMPTargetTeamsDistributeParallelForSimdDirective &S) {
  6324. // Emit SPMD target teams distribute parallel for simd region as a standalone
  6325. // region.
  6326. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6327. emitTargetTeamsDistributeParallelForSimdRegion(CGF, S, Action);
  6328. };
  6329. llvm::Function *Fn;
  6330. llvm::Constant *Addr;
  6331. // Emit target region as a standalone region.
  6332. CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
  6333. S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
  6334. assert(Fn && Addr && "Target device function emission failed.");
  6335. }
  6336. void CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForSimdDirective(
  6337. const OMPTargetTeamsDistributeParallelForSimdDirective &S) {
  6338. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6339. emitTargetTeamsDistributeParallelForSimdRegion(CGF, S, Action);
  6340. };
  6341. emitCommonOMPTargetDirective(*this, S, CodeGen);
  6342. }
  6343. void CodeGenFunction::EmitOMPCancellationPointDirective(
  6344. const OMPCancellationPointDirective &S) {
  6345. CGM.getOpenMPRuntime().emitCancellationPointCall(*this, S.getBeginLoc(),
  6346. S.getCancelRegion());
  6347. }
  6348. void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) {
  6349. const Expr *IfCond = nullptr;
  6350. for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
  6351. if (C->getNameModifier() == OMPD_unknown ||
  6352. C->getNameModifier() == OMPD_cancel) {
  6353. IfCond = C->getCondition();
  6354. break;
  6355. }
  6356. }
  6357. if (CGM.getLangOpts().OpenMPIRBuilder) {
  6358. llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
  6359. // TODO: This check is necessary as we only generate `omp parallel` through
  6360. // the OpenMPIRBuilder for now.
  6361. if (S.getCancelRegion() == OMPD_parallel ||
  6362. S.getCancelRegion() == OMPD_sections ||
  6363. S.getCancelRegion() == OMPD_section) {
  6364. llvm::Value *IfCondition = nullptr;
  6365. if (IfCond)
  6366. IfCondition = EmitScalarExpr(IfCond,
  6367. /*IgnoreResultAssign=*/true);
  6368. return Builder.restoreIP(
  6369. OMPBuilder.createCancel(Builder, IfCondition, S.getCancelRegion()));
  6370. }
  6371. }
  6372. CGM.getOpenMPRuntime().emitCancelCall(*this, S.getBeginLoc(), IfCond,
  6373. S.getCancelRegion());
  6374. }
  6375. CodeGenFunction::JumpDest
  6376. CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
  6377. if (Kind == OMPD_parallel || Kind == OMPD_task ||
  6378. Kind == OMPD_target_parallel || Kind == OMPD_taskloop ||
  6379. Kind == OMPD_master_taskloop || Kind == OMPD_parallel_master_taskloop)
  6380. return ReturnBlock;
  6381. assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
  6382. Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
  6383. Kind == OMPD_distribute_parallel_for ||
  6384. Kind == OMPD_target_parallel_for ||
  6385. Kind == OMPD_teams_distribute_parallel_for ||
  6386. Kind == OMPD_target_teams_distribute_parallel_for);
  6387. return OMPCancelStack.getExitBlock();
  6388. }
  6389. void CodeGenFunction::EmitOMPUseDevicePtrClause(
  6390. const OMPUseDevicePtrClause &C, OMPPrivateScope &PrivateScope,
  6391. const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap) {
  6392. auto OrigVarIt = C.varlist_begin();
  6393. auto InitIt = C.inits().begin();
  6394. for (const Expr *PvtVarIt : C.private_copies()) {
  6395. const auto *OrigVD =
  6396. cast<VarDecl>(cast<DeclRefExpr>(*OrigVarIt)->getDecl());
  6397. const auto *InitVD = cast<VarDecl>(cast<DeclRefExpr>(*InitIt)->getDecl());
  6398. const auto *PvtVD = cast<VarDecl>(cast<DeclRefExpr>(PvtVarIt)->getDecl());
  6399. // In order to identify the right initializer we need to match the
  6400. // declaration used by the mapping logic. In some cases we may get
  6401. // OMPCapturedExprDecl that refers to the original declaration.
  6402. const ValueDecl *MatchingVD = OrigVD;
  6403. if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {
  6404. // OMPCapturedExprDecl are used to privative fields of the current
  6405. // structure.
  6406. const auto *ME = cast<MemberExpr>(OED->getInit());
  6407. assert(isa<CXXThisExpr>(ME->getBase()) &&
  6408. "Base should be the current struct!");
  6409. MatchingVD = ME->getMemberDecl();
  6410. }
  6411. // If we don't have information about the current list item, move on to
  6412. // the next one.
  6413. auto InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);
  6414. if (InitAddrIt == CaptureDeviceAddrMap.end())
  6415. continue;
  6416. bool IsRegistered = PrivateScope.addPrivate(
  6417. OrigVD, [this, OrigVD, InitAddrIt, InitVD, PvtVD]() {
  6418. // Initialize the temporary initialization variable with the address
  6419. // we get from the runtime library. We have to cast the source address
  6420. // because it is always a void *. References are materialized in the
  6421. // privatization scope, so the initialization here disregards the fact
  6422. // the original variable is a reference.
  6423. QualType AddrQTy = getContext().getPointerType(
  6424. OrigVD->getType().getNonReferenceType());
  6425. llvm::Type *AddrTy = ConvertTypeForMem(AddrQTy);
  6426. Address InitAddr = Builder.CreateBitCast(InitAddrIt->second, AddrTy);
  6427. setAddrOfLocalVar(InitVD, InitAddr);
  6428. // Emit private declaration, it will be initialized by the value we
  6429. // declaration we just added to the local declarations map.
  6430. EmitDecl(*PvtVD);
  6431. // The initialization variables reached its purpose in the emission
  6432. // of the previous declaration, so we don't need it anymore.
  6433. LocalDeclMap.erase(InitVD);
  6434. // Return the address of the private variable.
  6435. return GetAddrOfLocalVar(PvtVD);
  6436. });
  6437. assert(IsRegistered && "firstprivate var already registered as private");
  6438. // Silence the warning about unused variable.
  6439. (void)IsRegistered;
  6440. ++OrigVarIt;
  6441. ++InitIt;
  6442. }
  6443. }
  6444. static const VarDecl *getBaseDecl(const Expr *Ref) {
  6445. const Expr *Base = Ref->IgnoreParenImpCasts();
  6446. while (const auto *OASE = dyn_cast<OMPArraySectionExpr>(Base))
  6447. Base = OASE->getBase()->IgnoreParenImpCasts();
  6448. while (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Base))
  6449. Base = ASE->getBase()->IgnoreParenImpCasts();
  6450. return cast<VarDecl>(cast<DeclRefExpr>(Base)->getDecl());
  6451. }
  6452. void CodeGenFunction::EmitOMPUseDeviceAddrClause(
  6453. const OMPUseDeviceAddrClause &C, OMPPrivateScope &PrivateScope,
  6454. const llvm::DenseMap<const ValueDecl *, Address> &CaptureDeviceAddrMap) {
  6455. llvm::SmallDenseSet<CanonicalDeclPtr<const Decl>, 4> Processed;
  6456. for (const Expr *Ref : C.varlists()) {
  6457. const VarDecl *OrigVD = getBaseDecl(Ref);
  6458. if (!Processed.insert(OrigVD).second)
  6459. continue;
  6460. // In order to identify the right initializer we need to match the
  6461. // declaration used by the mapping logic. In some cases we may get
  6462. // OMPCapturedExprDecl that refers to the original declaration.
  6463. const ValueDecl *MatchingVD = OrigVD;
  6464. if (const auto *OED = dyn_cast<OMPCapturedExprDecl>(MatchingVD)) {
  6465. // OMPCapturedExprDecl are used to privative fields of the current
  6466. // structure.
  6467. const auto *ME = cast<MemberExpr>(OED->getInit());
  6468. assert(isa<CXXThisExpr>(ME->getBase()) &&
  6469. "Base should be the current struct!");
  6470. MatchingVD = ME->getMemberDecl();
  6471. }
  6472. // If we don't have information about the current list item, move on to
  6473. // the next one.
  6474. auto InitAddrIt = CaptureDeviceAddrMap.find(MatchingVD);
  6475. if (InitAddrIt == CaptureDeviceAddrMap.end())
  6476. continue;
  6477. Address PrivAddr = InitAddrIt->getSecond();
  6478. // For declrefs and variable length array need to load the pointer for
  6479. // correct mapping, since the pointer to the data was passed to the runtime.
  6480. if (isa<DeclRefExpr>(Ref->IgnoreParenImpCasts()) ||
  6481. MatchingVD->getType()->isArrayType())
  6482. PrivAddr =
  6483. EmitLoadOfPointer(PrivAddr, getContext()
  6484. .getPointerType(OrigVD->getType())
  6485. ->castAs<PointerType>());
  6486. llvm::Type *RealTy =
  6487. ConvertTypeForMem(OrigVD->getType().getNonReferenceType())
  6488. ->getPointerTo();
  6489. PrivAddr = Builder.CreatePointerBitCastOrAddrSpaceCast(PrivAddr, RealTy);
  6490. (void)PrivateScope.addPrivate(OrigVD, [PrivAddr]() { return PrivAddr; });
  6491. }
  6492. }
  6493. // Generate the instructions for '#pragma omp target data' directive.
  6494. void CodeGenFunction::EmitOMPTargetDataDirective(
  6495. const OMPTargetDataDirective &S) {
  6496. CGOpenMPRuntime::TargetDataInfo Info(/*RequiresDevicePointerInfo=*/true,
  6497. /*SeparateBeginEndCalls=*/true);
  6498. // Create a pre/post action to signal the privatization of the device pointer.
  6499. // This action can be replaced by the OpenMP runtime code generation to
  6500. // deactivate privatization.
  6501. bool PrivatizeDevicePointers = false;
  6502. class DevicePointerPrivActionTy : public PrePostActionTy {
  6503. bool &PrivatizeDevicePointers;
  6504. public:
  6505. explicit DevicePointerPrivActionTy(bool &PrivatizeDevicePointers)
  6506. : PrivatizeDevicePointers(PrivatizeDevicePointers) {}
  6507. void Enter(CodeGenFunction &CGF) override {
  6508. PrivatizeDevicePointers = true;
  6509. }
  6510. };
  6511. DevicePointerPrivActionTy PrivAction(PrivatizeDevicePointers);
  6512. auto &&CodeGen = [&S, &Info, &PrivatizeDevicePointers](
  6513. CodeGenFunction &CGF, PrePostActionTy &Action) {
  6514. auto &&InnermostCodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  6515. CGF.EmitStmt(S.getInnermostCapturedStmt()->getCapturedStmt());
  6516. };
  6517. // Codegen that selects whether to generate the privatization code or not.
  6518. auto &&PrivCodeGen = [&S, &Info, &PrivatizeDevicePointers,
  6519. &InnermostCodeGen](CodeGenFunction &CGF,
  6520. PrePostActionTy &Action) {
  6521. RegionCodeGenTy RCG(InnermostCodeGen);
  6522. PrivatizeDevicePointers = false;
  6523. // Call the pre-action to change the status of PrivatizeDevicePointers if
  6524. // needed.
  6525. Action.Enter(CGF);
  6526. if (PrivatizeDevicePointers) {
  6527. OMPPrivateScope PrivateScope(CGF);
  6528. // Emit all instances of the use_device_ptr clause.
  6529. for (const auto *C : S.getClausesOfKind<OMPUseDevicePtrClause>())
  6530. CGF.EmitOMPUseDevicePtrClause(*C, PrivateScope,
  6531. Info.CaptureDeviceAddrMap);
  6532. for (const auto *C : S.getClausesOfKind<OMPUseDeviceAddrClause>())
  6533. CGF.EmitOMPUseDeviceAddrClause(*C, PrivateScope,
  6534. Info.CaptureDeviceAddrMap);
  6535. (void)PrivateScope.Privatize();
  6536. RCG(CGF);
  6537. } else {
  6538. OMPLexicalScope Scope(CGF, S, OMPD_unknown);
  6539. RCG(CGF);
  6540. }
  6541. };
  6542. // Forward the provided action to the privatization codegen.
  6543. RegionCodeGenTy PrivRCG(PrivCodeGen);
  6544. PrivRCG.setAction(Action);
  6545. // Notwithstanding the body of the region is emitted as inlined directive,
  6546. // we don't use an inline scope as changes in the references inside the
  6547. // region are expected to be visible outside, so we do not privative them.
  6548. OMPLexicalScope Scope(CGF, S);
  6549. CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_target_data,
  6550. PrivRCG);
  6551. };
  6552. RegionCodeGenTy RCG(CodeGen);
  6553. // If we don't have target devices, don't bother emitting the data mapping
  6554. // code.
  6555. if (CGM.getLangOpts().OMPTargetTriples.empty()) {
  6556. RCG(*this);
  6557. return;
  6558. }
  6559. // Check if we have any if clause associated with the directive.
  6560. const Expr *IfCond = nullptr;
  6561. if (const auto *C = S.getSingleClause<OMPIfClause>())
  6562. IfCond = C->getCondition();
  6563. // Check if we have any device clause associated with the directive.
  6564. const Expr *Device = nullptr;
  6565. if (const auto *C = S.getSingleClause<OMPDeviceClause>())
  6566. Device = C->getDevice();
  6567. // Set the action to signal privatization of device pointers.
  6568. RCG.setAction(PrivAction);
  6569. // Emit region code.
  6570. CGM.getOpenMPRuntime().emitTargetDataCalls(*this, S, IfCond, Device, RCG,
  6571. Info);
  6572. }
  6573. void CodeGenFunction::EmitOMPTargetEnterDataDirective(
  6574. const OMPTargetEnterDataDirective &S) {
  6575. // If we don't have target devices, don't bother emitting the data mapping
  6576. // code.
  6577. if (CGM.getLangOpts().OMPTargetTriples.empty())
  6578. return;
  6579. // Check if we have any if clause associated with the directive.
  6580. const Expr *IfCond = nullptr;
  6581. if (const auto *C = S.getSingleClause<OMPIfClause>())
  6582. IfCond = C->getCondition();
  6583. // Check if we have any device clause associated with the directive.
  6584. const Expr *Device = nullptr;
  6585. if (const auto *C = S.getSingleClause<OMPDeviceClause>())
  6586. Device = C->getDevice();
  6587. OMPLexicalScope Scope(*this, S, OMPD_task);
  6588. CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
  6589. }
  6590. void CodeGenFunction::EmitOMPTargetExitDataDirective(
  6591. const OMPTargetExitDataDirective &S) {
  6592. // If we don't have target devices, don't bother emitting the data mapping
  6593. // code.
  6594. if (CGM.getLangOpts().OMPTargetTriples.empty())
  6595. return;
  6596. // Check if we have any if clause associated with the directive.
  6597. const Expr *IfCond = nullptr;
  6598. if (const auto *C = S.getSingleClause<OMPIfClause>())
  6599. IfCond = C->getCondition();
  6600. // Check if we have any device clause associated with the directive.
  6601. const Expr *Device = nullptr;
  6602. if (const auto *C = S.getSingleClause<OMPDeviceClause>())
  6603. Device = C->getDevice();
  6604. OMPLexicalScope Scope(*this, S, OMPD_task);
  6605. CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
  6606. }
  6607. static void emitTargetParallelRegion(CodeGenFunction &CGF,
  6608. const OMPTargetParallelDirective &S,
  6609. PrePostActionTy &Action) {
  6610. // Get the captured statement associated with the 'parallel' region.
  6611. const CapturedStmt *CS = S.getCapturedStmt(OMPD_parallel);
  6612. Action.Enter(CGF);
  6613. auto &&CodeGen = [&S, CS](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6614. Action.Enter(CGF);
  6615. CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
  6616. (void)CGF.EmitOMPFirstprivateClause(S, PrivateScope);
  6617. CGF.EmitOMPPrivateClause(S, PrivateScope);
  6618. CGF.EmitOMPReductionClauseInit(S, PrivateScope);
  6619. (void)PrivateScope.Privatize();
  6620. if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
  6621. CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
  6622. // TODO: Add support for clauses.
  6623. CGF.EmitStmt(CS->getCapturedStmt());
  6624. CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_parallel);
  6625. };
  6626. emitCommonOMPParallelDirective(CGF, S, OMPD_parallel, CodeGen,
  6627. emitEmptyBoundParameters);
  6628. emitPostUpdateForReductionClause(CGF, S,
  6629. [](CodeGenFunction &) { return nullptr; });
  6630. }
  6631. void CodeGenFunction::EmitOMPTargetParallelDeviceFunction(
  6632. CodeGenModule &CGM, StringRef ParentName,
  6633. const OMPTargetParallelDirective &S) {
  6634. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6635. emitTargetParallelRegion(CGF, S, Action);
  6636. };
  6637. llvm::Function *Fn;
  6638. llvm::Constant *Addr;
  6639. // Emit target region as a standalone region.
  6640. CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
  6641. S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
  6642. assert(Fn && Addr && "Target device function emission failed.");
  6643. }
  6644. void CodeGenFunction::EmitOMPTargetParallelDirective(
  6645. const OMPTargetParallelDirective &S) {
  6646. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6647. emitTargetParallelRegion(CGF, S, Action);
  6648. };
  6649. emitCommonOMPTargetDirective(*this, S, CodeGen);
  6650. }
  6651. static void emitTargetParallelForRegion(CodeGenFunction &CGF,
  6652. const OMPTargetParallelForDirective &S,
  6653. PrePostActionTy &Action) {
  6654. Action.Enter(CGF);
  6655. // Emit directive as a combined directive that consists of two implicit
  6656. // directives: 'parallel' with 'for' directive.
  6657. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6658. Action.Enter(CGF);
  6659. CodeGenFunction::OMPCancelStackRAII CancelRegion(
  6660. CGF, OMPD_target_parallel_for, S.hasCancel());
  6661. CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
  6662. emitDispatchForLoopBounds);
  6663. };
  6664. emitCommonOMPParallelDirective(CGF, S, OMPD_for, CodeGen,
  6665. emitEmptyBoundParameters);
  6666. }
  6667. void CodeGenFunction::EmitOMPTargetParallelForDeviceFunction(
  6668. CodeGenModule &CGM, StringRef ParentName,
  6669. const OMPTargetParallelForDirective &S) {
  6670. // Emit SPMD target parallel for region as a standalone region.
  6671. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6672. emitTargetParallelForRegion(CGF, S, Action);
  6673. };
  6674. llvm::Function *Fn;
  6675. llvm::Constant *Addr;
  6676. // Emit target region as a standalone region.
  6677. CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
  6678. S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
  6679. assert(Fn && Addr && "Target device function emission failed.");
  6680. }
  6681. void CodeGenFunction::EmitOMPTargetParallelForDirective(
  6682. const OMPTargetParallelForDirective &S) {
  6683. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6684. emitTargetParallelForRegion(CGF, S, Action);
  6685. };
  6686. emitCommonOMPTargetDirective(*this, S, CodeGen);
  6687. }
  6688. static void
  6689. emitTargetParallelForSimdRegion(CodeGenFunction &CGF,
  6690. const OMPTargetParallelForSimdDirective &S,
  6691. PrePostActionTy &Action) {
  6692. Action.Enter(CGF);
  6693. // Emit directive as a combined directive that consists of two implicit
  6694. // directives: 'parallel' with 'for' directive.
  6695. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6696. Action.Enter(CGF);
  6697. CGF.EmitOMPWorksharingLoop(S, S.getEnsureUpperBound(), emitForLoopBounds,
  6698. emitDispatchForLoopBounds);
  6699. };
  6700. emitCommonOMPParallelDirective(CGF, S, OMPD_simd, CodeGen,
  6701. emitEmptyBoundParameters);
  6702. }
  6703. void CodeGenFunction::EmitOMPTargetParallelForSimdDeviceFunction(
  6704. CodeGenModule &CGM, StringRef ParentName,
  6705. const OMPTargetParallelForSimdDirective &S) {
  6706. // Emit SPMD target parallel for region as a standalone region.
  6707. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6708. emitTargetParallelForSimdRegion(CGF, S, Action);
  6709. };
  6710. llvm::Function *Fn;
  6711. llvm::Constant *Addr;
  6712. // Emit target region as a standalone region.
  6713. CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
  6714. S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
  6715. assert(Fn && Addr && "Target device function emission failed.");
  6716. }
  6717. void CodeGenFunction::EmitOMPTargetParallelForSimdDirective(
  6718. const OMPTargetParallelForSimdDirective &S) {
  6719. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6720. emitTargetParallelForSimdRegion(CGF, S, Action);
  6721. };
  6722. emitCommonOMPTargetDirective(*this, S, CodeGen);
  6723. }
  6724. /// Emit a helper variable and return corresponding lvalue.
  6725. static void mapParam(CodeGenFunction &CGF, const DeclRefExpr *Helper,
  6726. const ImplicitParamDecl *PVD,
  6727. CodeGenFunction::OMPPrivateScope &Privates) {
  6728. const auto *VDecl = cast<VarDecl>(Helper->getDecl());
  6729. Privates.addPrivate(VDecl,
  6730. [&CGF, PVD]() { return CGF.GetAddrOfLocalVar(PVD); });
  6731. }
  6732. void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {
  6733. assert(isOpenMPTaskLoopDirective(S.getDirectiveKind()));
  6734. // Emit outlined function for task construct.
  6735. const CapturedStmt *CS = S.getCapturedStmt(OMPD_taskloop);
  6736. Address CapturedStruct = Address::invalid();
  6737. {
  6738. OMPLexicalScope Scope(*this, S, OMPD_taskloop, /*EmitPreInitStmt=*/false);
  6739. CapturedStruct = GenerateCapturedStmtArgument(*CS);
  6740. }
  6741. QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
  6742. const Expr *IfCond = nullptr;
  6743. for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
  6744. if (C->getNameModifier() == OMPD_unknown ||
  6745. C->getNameModifier() == OMPD_taskloop) {
  6746. IfCond = C->getCondition();
  6747. break;
  6748. }
  6749. }
  6750. OMPTaskDataTy Data;
  6751. // Check if taskloop must be emitted without taskgroup.
  6752. Data.Nogroup = S.getSingleClause<OMPNogroupClause>();
  6753. // TODO: Check if we should emit tied or untied task.
  6754. Data.Tied = true;
  6755. // Set scheduling for taskloop
  6756. if (const auto *Clause = S.getSingleClause<OMPGrainsizeClause>()) {
  6757. // grainsize clause
  6758. Data.Schedule.setInt(/*IntVal=*/false);
  6759. Data.Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize()));
  6760. } else if (const auto *Clause = S.getSingleClause<OMPNumTasksClause>()) {
  6761. // num_tasks clause
  6762. Data.Schedule.setInt(/*IntVal=*/true);
  6763. Data.Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks()));
  6764. }
  6765. auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) {
  6766. // if (PreCond) {
  6767. // for (IV in 0..LastIteration) BODY;
  6768. // <Final counter/linear vars updates>;
  6769. // }
  6770. //
  6771. // Emit: if (PreCond) - begin.
  6772. // If the condition constant folds and can be elided, avoid emitting the
  6773. // whole loop.
  6774. bool CondConstant;
  6775. llvm::BasicBlock *ContBlock = nullptr;
  6776. OMPLoopScope PreInitScope(CGF, S);
  6777. if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
  6778. if (!CondConstant)
  6779. return;
  6780. } else {
  6781. llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("taskloop.if.then");
  6782. ContBlock = CGF.createBasicBlock("taskloop.if.end");
  6783. emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
  6784. CGF.getProfileCount(&S));
  6785. CGF.EmitBlock(ThenBlock);
  6786. CGF.incrementProfileCounter(&S);
  6787. }
  6788. (void)CGF.EmitOMPLinearClauseInit(S);
  6789. OMPPrivateScope LoopScope(CGF);
  6790. // Emit helper vars inits.
  6791. enum { LowerBound = 5, UpperBound, Stride, LastIter };
  6792. auto *I = CS->getCapturedDecl()->param_begin();
  6793. auto *LBP = std::next(I, LowerBound);
  6794. auto *UBP = std::next(I, UpperBound);
  6795. auto *STP = std::next(I, Stride);
  6796. auto *LIP = std::next(I, LastIter);
  6797. mapParam(CGF, cast<DeclRefExpr>(S.getLowerBoundVariable()), *LBP,
  6798. LoopScope);
  6799. mapParam(CGF, cast<DeclRefExpr>(S.getUpperBoundVariable()), *UBP,
  6800. LoopScope);
  6801. mapParam(CGF, cast<DeclRefExpr>(S.getStrideVariable()), *STP, LoopScope);
  6802. mapParam(CGF, cast<DeclRefExpr>(S.getIsLastIterVariable()), *LIP,
  6803. LoopScope);
  6804. CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
  6805. CGF.EmitOMPLinearClause(S, LoopScope);
  6806. bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
  6807. (void)LoopScope.Privatize();
  6808. // Emit the loop iteration variable.
  6809. const Expr *IVExpr = S.getIterationVariable();
  6810. const auto *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
  6811. CGF.EmitVarDecl(*IVDecl);
  6812. CGF.EmitIgnoredExpr(S.getInit());
  6813. // Emit the iterations count variable.
  6814. // If it is not a variable, Sema decided to calculate iterations count on
  6815. // each iteration (e.g., it is foldable into a constant).
  6816. if (const auto *LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
  6817. CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
  6818. // Emit calculation of the iterations count.
  6819. CGF.EmitIgnoredExpr(S.getCalcLastIteration());
  6820. }
  6821. {
  6822. OMPLexicalScope Scope(CGF, S, OMPD_taskloop, /*EmitPreInitStmt=*/false);
  6823. emitCommonSimdLoop(
  6824. CGF, S,
  6825. [&S](CodeGenFunction &CGF, PrePostActionTy &) {
  6826. if (isOpenMPSimdDirective(S.getDirectiveKind()))
  6827. CGF.EmitOMPSimdInit(S);
  6828. },
  6829. [&S, &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) {
  6830. CGF.EmitOMPInnerLoop(
  6831. S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),
  6832. [&S](CodeGenFunction &CGF) {
  6833. emitOMPLoopBodyWithStopPoint(CGF, S,
  6834. CodeGenFunction::JumpDest());
  6835. },
  6836. [](CodeGenFunction &) {});
  6837. });
  6838. }
  6839. // Emit: if (PreCond) - end.
  6840. if (ContBlock) {
  6841. CGF.EmitBranch(ContBlock);
  6842. CGF.EmitBlock(ContBlock, true);
  6843. }
  6844. // Emit final copy of the lastprivate variables if IsLastIter != 0.
  6845. if (HasLastprivateClause) {
  6846. CGF.EmitOMPLastprivateClauseFinal(
  6847. S, isOpenMPSimdDirective(S.getDirectiveKind()),
  6848. CGF.Builder.CreateIsNotNull(CGF.EmitLoadOfScalar(
  6849. CGF.GetAddrOfLocalVar(*LIP), /*Volatile=*/false,
  6850. (*LIP)->getType(), S.getBeginLoc())));
  6851. }
  6852. CGF.EmitOMPLinearClauseFinal(S, [LIP, &S](CodeGenFunction &CGF) {
  6853. return CGF.Builder.CreateIsNotNull(
  6854. CGF.EmitLoadOfScalar(CGF.GetAddrOfLocalVar(*LIP), /*Volatile=*/false,
  6855. (*LIP)->getType(), S.getBeginLoc()));
  6856. });
  6857. };
  6858. auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
  6859. IfCond](CodeGenFunction &CGF, llvm::Function *OutlinedFn,
  6860. const OMPTaskDataTy &Data) {
  6861. auto &&CodeGen = [&S, OutlinedFn, SharedsTy, CapturedStruct, IfCond,
  6862. &Data](CodeGenFunction &CGF, PrePostActionTy &) {
  6863. OMPLoopScope PreInitScope(CGF, S);
  6864. CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.getBeginLoc(), S,
  6865. OutlinedFn, SharedsTy,
  6866. CapturedStruct, IfCond, Data);
  6867. };
  6868. CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop,
  6869. CodeGen);
  6870. };
  6871. if (Data.Nogroup) {
  6872. EmitOMPTaskBasedDirective(S, OMPD_taskloop, BodyGen, TaskGen, Data);
  6873. } else {
  6874. CGM.getOpenMPRuntime().emitTaskgroupRegion(
  6875. *this,
  6876. [&S, &BodyGen, &TaskGen, &Data](CodeGenFunction &CGF,
  6877. PrePostActionTy &Action) {
  6878. Action.Enter(CGF);
  6879. CGF.EmitOMPTaskBasedDirective(S, OMPD_taskloop, BodyGen, TaskGen,
  6880. Data);
  6881. },
  6882. S.getBeginLoc());
  6883. }
  6884. }
  6885. void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) {
  6886. auto LPCRegion =
  6887. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  6888. EmitOMPTaskLoopBasedDirective(S);
  6889. }
  6890. void CodeGenFunction::EmitOMPTaskLoopSimdDirective(
  6891. const OMPTaskLoopSimdDirective &S) {
  6892. auto LPCRegion =
  6893. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  6894. OMPLexicalScope Scope(*this, S);
  6895. EmitOMPTaskLoopBasedDirective(S);
  6896. }
  6897. void CodeGenFunction::EmitOMPMasterTaskLoopDirective(
  6898. const OMPMasterTaskLoopDirective &S) {
  6899. auto &&CodeGen = [this, &S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6900. Action.Enter(CGF);
  6901. EmitOMPTaskLoopBasedDirective(S);
  6902. };
  6903. auto LPCRegion =
  6904. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  6905. OMPLexicalScope Scope(*this, S, llvm::None, /*EmitPreInitStmt=*/false);
  6906. CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getBeginLoc());
  6907. }
  6908. void CodeGenFunction::EmitOMPMasterTaskLoopSimdDirective(
  6909. const OMPMasterTaskLoopSimdDirective &S) {
  6910. auto &&CodeGen = [this, &S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6911. Action.Enter(CGF);
  6912. EmitOMPTaskLoopBasedDirective(S);
  6913. };
  6914. auto LPCRegion =
  6915. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  6916. OMPLexicalScope Scope(*this, S);
  6917. CGM.getOpenMPRuntime().emitMasterRegion(*this, CodeGen, S.getBeginLoc());
  6918. }
  6919. void CodeGenFunction::EmitOMPParallelMasterTaskLoopDirective(
  6920. const OMPParallelMasterTaskLoopDirective &S) {
  6921. auto &&CodeGen = [this, &S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6922. auto &&TaskLoopCodeGen = [&S](CodeGenFunction &CGF,
  6923. PrePostActionTy &Action) {
  6924. Action.Enter(CGF);
  6925. CGF.EmitOMPTaskLoopBasedDirective(S);
  6926. };
  6927. OMPLexicalScope Scope(CGF, S, OMPD_parallel, /*EmitPreInitStmt=*/false);
  6928. CGM.getOpenMPRuntime().emitMasterRegion(CGF, TaskLoopCodeGen,
  6929. S.getBeginLoc());
  6930. };
  6931. auto LPCRegion =
  6932. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  6933. emitCommonOMPParallelDirective(*this, S, OMPD_master_taskloop, CodeGen,
  6934. emitEmptyBoundParameters);
  6935. }
  6936. void CodeGenFunction::EmitOMPParallelMasterTaskLoopSimdDirective(
  6937. const OMPParallelMasterTaskLoopSimdDirective &S) {
  6938. auto &&CodeGen = [this, &S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6939. auto &&TaskLoopCodeGen = [&S](CodeGenFunction &CGF,
  6940. PrePostActionTy &Action) {
  6941. Action.Enter(CGF);
  6942. CGF.EmitOMPTaskLoopBasedDirective(S);
  6943. };
  6944. OMPLexicalScope Scope(CGF, S, OMPD_parallel, /*EmitPreInitStmt=*/false);
  6945. CGM.getOpenMPRuntime().emitMasterRegion(CGF, TaskLoopCodeGen,
  6946. S.getBeginLoc());
  6947. };
  6948. auto LPCRegion =
  6949. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, S);
  6950. emitCommonOMPParallelDirective(*this, S, OMPD_master_taskloop_simd, CodeGen,
  6951. emitEmptyBoundParameters);
  6952. }
  6953. // Generate the instructions for '#pragma omp target update' directive.
  6954. void CodeGenFunction::EmitOMPTargetUpdateDirective(
  6955. const OMPTargetUpdateDirective &S) {
  6956. // If we don't have target devices, don't bother emitting the data mapping
  6957. // code.
  6958. if (CGM.getLangOpts().OMPTargetTriples.empty())
  6959. return;
  6960. // Check if we have any if clause associated with the directive.
  6961. const Expr *IfCond = nullptr;
  6962. if (const auto *C = S.getSingleClause<OMPIfClause>())
  6963. IfCond = C->getCondition();
  6964. // Check if we have any device clause associated with the directive.
  6965. const Expr *Device = nullptr;
  6966. if (const auto *C = S.getSingleClause<OMPDeviceClause>())
  6967. Device = C->getDevice();
  6968. OMPLexicalScope Scope(*this, S, OMPD_task);
  6969. CGM.getOpenMPRuntime().emitTargetDataStandAloneCall(*this, S, IfCond, Device);
  6970. }
  6971. void CodeGenFunction::EmitOMPGenericLoopDirective(
  6972. const OMPGenericLoopDirective &S) {
  6973. // Unimplemented, just inline the underlying statement for now.
  6974. auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6975. CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
  6976. };
  6977. OMPLexicalScope Scope(*this, S, OMPD_unknown);
  6978. CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_loop, CodeGen);
  6979. }
  6980. void CodeGenFunction::EmitSimpleOMPExecutableDirective(
  6981. const OMPExecutableDirective &D) {
  6982. if (const auto *SD = dyn_cast<OMPScanDirective>(&D)) {
  6983. EmitOMPScanDirective(*SD);
  6984. return;
  6985. }
  6986. if (!D.hasAssociatedStmt() || !D.getAssociatedStmt())
  6987. return;
  6988. auto &&CodeGen = [&D](CodeGenFunction &CGF, PrePostActionTy &Action) {
  6989. OMPPrivateScope GlobalsScope(CGF);
  6990. if (isOpenMPTaskingDirective(D.getDirectiveKind())) {
  6991. // Capture global firstprivates to avoid crash.
  6992. for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) {
  6993. for (const Expr *Ref : C->varlists()) {
  6994. const auto *DRE = cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
  6995. if (!DRE)
  6996. continue;
  6997. const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
  6998. if (!VD || VD->hasLocalStorage())
  6999. continue;
  7000. if (!CGF.LocalDeclMap.count(VD)) {
  7001. LValue GlobLVal = CGF.EmitLValue(Ref);
  7002. GlobalsScope.addPrivate(
  7003. VD, [&GlobLVal, &CGF]() { return GlobLVal.getAddress(CGF); });
  7004. }
  7005. }
  7006. }
  7007. }
  7008. if (isOpenMPSimdDirective(D.getDirectiveKind())) {
  7009. (void)GlobalsScope.Privatize();
  7010. ParentLoopDirectiveForScanRegion ScanRegion(CGF, D);
  7011. emitOMPSimdRegion(CGF, cast<OMPLoopDirective>(D), Action);
  7012. } else {
  7013. if (const auto *LD = dyn_cast<OMPLoopDirective>(&D)) {
  7014. for (const Expr *E : LD->counters()) {
  7015. const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
  7016. if (!VD->hasLocalStorage() && !CGF.LocalDeclMap.count(VD)) {
  7017. LValue GlobLVal = CGF.EmitLValue(E);
  7018. GlobalsScope.addPrivate(
  7019. VD, [&GlobLVal, &CGF]() { return GlobLVal.getAddress(CGF); });
  7020. }
  7021. if (isa<OMPCapturedExprDecl>(VD)) {
  7022. // Emit only those that were not explicitly referenced in clauses.
  7023. if (!CGF.LocalDeclMap.count(VD))
  7024. CGF.EmitVarDecl(*VD);
  7025. }
  7026. }
  7027. for (const auto *C : D.getClausesOfKind<OMPOrderedClause>()) {
  7028. if (!C->getNumForLoops())
  7029. continue;
  7030. for (unsigned I = LD->getLoopsNumber(),
  7031. E = C->getLoopNumIterations().size();
  7032. I < E; ++I) {
  7033. if (const auto *VD = dyn_cast<OMPCapturedExprDecl>(
  7034. cast<DeclRefExpr>(C->getLoopCounter(I))->getDecl())) {
  7035. // Emit only those that were not explicitly referenced in clauses.
  7036. if (!CGF.LocalDeclMap.count(VD))
  7037. CGF.EmitVarDecl(*VD);
  7038. }
  7039. }
  7040. }
  7041. }
  7042. (void)GlobalsScope.Privatize();
  7043. CGF.EmitStmt(D.getInnermostCapturedStmt()->getCapturedStmt());
  7044. }
  7045. };
  7046. if (D.getDirectiveKind() == OMPD_atomic ||
  7047. D.getDirectiveKind() == OMPD_critical ||
  7048. D.getDirectiveKind() == OMPD_section ||
  7049. D.getDirectiveKind() == OMPD_master ||
  7050. D.getDirectiveKind() == OMPD_masked) {
  7051. EmitStmt(D.getAssociatedStmt());
  7052. } else {
  7053. auto LPCRegion =
  7054. CGOpenMPRuntime::LastprivateConditionalRAII::disable(*this, D);
  7055. OMPSimdLexicalScope Scope(*this, D);
  7056. CGM.getOpenMPRuntime().emitInlinedDirective(
  7057. *this,
  7058. isOpenMPSimdDirective(D.getDirectiveKind()) ? OMPD_simd
  7059. : D.getDirectiveKind(),
  7060. CodeGen);
  7061. }
  7062. // Check for outer lastprivate conditional update.
  7063. checkForLastprivateConditionalUpdate(*this, D);
  7064. }